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