[{"data":1,"prerenderedAt":3939},["ShallowReactive",2],{"navigation_docs":3,"-learn-catalogs":525,"-learn-catalogs-surround":3934},[4,30,80,128,308,440,495],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"CLI","\u002Fcli","3.cli",[85,88,93,98,103,108,113,118,123],{"title":36,"path":86,"stem":87,"icon":44},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":89,"path":90,"stem":91,"icon":92},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":94,"path":95,"stem":96,"icon":97},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":99,"path":100,"stem":101,"icon":102},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":104,"path":105,"stem":106,"icon":107},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":109,"path":110,"stem":111,"icon":112},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":114,"path":115,"stem":116,"icon":117},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":119,"path":120,"stem":121,"icon":122},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":124,"path":125,"stem":126,"icon":127},"agents","\u002Fcli\u002Fagents","3.cli\u002F8.agents","i-lucide-bot",{"title":129,"path":130,"stem":131,"children":132,"page":29},"Integrate","\u002Fintegrate","4.integrate",[133,137,220],{"title":36,"path":134,"stem":135,"icon":136},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[142,145,175,200],{"title":36,"path":143,"stem":144,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":146,"path":147,"stem":148,"children":149,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[150,155,160,165,170],{"title":151,"path":152,"stem":153,"icon":154},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F02.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F03.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F04.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F05.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"children":179,"page":29},"Cloud or Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fhybrid","4.integrate\u002Fadapters\u002Fhybrid",[180,185,190,195],{"title":181,"path":182,"stem":183,"icon":184},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Floki","4.integrate\u002Fadapters\u002Fhybrid\u002F01.loki","i-simple-icons-grafana",{"title":186,"path":187,"stem":188,"icon":189},"ClickHouse","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse","4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse","i-simple-icons-clickhouse",{"title":191,"path":192,"stem":193,"icon":194},"OTLP","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fotlp","4.integrate\u002Fadapters\u002Fhybrid\u002F03.otlp","i-simple-icons-opentelemetry",{"title":196,"path":197,"stem":198,"icon":199},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fhyperdx","4.integrate\u002Fadapters\u002Fhybrid\u002F04.hyperdx","i-custom-hyperdx",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[205,210,215],{"title":206,"path":207,"stem":208,"icon":209},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":211,"path":212,"stem":213,"icon":214},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":216,"path":217,"stem":218,"icon":219},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":221,"path":222,"stem":223,"children":224,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[225,229,234,239,244,249,254,259,264,269,274,279,284,289,293,298,303],{"title":36,"path":226,"stem":227,"icon":228},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":230,"path":231,"stem":232,"icon":233},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":235,"path":236,"stem":237,"icon":238},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":240,"path":241,"stem":242,"icon":243},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":245,"path":246,"stem":247,"icon":248},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":250,"path":251,"stem":252,"icon":253},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":255,"path":256,"stem":257,"icon":258},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":260,"path":261,"stem":262,"icon":263},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":265,"path":266,"stem":267,"icon":268},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":270,"path":271,"stem":272,"icon":273},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":275,"path":276,"stem":277,"icon":278},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":280,"path":281,"stem":282,"icon":283},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":285,"path":286,"stem":287,"icon":288},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":290,"path":291,"stem":292,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":294,"path":295,"stem":296,"icon":297},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":299,"path":300,"stem":301,"icon":302},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":304,"path":305,"stem":306,"icon":307},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":309,"path":310,"stem":311,"children":312,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[313,316,321,350,377,409,430,435],{"title":36,"path":314,"stem":315,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":317,"path":318,"stem":319,"icon":320},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":322,"icon":323,"path":324,"stem":325,"children":326,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[327,330,335,340,345],{"title":36,"path":328,"stem":329,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":331,"path":332,"stem":333,"icon":334},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":336,"path":337,"stem":338,"icon":339},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":341,"path":342,"stem":343,"icon":344},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":346,"path":347,"stem":348,"icon":349},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":351,"icon":352,"path":353,"stem":354,"children":355,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[356,359,364,369,373],{"title":36,"path":357,"stem":358,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":360,"path":361,"stem":362,"icon":363},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":365,"path":366,"stem":367,"icon":368},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":370,"path":371,"stem":372,"icon":320},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":374,"path":375,"stem":376,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[383,386,391,396,401,405],{"title":36,"path":384,"stem":385,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":387,"path":388,"stem":389,"icon":390},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":392,"path":393,"stem":394,"icon":395},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":397,"path":398,"stem":399,"icon":400},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":402,"path":403,"stem":404,"icon":379},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":406,"path":407,"stem":408,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":346,"icon":107,"path":410,"stem":411,"children":412,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[413,416,421,426],{"title":36,"path":414,"stem":415,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":417,"path":418,"stem":419,"icon":420},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":422,"path":423,"stem":424,"icon":425},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":427,"path":428,"stem":429,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":431,"path":432,"stem":433,"icon":434},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":436,"path":437,"stem":438,"icon":439},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":441,"path":442,"stem":443,"children":444,"page":29},"Extend","\u002Fextend","6.extend",[445,449,454,459,464,468,472,476,480,485,490],{"title":36,"path":446,"stem":447,"icon":448},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":450,"path":451,"stem":452,"icon":453},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":455,"path":456,"stem":457,"icon":458},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":460,"path":461,"stem":462,"icon":463},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":406,"path":465,"stem":466,"icon":467},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":469,"path":470,"stem":471,"icon":448},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":473,"path":474,"stem":475,"icon":434},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":477,"path":478,"stem":479,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":481,"path":482,"stem":483,"icon":484},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":486,"path":487,"stem":488,"icon":489},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":491,"path":492,"stem":493,"icon":494},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":427,"path":496,"stem":497,"children":498,"page":29},"\u002Freference","7.reference",[499,504,507,512,516,521],{"title":500,"path":501,"stem":502,"icon":503},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":374,"path":505,"stem":506,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":508,"path":509,"stem":510,"icon":511},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":513,"path":514,"stem":515,"icon":379},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":517,"path":518,"stem":519,"icon":520},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":522,"path":523,"stem":524,"icon":434},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":526,"title":76,"body":527,"description":3924,"extension":3925,"links":3926,"meta":3930,"navigation":3931,"path":77,"seo":3932,"stem":78,"__hash__":3933},"docs\u002F2.learn\u002F8.catalogs.md",{"type":528,"value":529,"toc":3897},"minimark",[530,549,700,713,718,721,824,830,834,837,842,853,1253,1257,1271,1279,1492,1502,1506,1518,1524,1704,1714,1718,1728,1734,1738,1744,1750,2001,2005,2295,2308,2312,2384,2441,2590,2611,2615,2619,2629,2857,2861,2864,2909,3031,3035,3059,3196,3200,3219,3223,3282,3288,3292,3295,3341,3424,3433,3437,3557,3564,3568,3584,3597,3613,3690,3694,3850,3856,3860,3893],[531,532,533,534,538,539,538,542,538,545,548],"p",{},"The catalog primitives (",[535,536,537],"code",{},"defineError",", ",[535,540,541],{},"defineErrorCatalog",[535,543,544],{},"defineAuditAction",[535,546,547],{},"defineAuditCatalog",") are the same regardless of project size. What changes is how you organise them. This page is the deep-dive: conventions, scaling recipes from one file to a published npm package, composition patterns, and the opt-in type augmentation.",[550,551,554,560,691],"prompt",{":actions":552,"description":553,"icon":79},"[\"copy\",\"cursor\",\"claude\"]","Set up typed error and audit catalogs in my app",[531,555,556,557,559],{},"Group errors and audit actions in typed catalogs to eliminate magic strings, get autocomplete on ",[535,558,535],{}," everywhere, and ship them as npm packages in a monorepo.",[561,562,563,575,585,599,608,618,625,632,650,657,671,681],"ul",{},[564,565,566,567,570,571,574],"li",{},"Use ",[535,568,569],{},"defineErrorCatalog(prefix, map)"," for error bundles, ",[535,572,573],{},"defineAuditCatalog(prefix, map)"," for audit bundles",[564,576,566,577,580,581,584],{},[535,578,579],{},"defineError(code, options)"," and ",[535,582,583],{},"defineAuditAction(action, opts?)"," for one-off factories that don't fit a catalog",[564,586,587,588,591,592,538,595,598],{},"Convention: UPPER_SNAKE_CASE keys, lower.dot.case prefix, wire format is ",[535,589,590],{},"${prefix}.${KEY}"," (e.g. ",[535,593,594],{},"billing.PAYMENT_DECLINED",[535,596,597],{},"billing.INVOICE_REFUND",")",[564,600,601,602,538,605,598],{},"One catalog = one bounded context = one prefix = one file (e.g. ",[535,603,604],{},"errors\u002Fbilling.ts",[535,606,607],{},"audit\u002Fbilling.ts",[564,609,610,611,614,615],{},"Throw with ",[535,612,613],{},"billingErrors.PAYMENT_DECLINED({ cause, internal })",", audit with ",[535,616,617],{},"log.audit(billingAudit.INVOICE_REFUND({ actor, target }))",[564,619,620,621,624],{},"Use templated messages (",[535,622,623],{},"message: ({ id }) => \\","User ${id} not found``) when params are dynamic and required",[564,626,627,628,631],{},"Catalog defaults for ",[535,629,630],{},"internal"," are shallow-merged with call-site values (call-site wins)",[564,633,634,635,638,639,538,642,645,646,649],{},"Add the opt-in ",[535,636,637],{},"declare module 'evlog' { interface RegisteredErrorCatalogs { billing: typeof billingErrors } }"," augmentation to surface autocomplete on ",[535,640,641],{},"createError({ code })",[535,643,644],{},"parseError(err).code",", and ",[535,647,648],{},"throwError(code)"," everywhere",[564,651,652,653,656],{},"Scale by sharding: single file → folder per domain → sub-prefixes (",[535,654,655],{},"billing.payment",") → one npm package per bounded context (each owns its prefix, no conflicts possible)",[564,658,659,660,663,664,667,668],{},"Each shared package ships its own ",[535,661,662],{},"declare module 'evlog'"," block in ",[535,665,666],{},"src\u002Findex.ts"," so the type augmentation propagates to consumers via the published ",[535,669,670],{},".d.ts",[564,672,673,674,677,678],{},"Compare on ",[535,675,676],{},"factory.code"," in tests instead of string literals so renames are TS errors, not silent breaks: ",[535,679,680],{},"expect(err.code).toBe(billingErrors.PAYMENT_DECLINED.code)",[564,682,683,684,686,687,690],{},"Never override ",[535,685,535],{}," at the call site (the catalog defines the code identity); never put ",[535,688,689],{},"declare module"," blocks in test files (they leak into the main type-checker)",[531,692,693,694],{},"Docs: ",[695,696,697],"a",{"href":697,"rel":698},"https:\u002F\u002Fwww.evlog.dev\u002Flearn\u002Fcatalogs",[699],"nofollow",[701,702,703,704,580,708,712],"tip",{},"If you haven't yet, start with ",[695,705,707],{"href":706},"\u002Flearn\u002Fstructured-errors#error-catalogs","Structured Errors → Error Catalogs",[695,709,711],{"href":710},"\u002Fuse-cases\u002Faudit\u002Frecording#defineauditcatalog","Audit → defineAuditCatalog"," for the basics. This page assumes you've used the primitives at least once.",[714,715,717],"h2",{"id":716},"conventions","Conventions",[531,719,720],{},"A single set of conventions covers both error and audit catalogs.",[722,723,724,739],"table",{},[725,726,727],"thead",{},[728,729,730,733,736],"tr",{},[731,732],"th",{},[731,734,735],{},"Convention",[731,737,738],{},"Example",[740,741,742,765,789,808],"tbody",{},[728,743,744,751,757],{},[745,746,747],"td",{},[748,749,750],"strong",{},"Catalog key",[745,752,753,756],{},[535,754,755],{},"UPPER_SNAKE_CASE"," (enum-style, scales to hundreds of entries)",[745,758,759,538,762],{},[535,760,761],{},"PAYMENT_DECLINED",[535,763,764],{},"INVOICE_REFUND",[728,766,767,772,778],{},[745,768,769],{},[748,770,771],{},"Prefix",[745,773,774,777],{},[535,775,776],{},"lower.dot.case",", can be hierarchical",[745,779,780,538,783,538,786],{},[535,781,782],{},"'billing'",[535,784,785],{},"'billing.payment'",[535,787,788],{},"'auth.session'",[728,790,791,796,801],{},[745,792,793],{},[748,794,795],{},"Wire format",[745,797,798,800],{},[535,799,590],{}," (preserved casing)",[745,802,803,538,805],{},[535,804,594],{},[535,806,807],{},"auth.INVALID_TOKEN",[728,809,810,815,818],{},[745,811,812],{},[748,813,814],{},"One catalog =",[745,816,817],{},"One bounded context, one prefix, one file",[745,819,820,538,822],{},[535,821,604],{},[535,823,607],{},[531,825,826,827,829],{},"The wire format ends up in HTTP responses, wide events, drains, and dashboards. Stick to it across services so a ",[535,828,535],{}," from one service is recognisable in another.",[714,831,833],{"id":832},"scaling-story","Scaling story",[531,835,836],{},"The same primitives cover four scales without API change.",[838,839,841],"h3",{"id":840},"_1-file-small-repo","1 file — small repo",[531,843,844,845,848,849,852],{},"One ",[535,846,847],{},"errors.ts",", one ",[535,850,851],{},"audit.ts",". Done.",[854,855,856,1102],"code-group",{},[857,858,864],"pre",{"className":859,"code":860,"filename":861,"language":862,"meta":863,"style":863},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineErrorCatalog } from 'evlog'\n\nexport const errors = defineErrorCatalog('app', {\n  USER_NOT_FOUND: { status: 404, message: 'User not found' },\n  FORBIDDEN: { status: 403, message: 'Forbidden' },\n  VALIDATION_FAILED: {\n    status: 400,\n    message: ({ field }: { field: string }) => `Invalid ${field}`,\n  },\n})\n","src\u002Ferrors.ts","typescript","",[535,865,866,899,906,942,980,1012,1022,1036,1087,1093],{"__ignoreMap":863},[867,868,871,875,879,883,886,889,892,896],"span",{"class":869,"line":870},"line",1,[867,872,874],{"class":873},"s7zQu","import",[867,876,878],{"class":877},"sMK4o"," {",[867,880,882],{"class":881},"sTEyZ"," defineErrorCatalog",[867,884,885],{"class":877}," }",[867,887,888],{"class":873}," from",[867,890,891],{"class":877}," '",[867,893,895],{"class":894},"sfazB","evlog",[867,897,898],{"class":877},"'\n",[867,900,902],{"class":869,"line":901},2,[867,903,905],{"emptyLinePlaceholder":904},true,"\n",[867,907,909,912,916,919,922,925,928,931,934,936,939],{"class":869,"line":908},3,[867,910,911],{"class":873},"export",[867,913,915],{"class":914},"spNyl"," const",[867,917,918],{"class":881}," errors ",[867,920,921],{"class":877},"=",[867,923,882],{"class":924},"s2Zo4",[867,926,927],{"class":881},"(",[867,929,930],{"class":877},"'",[867,932,933],{"class":894},"app",[867,935,930],{"class":877},[867,937,938],{"class":877},",",[867,940,941],{"class":877}," {\n",[867,943,945,949,952,954,957,959,963,965,968,970,972,975,977],{"class":869,"line":944},4,[867,946,948],{"class":947},"swJcz","  USER_NOT_FOUND",[867,950,951],{"class":877},":",[867,953,878],{"class":877},[867,955,956],{"class":947}," status",[867,958,951],{"class":877},[867,960,962],{"class":961},"sbssI"," 404",[867,964,938],{"class":877},[867,966,967],{"class":947}," message",[867,969,951],{"class":877},[867,971,891],{"class":877},[867,973,974],{"class":894},"User not found",[867,976,930],{"class":877},[867,978,979],{"class":877}," },\n",[867,981,983,986,988,990,992,994,997,999,1001,1003,1005,1008,1010],{"class":869,"line":982},5,[867,984,985],{"class":947},"  FORBIDDEN",[867,987,951],{"class":877},[867,989,878],{"class":877},[867,991,956],{"class":947},[867,993,951],{"class":877},[867,995,996],{"class":961}," 403",[867,998,938],{"class":877},[867,1000,967],{"class":947},[867,1002,951],{"class":877},[867,1004,891],{"class":877},[867,1006,1007],{"class":894},"Forbidden",[867,1009,930],{"class":877},[867,1011,979],{"class":877},[867,1013,1015,1018,1020],{"class":869,"line":1014},6,[867,1016,1017],{"class":947},"  VALIDATION_FAILED",[867,1019,951],{"class":877},[867,1021,941],{"class":877},[867,1023,1025,1028,1030,1033],{"class":869,"line":1024},7,[867,1026,1027],{"class":947},"    status",[867,1029,951],{"class":877},[867,1031,1032],{"class":961}," 400",[867,1034,1035],{"class":877},",\n",[867,1037,1039,1042,1044,1047,1051,1054,1056,1058,1060,1064,1067,1070,1073,1076,1079,1082,1085],{"class":869,"line":1038},8,[867,1040,1041],{"class":924},"    message",[867,1043,951],{"class":877},[867,1045,1046],{"class":877}," ({",[867,1048,1050],{"class":1049},"sHdIc"," field",[867,1052,1053],{"class":877}," }:",[867,1055,878],{"class":877},[867,1057,1050],{"class":947},[867,1059,951],{"class":877},[867,1061,1063],{"class":1062},"sBMFI"," string",[867,1065,1066],{"class":877}," })",[867,1068,1069],{"class":914}," =>",[867,1071,1072],{"class":877}," `",[867,1074,1075],{"class":894},"Invalid ",[867,1077,1078],{"class":877},"${",[867,1080,1081],{"class":881},"field",[867,1083,1084],{"class":877},"}`",[867,1086,1035],{"class":877},[867,1088,1090],{"class":869,"line":1089},9,[867,1091,1092],{"class":877},"  },\n",[867,1094,1096,1099],{"class":869,"line":1095},10,[867,1097,1098],{"class":877},"}",[867,1100,1101],{"class":881},")\n",[857,1103,1106],{"className":859,"code":1104,"filename":1105,"language":862,"meta":863,"style":863},"import { defineAuditCatalog } from 'evlog'\n\nexport const audit = defineAuditCatalog('app', {\n  USER_LOGIN: { target: 'user', severity: 'medium' },\n  USER_DELETE: { target: 'user', severity: 'high', requiresChanges: true, requiresReason: true },\n})\n","src\u002Faudit.ts",[535,1107,1108,1127,1131,1156,1193,1247],{"__ignoreMap":863},[867,1109,1110,1112,1114,1117,1119,1121,1123,1125],{"class":869,"line":870},[867,1111,874],{"class":873},[867,1113,878],{"class":877},[867,1115,1116],{"class":881}," defineAuditCatalog",[867,1118,885],{"class":877},[867,1120,888],{"class":873},[867,1122,891],{"class":877},[867,1124,895],{"class":894},[867,1126,898],{"class":877},[867,1128,1129],{"class":869,"line":901},[867,1130,905],{"emptyLinePlaceholder":904},[867,1132,1133,1135,1137,1140,1142,1144,1146,1148,1150,1152,1154],{"class":869,"line":908},[867,1134,911],{"class":873},[867,1136,915],{"class":914},[867,1138,1139],{"class":881}," audit ",[867,1141,921],{"class":877},[867,1143,1116],{"class":924},[867,1145,927],{"class":881},[867,1147,930],{"class":877},[867,1149,933],{"class":894},[867,1151,930],{"class":877},[867,1153,938],{"class":877},[867,1155,941],{"class":877},[867,1157,1158,1161,1163,1165,1168,1170,1172,1175,1177,1179,1182,1184,1186,1189,1191],{"class":869,"line":944},[867,1159,1160],{"class":947},"  USER_LOGIN",[867,1162,951],{"class":877},[867,1164,878],{"class":877},[867,1166,1167],{"class":947}," target",[867,1169,951],{"class":877},[867,1171,891],{"class":877},[867,1173,1174],{"class":894},"user",[867,1176,930],{"class":877},[867,1178,938],{"class":877},[867,1180,1181],{"class":947}," severity",[867,1183,951],{"class":877},[867,1185,891],{"class":877},[867,1187,1188],{"class":894},"medium",[867,1190,930],{"class":877},[867,1192,979],{"class":877},[867,1194,1195,1198,1200,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220,1223,1225,1227,1230,1232,1236,1238,1241,1243,1245],{"class":869,"line":982},[867,1196,1197],{"class":947},"  USER_DELETE",[867,1199,951],{"class":877},[867,1201,878],{"class":877},[867,1203,1167],{"class":947},[867,1205,951],{"class":877},[867,1207,891],{"class":877},[867,1209,1174],{"class":894},[867,1211,930],{"class":877},[867,1213,938],{"class":877},[867,1215,1181],{"class":947},[867,1217,951],{"class":877},[867,1219,891],{"class":877},[867,1221,1222],{"class":894},"high",[867,1224,930],{"class":877},[867,1226,938],{"class":877},[867,1228,1229],{"class":947}," requiresChanges",[867,1231,951],{"class":877},[867,1233,1235],{"class":1234},"sfNiH"," true",[867,1237,938],{"class":877},[867,1239,1240],{"class":947}," requiresReason",[867,1242,951],{"class":877},[867,1244,1235],{"class":1234},[867,1246,979],{"class":877},[867,1248,1249,1251],{"class":869,"line":1014},[867,1250,1098],{"class":877},[867,1252,1101],{"class":881},[838,1254,1256],{"id":1255},"_1-folder-1-file-per-domain-medium-repo","1 folder, 1 file per domain — medium repo",[531,1258,1259,1260,580,1263,1266,1267,1270],{},"Group by bounded context. One file per domain in ",[535,1261,1262],{},"src\u002Ferrors\u002F",[535,1264,1265],{},"src\u002Faudit\u002F",". An ",[535,1268,1269],{},"index.ts"," re-exports for ergonomic imports and centralises the type augmentation.",[857,1272,1277],{"className":1273,"code":1275,"language":1276},[1274],"language-text","src\u002F\n├── errors\u002F\n│   ├── billing.ts        → billingErrors (prefix: 'billing')\n│   ├── auth.ts           → authErrors    (prefix: 'auth')\n│   ├── user.ts           → userErrors    (prefix: 'user')\n│   └── index.ts          → re-export + declare module\n├── audit\u002F\n│   ├── billing.ts        → billingAudit\n│   ├── auth.ts           → authAudit\n│   └── index.ts\n","text",[535,1278,1275],{"__ignoreMap":863},[857,1280,1283],{"className":859,"code":1281,"filename":1282,"language":862,"meta":863,"style":863},"import type { authErrors } from '.\u002Fauth'\nimport type { billingErrors } from '.\u002Fbilling'\nimport type { userErrors } from '.\u002Fuser'\n\nexport { authErrors } from '.\u002Fauth'\nexport { billingErrors } from '.\u002Fbilling'\nexport { userErrors } from '.\u002Fuser'\n\ndeclare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    auth: typeof authErrors\n    billing: typeof billingErrors\n    user: typeof userErrors\n  }\n}\n","src\u002Ferrors\u002Findex.ts",[535,1284,1285,1308,1330,1352,1356,1374,1392,1410,1414,1430,1440,1454,1467,1480,1486],{"__ignoreMap":863},[867,1286,1287,1289,1292,1294,1297,1299,1301,1303,1306],{"class":869,"line":870},[867,1288,874],{"class":873},[867,1290,1291],{"class":873}," type",[867,1293,878],{"class":877},[867,1295,1296],{"class":881}," authErrors",[867,1298,885],{"class":877},[867,1300,888],{"class":873},[867,1302,891],{"class":877},[867,1304,1305],{"class":894},".\u002Fauth",[867,1307,898],{"class":877},[867,1309,1310,1312,1314,1316,1319,1321,1323,1325,1328],{"class":869,"line":901},[867,1311,874],{"class":873},[867,1313,1291],{"class":873},[867,1315,878],{"class":877},[867,1317,1318],{"class":881}," billingErrors",[867,1320,885],{"class":877},[867,1322,888],{"class":873},[867,1324,891],{"class":877},[867,1326,1327],{"class":894},".\u002Fbilling",[867,1329,898],{"class":877},[867,1331,1332,1334,1336,1338,1341,1343,1345,1347,1350],{"class":869,"line":908},[867,1333,874],{"class":873},[867,1335,1291],{"class":873},[867,1337,878],{"class":877},[867,1339,1340],{"class":881}," userErrors",[867,1342,885],{"class":877},[867,1344,888],{"class":873},[867,1346,891],{"class":877},[867,1348,1349],{"class":894},".\u002Fuser",[867,1351,898],{"class":877},[867,1353,1354],{"class":869,"line":944},[867,1355,905],{"emptyLinePlaceholder":904},[867,1357,1358,1360,1362,1364,1366,1368,1370,1372],{"class":869,"line":982},[867,1359,911],{"class":873},[867,1361,878],{"class":877},[867,1363,1296],{"class":881},[867,1365,885],{"class":877},[867,1367,888],{"class":873},[867,1369,891],{"class":877},[867,1371,1305],{"class":894},[867,1373,898],{"class":877},[867,1375,1376,1378,1380,1382,1384,1386,1388,1390],{"class":869,"line":1014},[867,1377,911],{"class":873},[867,1379,878],{"class":877},[867,1381,1318],{"class":881},[867,1383,885],{"class":877},[867,1385,888],{"class":873},[867,1387,891],{"class":877},[867,1389,1327],{"class":894},[867,1391,898],{"class":877},[867,1393,1394,1396,1398,1400,1402,1404,1406,1408],{"class":869,"line":1024},[867,1395,911],{"class":873},[867,1397,878],{"class":877},[867,1399,1340],{"class":881},[867,1401,885],{"class":877},[867,1403,888],{"class":873},[867,1405,891],{"class":877},[867,1407,1349],{"class":894},[867,1409,898],{"class":877},[867,1411,1412],{"class":869,"line":1038},[867,1413,905],{"emptyLinePlaceholder":904},[867,1415,1416,1419,1422,1424,1426,1428],{"class":869,"line":1089},[867,1417,1418],{"class":914},"declare",[867,1420,1421],{"class":914}," module",[867,1423,891],{"class":877},[867,1425,895],{"class":894},[867,1427,930],{"class":877},[867,1429,941],{"class":877},[867,1431,1432,1435,1438],{"class":869,"line":1095},[867,1433,1434],{"class":914},"  interface",[867,1436,1437],{"class":1062}," RegisteredErrorCatalogs",[867,1439,941],{"class":877},[867,1441,1443,1446,1448,1451],{"class":869,"line":1442},11,[867,1444,1445],{"class":947},"    auth",[867,1447,951],{"class":877},[867,1449,1450],{"class":877}," typeof",[867,1452,1453],{"class":881}," authErrors\n",[867,1455,1457,1460,1462,1464],{"class":869,"line":1456},12,[867,1458,1459],{"class":947},"    billing",[867,1461,951],{"class":877},[867,1463,1450],{"class":877},[867,1465,1466],{"class":881}," billingErrors\n",[867,1468,1470,1473,1475,1477],{"class":869,"line":1469},13,[867,1471,1472],{"class":947},"    user",[867,1474,951],{"class":877},[867,1476,1450],{"class":877},[867,1478,1479],{"class":881}," userErrors\n",[867,1481,1483],{"class":869,"line":1482},14,[867,1484,1485],{"class":877},"  }\n",[867,1487,1489],{"class":869,"line":1488},15,[867,1490,1491],{"class":877},"}\n",[531,1493,1494,1495,1497,1498,1501],{},"The augmentation is purely type-level: there is no ",[535,1496,89],{}," step, no runtime registration. Importing ",[535,1499,1500],{},"~\u002Ferrors"," once anywhere in your app is enough for TypeScript to pick up the merged type.",[838,1503,1505],{"id":1504},"sub-prefixes-very-large-repo","Sub-prefixes — very large repo",[531,1507,1508,1509,538,1511,538,1514,1517],{},"Hierarchical prefixes (",[535,1510,655],{},[535,1512,1513],{},"billing.subscription",[535,1515,1516],{},"auth.session",") keep keys short while preserving namespace clarity. One catalog per sub-domain.",[857,1519,1522],{"className":1520,"code":1521,"language":1276},[1274],"src\u002Ffeatures\u002F\n├── billing\u002F\n│   └── errors\u002F\n│       ├── payment.ts        → billingPaymentErrors (prefix: 'billing.payment')\n│       ├── subscription.ts   → billingSubscriptionErrors\n│       └── invoice.ts        → billingInvoiceErrors\n├── auth\u002F\n│   └── errors\u002F\n│       ├── session.ts        → authSessionErrors (prefix: 'auth.session')\n│       ├── oauth.ts          → authOAuthErrors\n│       └── mfa.ts            → authMfaErrors\n",[535,1523,1521],{"__ignoreMap":863},[857,1525,1528],{"className":859,"code":1526,"filename":1527,"language":862,"meta":863,"style":863},"import { defineErrorCatalog } from 'evlog'\n\nexport const billingPaymentErrors = defineErrorCatalog('billing.payment', {\n  DECLINED: { status: 402, message: 'Card declined' },\n  INSUFFICIENT_FUNDS: { status: 402, message: 'Insufficient funds' },\n  EXPIRED_CARD: { status: 402, message: 'Card expired' },\n  CVV_MISMATCH: { status: 402, message: 'CVV mismatch' },\n})\n","src\u002Ffeatures\u002Fbilling\u002Ferrors\u002Fpayment.ts",[535,1529,1530,1548,1552,1577,1608,1638,1668,1698],{"__ignoreMap":863},[867,1531,1532,1534,1536,1538,1540,1542,1544,1546],{"class":869,"line":870},[867,1533,874],{"class":873},[867,1535,878],{"class":877},[867,1537,882],{"class":881},[867,1539,885],{"class":877},[867,1541,888],{"class":873},[867,1543,891],{"class":877},[867,1545,895],{"class":894},[867,1547,898],{"class":877},[867,1549,1550],{"class":869,"line":901},[867,1551,905],{"emptyLinePlaceholder":904},[867,1553,1554,1556,1558,1561,1563,1565,1567,1569,1571,1573,1575],{"class":869,"line":908},[867,1555,911],{"class":873},[867,1557,915],{"class":914},[867,1559,1560],{"class":881}," billingPaymentErrors ",[867,1562,921],{"class":877},[867,1564,882],{"class":924},[867,1566,927],{"class":881},[867,1568,930],{"class":877},[867,1570,655],{"class":894},[867,1572,930],{"class":877},[867,1574,938],{"class":877},[867,1576,941],{"class":877},[867,1578,1579,1582,1584,1586,1588,1590,1593,1595,1597,1599,1601,1604,1606],{"class":869,"line":944},[867,1580,1581],{"class":947},"  DECLINED",[867,1583,951],{"class":877},[867,1585,878],{"class":877},[867,1587,956],{"class":947},[867,1589,951],{"class":877},[867,1591,1592],{"class":961}," 402",[867,1594,938],{"class":877},[867,1596,967],{"class":947},[867,1598,951],{"class":877},[867,1600,891],{"class":877},[867,1602,1603],{"class":894},"Card declined",[867,1605,930],{"class":877},[867,1607,979],{"class":877},[867,1609,1610,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1634,1636],{"class":869,"line":982},[867,1611,1612],{"class":947},"  INSUFFICIENT_FUNDS",[867,1614,951],{"class":877},[867,1616,878],{"class":877},[867,1618,956],{"class":947},[867,1620,951],{"class":877},[867,1622,1592],{"class":961},[867,1624,938],{"class":877},[867,1626,967],{"class":947},[867,1628,951],{"class":877},[867,1630,891],{"class":877},[867,1632,1633],{"class":894},"Insufficient funds",[867,1635,930],{"class":877},[867,1637,979],{"class":877},[867,1639,1640,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661,1664,1666],{"class":869,"line":1014},[867,1641,1642],{"class":947},"  EXPIRED_CARD",[867,1644,951],{"class":877},[867,1646,878],{"class":877},[867,1648,956],{"class":947},[867,1650,951],{"class":877},[867,1652,1592],{"class":961},[867,1654,938],{"class":877},[867,1656,967],{"class":947},[867,1658,951],{"class":877},[867,1660,891],{"class":877},[867,1662,1663],{"class":894},"Card expired",[867,1665,930],{"class":877},[867,1667,979],{"class":877},[867,1669,1670,1673,1675,1677,1679,1681,1683,1685,1687,1689,1691,1694,1696],{"class":869,"line":1024},[867,1671,1672],{"class":947},"  CVV_MISMATCH",[867,1674,951],{"class":877},[867,1676,878],{"class":877},[867,1678,956],{"class":947},[867,1680,951],{"class":877},[867,1682,1592],{"class":961},[867,1684,938],{"class":877},[867,1686,967],{"class":947},[867,1688,951],{"class":877},[867,1690,891],{"class":877},[867,1692,1693],{"class":894},"CVV mismatch",[867,1695,930],{"class":877},[867,1697,979],{"class":877},[867,1699,1700,1702],{"class":869,"line":1038},[867,1701,1098],{"class":877},[867,1703,1101],{"class":881},[531,1705,1706,1707,538,1710,1713],{},"Wire codes become ",[535,1708,1709],{},"billing.payment.DECLINED",[535,1711,1712],{},"billing.payment.INSUFFICIENT_FUNDS",", etc. The convention scales to hundreds of entries without collisions.",[838,1715,1717],{"id":1716},"npm-packages-monorepo","npm packages — monorepo",[531,1719,1720,1721,1723,1724,1727],{},"In a monorepo, each bounded context can ship as its own npm package. Type augmentation propagates through the published ",[535,1722,670],{},", so consumers get autocomplete just by ",[535,1725,1726],{},"pnpm add @acme\u002Ferrors-billing",".",[857,1729,1732],{"className":1730,"code":1731,"language":1276},[1274],"acme-monorepo\u002F\n├── packages\u002F\n│   ├── errors-billing\u002F         → @acme\u002Ferrors-billing\n│   │   └── src\u002Findex.ts\n│   ├── errors-auth\u002F            → @acme\u002Ferrors-auth\n│   │   └── src\u002Findex.ts\n│   └── audit-billing\u002F          → @acme\u002Faudit-billing\n│       └── src\u002Findex.ts\n└── apps\u002F\n    ├── api\u002F                    → imports + re-exports the catalogs\n    └── worker\u002F\n",[535,1733,1731],{"__ignoreMap":863},[714,1735,1737],{"id":1736},"publishing-a-catalog-as-an-npm-package","Publishing a catalog as an npm package",[531,1739,1740,1741,1743],{},"A catalog is just regular TypeScript that depends on ",[535,1742,895],{}," as a peer dep. Here is the minimal recipe.",[838,1745,1747],{"id":1746},"packagejson",[535,1748,1749],{},"package.json",[857,1751,1756],{"className":1752,"code":1753,"filename":1754,"language":1755,"meta":863,"style":863},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"name\": \"@acme\u002Ferrors-billing\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"main\": \".\u002Fdist\u002Findex.mjs\",\n  \"types\": \".\u002Fdist\u002Findex.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": \".\u002Fdist\u002Findex.mjs\",\n      \"types\": \".\u002Fdist\u002Findex.d.ts\"\n    }\n  },\n  \"peerDependencies\": {\n    \"evlog\": \"^3.0.0\"\n  },\n  \"files\": [\"dist\"]\n}\n","packages\u002Ferrors-billing\u002Fpackage.json","json",[535,1757,1758,1763,1786,1806,1826,1846,1866,1879,1892,1911,1928,1933,1937,1950,1967,1971,1996],{"__ignoreMap":863},[867,1759,1760],{"class":869,"line":870},[867,1761,1762],{"class":877},"{\n",[867,1764,1765,1768,1771,1774,1776,1779,1782,1784],{"class":869,"line":901},[867,1766,1767],{"class":877},"  \"",[867,1769,1770],{"class":914},"name",[867,1772,1773],{"class":877},"\"",[867,1775,951],{"class":877},[867,1777,1778],{"class":877}," \"",[867,1780,1781],{"class":894},"@acme\u002Ferrors-billing",[867,1783,1773],{"class":877},[867,1785,1035],{"class":877},[867,1787,1788,1790,1793,1795,1797,1799,1802,1804],{"class":869,"line":908},[867,1789,1767],{"class":877},[867,1791,1792],{"class":914},"version",[867,1794,1773],{"class":877},[867,1796,951],{"class":877},[867,1798,1778],{"class":877},[867,1800,1801],{"class":894},"1.0.0",[867,1803,1773],{"class":877},[867,1805,1035],{"class":877},[867,1807,1808,1810,1813,1815,1817,1819,1822,1824],{"class":869,"line":944},[867,1809,1767],{"class":877},[867,1811,1812],{"class":914},"type",[867,1814,1773],{"class":877},[867,1816,951],{"class":877},[867,1818,1778],{"class":877},[867,1820,1821],{"class":894},"module",[867,1823,1773],{"class":877},[867,1825,1035],{"class":877},[867,1827,1828,1830,1833,1835,1837,1839,1842,1844],{"class":869,"line":982},[867,1829,1767],{"class":877},[867,1831,1832],{"class":914},"main",[867,1834,1773],{"class":877},[867,1836,951],{"class":877},[867,1838,1778],{"class":877},[867,1840,1841],{"class":894},".\u002Fdist\u002Findex.mjs",[867,1843,1773],{"class":877},[867,1845,1035],{"class":877},[867,1847,1848,1850,1853,1855,1857,1859,1862,1864],{"class":869,"line":1014},[867,1849,1767],{"class":877},[867,1851,1852],{"class":914},"types",[867,1854,1773],{"class":877},[867,1856,951],{"class":877},[867,1858,1778],{"class":877},[867,1860,1861],{"class":894},".\u002Fdist\u002Findex.d.ts",[867,1863,1773],{"class":877},[867,1865,1035],{"class":877},[867,1867,1868,1870,1873,1875,1877],{"class":869,"line":1024},[867,1869,1767],{"class":877},[867,1871,1872],{"class":914},"exports",[867,1874,1773],{"class":877},[867,1876,951],{"class":877},[867,1878,941],{"class":877},[867,1880,1881,1884,1886,1888,1890],{"class":869,"line":1038},[867,1882,1883],{"class":877},"    \"",[867,1885,1727],{"class":1062},[867,1887,1773],{"class":877},[867,1889,951],{"class":877},[867,1891,941],{"class":877},[867,1893,1894,1897,1899,1901,1903,1905,1907,1909],{"class":869,"line":1089},[867,1895,1896],{"class":877},"      \"",[867,1898,874],{"class":961},[867,1900,1773],{"class":877},[867,1902,951],{"class":877},[867,1904,1778],{"class":877},[867,1906,1841],{"class":894},[867,1908,1773],{"class":877},[867,1910,1035],{"class":877},[867,1912,1913,1915,1917,1919,1921,1923,1925],{"class":869,"line":1095},[867,1914,1896],{"class":877},[867,1916,1852],{"class":961},[867,1918,1773],{"class":877},[867,1920,951],{"class":877},[867,1922,1778],{"class":877},[867,1924,1861],{"class":894},[867,1926,1927],{"class":877},"\"\n",[867,1929,1930],{"class":869,"line":1442},[867,1931,1932],{"class":877},"    }\n",[867,1934,1935],{"class":869,"line":1456},[867,1936,1092],{"class":877},[867,1938,1939,1941,1944,1946,1948],{"class":869,"line":1469},[867,1940,1767],{"class":877},[867,1942,1943],{"class":914},"peerDependencies",[867,1945,1773],{"class":877},[867,1947,951],{"class":877},[867,1949,941],{"class":877},[867,1951,1952,1954,1956,1958,1960,1962,1965],{"class":869,"line":1482},[867,1953,1883],{"class":877},[867,1955,895],{"class":1062},[867,1957,1773],{"class":877},[867,1959,951],{"class":877},[867,1961,1778],{"class":877},[867,1963,1964],{"class":894},"^3.0.0",[867,1966,1927],{"class":877},[867,1968,1969],{"class":869,"line":1488},[867,1970,1092],{"class":877},[867,1972,1974,1976,1979,1981,1983,1986,1988,1991,1993],{"class":869,"line":1973},16,[867,1975,1767],{"class":877},[867,1977,1978],{"class":914},"files",[867,1980,1773],{"class":877},[867,1982,951],{"class":877},[867,1984,1985],{"class":877}," [",[867,1987,1773],{"class":877},[867,1989,1990],{"class":894},"dist",[867,1992,1773],{"class":877},[867,1994,1995],{"class":877},"]\n",[867,1997,1999],{"class":869,"line":1998},17,[867,2000,1491],{"class":877},[838,2002,2004],{"id":2003},"source-catalog-augmentation-in-the-same-file","Source — catalog + augmentation in the same file",[857,2006,2009],{"className":859,"code":2007,"filename":2008,"language":862,"meta":863,"style":863},"import { defineErrorCatalog } from 'evlog'\n\nexport const billingErrors = defineErrorCatalog('billing', {\n  PAYMENT_DECLINED: {\n    status: 402,\n    message: 'Card declined',\n    why: 'Issuer declined the charge',\n    fix: 'Try a different payment method',\n    link: 'https:\u002F\u002Fdocs.example.com\u002Ferrors\u002Fbilling.payment_declined',\n  },\n  INSUFFICIENT_FUNDS: {\n    status: 402,\n    message: ({ available, required }: { available: number, required: number }) =>\n      `Insufficient funds: $${available}\u002F$${required}`,\n  },\n  \u002F\u002F ...\n})\n\ndeclare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    billing: typeof billingErrors\n  }\n}\n","packages\u002Ferrors-billing\u002Fsrc\u002Findex.ts",[535,2010,2011,2029,2033,2059,2068,2078,2092,2108,2124,2140,2144,2152,2162,2202,2229,2233,2239,2245,2250,2265,2274,2285,2290],{"__ignoreMap":863},[867,2012,2013,2015,2017,2019,2021,2023,2025,2027],{"class":869,"line":870},[867,2014,874],{"class":873},[867,2016,878],{"class":877},[867,2018,882],{"class":881},[867,2020,885],{"class":877},[867,2022,888],{"class":873},[867,2024,891],{"class":877},[867,2026,895],{"class":894},[867,2028,898],{"class":877},[867,2030,2031],{"class":869,"line":901},[867,2032,905],{"emptyLinePlaceholder":904},[867,2034,2035,2037,2039,2042,2044,2046,2048,2050,2053,2055,2057],{"class":869,"line":908},[867,2036,911],{"class":873},[867,2038,915],{"class":914},[867,2040,2041],{"class":881}," billingErrors ",[867,2043,921],{"class":877},[867,2045,882],{"class":924},[867,2047,927],{"class":881},[867,2049,930],{"class":877},[867,2051,2052],{"class":894},"billing",[867,2054,930],{"class":877},[867,2056,938],{"class":877},[867,2058,941],{"class":877},[867,2060,2061,2064,2066],{"class":869,"line":944},[867,2062,2063],{"class":947},"  PAYMENT_DECLINED",[867,2065,951],{"class":877},[867,2067,941],{"class":877},[867,2069,2070,2072,2074,2076],{"class":869,"line":982},[867,2071,1027],{"class":947},[867,2073,951],{"class":877},[867,2075,1592],{"class":961},[867,2077,1035],{"class":877},[867,2079,2080,2082,2084,2086,2088,2090],{"class":869,"line":1014},[867,2081,1041],{"class":947},[867,2083,951],{"class":877},[867,2085,891],{"class":877},[867,2087,1603],{"class":894},[867,2089,930],{"class":877},[867,2091,1035],{"class":877},[867,2093,2094,2097,2099,2101,2104,2106],{"class":869,"line":1024},[867,2095,2096],{"class":947},"    why",[867,2098,951],{"class":877},[867,2100,891],{"class":877},[867,2102,2103],{"class":894},"Issuer declined the charge",[867,2105,930],{"class":877},[867,2107,1035],{"class":877},[867,2109,2110,2113,2115,2117,2120,2122],{"class":869,"line":1038},[867,2111,2112],{"class":947},"    fix",[867,2114,951],{"class":877},[867,2116,891],{"class":877},[867,2118,2119],{"class":894},"Try a different payment method",[867,2121,930],{"class":877},[867,2123,1035],{"class":877},[867,2125,2126,2129,2131,2133,2136,2138],{"class":869,"line":1089},[867,2127,2128],{"class":947},"    link",[867,2130,951],{"class":877},[867,2132,891],{"class":877},[867,2134,2135],{"class":894},"https:\u002F\u002Fdocs.example.com\u002Ferrors\u002Fbilling.payment_declined",[867,2137,930],{"class":877},[867,2139,1035],{"class":877},[867,2141,2142],{"class":869,"line":1095},[867,2143,1092],{"class":877},[867,2145,2146,2148,2150],{"class":869,"line":1442},[867,2147,1612],{"class":947},[867,2149,951],{"class":877},[867,2151,941],{"class":877},[867,2153,2154,2156,2158,2160],{"class":869,"line":1456},[867,2155,1027],{"class":947},[867,2157,951],{"class":877},[867,2159,1592],{"class":961},[867,2161,1035],{"class":877},[867,2163,2164,2166,2168,2170,2173,2175,2178,2180,2182,2184,2186,2189,2191,2193,2195,2197,2199],{"class":869,"line":1469},[867,2165,1041],{"class":924},[867,2167,951],{"class":877},[867,2169,1046],{"class":877},[867,2171,2172],{"class":1049}," available",[867,2174,938],{"class":877},[867,2176,2177],{"class":1049}," required",[867,2179,1053],{"class":877},[867,2181,878],{"class":877},[867,2183,2172],{"class":947},[867,2185,951],{"class":877},[867,2187,2188],{"class":1062}," number",[867,2190,938],{"class":877},[867,2192,2177],{"class":947},[867,2194,951],{"class":877},[867,2196,2188],{"class":1062},[867,2198,1066],{"class":877},[867,2200,2201],{"class":914}," =>\n",[867,2203,2204,2207,2210,2212,2215,2217,2220,2222,2225,2227],{"class":869,"line":1482},[867,2205,2206],{"class":877},"      `",[867,2208,2209],{"class":894},"Insufficient funds: $",[867,2211,1078],{"class":877},[867,2213,2214],{"class":881},"available",[867,2216,1098],{"class":877},[867,2218,2219],{"class":894},"\u002F$",[867,2221,1078],{"class":877},[867,2223,2224],{"class":881},"required",[867,2226,1084],{"class":877},[867,2228,1035],{"class":877},[867,2230,2231],{"class":869,"line":1488},[867,2232,1092],{"class":877},[867,2234,2235],{"class":869,"line":1973},[867,2236,2238],{"class":2237},"sHwdD","  \u002F\u002F ...\n",[867,2240,2241,2243],{"class":869,"line":1998},[867,2242,1098],{"class":877},[867,2244,1101],{"class":881},[867,2246,2248],{"class":869,"line":2247},18,[867,2249,905],{"emptyLinePlaceholder":904},[867,2251,2253,2255,2257,2259,2261,2263],{"class":869,"line":2252},19,[867,2254,1418],{"class":914},[867,2256,1421],{"class":914},[867,2258,891],{"class":877},[867,2260,895],{"class":894},[867,2262,930],{"class":877},[867,2264,941],{"class":877},[867,2266,2268,2270,2272],{"class":869,"line":2267},20,[867,2269,1434],{"class":914},[867,2271,1437],{"class":1062},[867,2273,941],{"class":877},[867,2275,2277,2279,2281,2283],{"class":869,"line":2276},21,[867,2278,1459],{"class":947},[867,2280,951],{"class":877},[867,2282,1450],{"class":877},[867,2284,1466],{"class":881},[867,2286,2288],{"class":869,"line":2287},22,[867,2289,1485],{"class":877},[867,2291,2293],{"class":869,"line":2292},23,[867,2294,1491],{"class":877},[531,2296,2297,2298,2300,2301,2304,2305,2307],{},"The ",[535,2299,689],{}," block lives inside the source file so the bundler emits it into the ",[535,2302,2303],{},"dist\u002Findex.d.ts",". Any consumer that imports from ",[535,2306,1781],{}," gets the augmentation transitively — no extra setup required on their side.",[838,2309,2311],{"id":2310},"consumption","Consumption",[857,2313,2316],{"className":859,"code":2314,"filename":2315,"language":862,"meta":863,"style":863},"\u002F\u002F Importing the package activates both the runtime catalog and the type augmentation.\nimport { billingErrors } from '@acme\u002Ferrors-billing'\nimport { authErrors } from '@acme\u002Ferrors-auth'\n\n\u002F\u002F Re-export from a central place so the rest of the app has one import path.\nexport { billingErrors, authErrors }\n","apps\u002Fapi\u002Fsrc\u002Finit.ts",[535,2317,2318,2323,2341,2360,2364,2369],{"__ignoreMap":863},[867,2319,2320],{"class":869,"line":870},[867,2321,2322],{"class":2237},"\u002F\u002F Importing the package activates both the runtime catalog and the type augmentation.\n",[867,2324,2325,2327,2329,2331,2333,2335,2337,2339],{"class":869,"line":901},[867,2326,874],{"class":873},[867,2328,878],{"class":877},[867,2330,1318],{"class":881},[867,2332,885],{"class":877},[867,2334,888],{"class":873},[867,2336,891],{"class":877},[867,2338,1781],{"class":894},[867,2340,898],{"class":877},[867,2342,2343,2345,2347,2349,2351,2353,2355,2358],{"class":869,"line":908},[867,2344,874],{"class":873},[867,2346,878],{"class":877},[867,2348,1296],{"class":881},[867,2350,885],{"class":877},[867,2352,888],{"class":873},[867,2354,891],{"class":877},[867,2356,2357],{"class":894},"@acme\u002Ferrors-auth",[867,2359,898],{"class":877},[867,2361,2362],{"class":869,"line":944},[867,2363,905],{"emptyLinePlaceholder":904},[867,2365,2366],{"class":869,"line":982},[867,2367,2368],{"class":2237},"\u002F\u002F Re-export from a central place so the rest of the app has one import path.\n",[867,2370,2371,2373,2375,2377,2379,2381],{"class":869,"line":1014},[867,2372,911],{"class":873},[867,2374,878],{"class":877},[867,2376,1318],{"class":881},[867,2378,938],{"class":877},[867,2380,1296],{"class":881},[867,2382,2383],{"class":877}," }\n",[857,2385,2388],{"className":859,"code":2386,"filename":2387,"language":862,"meta":863,"style":863},"import { billingErrors } from '~\u002Finit'\n\nthrow billingErrors.PAYMENT_DECLINED({ cause: stripeErr })\n","apps\u002Fapi\u002Fsrc\u002Froutes\u002Fcheckout.post.ts",[535,2389,2390,2409,2413],{"__ignoreMap":863},[867,2391,2392,2394,2396,2398,2400,2402,2404,2407],{"class":869,"line":870},[867,2393,874],{"class":873},[867,2395,878],{"class":877},[867,2397,1318],{"class":881},[867,2399,885],{"class":877},[867,2401,888],{"class":873},[867,2403,891],{"class":877},[867,2405,2406],{"class":894},"~\u002Finit",[867,2408,898],{"class":877},[867,2410,2411],{"class":869,"line":901},[867,2412,905],{"emptyLinePlaceholder":904},[867,2414,2415,2418,2420,2422,2424,2426,2429,2432,2434,2437,2439],{"class":869,"line":908},[867,2416,2417],{"class":873},"throw",[867,2419,1318],{"class":881},[867,2421,1727],{"class":877},[867,2423,761],{"class":924},[867,2425,927],{"class":881},[867,2427,2428],{"class":877},"{",[867,2430,2431],{"class":947}," cause",[867,2433,951],{"class":877},[867,2435,2436],{"class":881}," stripeErr ",[867,2438,1098],{"class":877},[867,2440,1101],{"class":881},[857,2442,2445],{"className":859,"code":2443,"filename":2444,"language":862,"meta":863,"style":863},"import { createError, parseError } from 'evlog'\n\nthrow createError({\n  code: 'billing.PAYMENT_DECLINED', \u002F\u002F ← autocomplete from the registered catalog\n  message: 'Card declined',\n  status: 402,\n})\n\nconst err = parseError(caught)\nif (err.code === 'billing.PAYMENT_DECLINED') retry()\n\u002F\u002F                ↑ TypeScript knows the union of all registered codes\n","Anywhere in the app — autocomplete works",[535,2446,2447,2471,2475,2485,2503,2518,2529,2535,2539,2554,2585],{"__ignoreMap":863},[867,2448,2449,2451,2453,2456,2458,2461,2463,2465,2467,2469],{"class":869,"line":870},[867,2450,874],{"class":873},[867,2452,878],{"class":877},[867,2454,2455],{"class":881}," createError",[867,2457,938],{"class":877},[867,2459,2460],{"class":881}," parseError",[867,2462,885],{"class":877},[867,2464,888],{"class":873},[867,2466,891],{"class":877},[867,2468,895],{"class":894},[867,2470,898],{"class":877},[867,2472,2473],{"class":869,"line":901},[867,2474,905],{"emptyLinePlaceholder":904},[867,2476,2477,2479,2481,2483],{"class":869,"line":908},[867,2478,2417],{"class":873},[867,2480,2455],{"class":924},[867,2482,927],{"class":881},[867,2484,1762],{"class":877},[867,2486,2487,2490,2492,2494,2496,2498,2500],{"class":869,"line":944},[867,2488,2489],{"class":947},"  code",[867,2491,951],{"class":877},[867,2493,891],{"class":877},[867,2495,594],{"class":894},[867,2497,930],{"class":877},[867,2499,938],{"class":877},[867,2501,2502],{"class":2237}," \u002F\u002F ← autocomplete from the registered catalog\n",[867,2504,2505,2508,2510,2512,2514,2516],{"class":869,"line":982},[867,2506,2507],{"class":947},"  message",[867,2509,951],{"class":877},[867,2511,891],{"class":877},[867,2513,1603],{"class":894},[867,2515,930],{"class":877},[867,2517,1035],{"class":877},[867,2519,2520,2523,2525,2527],{"class":869,"line":1014},[867,2521,2522],{"class":947},"  status",[867,2524,951],{"class":877},[867,2526,1592],{"class":961},[867,2528,1035],{"class":877},[867,2530,2531,2533],{"class":869,"line":1024},[867,2532,1098],{"class":877},[867,2534,1101],{"class":881},[867,2536,2537],{"class":869,"line":1038},[867,2538,905],{"emptyLinePlaceholder":904},[867,2540,2541,2544,2547,2549,2551],{"class":869,"line":1089},[867,2542,2543],{"class":914},"const",[867,2545,2546],{"class":881}," err ",[867,2548,921],{"class":877},[867,2550,2460],{"class":924},[867,2552,2553],{"class":881},"(caught)\n",[867,2555,2556,2559,2562,2564,2567,2570,2572,2574,2576,2579,2582],{"class":869,"line":1095},[867,2557,2558],{"class":873},"if",[867,2560,2561],{"class":881}," (err",[867,2563,1727],{"class":877},[867,2565,2566],{"class":881},"code ",[867,2568,2569],{"class":877},"===",[867,2571,891],{"class":877},[867,2573,594],{"class":894},[867,2575,930],{"class":877},[867,2577,2578],{"class":881},") ",[867,2580,2581],{"class":924},"retry",[867,2583,2584],{"class":881},"()\n",[867,2586,2587],{"class":869,"line":1442},[867,2588,2589],{"class":2237},"\u002F\u002F                ↑ TypeScript knows the union of all registered codes\n",[2591,2592,2595,2598,2599,2601,2602,538,2605,2601,2607,2610],"callout",{"color":2593,"icon":2594},"neutral","i-lucide-package",[748,2596,2597],{},"Each shared package owns its prefix."," ",[535,2600,1781],{}," owns ",[535,2603,2604],{},"billing.*",[535,2606,2357],{},[535,2608,2609],{},"auth.*",". Conflicts are impossible by construction. Bumping a catalog to a new minor (adding entries) propagates to consumers via the regular semver upgrade path — no codegen, no migration step.",[714,2612,2614],{"id":2613},"composition-patterns","Composition patterns",[838,2616,2618],{"id":2617},"mix-catalogs-and-standalone-factories","Mix catalogs and standalone factories",[531,2620,2621,580,2623,2625,2626,2628],{},[535,2622,537],{},[535,2624,541],{}," produce identical call-site shapes. Use catalogs for grouped errors, ",[535,2627,537],{}," for one-offs (e.g. cross-cutting concerns like rate-limiting that don't belong to a specific domain).",[857,2630,2632],{"className":859,"code":2631,"filename":1282,"language":862,"meta":863,"style":863},"import { defineError, defineErrorCatalog } from 'evlog'\n\nexport const billingErrors = defineErrorCatalog('billing', {\n  PAYMENT_DECLINED: { status: 402, message: 'Card declined' },\n})\n\nexport const rateLimited = defineError('app.RATE_LIMITED', {\n  status: 429,\n  message: ({ retryAfter }: { retryAfter: number }) =>\n    `Rate limited: retry in ${retryAfter}s`,\n})\n\n\u002F\u002F Both look identical at the call site:\nthrow billingErrors.PAYMENT_DECLINED()\nthrow rateLimited({ retryAfter: 30 })\n",[535,2633,2634,2657,2661,2685,2713,2719,2723,2749,2760,2785,2808,2814,2818,2823,2835],{"__ignoreMap":863},[867,2635,2636,2638,2640,2643,2645,2647,2649,2651,2653,2655],{"class":869,"line":870},[867,2637,874],{"class":873},[867,2639,878],{"class":877},[867,2641,2642],{"class":881}," defineError",[867,2644,938],{"class":877},[867,2646,882],{"class":881},[867,2648,885],{"class":877},[867,2650,888],{"class":873},[867,2652,891],{"class":877},[867,2654,895],{"class":894},[867,2656,898],{"class":877},[867,2658,2659],{"class":869,"line":901},[867,2660,905],{"emptyLinePlaceholder":904},[867,2662,2663,2665,2667,2669,2671,2673,2675,2677,2679,2681,2683],{"class":869,"line":908},[867,2664,911],{"class":873},[867,2666,915],{"class":914},[867,2668,2041],{"class":881},[867,2670,921],{"class":877},[867,2672,882],{"class":924},[867,2674,927],{"class":881},[867,2676,930],{"class":877},[867,2678,2052],{"class":894},[867,2680,930],{"class":877},[867,2682,938],{"class":877},[867,2684,941],{"class":877},[867,2686,2687,2689,2691,2693,2695,2697,2699,2701,2703,2705,2707,2709,2711],{"class":869,"line":944},[867,2688,2063],{"class":947},[867,2690,951],{"class":877},[867,2692,878],{"class":877},[867,2694,956],{"class":947},[867,2696,951],{"class":877},[867,2698,1592],{"class":961},[867,2700,938],{"class":877},[867,2702,967],{"class":947},[867,2704,951],{"class":877},[867,2706,891],{"class":877},[867,2708,1603],{"class":894},[867,2710,930],{"class":877},[867,2712,979],{"class":877},[867,2714,2715,2717],{"class":869,"line":982},[867,2716,1098],{"class":877},[867,2718,1101],{"class":881},[867,2720,2721],{"class":869,"line":1014},[867,2722,905],{"emptyLinePlaceholder":904},[867,2724,2725,2727,2729,2732,2734,2736,2738,2740,2743,2745,2747],{"class":869,"line":1024},[867,2726,911],{"class":873},[867,2728,915],{"class":914},[867,2730,2731],{"class":881}," rateLimited ",[867,2733,921],{"class":877},[867,2735,2642],{"class":924},[867,2737,927],{"class":881},[867,2739,930],{"class":877},[867,2741,2742],{"class":894},"app.RATE_LIMITED",[867,2744,930],{"class":877},[867,2746,938],{"class":877},[867,2748,941],{"class":877},[867,2750,2751,2753,2755,2758],{"class":869,"line":1038},[867,2752,2522],{"class":947},[867,2754,951],{"class":877},[867,2756,2757],{"class":961}," 429",[867,2759,1035],{"class":877},[867,2761,2762,2764,2766,2768,2771,2773,2775,2777,2779,2781,2783],{"class":869,"line":1089},[867,2763,2507],{"class":924},[867,2765,951],{"class":877},[867,2767,1046],{"class":877},[867,2769,2770],{"class":1049}," retryAfter",[867,2772,1053],{"class":877},[867,2774,878],{"class":877},[867,2776,2770],{"class":947},[867,2778,951],{"class":877},[867,2780,2188],{"class":1062},[867,2782,1066],{"class":877},[867,2784,2201],{"class":914},[867,2786,2787,2790,2793,2795,2798,2800,2803,2806],{"class":869,"line":1095},[867,2788,2789],{"class":877},"    `",[867,2791,2792],{"class":894},"Rate limited: retry in ",[867,2794,1078],{"class":877},[867,2796,2797],{"class":881},"retryAfter",[867,2799,1098],{"class":877},[867,2801,2802],{"class":894},"s",[867,2804,2805],{"class":877},"`",[867,2807,1035],{"class":877},[867,2809,2810,2812],{"class":869,"line":1442},[867,2811,1098],{"class":877},[867,2813,1101],{"class":881},[867,2815,2816],{"class":869,"line":1456},[867,2817,905],{"emptyLinePlaceholder":904},[867,2819,2820],{"class":869,"line":1469},[867,2821,2822],{"class":2237},"\u002F\u002F Both look identical at the call site:\n",[867,2824,2825,2827,2829,2831,2833],{"class":869,"line":1482},[867,2826,2417],{"class":873},[867,2828,1318],{"class":881},[867,2830,1727],{"class":877},[867,2832,761],{"class":924},[867,2834,2584],{"class":881},[867,2836,2837,2839,2842,2844,2846,2848,2850,2853,2855],{"class":869,"line":1488},[867,2838,2417],{"class":873},[867,2840,2841],{"class":924}," rateLimited",[867,2843,927],{"class":881},[867,2845,2428],{"class":877},[867,2847,2770],{"class":947},[867,2849,951],{"class":877},[867,2851,2852],{"class":961}," 30",[867,2854,885],{"class":877},[867,2856,1101],{"class":881},[838,2858,2860],{"id":2859},"re-export-from-one-entry-per-domain","Re-export from one entry per domain",[531,2862,2863],{},"If a feature ships errors and audits together, give it a single re-export module so call sites only import once.",[857,2865,2868],{"className":859,"code":2866,"filename":2867,"language":862,"meta":863,"style":863},"export { billingErrors } from '.\u002Ferrors\u002Fbilling'\nexport { billingAudit } from '.\u002Faudit\u002Fbilling'\n","src\u002Ffeatures\u002Fbilling\u002Findex.ts",[535,2869,2870,2889],{"__ignoreMap":863},[867,2871,2872,2874,2876,2878,2880,2882,2884,2887],{"class":869,"line":870},[867,2873,911],{"class":873},[867,2875,878],{"class":877},[867,2877,1318],{"class":881},[867,2879,885],{"class":877},[867,2881,888],{"class":873},[867,2883,891],{"class":877},[867,2885,2886],{"class":894},".\u002Ferrors\u002Fbilling",[867,2888,898],{"class":877},[867,2890,2891,2893,2895,2898,2900,2902,2904,2907],{"class":869,"line":901},[867,2892,911],{"class":873},[867,2894,878],{"class":877},[867,2896,2897],{"class":881}," billingAudit",[867,2899,885],{"class":877},[867,2901,888],{"class":873},[867,2903,891],{"class":877},[867,2905,2906],{"class":894},".\u002Faudit\u002Fbilling",[867,2908,898],{"class":877},[857,2910,2913],{"className":859,"code":2911,"filename":2912,"language":862,"meta":863,"style":863},"import { billingErrors, billingAudit } from '~\u002Ffeatures\u002Fbilling'\n\nif (!cart.items.length) throw billingErrors.CART_EMPTY()\n\nlog.audit(billingAudit.INVOICE_REFUND({ actor, target: { id: 'inv_889' } }))\n","server\u002Fapi\u002Frefund.post.ts",[535,2914,2915,2938,2942,2976,2980],{"__ignoreMap":863},[867,2916,2917,2919,2921,2923,2925,2927,2929,2931,2933,2936],{"class":869,"line":870},[867,2918,874],{"class":873},[867,2920,878],{"class":877},[867,2922,1318],{"class":881},[867,2924,938],{"class":877},[867,2926,2897],{"class":881},[867,2928,885],{"class":877},[867,2930,888],{"class":873},[867,2932,891],{"class":877},[867,2934,2935],{"class":894},"~\u002Ffeatures\u002Fbilling",[867,2937,898],{"class":877},[867,2939,2940],{"class":869,"line":901},[867,2941,905],{"emptyLinePlaceholder":904},[867,2943,2944,2946,2949,2952,2955,2957,2960,2962,2965,2967,2969,2971,2974],{"class":869,"line":908},[867,2945,2558],{"class":873},[867,2947,2948],{"class":881}," (",[867,2950,2951],{"class":877},"!",[867,2953,2954],{"class":881},"cart",[867,2956,1727],{"class":877},[867,2958,2959],{"class":881},"items",[867,2961,1727],{"class":877},[867,2963,2964],{"class":881},"length) ",[867,2966,2417],{"class":873},[867,2968,1318],{"class":881},[867,2970,1727],{"class":877},[867,2972,2973],{"class":924},"CART_EMPTY",[867,2975,2584],{"class":881},[867,2977,2978],{"class":869,"line":944},[867,2979,905],{"emptyLinePlaceholder":904},[867,2981,2982,2985,2987,2990,2993,2995,2997,2999,3001,3004,3006,3008,3010,3012,3015,3017,3019,3022,3024,3026,3028],{"class":869,"line":982},[867,2983,2984],{"class":881},"log",[867,2986,1727],{"class":877},[867,2988,2989],{"class":924},"audit",[867,2991,2992],{"class":881},"(billingAudit",[867,2994,1727],{"class":877},[867,2996,764],{"class":924},[867,2998,927],{"class":881},[867,3000,2428],{"class":877},[867,3002,3003],{"class":881}," actor",[867,3005,938],{"class":877},[867,3007,1167],{"class":947},[867,3009,951],{"class":877},[867,3011,878],{"class":877},[867,3013,3014],{"class":947}," id",[867,3016,951],{"class":877},[867,3018,891],{"class":877},[867,3020,3021],{"class":894},"inv_889",[867,3023,930],{"class":877},[867,3025,885],{"class":877},[867,3027,885],{"class":877},[867,3029,3030],{"class":881},"))\n",[838,3032,3034],{"id":3033},"override-catalog-defaults-at-the-call-site","Override catalog defaults at the call site",[531,3036,3037,3038,538,3041,538,3044,538,3047,538,3050,538,3053,3055,3056,3058],{},"Every entry's defaults (",[535,3039,3040],{},"message",[535,3042,3043],{},"status",[535,3045,3046],{},"why",[535,3048,3049],{},"fix",[535,3051,3052],{},"link",[535,3054,630],{},") are overridable per call. ",[535,3057,630],{}," is shallow-merged (call-site wins on conflict).",[857,3060,3062],{"className":859,"code":3061,"language":862,"meta":863,"style":863},"\u002F\u002F Catalog default:\n\u002F\u002F message: 'Card declined'\n\u002F\u002F internal: { category: 'gateway' }\n\nthrow billingErrors.PAYMENT_DECLINED({\n  message: 'Custom message for this specific call',\n  internal: { stripeRef: 'ch_x', category: 'gateway-overridden' },\n  cause: stripeErr,\n})\n\n\u002F\u002F Resulting EvlogError:\n\u002F\u002F - message: 'Custom message for this specific call' (override)\n\u002F\u002F - status: 402 (catalog default)\n\u002F\u002F - why: 'Issuer declined the charge' (catalog default)\n\u002F\u002F - internal: { category: 'gateway-overridden', stripeRef: 'ch_x' }\n",[535,3063,3064,3069,3074,3079,3083,3097,3112,3149,3161,3167,3171,3176,3181,3186,3191],{"__ignoreMap":863},[867,3065,3066],{"class":869,"line":870},[867,3067,3068],{"class":2237},"\u002F\u002F Catalog default:\n",[867,3070,3071],{"class":869,"line":901},[867,3072,3073],{"class":2237},"\u002F\u002F message: 'Card declined'\n",[867,3075,3076],{"class":869,"line":908},[867,3077,3078],{"class":2237},"\u002F\u002F internal: { category: 'gateway' }\n",[867,3080,3081],{"class":869,"line":944},[867,3082,905],{"emptyLinePlaceholder":904},[867,3084,3085,3087,3089,3091,3093,3095],{"class":869,"line":982},[867,3086,2417],{"class":873},[867,3088,1318],{"class":881},[867,3090,1727],{"class":877},[867,3092,761],{"class":924},[867,3094,927],{"class":881},[867,3096,1762],{"class":877},[867,3098,3099,3101,3103,3105,3108,3110],{"class":869,"line":1014},[867,3100,2507],{"class":947},[867,3102,951],{"class":877},[867,3104,891],{"class":877},[867,3106,3107],{"class":894},"Custom message for this specific call",[867,3109,930],{"class":877},[867,3111,1035],{"class":877},[867,3113,3114,3117,3119,3121,3124,3126,3128,3131,3133,3135,3138,3140,3142,3145,3147],{"class":869,"line":1024},[867,3115,3116],{"class":947},"  internal",[867,3118,951],{"class":877},[867,3120,878],{"class":877},[867,3122,3123],{"class":947}," stripeRef",[867,3125,951],{"class":877},[867,3127,891],{"class":877},[867,3129,3130],{"class":894},"ch_x",[867,3132,930],{"class":877},[867,3134,938],{"class":877},[867,3136,3137],{"class":947}," category",[867,3139,951],{"class":877},[867,3141,891],{"class":877},[867,3143,3144],{"class":894},"gateway-overridden",[867,3146,930],{"class":877},[867,3148,979],{"class":877},[867,3150,3151,3154,3156,3159],{"class":869,"line":1038},[867,3152,3153],{"class":947},"  cause",[867,3155,951],{"class":877},[867,3157,3158],{"class":881}," stripeErr",[867,3160,1035],{"class":877},[867,3162,3163,3165],{"class":869,"line":1089},[867,3164,1098],{"class":877},[867,3166,1101],{"class":881},[867,3168,3169],{"class":869,"line":1095},[867,3170,905],{"emptyLinePlaceholder":904},[867,3172,3173],{"class":869,"line":1442},[867,3174,3175],{"class":2237},"\u002F\u002F Resulting EvlogError:\n",[867,3177,3178],{"class":869,"line":1456},[867,3179,3180],{"class":2237},"\u002F\u002F - message: 'Custom message for this specific call' (override)\n",[867,3182,3183],{"class":869,"line":1469},[867,3184,3185],{"class":2237},"\u002F\u002F - status: 402 (catalog default)\n",[867,3187,3188],{"class":869,"line":1482},[867,3189,3190],{"class":2237},"\u002F\u002F - why: 'Issuer declined the charge' (catalog default)\n",[867,3192,3193],{"class":869,"line":1488},[867,3194,3195],{"class":2237},"\u002F\u002F - internal: { category: 'gateway-overridden', stripeRef: 'ch_x' }\n",[714,3197,3199],{"id":3198},"type-augmentation-deep-dive","Type augmentation — deep dive",[531,3201,3202,3203,3205,3206,538,3208,3210,3211,3214,3215,3218],{},"The opt-in ",[535,3204,662],{}," block is what surfaces autocomplete on ",[535,3207,641],{},[535,3209,644],{},", and the typed ",[535,3212,3213],{},"ErrorCode"," \u002F ",[535,3216,3217],{},"AuditAction"," exports.",[838,3220,3222],{"id":3221},"where-to-put-the-augmentation","Where to put the augmentation",[722,3224,3225,3235],{},[725,3226,3227],{},[728,3228,3229,3232],{},[731,3230,3231],{},"Repo shape",[731,3233,3234],{},"Recommended location",[740,3236,3237,3247,3261,3274],{},[728,3238,3239,3244],{},[745,3240,3241,3242,598],{},"Single file (",[535,3243,861],{},[745,3245,3246],{},"At the bottom of the same file",[728,3248,3249,3255],{},[745,3250,3251,3252,598],{},"Folder (",[535,3253,3254],{},"src\u002Ferrors\u002F*.ts",[745,3256,3257,3258,3260],{},"In ",[535,3259,1282],{}," (centralised) or each catalog file (decentralised)",[728,3262,3263,3266],{},[745,3264,3265],{},"npm package",[745,3267,3268,3269,3271,3272],{},"At the bottom of the package's main ",[535,3270,666],{}," so it ships in the published ",[535,3273,670],{},[728,3275,3276,3279],{},[745,3277,3278],{},"Monorepo",[745,3280,3281],{},"One augmentation per package, no central registry needed",[531,3283,3284,3285,3287],{},"Both centralised and decentralised work — TypeScript merges multiple ",[535,3286,662],{}," blocks across files automatically.",[838,3289,3291],{"id":3290},"how-to-add-custom-domains","How to add custom domains",[531,3293,3294],{},"Each augmentation key is the namespace name. Multiple catalogs sharing a prefix can either be merged into one key or split:",[857,3296,3299],{"className":859,"code":3297,"filename":3298,"language":862,"meta":863,"style":863},"declare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    billing: typeof billingErrors\n  }\n}\n","Centralised — one key per package",[535,3300,3301,3315,3323,3333,3337],{"__ignoreMap":863},[867,3302,3303,3305,3307,3309,3311,3313],{"class":869,"line":870},[867,3304,1418],{"class":914},[867,3306,1421],{"class":914},[867,3308,891],{"class":877},[867,3310,895],{"class":894},[867,3312,930],{"class":877},[867,3314,941],{"class":877},[867,3316,3317,3319,3321],{"class":869,"line":901},[867,3318,1434],{"class":914},[867,3320,1437],{"class":1062},[867,3322,941],{"class":877},[867,3324,3325,3327,3329,3331],{"class":869,"line":908},[867,3326,1459],{"class":947},[867,3328,951],{"class":877},[867,3330,1450],{"class":877},[867,3332,1466],{"class":881},[867,3334,3335],{"class":869,"line":944},[867,3336,1485],{"class":877},[867,3338,3339],{"class":869,"line":982},[867,3340,1491],{"class":877},[857,3342,3345],{"className":859,"code":3343,"filename":3344,"language":862,"meta":863,"style":863},"declare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    'billing.payment': typeof billingPaymentErrors\n    'billing.subscription': typeof billingSubscriptionErrors\n    'billing.invoice': typeof billingInvoiceErrors\n  }\n}\n","Decentralised — one key per sub-domain",[535,3346,3347,3361,3369,3385,3400,3416,3420],{"__ignoreMap":863},[867,3348,3349,3351,3353,3355,3357,3359],{"class":869,"line":870},[867,3350,1418],{"class":914},[867,3352,1421],{"class":914},[867,3354,891],{"class":877},[867,3356,895],{"class":894},[867,3358,930],{"class":877},[867,3360,941],{"class":877},[867,3362,3363,3365,3367],{"class":869,"line":901},[867,3364,1434],{"class":914},[867,3366,1437],{"class":1062},[867,3368,941],{"class":877},[867,3370,3371,3374,3376,3378,3380,3382],{"class":869,"line":908},[867,3372,3373],{"class":877},"    '",[867,3375,655],{"class":894},[867,3377,930],{"class":877},[867,3379,951],{"class":877},[867,3381,1450],{"class":877},[867,3383,3384],{"class":881}," billingPaymentErrors\n",[867,3386,3387,3389,3391,3393,3395,3397],{"class":869,"line":944},[867,3388,3373],{"class":877},[867,3390,1513],{"class":894},[867,3392,930],{"class":877},[867,3394,951],{"class":877},[867,3396,1450],{"class":877},[867,3398,3399],{"class":881}," billingSubscriptionErrors\n",[867,3401,3402,3404,3407,3409,3411,3413],{"class":869,"line":982},[867,3403,3373],{"class":877},[867,3405,3406],{"class":894},"billing.invoice",[867,3408,930],{"class":877},[867,3410,951],{"class":877},[867,3412,1450],{"class":877},[867,3414,3415],{"class":881}," billingInvoiceErrors\n",[867,3417,3418],{"class":869,"line":1014},[867,3419,1485],{"class":877},[867,3421,3422],{"class":869,"line":1024},[867,3423,1491],{"class":877},[531,3425,2297,3426,3429,3430,3432],{},[535,3427,3428],{},"_codes"," literal union is what produces the actual ",[535,3431,3213],{}," type — the keys themselves are arbitrary, choose what feels right for your structure.",[838,3434,3436],{"id":3435},"verifying-the-augmentation","Verifying the augmentation",[857,3438,3441],{"className":859,"code":3439,"filename":3440,"language":862,"meta":863,"style":863},"import type { ErrorCode, AuditAction } from 'evlog'\n\n\u002F\u002F Hover the type in your IDE — should show the union of all registered codes.\ntype AllErrorCodes = ErrorCode\ntype AllAuditActions = AuditAction\n\n\u002F\u002F Compile-time check:\nconst validCode: ErrorCode = 'billing.PAYMENT_DECLINED' \u002F\u002F OK\nconst invalidCode: ErrorCode = 'billing.NOPE' \u002F\u002F ← TS error if catalog is registered\n","Anywhere in the codebase",[535,3442,3443,3469,3473,3478,3491,3503,3507,3512,3534],{"__ignoreMap":863},[867,3444,3445,3447,3449,3451,3454,3456,3459,3461,3463,3465,3467],{"class":869,"line":870},[867,3446,874],{"class":873},[867,3448,1291],{"class":873},[867,3450,878],{"class":877},[867,3452,3453],{"class":881}," ErrorCode",[867,3455,938],{"class":877},[867,3457,3458],{"class":881}," AuditAction",[867,3460,885],{"class":877},[867,3462,888],{"class":873},[867,3464,891],{"class":877},[867,3466,895],{"class":894},[867,3468,898],{"class":877},[867,3470,3471],{"class":869,"line":901},[867,3472,905],{"emptyLinePlaceholder":904},[867,3474,3475],{"class":869,"line":908},[867,3476,3477],{"class":2237},"\u002F\u002F Hover the type in your IDE — should show the union of all registered codes.\n",[867,3479,3480,3482,3485,3488],{"class":869,"line":944},[867,3481,1812],{"class":914},[867,3483,3484],{"class":1062}," AllErrorCodes",[867,3486,3487],{"class":877}," =",[867,3489,3490],{"class":1062}," ErrorCode\n",[867,3492,3493,3495,3498,3500],{"class":869,"line":982},[867,3494,1812],{"class":914},[867,3496,3497],{"class":1062}," AllAuditActions",[867,3499,3487],{"class":877},[867,3501,3502],{"class":1062}," AuditAction\n",[867,3504,3505],{"class":869,"line":1014},[867,3506,905],{"emptyLinePlaceholder":904},[867,3508,3509],{"class":869,"line":1024},[867,3510,3511],{"class":2237},"\u002F\u002F Compile-time check:\n",[867,3513,3514,3516,3519,3521,3523,3525,3527,3529,3531],{"class":869,"line":1038},[867,3515,2543],{"class":914},[867,3517,3518],{"class":881}," validCode",[867,3520,951],{"class":877},[867,3522,3453],{"class":1062},[867,3524,3487],{"class":877},[867,3526,891],{"class":877},[867,3528,594],{"class":894},[867,3530,930],{"class":877},[867,3532,3533],{"class":2237}," \u002F\u002F OK\n",[867,3535,3536,3538,3541,3543,3545,3547,3549,3552,3554],{"class":869,"line":1089},[867,3537,2543],{"class":914},[867,3539,3540],{"class":881}," invalidCode",[867,3542,951],{"class":877},[867,3544,3453],{"class":1062},[867,3546,3487],{"class":877},[867,3548,891],{"class":877},[867,3550,3551],{"class":894},"billing.NOPE",[867,3553,930],{"class":877},[867,3555,3556],{"class":2237}," \u002F\u002F ← TS error if catalog is registered\n",[531,3558,3559,3560,3563],{},"If autocomplete is empty, either no catalog is registered yet, or the augmentation file is not in the TypeScript program (check ",[535,3561,3562],{},"tsconfig.json"," includes).",[714,3565,3567],{"id":3566},"common-pitfalls","Common pitfalls",[3569,3570,3571,3577,3578,3580,3581,1727],"warning",{},[748,3572,3573,3574,3576],{},"Don't put ",[535,3575,689],{}," blocks in test files."," Augmentations from test files leak into the type-checker for the rest of the codebase if the test files are included in the main ",[535,3579,3562],{},". Keep augmentations next to the catalog source, never inside ",[535,3582,3583],{},"*.test.ts",[3569,3585,3586,3589,3590,3593,3594,3596],{},[748,3587,3588],{},"Avoid prefix collisions across packages."," If two packages augment the same ",[535,3591,3592],{},"RegisteredErrorCatalogs"," key (say both ship a ",[535,3595,2052],{}," catalog), TypeScript merges them silently and the runtime keeps the last-registered factory. Convention: one prefix per package, no overlap.",[3569,3598,3599,3605,3606,3609,3610,3612],{},[748,3600,3601,3602,3604],{},"Never override the ",[535,3603,535],{}," at the call site."," The catalog defines the code identity — overriding it would break dashboards, alerts, and consumer code branching on ",[535,3607,3608],{},"err.code",". The factory's call-site signature deliberately omits ",[535,3611,535],{}," from the overridable fields.",[701,3614,3615,3624],{},[531,3616,3617,3623],{},[748,3618,3619,3620,3622],{},"Prefer ",[535,3621,676],{}," over string comparisons in tests."," Both forms below are valid; the first survives renames (refactor-safe), the second doesn't.",[857,3625,3627],{"className":859,"code":3626,"language":862,"meta":863,"style":863},"expect(err.code).toBe(billingErrors.PAYMENT_DECLINED.code) \u002F\u002F ✓ refactor-safe\nexpect(err.code).toBe('billing.PAYMENT_DECLINED')          \u002F\u002F ✗ string literal\n",[535,3628,3629,3662],{"__ignoreMap":863},[867,3630,3631,3634,3637,3639,3642,3644,3647,3650,3652,3654,3656,3659],{"class":869,"line":870},[867,3632,3633],{"class":924},"expect",[867,3635,3636],{"class":881},"(err",[867,3638,1727],{"class":877},[867,3640,3641],{"class":881},"code)",[867,3643,1727],{"class":877},[867,3645,3646],{"class":924},"toBe",[867,3648,3649],{"class":881},"(billingErrors",[867,3651,1727],{"class":877},[867,3653,761],{"class":881},[867,3655,1727],{"class":877},[867,3657,3658],{"class":881},"code) ",[867,3660,3661],{"class":2237},"\u002F\u002F ✓ refactor-safe\n",[867,3663,3664,3666,3668,3670,3672,3674,3676,3678,3680,3682,3684,3687],{"class":869,"line":901},[867,3665,3633],{"class":924},[867,3667,3636],{"class":881},[867,3669,1727],{"class":877},[867,3671,3641],{"class":881},[867,3673,1727],{"class":877},[867,3675,3646],{"class":924},[867,3677,927],{"class":881},[867,3679,930],{"class":877},[867,3681,594],{"class":894},[867,3683,930],{"class":877},[867,3685,3686],{"class":881},")          ",[867,3688,3689],{"class":2237},"\u002F\u002F ✗ string literal\n",[714,3691,3693],{"id":3692},"api-reference","API reference",[722,3695,3696,3709],{},[725,3697,3698],{},[728,3699,3700,3703,3706],{},[731,3701,3702],{},"Symbol",[731,3704,3705],{},"Kind",[731,3707,3708],{},"Purpose",[740,3710,3711,3723,3734,3745,3774,3790,3804,3816,3828,3839],{},[728,3712,3713,3717,3720],{},[745,3714,3715],{},[535,3716,579],{},[745,3718,3719],{},"factory",[745,3721,3722],{},"Standalone single-error factory. No prefix derivation.",[728,3724,3725,3729,3731],{},[745,3726,3727],{},[535,3728,569],{},[745,3730,3719],{},[745,3732,3733],{},"Bundle of typed errors sharing a prefix.",[728,3735,3736,3740,3742],{},[745,3737,3738],{},[535,3739,583],{},[745,3741,3719],{},[745,3743,3744],{},"Standalone single-action audit factory.",[728,3746,3747,3751,3753],{},[745,3748,3749],{},[535,3750,573],{},[745,3752,3719],{},[745,3754,3755,3756,538,3759,538,3762,538,3765,538,3768,538,3771,1727],{},"Bundle of typed audit actions sharing a prefix. Each entry accepts ",[535,3757,3758],{},"target",[535,3760,3761],{},"description",[535,3763,3764],{},"severity",[535,3766,3767],{},"requiresChanges",[535,3769,3770],{},"requiresReason",[535,3772,3773],{},"redactPaths",[728,3775,3776,3781,3783],{},[745,3777,3778],{},[535,3779,3780],{},"AuditCatalogEntry",[745,3782,1812],{},[745,3784,3785,3786,3789],{},"Metadata shape for a single catalog entry (alias of ",[535,3787,3788],{},"AuditActionDefinition",").",[728,3791,3792,3797,3799],{},[745,3793,3794],{},[535,3795,3796],{},"AuditSeverity",[745,3798,1812],{},[745,3800,3801,1727],{},[535,3802,3803],{},"'low' | 'medium' | 'high' | 'critical'",[728,3805,3806,3810,3813],{},[745,3807,3808],{},[535,3809,3592],{},[745,3811,3812],{},"interface",[745,3814,3815],{},"Augmentable registry of error catalogs.",[728,3817,3818,3823,3825],{},[745,3819,3820],{},[535,3821,3822],{},"RegisteredAuditCatalogs",[745,3824,3812],{},[745,3826,3827],{},"Augmentable registry of audit catalogs.",[728,3829,3830,3834,3836],{},[745,3831,3832],{},[535,3833,3213],{},[745,3835,1812],{},[745,3837,3838],{},"Union of all registered error codes.",[728,3840,3841,3845,3847],{},[745,3842,3843],{},[535,3844,3217],{},[745,3846,1812],{},[745,3848,3849],{},"Union of all registered audit actions.",[531,3851,3852,3853,3855],{},"Everything ships from the main ",[535,3854,895],{}," entrypoint.",[714,3857,3859],{"id":3858},"next-steps","Next Steps",[561,3861,3862,3875,3888],{},[564,3863,3864,3866,3867,3870,3871,3874],{},[695,3865,51],{"href":52},": The full ",[535,3868,3869],{},"createError"," API and ",[535,3872,3873],{},"parseError"," reference.",[564,3876,3877,3880,3881,538,3884,3887],{},[695,3878,3879],{"href":393},"Audit → Recording",": All audit-emission APIs (",[535,3882,3883],{},"log.audit",[535,3885,3886],{},"withAudit",", etc.).",[564,3889,3890,3892],{},[695,3891,221],{"href":226},": Auto-managed per-request loggers and HTTP error serialization.",[3894,3895,3896],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":863,"searchDepth":901,"depth":901,"links":3898},[3899,3900,3906,3911,3916,3921,3922,3923],{"id":716,"depth":901,"text":717},{"id":832,"depth":901,"text":833,"children":3901},[3902,3903,3904,3905],{"id":840,"depth":908,"text":841},{"id":1255,"depth":908,"text":1256},{"id":1504,"depth":908,"text":1505},{"id":1716,"depth":908,"text":1717},{"id":1736,"depth":901,"text":1737,"children":3907},[3908,3909,3910],{"id":1746,"depth":908,"text":1749},{"id":2003,"depth":908,"text":2004},{"id":2310,"depth":908,"text":2311},{"id":2613,"depth":901,"text":2614,"children":3912},[3913,3914,3915],{"id":2617,"depth":908,"text":2618},{"id":2859,"depth":908,"text":2860},{"id":3033,"depth":908,"text":3034},{"id":3198,"depth":901,"text":3199,"children":3917},[3918,3919,3920],{"id":3221,"depth":908,"text":3222},{"id":3290,"depth":908,"text":3291},{"id":3435,"depth":908,"text":3436},{"id":3566,"depth":901,"text":3567},{"id":3692,"depth":901,"text":3693},{"id":3858,"depth":901,"text":3859},"Scale typed error and audit catalogs from a single file to multi-package monorepos. Conventions, npm packaging recipe, composition patterns, and the type-augmentation deep dive.","md",[3927,3929],{"label":51,"icon":54,"to":52,"color":2593,"variant":3928},"subtle",{"label":378,"icon":379,"to":384,"color":2593,"variant":3928},{},{"icon":79},{"title":76,"description":3924},"wfaoWToc1ysqdEChFo0Q0Ng4sA3VJqnL47GFVg5kayY",[3935,3937],{"title":71,"path":72,"stem":73,"description":3936,"icon":74,"children":-1},"Add compile-time type safety to your wide events with TypeScript module augmentation. Prevent typos and ensure consistent field names across your codebase.",{"title":36,"path":86,"stem":87,"description":3938,"icon":44,"children":-1},"The evlog command line — map your app's observability coverage, diagnose your setup, and control telemetry. Install, global flags, output streams, exit codes, and monorepo behaviour.",1785674473357]