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