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