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