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