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