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