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