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