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