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