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