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