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