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