[{"data":1,"prerenderedAt":5618},["ShallowReactive",2],{"navigation_docs":3,"-docs-essentials-testing":493,"-docs-essentials-testing-surround":5613},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":111,"body":495,"description":5606,"extension":5607,"links":5608,"meta":5609,"navigation":5610,"path":112,"seo":5611,"stem":113,"__hash__":5612},"docs\u002Fdocs\u002F02.essentials\u002F13.testing.md",{"type":496,"value":497,"toc":5596},"minimark",[498,507,919,922,1023,1026,1270,1275,1286,1622,1629,1968,1979,1983,2000,2014,2402,2417,2867,2887,2891,2905,3334,3348,3352,3359,3366,3803,3818,3822,3835,3852,4322,4340,4358,4372,4376,4401,5112,5133,5411,5415,5435,5496,5512,5516,5592],[499,500,501,502,506],"p",{},"A dependency in Heximon is a constructor parameter, so a fake is just an argument — there's no runtime\ncontainer to stand up, no token registry to mock, and no decorator metadata to fight. That single fact is\nwhy most of a Heximon app tests like plain TypeScript: ",[503,504,505],"code",{},"new"," the class with fakes, call a method, assert.",[508,509,515],"pre",{"className":510,"code":511,"filename":512,"language":513,"meta":514,"style":514},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F The L01-minimal repository — the smallest real shape (starters\u002Fminimal ships the same file).\nimport { expect, test } from \"vitest\";\nimport { UsersRepository } from \"..\u002Fsrc\u002Fusers\u002Fusers.repository\";\n\ntest(\"UsersRepository lists seeded users\", async () => {\n  const repo = new UsersRepository();\n  const users = await repo.list();\n  expect(users).toHaveLength(2);\n  expect(users[0]?.name).toBe(\"Alice\");\n});\n\ntest(\"UsersRepository finds a user by id\", async () => {\n  const repo = new UsersRepository();\n  expect(await repo.findById(\"2\")).toEqual({ id: \"2\", name: \"Bob\" });\n  expect(await repo.findById(\"999\")).toBeUndefined();\n});\n","test\u002Fusers.test.ts","ts","",[503,516,517,526,566,589,596,628,651,676,705,749,759,764,788,805,875,910],{"__ignoreMap":514},[518,519,522],"span",{"class":520,"line":521},"line",1,[518,523,525],{"class":524},"sHwdD","\u002F\u002F The L01-minimal repository — the smallest real shape (starters\u002Fminimal ships the same file).\n",[518,527,529,533,537,541,544,547,550,553,556,560,563],{"class":520,"line":528},2,[518,530,532],{"class":531},"s7zQu","import",[518,534,536],{"class":535},"sMK4o"," {",[518,538,540],{"class":539},"sTEyZ"," expect",[518,542,543],{"class":535},",",[518,545,546],{"class":539}," test",[518,548,549],{"class":535}," }",[518,551,552],{"class":531}," from",[518,554,555],{"class":535}," \"",[518,557,559],{"class":558},"sfazB","vitest",[518,561,562],{"class":535},"\"",[518,564,565],{"class":535},";\n",[518,567,569,571,573,576,578,580,582,585,587],{"class":520,"line":568},3,[518,570,532],{"class":531},[518,572,536],{"class":535},[518,574,575],{"class":539}," UsersRepository",[518,577,549],{"class":535},[518,579,552],{"class":531},[518,581,555],{"class":535},[518,583,584],{"class":558},"..\u002Fsrc\u002Fusers\u002Fusers.repository",[518,586,562],{"class":535},[518,588,565],{"class":535},[518,590,592],{"class":520,"line":591},4,[518,593,595],{"emptyLinePlaceholder":594},true,"\n",[518,597,599,603,606,608,611,613,615,619,622,625],{"class":520,"line":598},5,[518,600,602],{"class":601},"s2Zo4","test",[518,604,605],{"class":539},"(",[518,607,562],{"class":535},[518,609,610],{"class":558},"UsersRepository lists seeded users",[518,612,562],{"class":535},[518,614,543],{"class":535},[518,616,618],{"class":617},"spNyl"," async",[518,620,621],{"class":535}," ()",[518,623,624],{"class":617}," =>",[518,626,627],{"class":535}," {\n",[518,629,631,634,637,640,643,645,649],{"class":520,"line":630},6,[518,632,633],{"class":617},"  const",[518,635,636],{"class":539}," repo",[518,638,639],{"class":535}," =",[518,641,642],{"class":535}," new",[518,644,575],{"class":601},[518,646,648],{"class":647},"swJcz","()",[518,650,565],{"class":535},[518,652,654,656,659,661,664,666,669,672,674],{"class":520,"line":653},7,[518,655,633],{"class":617},[518,657,658],{"class":539}," users",[518,660,639],{"class":535},[518,662,663],{"class":531}," await",[518,665,636],{"class":539},[518,667,668],{"class":535},".",[518,670,671],{"class":601},"list",[518,673,648],{"class":647},[518,675,565],{"class":535},[518,677,679,682,684,687,690,692,695,697,701,703],{"class":520,"line":678},8,[518,680,681],{"class":601},"  expect",[518,683,605],{"class":647},[518,685,686],{"class":539},"users",[518,688,689],{"class":647},")",[518,691,668],{"class":535},[518,693,694],{"class":601},"toHaveLength",[518,696,605],{"class":647},[518,698,700],{"class":699},"sbssI","2",[518,702,689],{"class":647},[518,704,565],{"class":535},[518,706,708,710,712,714,717,720,723,726,729,731,733,736,738,740,743,745,747],{"class":520,"line":707},9,[518,709,681],{"class":601},[518,711,605],{"class":647},[518,713,686],{"class":539},[518,715,716],{"class":647},"[",[518,718,719],{"class":699},"0",[518,721,722],{"class":647},"]",[518,724,725],{"class":535},"?.",[518,727,728],{"class":539},"name",[518,730,689],{"class":647},[518,732,668],{"class":535},[518,734,735],{"class":601},"toBe",[518,737,605],{"class":647},[518,739,562],{"class":535},[518,741,742],{"class":558},"Alice",[518,744,562],{"class":535},[518,746,689],{"class":647},[518,748,565],{"class":535},[518,750,752,755,757],{"class":520,"line":751},10,[518,753,754],{"class":535},"}",[518,756,689],{"class":539},[518,758,565],{"class":535},[518,760,762],{"class":520,"line":761},11,[518,763,595],{"emptyLinePlaceholder":594},[518,765,767,769,771,773,776,778,780,782,784,786],{"class":520,"line":766},12,[518,768,602],{"class":601},[518,770,605],{"class":539},[518,772,562],{"class":535},[518,774,775],{"class":558},"UsersRepository finds a user by id",[518,777,562],{"class":535},[518,779,543],{"class":535},[518,781,618],{"class":617},[518,783,621],{"class":535},[518,785,624],{"class":617},[518,787,627],{"class":535},[518,789,791,793,795,797,799,801,803],{"class":520,"line":790},13,[518,792,633],{"class":617},[518,794,636],{"class":539},[518,796,639],{"class":535},[518,798,642],{"class":535},[518,800,575],{"class":601},[518,802,648],{"class":647},[518,804,565],{"class":535},[518,806,808,810,812,815,817,819,822,824,826,828,830,833,835,838,840,843,846,849,851,853,855,857,860,862,864,867,869,871,873],{"class":520,"line":807},14,[518,809,681],{"class":601},[518,811,605],{"class":647},[518,813,814],{"class":531},"await",[518,816,636],{"class":539},[518,818,668],{"class":535},[518,820,821],{"class":601},"findById",[518,823,605],{"class":647},[518,825,562],{"class":535},[518,827,700],{"class":558},[518,829,562],{"class":535},[518,831,832],{"class":647},"))",[518,834,668],{"class":535},[518,836,837],{"class":601},"toEqual",[518,839,605],{"class":647},[518,841,842],{"class":535},"{",[518,844,845],{"class":647}," id",[518,847,848],{"class":535},":",[518,850,555],{"class":535},[518,852,700],{"class":558},[518,854,562],{"class":535},[518,856,543],{"class":535},[518,858,859],{"class":647}," name",[518,861,848],{"class":535},[518,863,555],{"class":535},[518,865,866],{"class":558},"Bob",[518,868,562],{"class":535},[518,870,549],{"class":535},[518,872,689],{"class":647},[518,874,565],{"class":535},[518,876,878,880,882,884,886,888,890,892,894,897,899,901,903,906,908],{"class":520,"line":877},15,[518,879,681],{"class":601},[518,881,605],{"class":647},[518,883,814],{"class":531},[518,885,636],{"class":539},[518,887,668],{"class":535},[518,889,821],{"class":601},[518,891,605],{"class":647},[518,893,562],{"class":535},[518,895,896],{"class":558},"999",[518,898,562],{"class":535},[518,900,832],{"class":647},[518,902,668],{"class":535},[518,904,905],{"class":601},"toBeUndefined",[518,907,648],{"class":647},[518,909,565],{"class":535},[518,911,913,915,917],{"class":520,"line":912},16,[518,914,754],{"class":535},[518,916,689],{"class":539},[518,918,565],{"class":535},[499,920,921],{},"No framework is involved because none is needed — there are no hidden dependencies to reconstruct.\nReach past a plain unit test only when the thing you want to prove genuinely needs more:",[923,924,925,942],"table",{},[926,927,928],"thead",{},[929,930,931,936,939],"tr",{},[932,933,935],"th",{"align":934},"left","Shape",[932,937,938],{"align":934},"What it proves",[932,940,941],{"align":934},"How",[943,944,945,963,982,1004],"tbody",{},[929,946,947,954,957],{},[948,949,950],"td",{"align":934},[951,952,953],"strong",{},"Unit",[948,955,956],{"align":934},"One provider or handler in isolation",[948,958,959,962],{"align":934},[503,960,961],{},"new Service(fakeDep)",", call a method, assert",[929,964,965,970,973],{},[948,966,967],{"align":934},[951,968,969],{},"App harness",[948,971,972],{"align":934},"Any provider over the real compiled wiring",[948,974,975,978,979],{"align":934},[503,976,977],{},"createTestApp(...)",", then ",[503,980,981],{},"app.get(Token)",[929,983,984,989,995],{},[948,985,986],{"align":934},[951,987,988],{},"HTTP in-process",[948,990,991,992],{"align":934},"The full route chain over a real ",[503,993,994],{},"Request",[948,996,997,1000,1001],{"align":934},[503,998,999],{},"createTestApp"," + ",[503,1002,1003],{},"createTestClient(app)",[929,1005,1006,1011,1014],{},[948,1007,1008],{"align":934},[951,1009,1010],{},"Self-client",[948,1012,1013],{"align":934},"URL build, body serialization, response validation",[948,1015,1016,1019,1020],{"align":934},[503,1017,1018],{},"new SomeApi(ClientTransport.mock({...}))",", call ",[503,1021,1022],{},".client",[499,1024,1025],{},"A repository also owns domain rules worth proving directly — a duplicate email should raise a domain\nerror, not a generic throw:",[508,1027,1030],{"className":510,"code":1028,"filename":1029,"language":513,"meta":514,"style":514},"import { describe, expect, test } from \"vitest\";\nimport { EmailAlreadyInUseError } from \"..\u002Fsrc\u002Fusers\u002Fuser-errors\";\nimport { UsersRepository } from \"..\u002Fsrc\u002Fusers\u002Fusers.repository\";\n\ndescribe(\"UsersRepository\", () => {\n  test(\"rejects a duplicate email with a domain error\", async () => {\n    const repository = new UsersRepository();\n\n    await expect(repository.create({ name: \"Another Alice\", email: \"alice@example.com\" })).rejects.toBeInstanceOf(\n      EmailAlreadyInUseError,\n    );\n  });\n});\n","test\u002Fusers.repository.test.ts",[503,1031,1032,1061,1083,1103,1107,1129,1153,1171,1175,1238,1246,1253,1262],{"__ignoreMap":514},[518,1033,1034,1036,1038,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059],{"class":520,"line":521},[518,1035,532],{"class":531},[518,1037,536],{"class":535},[518,1039,1040],{"class":539}," describe",[518,1042,543],{"class":535},[518,1044,540],{"class":539},[518,1046,543],{"class":535},[518,1048,546],{"class":539},[518,1050,549],{"class":535},[518,1052,552],{"class":531},[518,1054,555],{"class":535},[518,1056,559],{"class":558},[518,1058,562],{"class":535},[518,1060,565],{"class":535},[518,1062,1063,1065,1067,1070,1072,1074,1076,1079,1081],{"class":520,"line":528},[518,1064,532],{"class":531},[518,1066,536],{"class":535},[518,1068,1069],{"class":539}," EmailAlreadyInUseError",[518,1071,549],{"class":535},[518,1073,552],{"class":531},[518,1075,555],{"class":535},[518,1077,1078],{"class":558},"..\u002Fsrc\u002Fusers\u002Fuser-errors",[518,1080,562],{"class":535},[518,1082,565],{"class":535},[518,1084,1085,1087,1089,1091,1093,1095,1097,1099,1101],{"class":520,"line":568},[518,1086,532],{"class":531},[518,1088,536],{"class":535},[518,1090,575],{"class":539},[518,1092,549],{"class":535},[518,1094,552],{"class":531},[518,1096,555],{"class":535},[518,1098,584],{"class":558},[518,1100,562],{"class":535},[518,1102,565],{"class":535},[518,1104,1105],{"class":520,"line":591},[518,1106,595],{"emptyLinePlaceholder":594},[518,1108,1109,1112,1114,1116,1119,1121,1123,1125,1127],{"class":520,"line":598},[518,1110,1111],{"class":601},"describe",[518,1113,605],{"class":539},[518,1115,562],{"class":535},[518,1117,1118],{"class":558},"UsersRepository",[518,1120,562],{"class":535},[518,1122,543],{"class":535},[518,1124,621],{"class":535},[518,1126,624],{"class":617},[518,1128,627],{"class":535},[518,1130,1131,1134,1136,1138,1141,1143,1145,1147,1149,1151],{"class":520,"line":630},[518,1132,1133],{"class":601},"  test",[518,1135,605],{"class":647},[518,1137,562],{"class":535},[518,1139,1140],{"class":558},"rejects a duplicate email with a domain error",[518,1142,562],{"class":535},[518,1144,543],{"class":535},[518,1146,618],{"class":617},[518,1148,621],{"class":535},[518,1150,624],{"class":617},[518,1152,627],{"class":535},[518,1154,1155,1158,1161,1163,1165,1167,1169],{"class":520,"line":653},[518,1156,1157],{"class":617},"    const",[518,1159,1160],{"class":539}," repository",[518,1162,639],{"class":535},[518,1164,642],{"class":535},[518,1166,575],{"class":601},[518,1168,648],{"class":647},[518,1170,565],{"class":535},[518,1172,1173],{"class":520,"line":678},[518,1174,595],{"emptyLinePlaceholder":594},[518,1176,1177,1180,1182,1184,1187,1189,1192,1194,1196,1198,1200,1202,1205,1207,1209,1212,1214,1216,1219,1221,1223,1225,1227,1230,1232,1235],{"class":520,"line":707},[518,1178,1179],{"class":531},"    await",[518,1181,540],{"class":601},[518,1183,605],{"class":647},[518,1185,1186],{"class":539},"repository",[518,1188,668],{"class":535},[518,1190,1191],{"class":601},"create",[518,1193,605],{"class":647},[518,1195,842],{"class":535},[518,1197,859],{"class":647},[518,1199,848],{"class":535},[518,1201,555],{"class":535},[518,1203,1204],{"class":558},"Another Alice",[518,1206,562],{"class":535},[518,1208,543],{"class":535},[518,1210,1211],{"class":647}," email",[518,1213,848],{"class":535},[518,1215,555],{"class":535},[518,1217,1218],{"class":558},"alice@example.com",[518,1220,562],{"class":535},[518,1222,549],{"class":535},[518,1224,832],{"class":647},[518,1226,668],{"class":535},[518,1228,1229],{"class":539},"rejects",[518,1231,668],{"class":535},[518,1233,1234],{"class":601},"toBeInstanceOf",[518,1236,1237],{"class":647},"(\n",[518,1239,1240,1243],{"class":520,"line":751},[518,1241,1242],{"class":539},"      EmailAlreadyInUseError",[518,1244,1245],{"class":535},",\n",[518,1247,1248,1251],{"class":520,"line":761},[518,1249,1250],{"class":647},"    )",[518,1252,565],{"class":535},[518,1254,1255,1258,1260],{"class":520,"line":766},[518,1256,1257],{"class":535},"  }",[518,1259,689],{"class":647},[518,1261,565],{"class":535},[518,1263,1264,1266,1268],{"class":520,"line":790},[518,1265,754],{"class":535},[518,1267,689],{"class":539},[518,1269,565],{"class":535},[1271,1272,1274],"h2",{"id":1273},"inject-fakes-through-the-constructor","Inject fakes through the constructor",[499,1276,1277,1278,1281,1282,1285],{},"When the class under test has collaborators, pass fakes straight into the constructor. A fake is any\nobject that satisfies the parameter's type. A CQRS handler is exactly this shape:\n",[503,1279,1280],{},"implements CommandHandler\u003C...>"," adds the message binding, but the constructor is still the dependency\ndeclaration, and ",[503,1283,1284],{},"handle"," is still a plain method you can call:",[508,1287,1290],{"className":510,"code":1288,"filename":1289,"language":513,"meta":514,"style":514},"import { expect, test, vi } from \"vitest\";\nimport { CreateUserCommand } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.command\";\nimport { CreateUserCommandHandler } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.handler\";\nimport { UserId } from \"..\u002Fsrc\u002Fusers\u002Fuser\";\n\n\u002F\u002F The constructor IS the dependency declaration — pass a fake store directly, no DI involved.\ntest(\"handle saves a new user at version 1\", () => {\n  const store = { save: vi.fn(), findById: vi.fn() };\n  const handler = new CreateUserCommandHandler(store as never);\n\n  handler.handle(new CreateUserCommand(UserId.from(\"u-1\"), \"Alice\", \"alice@example.com\"));\n\n  expect(store.save).toHaveBeenCalledWith(expect.objectContaining({ name: \"Alice\", version: 1 }));\n});\n","test\u002Fcreate-user.handler.test.ts",[503,1291,1292,1321,1343,1365,1387,1391,1396,1417,1461,1490,1494,1550,1554,1614],{"__ignoreMap":514},[518,1293,1294,1296,1298,1300,1302,1304,1306,1309,1311,1313,1315,1317,1319],{"class":520,"line":521},[518,1295,532],{"class":531},[518,1297,536],{"class":535},[518,1299,540],{"class":539},[518,1301,543],{"class":535},[518,1303,546],{"class":539},[518,1305,543],{"class":535},[518,1307,1308],{"class":539}," vi",[518,1310,549],{"class":535},[518,1312,552],{"class":531},[518,1314,555],{"class":535},[518,1316,559],{"class":558},[518,1318,562],{"class":535},[518,1320,565],{"class":535},[518,1322,1323,1325,1327,1330,1332,1334,1336,1339,1341],{"class":520,"line":528},[518,1324,532],{"class":531},[518,1326,536],{"class":535},[518,1328,1329],{"class":539}," CreateUserCommand",[518,1331,549],{"class":535},[518,1333,552],{"class":531},[518,1335,555],{"class":535},[518,1337,1338],{"class":558},"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.command",[518,1340,562],{"class":535},[518,1342,565],{"class":535},[518,1344,1345,1347,1349,1352,1354,1356,1358,1361,1363],{"class":520,"line":568},[518,1346,532],{"class":531},[518,1348,536],{"class":535},[518,1350,1351],{"class":539}," CreateUserCommandHandler",[518,1353,549],{"class":535},[518,1355,552],{"class":531},[518,1357,555],{"class":535},[518,1359,1360],{"class":558},"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.handler",[518,1362,562],{"class":535},[518,1364,565],{"class":535},[518,1366,1367,1369,1371,1374,1376,1378,1380,1383,1385],{"class":520,"line":591},[518,1368,532],{"class":531},[518,1370,536],{"class":535},[518,1372,1373],{"class":539}," UserId",[518,1375,549],{"class":535},[518,1377,552],{"class":531},[518,1379,555],{"class":535},[518,1381,1382],{"class":558},"..\u002Fsrc\u002Fusers\u002Fuser",[518,1384,562],{"class":535},[518,1386,565],{"class":535},[518,1388,1389],{"class":520,"line":598},[518,1390,595],{"emptyLinePlaceholder":594},[518,1392,1393],{"class":520,"line":630},[518,1394,1395],{"class":524},"\u002F\u002F The constructor IS the dependency declaration — pass a fake store directly, no DI involved.\n",[518,1397,1398,1400,1402,1404,1407,1409,1411,1413,1415],{"class":520,"line":653},[518,1399,602],{"class":601},[518,1401,605],{"class":539},[518,1403,562],{"class":535},[518,1405,1406],{"class":558},"handle saves a new user at version 1",[518,1408,562],{"class":535},[518,1410,543],{"class":535},[518,1412,621],{"class":535},[518,1414,624],{"class":617},[518,1416,627],{"class":535},[518,1418,1419,1421,1424,1426,1428,1431,1433,1435,1437,1440,1442,1444,1447,1449,1451,1453,1455,1458],{"class":520,"line":678},[518,1420,633],{"class":617},[518,1422,1423],{"class":539}," store",[518,1425,639],{"class":535},[518,1427,536],{"class":535},[518,1429,1430],{"class":647}," save",[518,1432,848],{"class":535},[518,1434,1308],{"class":539},[518,1436,668],{"class":535},[518,1438,1439],{"class":601},"fn",[518,1441,648],{"class":647},[518,1443,543],{"class":535},[518,1445,1446],{"class":647}," findById",[518,1448,848],{"class":535},[518,1450,1308],{"class":539},[518,1452,668],{"class":535},[518,1454,1439],{"class":601},[518,1456,1457],{"class":647},"() ",[518,1459,1460],{"class":535},"};\n",[518,1462,1463,1465,1468,1470,1472,1474,1476,1479,1482,1486,1488],{"class":520,"line":707},[518,1464,633],{"class":617},[518,1466,1467],{"class":539}," handler",[518,1469,639],{"class":535},[518,1471,642],{"class":535},[518,1473,1351],{"class":601},[518,1475,605],{"class":647},[518,1477,1478],{"class":539},"store",[518,1480,1481],{"class":531}," as",[518,1483,1485],{"class":1484},"sBMFI"," never",[518,1487,689],{"class":647},[518,1489,565],{"class":535},[518,1491,1492],{"class":520,"line":751},[518,1493,595],{"emptyLinePlaceholder":594},[518,1495,1496,1499,1501,1503,1505,1507,1509,1511,1514,1516,1519,1521,1523,1526,1528,1530,1532,1534,1536,1538,1540,1542,1544,1546,1548],{"class":520,"line":761},[518,1497,1498],{"class":539},"  handler",[518,1500,668],{"class":535},[518,1502,1284],{"class":601},[518,1504,605],{"class":647},[518,1506,505],{"class":535},[518,1508,1329],{"class":601},[518,1510,605],{"class":647},[518,1512,1513],{"class":539},"UserId",[518,1515,668],{"class":535},[518,1517,1518],{"class":601},"from",[518,1520,605],{"class":647},[518,1522,562],{"class":535},[518,1524,1525],{"class":558},"u-1",[518,1527,562],{"class":535},[518,1529,689],{"class":647},[518,1531,543],{"class":535},[518,1533,555],{"class":535},[518,1535,742],{"class":558},[518,1537,562],{"class":535},[518,1539,543],{"class":535},[518,1541,555],{"class":535},[518,1543,1218],{"class":558},[518,1545,562],{"class":535},[518,1547,832],{"class":647},[518,1549,565],{"class":535},[518,1551,1552],{"class":520,"line":766},[518,1553,595],{"emptyLinePlaceholder":594},[518,1555,1556,1558,1560,1562,1564,1567,1569,1571,1574,1576,1579,1581,1584,1586,1588,1590,1592,1594,1596,1598,1600,1603,1605,1608,1610,1612],{"class":520,"line":790},[518,1557,681],{"class":601},[518,1559,605],{"class":647},[518,1561,1478],{"class":539},[518,1563,668],{"class":535},[518,1565,1566],{"class":539},"save",[518,1568,689],{"class":647},[518,1570,668],{"class":535},[518,1572,1573],{"class":601},"toHaveBeenCalledWith",[518,1575,605],{"class":647},[518,1577,1578],{"class":539},"expect",[518,1580,668],{"class":535},[518,1582,1583],{"class":601},"objectContaining",[518,1585,605],{"class":647},[518,1587,842],{"class":535},[518,1589,859],{"class":647},[518,1591,848],{"class":535},[518,1593,555],{"class":535},[518,1595,742],{"class":558},[518,1597,562],{"class":535},[518,1599,543],{"class":535},[518,1601,1602],{"class":647}," version",[518,1604,848],{"class":535},[518,1606,1607],{"class":699}," 1",[518,1609,549],{"class":535},[518,1611,832],{"class":647},[518,1613,565],{"class":535},[518,1615,1616,1618,1620],{"class":520,"line":807},[518,1617,754],{"class":535},[518,1619,689],{"class":539},[518,1621,565],{"class":535},[499,1623,1624,1625,1628],{},"You only ever fake what the ",[951,1626,1627],{},"constructor"," declares — there's no token resolution and no module wiring to\naccount for, so testing a handler is no harder than testing a function. Error paths test the same way:\ndrive the fake into the failing state and assert the throw.",[508,1630,1633],{"className":510,"code":1631,"filename":1632,"language":513,"meta":514,"style":514},"import { NotFoundError } from \"@heximon\u002Fruntime\u002Ferrors\";\nimport { expect, test, vi } from \"vitest\";\nimport { UpdateUserCommand } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fupdate-user.command\";\nimport { UpdateUserCommandHandler } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fupdate-user.handler\";\nimport { UserId } from \"..\u002Fsrc\u002Fusers\u002Fuser\";\n\n\u002F\u002F Error paths test the same way: drive the fake into the failing state and assert the throw.\ntest(\"handle throws NotFoundError for an unknown id\", () => {\n  const store = { findById: vi.fn().mockReturnValue(undefined), save: vi.fn() };\n  const handler = new UpdateUserCommandHandler(store as never);\n\n  expect(() => handler.handle(new UpdateUserCommand(UserId.from(\"missing\"), { name: \"X\" }))).toThrow(NotFoundError);\n  expect(store.save).not.toHaveBeenCalled();\n});\n","test\u002Fupdate-user.handler.test.ts",[503,1634,1635,1657,1685,1707,1729,1749,1753,1758,1779,1829,1853,1857,1932,1960],{"__ignoreMap":514},[518,1636,1637,1639,1641,1644,1646,1648,1650,1653,1655],{"class":520,"line":521},[518,1638,532],{"class":531},[518,1640,536],{"class":535},[518,1642,1643],{"class":539}," NotFoundError",[518,1645,549],{"class":535},[518,1647,552],{"class":531},[518,1649,555],{"class":535},[518,1651,1652],{"class":558},"@heximon\u002Fruntime\u002Ferrors",[518,1654,562],{"class":535},[518,1656,565],{"class":535},[518,1658,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683],{"class":520,"line":528},[518,1660,532],{"class":531},[518,1662,536],{"class":535},[518,1664,540],{"class":539},[518,1666,543],{"class":535},[518,1668,546],{"class":539},[518,1670,543],{"class":535},[518,1672,1308],{"class":539},[518,1674,549],{"class":535},[518,1676,552],{"class":531},[518,1678,555],{"class":535},[518,1680,559],{"class":558},[518,1682,562],{"class":535},[518,1684,565],{"class":535},[518,1686,1687,1689,1691,1694,1696,1698,1700,1703,1705],{"class":520,"line":568},[518,1688,532],{"class":531},[518,1690,536],{"class":535},[518,1692,1693],{"class":539}," UpdateUserCommand",[518,1695,549],{"class":535},[518,1697,552],{"class":531},[518,1699,555],{"class":535},[518,1701,1702],{"class":558},"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fupdate-user.command",[518,1704,562],{"class":535},[518,1706,565],{"class":535},[518,1708,1709,1711,1713,1716,1718,1720,1722,1725,1727],{"class":520,"line":591},[518,1710,532],{"class":531},[518,1712,536],{"class":535},[518,1714,1715],{"class":539}," UpdateUserCommandHandler",[518,1717,549],{"class":535},[518,1719,552],{"class":531},[518,1721,555],{"class":535},[518,1723,1724],{"class":558},"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fupdate-user.handler",[518,1726,562],{"class":535},[518,1728,565],{"class":535},[518,1730,1731,1733,1735,1737,1739,1741,1743,1745,1747],{"class":520,"line":598},[518,1732,532],{"class":531},[518,1734,536],{"class":535},[518,1736,1373],{"class":539},[518,1738,549],{"class":535},[518,1740,552],{"class":531},[518,1742,555],{"class":535},[518,1744,1382],{"class":558},[518,1746,562],{"class":535},[518,1748,565],{"class":535},[518,1750,1751],{"class":520,"line":630},[518,1752,595],{"emptyLinePlaceholder":594},[518,1754,1755],{"class":520,"line":653},[518,1756,1757],{"class":524},"\u002F\u002F Error paths test the same way: drive the fake into the failing state and assert the throw.\n",[518,1759,1760,1762,1764,1766,1769,1771,1773,1775,1777],{"class":520,"line":678},[518,1761,602],{"class":601},[518,1763,605],{"class":539},[518,1765,562],{"class":535},[518,1767,1768],{"class":558},"handle throws NotFoundError for an unknown id",[518,1770,562],{"class":535},[518,1772,543],{"class":535},[518,1774,621],{"class":535},[518,1776,624],{"class":617},[518,1778,627],{"class":535},[518,1780,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1806,1808,1811,1813,1815,1817,1819,1821,1823,1825,1827],{"class":520,"line":707},[518,1782,633],{"class":617},[518,1784,1423],{"class":539},[518,1786,639],{"class":535},[518,1788,536],{"class":535},[518,1790,1446],{"class":647},[518,1792,848],{"class":535},[518,1794,1308],{"class":539},[518,1796,668],{"class":535},[518,1798,1439],{"class":601},[518,1800,648],{"class":647},[518,1802,668],{"class":535},[518,1804,1805],{"class":601},"mockReturnValue",[518,1807,605],{"class":647},[518,1809,1810],{"class":535},"undefined",[518,1812,689],{"class":647},[518,1814,543],{"class":535},[518,1816,1430],{"class":647},[518,1818,848],{"class":535},[518,1820,1308],{"class":539},[518,1822,668],{"class":535},[518,1824,1439],{"class":601},[518,1826,1457],{"class":647},[518,1828,1460],{"class":535},[518,1830,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851],{"class":520,"line":751},[518,1832,633],{"class":617},[518,1834,1467],{"class":539},[518,1836,639],{"class":535},[518,1838,642],{"class":535},[518,1840,1715],{"class":601},[518,1842,605],{"class":647},[518,1844,1478],{"class":539},[518,1846,1481],{"class":531},[518,1848,1485],{"class":1484},[518,1850,689],{"class":647},[518,1852,565],{"class":535},[518,1854,1855],{"class":520,"line":761},[518,1856,595],{"emptyLinePlaceholder":594},[518,1858,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1889,1891,1894,1896,1898,1900,1902,1904,1906,1908,1911,1913,1915,1918,1920,1923,1925,1928,1930],{"class":520,"line":766},[518,1860,681],{"class":601},[518,1862,605],{"class":647},[518,1864,648],{"class":535},[518,1866,624],{"class":617},[518,1868,1467],{"class":539},[518,1870,668],{"class":535},[518,1872,1284],{"class":601},[518,1874,605],{"class":647},[518,1876,505],{"class":535},[518,1878,1693],{"class":601},[518,1880,605],{"class":647},[518,1882,1513],{"class":539},[518,1884,668],{"class":535},[518,1886,1518],{"class":601},[518,1888,605],{"class":647},[518,1890,562],{"class":535},[518,1892,1893],{"class":558},"missing",[518,1895,562],{"class":535},[518,1897,689],{"class":647},[518,1899,543],{"class":535},[518,1901,536],{"class":535},[518,1903,859],{"class":647},[518,1905,848],{"class":535},[518,1907,555],{"class":535},[518,1909,1910],{"class":558},"X",[518,1912,562],{"class":535},[518,1914,549],{"class":535},[518,1916,1917],{"class":647},")))",[518,1919,668],{"class":535},[518,1921,1922],{"class":601},"toThrow",[518,1924,605],{"class":647},[518,1926,1927],{"class":539},"NotFoundError",[518,1929,689],{"class":647},[518,1931,565],{"class":535},[518,1933,1934,1936,1938,1940,1942,1944,1946,1948,1951,1953,1956,1958],{"class":520,"line":790},[518,1935,681],{"class":601},[518,1937,605],{"class":647},[518,1939,1478],{"class":539},[518,1941,668],{"class":535},[518,1943,1566],{"class":539},[518,1945,689],{"class":647},[518,1947,668],{"class":535},[518,1949,1950],{"class":539},"not",[518,1952,668],{"class":535},[518,1954,1955],{"class":601},"toHaveBeenCalled",[518,1957,648],{"class":647},[518,1959,565],{"class":535},[518,1961,1962,1964,1966],{"class":520,"line":807},[518,1963,754],{"class":535},[518,1965,689],{"class":539},[518,1967,565],{"class":535},[499,1969,1970,1971,1974,1975,1978],{},"This proves the error path at the method level. Proving the ",[951,1972,1973],{},"bus retries"," a ",[503,1976,1977],{},"ConcurrencyError"," — the\n3-attempt policy baked into the wiring — needs the real compiled dispatch, covered below.",[1271,1980,1982],{"id":1981},"drive-routes-with-the-in-process-client","Drive routes with the in-process client",[499,1984,1985,1986,1988,1989,1992,1993,1999],{},"When you want to test what a request actually does — the typed route, the middleware chain, body\nvalidation, the error filters, the per-request context — boot the compiled app and send it real\n",[503,1987,994],{},"s. ",[503,1990,1991],{},"createTestClient"," runs the ",[951,1994,1995,1996],{},"same generated ",[503,1997,1998],{},"fetch"," a production host serves, so the\nround-trip exercises the real wiring with no port and no network.",[499,2001,2002,2003,2005,2006,2009,2010,2013],{},"The recommended way to boot the app in a test is ",[503,2004,999],{}," from ",[503,2007,2008],{},"@heximon\u002Ftesting",". It compiles\nand boots a fresh, isolated app in one call — no manual ",[503,2011,2012],{},".heximon\u002F"," imports, no temp-dir cleanup:",[508,2015,2017],{"className":510,"code":2016,"filename":512,"language":513,"meta":514,"style":514},"import { createTestClient } from \"@heximon\u002Fhttp\u002Ftesting\";\nimport { createTestApp } from \"@heximon\u002Ftesting\";\nimport { expect, test } from \"vitest\";\nimport { UsersRepository } from \"..\u002Fsrc\u002Fusers\u002Fusers.repository\";\n\ntest(\"createTestApp() resolves a DI token\", async () => {\n  await using app = await createTestApp();\n\n  const repository = await app.get(UsersRepository);\n\n  expect(await repository.list()).toHaveLength(2);\n});\n\ntest(\"createTestApp() + createTestClient(app) drive GET \u002Fusers\", async () => {\n  await using app = await createTestApp();\n  const client = createTestClient(app);\n\n  const response = await client.request(new Request(\"http:\u002F\u002Flocalhost\u002Fusers\"));\n\n  expect(response.status).toBe(200);\n  expect(await response.json()).toHaveLength(2);\n});\n",[503,2018,2019,2041,2062,2086,2106,2110,2133,2151,2155,2180,2184,2213,2221,2225,2248,2264,2284,2289,2328,2333,2363,2393],{"__ignoreMap":514},[518,2020,2021,2023,2025,2028,2030,2032,2034,2037,2039],{"class":520,"line":521},[518,2022,532],{"class":531},[518,2024,536],{"class":535},[518,2026,2027],{"class":539}," createTestClient",[518,2029,549],{"class":535},[518,2031,552],{"class":531},[518,2033,555],{"class":535},[518,2035,2036],{"class":558},"@heximon\u002Fhttp\u002Ftesting",[518,2038,562],{"class":535},[518,2040,565],{"class":535},[518,2042,2043,2045,2047,2050,2052,2054,2056,2058,2060],{"class":520,"line":528},[518,2044,532],{"class":531},[518,2046,536],{"class":535},[518,2048,2049],{"class":539}," createTestApp",[518,2051,549],{"class":535},[518,2053,552],{"class":531},[518,2055,555],{"class":535},[518,2057,2008],{"class":558},[518,2059,562],{"class":535},[518,2061,565],{"class":535},[518,2063,2064,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084],{"class":520,"line":568},[518,2065,532],{"class":531},[518,2067,536],{"class":535},[518,2069,540],{"class":539},[518,2071,543],{"class":535},[518,2073,546],{"class":539},[518,2075,549],{"class":535},[518,2077,552],{"class":531},[518,2079,555],{"class":535},[518,2081,559],{"class":558},[518,2083,562],{"class":535},[518,2085,565],{"class":535},[518,2087,2088,2090,2092,2094,2096,2098,2100,2102,2104],{"class":520,"line":591},[518,2089,532],{"class":531},[518,2091,536],{"class":535},[518,2093,575],{"class":539},[518,2095,549],{"class":535},[518,2097,552],{"class":531},[518,2099,555],{"class":535},[518,2101,584],{"class":558},[518,2103,562],{"class":535},[518,2105,565],{"class":535},[518,2107,2108],{"class":520,"line":598},[518,2109,595],{"emptyLinePlaceholder":594},[518,2111,2112,2114,2116,2118,2121,2123,2125,2127,2129,2131],{"class":520,"line":630},[518,2113,602],{"class":601},[518,2115,605],{"class":539},[518,2117,562],{"class":535},[518,2119,2120],{"class":558},"createTestApp() resolves a DI token",[518,2122,562],{"class":535},[518,2124,543],{"class":535},[518,2126,618],{"class":617},[518,2128,621],{"class":535},[518,2130,624],{"class":617},[518,2132,627],{"class":535},[518,2134,2135,2138,2141,2143,2145,2147,2149],{"class":520,"line":653},[518,2136,2137],{"class":617},"  await using",[518,2139,2140],{"class":539}," app",[518,2142,639],{"class":535},[518,2144,663],{"class":531},[518,2146,2049],{"class":601},[518,2148,648],{"class":647},[518,2150,565],{"class":535},[518,2152,2153],{"class":520,"line":678},[518,2154,595],{"emptyLinePlaceholder":594},[518,2156,2157,2159,2161,2163,2165,2167,2169,2172,2174,2176,2178],{"class":520,"line":707},[518,2158,633],{"class":617},[518,2160,1160],{"class":539},[518,2162,639],{"class":535},[518,2164,663],{"class":531},[518,2166,2140],{"class":539},[518,2168,668],{"class":535},[518,2170,2171],{"class":601},"get",[518,2173,605],{"class":647},[518,2175,1118],{"class":539},[518,2177,689],{"class":647},[518,2179,565],{"class":535},[518,2181,2182],{"class":520,"line":751},[518,2183,595],{"emptyLinePlaceholder":594},[518,2185,2186,2188,2190,2192,2194,2196,2198,2201,2203,2205,2207,2209,2211],{"class":520,"line":761},[518,2187,681],{"class":601},[518,2189,605],{"class":647},[518,2191,814],{"class":531},[518,2193,1160],{"class":539},[518,2195,668],{"class":535},[518,2197,671],{"class":601},[518,2199,2200],{"class":647},"())",[518,2202,668],{"class":535},[518,2204,694],{"class":601},[518,2206,605],{"class":647},[518,2208,700],{"class":699},[518,2210,689],{"class":647},[518,2212,565],{"class":535},[518,2214,2215,2217,2219],{"class":520,"line":766},[518,2216,754],{"class":535},[518,2218,689],{"class":539},[518,2220,565],{"class":535},[518,2222,2223],{"class":520,"line":790},[518,2224,595],{"emptyLinePlaceholder":594},[518,2226,2227,2229,2231,2233,2236,2238,2240,2242,2244,2246],{"class":520,"line":807},[518,2228,602],{"class":601},[518,2230,605],{"class":539},[518,2232,562],{"class":535},[518,2234,2235],{"class":558},"createTestApp() + createTestClient(app) drive GET \u002Fusers",[518,2237,562],{"class":535},[518,2239,543],{"class":535},[518,2241,618],{"class":617},[518,2243,621],{"class":535},[518,2245,624],{"class":617},[518,2247,627],{"class":535},[518,2249,2250,2252,2254,2256,2258,2260,2262],{"class":520,"line":877},[518,2251,2137],{"class":617},[518,2253,2140],{"class":539},[518,2255,639],{"class":535},[518,2257,663],{"class":531},[518,2259,2049],{"class":601},[518,2261,648],{"class":647},[518,2263,565],{"class":535},[518,2265,2266,2268,2271,2273,2275,2277,2280,2282],{"class":520,"line":912},[518,2267,633],{"class":617},[518,2269,2270],{"class":539}," client",[518,2272,639],{"class":535},[518,2274,2027],{"class":601},[518,2276,605],{"class":647},[518,2278,2279],{"class":539},"app",[518,2281,689],{"class":647},[518,2283,565],{"class":535},[518,2285,2287],{"class":520,"line":2286},17,[518,2288,595],{"emptyLinePlaceholder":594},[518,2290,2292,2294,2297,2299,2301,2303,2305,2308,2310,2312,2315,2317,2319,2322,2324,2326],{"class":520,"line":2291},18,[518,2293,633],{"class":617},[518,2295,2296],{"class":539}," response",[518,2298,639],{"class":535},[518,2300,663],{"class":531},[518,2302,2270],{"class":539},[518,2304,668],{"class":535},[518,2306,2307],{"class":601},"request",[518,2309,605],{"class":647},[518,2311,505],{"class":535},[518,2313,2314],{"class":601}," Request",[518,2316,605],{"class":647},[518,2318,562],{"class":535},[518,2320,2321],{"class":558},"http:\u002F\u002Flocalhost\u002Fusers",[518,2323,562],{"class":535},[518,2325,832],{"class":647},[518,2327,565],{"class":535},[518,2329,2331],{"class":520,"line":2330},19,[518,2332,595],{"emptyLinePlaceholder":594},[518,2334,2336,2338,2340,2343,2345,2348,2350,2352,2354,2356,2359,2361],{"class":520,"line":2335},20,[518,2337,681],{"class":601},[518,2339,605],{"class":647},[518,2341,2342],{"class":539},"response",[518,2344,668],{"class":535},[518,2346,2347],{"class":539},"status",[518,2349,689],{"class":647},[518,2351,668],{"class":535},[518,2353,735],{"class":601},[518,2355,605],{"class":647},[518,2357,2358],{"class":699},"200",[518,2360,689],{"class":647},[518,2362,565],{"class":535},[518,2364,2366,2368,2370,2372,2374,2376,2379,2381,2383,2385,2387,2389,2391],{"class":520,"line":2365},21,[518,2367,681],{"class":601},[518,2369,605],{"class":647},[518,2371,814],{"class":531},[518,2373,2296],{"class":539},[518,2375,668],{"class":535},[518,2377,2378],{"class":601},"json",[518,2380,2200],{"class":647},[518,2382,668],{"class":535},[518,2384,694],{"class":601},[518,2386,605],{"class":647},[518,2388,700],{"class":699},[518,2390,689],{"class":647},[518,2392,565],{"class":535},[518,2394,2396,2398,2400],{"class":520,"line":2395},22,[518,2397,754],{"class":535},[518,2399,689],{"class":539},[518,2401,565],{"class":535},[499,2403,2404,2405,2408,2409,2412,2413,2416],{},"A ",[503,2406,2407],{},"POST"," is the same call with a JSON body, and an invalid body proves the validation filter runs\n",[951,2410,2411],{},"before"," your handler — the ",[503,2414,2415],{},"400"," comes from the boundary, not from code you wrote:",[508,2418,2420],{"className":510,"code":2419,"filename":512,"language":513,"meta":514,"style":514},"import { type TestClient, createTestClient } from \"@heximon\u002Fhttp\u002Ftesting\";\nimport { type TestApp, createTestApp } from \"@heximon\u002Ftesting\";\nimport { afterAll, beforeAll, expect, test } from \"vitest\";\n\nlet app: TestApp;\nlet client: TestClient;\n\nbeforeAll(async () => {\n  app = await createTestApp();\n  client = createTestClient(app);\n});\n\nafterAll(() => app[Symbol.asyncDispose]());\n\ntest(\"POST \u002Fusers rejects an invalid body with a 4xx (built-in validation filter)\", async () => {\n  const response = await client.request(\n    new Request(\"http:\u002F\u002Flocalhost\u002Fusers\", {\n      method: \"POST\",\n      headers: { \"content-type\": \"application\u002Fjson\" },\n      body: JSON.stringify({ name: \"\", email: \"not-an-email\" }), \u002F\u002F fails the create schema\n    }),\n  );\n\n  expect(response.status).toBeGreaterThanOrEqual(400);\n  expect(response.status).toBeLessThan(500);\n});\n",[503,2421,2422,2450,2477,2511,2515,2528,2540,2544,2560,2575,2592,2600,2604,2625,2629,2652,2670,2689,2704,2732,2780,2789,2796,2801,2829,2858],{"__ignoreMap":514},[518,2423,2424,2426,2428,2431,2434,2436,2438,2440,2442,2444,2446,2448],{"class":520,"line":521},[518,2425,532],{"class":531},[518,2427,536],{"class":535},[518,2429,2430],{"class":531}," type",[518,2432,2433],{"class":539}," TestClient",[518,2435,543],{"class":535},[518,2437,2027],{"class":539},[518,2439,549],{"class":535},[518,2441,552],{"class":531},[518,2443,555],{"class":535},[518,2445,2036],{"class":558},[518,2447,562],{"class":535},[518,2449,565],{"class":535},[518,2451,2452,2454,2456,2458,2461,2463,2465,2467,2469,2471,2473,2475],{"class":520,"line":528},[518,2453,532],{"class":531},[518,2455,536],{"class":535},[518,2457,2430],{"class":531},[518,2459,2460],{"class":539}," TestApp",[518,2462,543],{"class":535},[518,2464,2049],{"class":539},[518,2466,549],{"class":535},[518,2468,552],{"class":531},[518,2470,555],{"class":535},[518,2472,2008],{"class":558},[518,2474,562],{"class":535},[518,2476,565],{"class":535},[518,2478,2479,2481,2483,2486,2488,2491,2493,2495,2497,2499,2501,2503,2505,2507,2509],{"class":520,"line":568},[518,2480,532],{"class":531},[518,2482,536],{"class":535},[518,2484,2485],{"class":539}," afterAll",[518,2487,543],{"class":535},[518,2489,2490],{"class":539}," beforeAll",[518,2492,543],{"class":535},[518,2494,540],{"class":539},[518,2496,543],{"class":535},[518,2498,546],{"class":539},[518,2500,549],{"class":535},[518,2502,552],{"class":531},[518,2504,555],{"class":535},[518,2506,559],{"class":558},[518,2508,562],{"class":535},[518,2510,565],{"class":535},[518,2512,2513],{"class":520,"line":591},[518,2514,595],{"emptyLinePlaceholder":594},[518,2516,2517,2520,2522,2524,2526],{"class":520,"line":598},[518,2518,2519],{"class":617},"let",[518,2521,2140],{"class":539},[518,2523,848],{"class":535},[518,2525,2460],{"class":1484},[518,2527,565],{"class":535},[518,2529,2530,2532,2534,2536,2538],{"class":520,"line":630},[518,2531,2519],{"class":617},[518,2533,2270],{"class":539},[518,2535,848],{"class":535},[518,2537,2433],{"class":1484},[518,2539,565],{"class":535},[518,2541,2542],{"class":520,"line":653},[518,2543,595],{"emptyLinePlaceholder":594},[518,2545,2546,2549,2551,2554,2556,2558],{"class":520,"line":678},[518,2547,2548],{"class":601},"beforeAll",[518,2550,605],{"class":539},[518,2552,2553],{"class":617},"async",[518,2555,621],{"class":535},[518,2557,624],{"class":617},[518,2559,627],{"class":535},[518,2561,2562,2565,2567,2569,2571,2573],{"class":520,"line":707},[518,2563,2564],{"class":539},"  app",[518,2566,639],{"class":535},[518,2568,663],{"class":531},[518,2570,2049],{"class":601},[518,2572,648],{"class":647},[518,2574,565],{"class":535},[518,2576,2577,2580,2582,2584,2586,2588,2590],{"class":520,"line":751},[518,2578,2579],{"class":539},"  client",[518,2581,639],{"class":535},[518,2583,2027],{"class":601},[518,2585,605],{"class":647},[518,2587,2279],{"class":539},[518,2589,689],{"class":647},[518,2591,565],{"class":535},[518,2593,2594,2596,2598],{"class":520,"line":761},[518,2595,754],{"class":535},[518,2597,689],{"class":539},[518,2599,565],{"class":535},[518,2601,2602],{"class":520,"line":766},[518,2603,595],{"emptyLinePlaceholder":594},[518,2605,2606,2609,2611,2613,2615,2618,2620,2623],{"class":520,"line":790},[518,2607,2608],{"class":601},"afterAll",[518,2610,605],{"class":539},[518,2612,648],{"class":535},[518,2614,624],{"class":617},[518,2616,2617],{"class":539}," app[Symbol",[518,2619,668],{"class":535},[518,2621,2622],{"class":539},"asyncDispose]())",[518,2624,565],{"class":535},[518,2626,2627],{"class":520,"line":807},[518,2628,595],{"emptyLinePlaceholder":594},[518,2630,2631,2633,2635,2637,2640,2642,2644,2646,2648,2650],{"class":520,"line":877},[518,2632,602],{"class":601},[518,2634,605],{"class":539},[518,2636,562],{"class":535},[518,2638,2639],{"class":558},"POST \u002Fusers rejects an invalid body with a 4xx (built-in validation filter)",[518,2641,562],{"class":535},[518,2643,543],{"class":535},[518,2645,618],{"class":617},[518,2647,621],{"class":535},[518,2649,624],{"class":617},[518,2651,627],{"class":535},[518,2653,2654,2656,2658,2660,2662,2664,2666,2668],{"class":520,"line":912},[518,2655,633],{"class":617},[518,2657,2296],{"class":539},[518,2659,639],{"class":535},[518,2661,663],{"class":531},[518,2663,2270],{"class":539},[518,2665,668],{"class":535},[518,2667,2307],{"class":601},[518,2669,1237],{"class":647},[518,2671,2672,2675,2677,2679,2681,2683,2685,2687],{"class":520,"line":2286},[518,2673,2674],{"class":535},"    new",[518,2676,2314],{"class":601},[518,2678,605],{"class":647},[518,2680,562],{"class":535},[518,2682,2321],{"class":558},[518,2684,562],{"class":535},[518,2686,543],{"class":535},[518,2688,627],{"class":535},[518,2690,2691,2694,2696,2698,2700,2702],{"class":520,"line":2291},[518,2692,2693],{"class":647},"      method",[518,2695,848],{"class":535},[518,2697,555],{"class":535},[518,2699,2407],{"class":558},[518,2701,562],{"class":535},[518,2703,1245],{"class":535},[518,2705,2706,2709,2711,2713,2715,2718,2720,2722,2724,2727,2729],{"class":520,"line":2330},[518,2707,2708],{"class":647},"      headers",[518,2710,848],{"class":535},[518,2712,536],{"class":535},[518,2714,555],{"class":535},[518,2716,2717],{"class":647},"content-type",[518,2719,562],{"class":535},[518,2721,848],{"class":535},[518,2723,555],{"class":535},[518,2725,2726],{"class":558},"application\u002Fjson",[518,2728,562],{"class":535},[518,2730,2731],{"class":535}," },\n",[518,2733,2734,2737,2739,2742,2744,2747,2749,2751,2753,2755,2758,2760,2762,2764,2766,2769,2771,2773,2775,2777],{"class":520,"line":2335},[518,2735,2736],{"class":647},"      body",[518,2738,848],{"class":535},[518,2740,2741],{"class":539}," JSON",[518,2743,668],{"class":535},[518,2745,2746],{"class":601},"stringify",[518,2748,605],{"class":647},[518,2750,842],{"class":535},[518,2752,859],{"class":647},[518,2754,848],{"class":535},[518,2756,2757],{"class":535}," \"\"",[518,2759,543],{"class":535},[518,2761,1211],{"class":647},[518,2763,848],{"class":535},[518,2765,555],{"class":535},[518,2767,2768],{"class":558},"not-an-email",[518,2770,562],{"class":535},[518,2772,549],{"class":535},[518,2774,689],{"class":647},[518,2776,543],{"class":535},[518,2778,2779],{"class":524}," \u002F\u002F fails the create schema\n",[518,2781,2782,2785,2787],{"class":520,"line":2365},[518,2783,2784],{"class":535},"    }",[518,2786,689],{"class":647},[518,2788,1245],{"class":535},[518,2790,2791,2794],{"class":520,"line":2395},[518,2792,2793],{"class":647},"  )",[518,2795,565],{"class":535},[518,2797,2799],{"class":520,"line":2798},23,[518,2800,595],{"emptyLinePlaceholder":594},[518,2802,2804,2806,2808,2810,2812,2814,2816,2818,2821,2823,2825,2827],{"class":520,"line":2803},24,[518,2805,681],{"class":601},[518,2807,605],{"class":647},[518,2809,2342],{"class":539},[518,2811,668],{"class":535},[518,2813,2347],{"class":539},[518,2815,689],{"class":647},[518,2817,668],{"class":535},[518,2819,2820],{"class":601},"toBeGreaterThanOrEqual",[518,2822,605],{"class":647},[518,2824,2415],{"class":699},[518,2826,689],{"class":647},[518,2828,565],{"class":535},[518,2830,2832,2834,2836,2838,2840,2842,2844,2846,2849,2851,2854,2856],{"class":520,"line":2831},25,[518,2833,681],{"class":601},[518,2835,605],{"class":647},[518,2837,2342],{"class":539},[518,2839,668],{"class":535},[518,2841,2347],{"class":539},[518,2843,689],{"class":647},[518,2845,668],{"class":535},[518,2847,2848],{"class":601},"toBeLessThan",[518,2850,605],{"class":647},[518,2852,2853],{"class":699},"500",[518,2855,689],{"class":647},[518,2857,565],{"class":535},[518,2859,2861,2863,2865],{"class":520,"line":2860},26,[518,2862,754],{"class":535},[518,2864,689],{"class":539},[518,2866,565],{"class":535},[499,2868,2869,2870,2873,2874,2876,2877,2879,2880,2883,2884,668],{},"Reuse one ",[503,2871,2872],{},"client"," across a test's requests — ",[503,2875,1003],{}," is cheap; the boot cost is in\n",[503,2878,999],{},". See ",[2881,2882,116],"a",{"href":117}," for the full reference: provider\noverrides, database isolation, contract-mode registration, multi-app isolation, and configuring plugins\nvia ",[503,2885,2886],{},"heximon.config.ts",[1271,2888,2890],{"id":2889},"dispatch-commands-and-queries-over-the-real-bus","Dispatch commands and queries over the real bus",[499,2892,2893,2894,2896,2897,2900,2901,2904],{},"A command or query handler is wired to its bus at compile time, so the most faithful way to test one is\nto dispatch through the real bus. Boot the app, ",[503,2895,2171],{}," the bus by its class token, and ",[503,2898,2899],{},"execute"," a\nmessage — exactly what a controller does. Because commands return ",[503,2902,2903],{},"void",", mint the id up front and read\nthe new state back with a query.",[508,2906,2909],{"className":510,"code":2907,"filename":2908,"language":513,"meta":514,"style":514},"import { CommandBus, QueryBus } from \"@heximon\u002Fcqrs\";\nimport { createTestApp } from \"@heximon\u002Ftesting\";\nimport { expect, test } from \"vitest\";\nimport { CreateUserCommand } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.command\";\nimport { ListUsersQuery } from \"..\u002Fsrc\u002Fusers\u002Fqueries\u002Flist-users.query\";\nimport { UserId } from \"..\u002Fsrc\u002Fusers\u002Fuser\";\n\ntest(\"createTestApp() dispatches a command and reads it back through a query\", async () => {\n  await using app = await createTestApp();\n\n  const commandBus = await app.get(CommandBus);\n  const queryBus = await app.get(QueryBus);\n  const id = UserId.generate();\n\n  await app.context.run(async () => {\n    await commandBus.execute(new CreateUserCommand(id, \"Alice\", \"alice@example.com\"));\n\n    const users = await queryBus.execute(new ListUsersQuery());\n    expect(users.some((user) => user.id === id)).toBe(true);\n  });\n});\n","test\u002Fcqrs.test.ts",[503,2910,2911,2938,2958,2982,3002,3024,3044,3048,3071,3087,3091,3117,3143,3162,3166,3193,3234,3238,3264,3318,3326],{"__ignoreMap":514},[518,2912,2913,2915,2917,2920,2922,2925,2927,2929,2931,2934,2936],{"class":520,"line":521},[518,2914,532],{"class":531},[518,2916,536],{"class":535},[518,2918,2919],{"class":539}," CommandBus",[518,2921,543],{"class":535},[518,2923,2924],{"class":539}," QueryBus",[518,2926,549],{"class":535},[518,2928,552],{"class":531},[518,2930,555],{"class":535},[518,2932,2933],{"class":558},"@heximon\u002Fcqrs",[518,2935,562],{"class":535},[518,2937,565],{"class":535},[518,2939,2940,2942,2944,2946,2948,2950,2952,2954,2956],{"class":520,"line":528},[518,2941,532],{"class":531},[518,2943,536],{"class":535},[518,2945,2049],{"class":539},[518,2947,549],{"class":535},[518,2949,552],{"class":531},[518,2951,555],{"class":535},[518,2953,2008],{"class":558},[518,2955,562],{"class":535},[518,2957,565],{"class":535},[518,2959,2960,2962,2964,2966,2968,2970,2972,2974,2976,2978,2980],{"class":520,"line":568},[518,2961,532],{"class":531},[518,2963,536],{"class":535},[518,2965,540],{"class":539},[518,2967,543],{"class":535},[518,2969,546],{"class":539},[518,2971,549],{"class":535},[518,2973,552],{"class":531},[518,2975,555],{"class":535},[518,2977,559],{"class":558},[518,2979,562],{"class":535},[518,2981,565],{"class":535},[518,2983,2984,2986,2988,2990,2992,2994,2996,2998,3000],{"class":520,"line":591},[518,2985,532],{"class":531},[518,2987,536],{"class":535},[518,2989,1329],{"class":539},[518,2991,549],{"class":535},[518,2993,552],{"class":531},[518,2995,555],{"class":535},[518,2997,1338],{"class":558},[518,2999,562],{"class":535},[518,3001,565],{"class":535},[518,3003,3004,3006,3008,3011,3013,3015,3017,3020,3022],{"class":520,"line":598},[518,3005,532],{"class":531},[518,3007,536],{"class":535},[518,3009,3010],{"class":539}," ListUsersQuery",[518,3012,549],{"class":535},[518,3014,552],{"class":531},[518,3016,555],{"class":535},[518,3018,3019],{"class":558},"..\u002Fsrc\u002Fusers\u002Fqueries\u002Flist-users.query",[518,3021,562],{"class":535},[518,3023,565],{"class":535},[518,3025,3026,3028,3030,3032,3034,3036,3038,3040,3042],{"class":520,"line":630},[518,3027,532],{"class":531},[518,3029,536],{"class":535},[518,3031,1373],{"class":539},[518,3033,549],{"class":535},[518,3035,552],{"class":531},[518,3037,555],{"class":535},[518,3039,1382],{"class":558},[518,3041,562],{"class":535},[518,3043,565],{"class":535},[518,3045,3046],{"class":520,"line":653},[518,3047,595],{"emptyLinePlaceholder":594},[518,3049,3050,3052,3054,3056,3059,3061,3063,3065,3067,3069],{"class":520,"line":678},[518,3051,602],{"class":601},[518,3053,605],{"class":539},[518,3055,562],{"class":535},[518,3057,3058],{"class":558},"createTestApp() dispatches a command and reads it back through a query",[518,3060,562],{"class":535},[518,3062,543],{"class":535},[518,3064,618],{"class":617},[518,3066,621],{"class":535},[518,3068,624],{"class":617},[518,3070,627],{"class":535},[518,3072,3073,3075,3077,3079,3081,3083,3085],{"class":520,"line":707},[518,3074,2137],{"class":617},[518,3076,2140],{"class":539},[518,3078,639],{"class":535},[518,3080,663],{"class":531},[518,3082,2049],{"class":601},[518,3084,648],{"class":647},[518,3086,565],{"class":535},[518,3088,3089],{"class":520,"line":751},[518,3090,595],{"emptyLinePlaceholder":594},[518,3092,3093,3095,3098,3100,3102,3104,3106,3108,3110,3113,3115],{"class":520,"line":761},[518,3094,633],{"class":617},[518,3096,3097],{"class":539}," commandBus",[518,3099,639],{"class":535},[518,3101,663],{"class":531},[518,3103,2140],{"class":539},[518,3105,668],{"class":535},[518,3107,2171],{"class":601},[518,3109,605],{"class":647},[518,3111,3112],{"class":539},"CommandBus",[518,3114,689],{"class":647},[518,3116,565],{"class":535},[518,3118,3119,3121,3124,3126,3128,3130,3132,3134,3136,3139,3141],{"class":520,"line":766},[518,3120,633],{"class":617},[518,3122,3123],{"class":539}," queryBus",[518,3125,639],{"class":535},[518,3127,663],{"class":531},[518,3129,2140],{"class":539},[518,3131,668],{"class":535},[518,3133,2171],{"class":601},[518,3135,605],{"class":647},[518,3137,3138],{"class":539},"QueryBus",[518,3140,689],{"class":647},[518,3142,565],{"class":535},[518,3144,3145,3147,3149,3151,3153,3155,3158,3160],{"class":520,"line":790},[518,3146,633],{"class":617},[518,3148,845],{"class":539},[518,3150,639],{"class":535},[518,3152,1373],{"class":539},[518,3154,668],{"class":535},[518,3156,3157],{"class":601},"generate",[518,3159,648],{"class":647},[518,3161,565],{"class":535},[518,3163,3164],{"class":520,"line":807},[518,3165,595],{"emptyLinePlaceholder":594},[518,3167,3168,3171,3173,3175,3178,3180,3183,3185,3187,3189,3191],{"class":520,"line":877},[518,3169,3170],{"class":531},"  await",[518,3172,2140],{"class":539},[518,3174,668],{"class":535},[518,3176,3177],{"class":539},"context",[518,3179,668],{"class":535},[518,3181,3182],{"class":601},"run",[518,3184,605],{"class":647},[518,3186,2553],{"class":617},[518,3188,621],{"class":535},[518,3190,624],{"class":617},[518,3192,627],{"class":535},[518,3194,3195,3197,3199,3201,3203,3205,3207,3209,3211,3214,3216,3218,3220,3222,3224,3226,3228,3230,3232],{"class":520,"line":912},[518,3196,1179],{"class":531},[518,3198,3097],{"class":539},[518,3200,668],{"class":535},[518,3202,2899],{"class":601},[518,3204,605],{"class":647},[518,3206,505],{"class":535},[518,3208,1329],{"class":601},[518,3210,605],{"class":647},[518,3212,3213],{"class":539},"id",[518,3215,543],{"class":535},[518,3217,555],{"class":535},[518,3219,742],{"class":558},[518,3221,562],{"class":535},[518,3223,543],{"class":535},[518,3225,555],{"class":535},[518,3227,1218],{"class":558},[518,3229,562],{"class":535},[518,3231,832],{"class":647},[518,3233,565],{"class":535},[518,3235,3236],{"class":520,"line":2286},[518,3237,595],{"emptyLinePlaceholder":594},[518,3239,3240,3242,3244,3246,3248,3250,3252,3254,3256,3258,3260,3262],{"class":520,"line":2291},[518,3241,1157],{"class":617},[518,3243,658],{"class":539},[518,3245,639],{"class":535},[518,3247,663],{"class":531},[518,3249,3123],{"class":539},[518,3251,668],{"class":535},[518,3253,2899],{"class":601},[518,3255,605],{"class":647},[518,3257,505],{"class":535},[518,3259,3010],{"class":601},[518,3261,2200],{"class":647},[518,3263,565],{"class":535},[518,3265,3266,3269,3271,3273,3275,3278,3280,3282,3286,3288,3290,3293,3295,3297,3300,3302,3304,3306,3308,3310,3314,3316],{"class":520,"line":2330},[518,3267,3268],{"class":601},"    expect",[518,3270,605],{"class":647},[518,3272,686],{"class":539},[518,3274,668],{"class":535},[518,3276,3277],{"class":601},"some",[518,3279,605],{"class":647},[518,3281,605],{"class":535},[518,3283,3285],{"class":3284},"sHdIc","user",[518,3287,689],{"class":535},[518,3289,624],{"class":617},[518,3291,3292],{"class":539}," user",[518,3294,668],{"class":535},[518,3296,3213],{"class":539},[518,3298,3299],{"class":535}," ===",[518,3301,845],{"class":539},[518,3303,832],{"class":647},[518,3305,668],{"class":535},[518,3307,735],{"class":601},[518,3309,605],{"class":647},[518,3311,3313],{"class":3312},"sfNiH","true",[518,3315,689],{"class":647},[518,3317,565],{"class":535},[518,3319,3320,3322,3324],{"class":520,"line":2335},[518,3321,1257],{"class":535},[518,3323,689],{"class":647},[518,3325,565],{"class":535},[518,3327,3328,3330,3332],{"class":520,"line":2365},[518,3329,754],{"class":535},[518,3331,689],{"class":539},[518,3333,565],{"class":535},[499,3335,3336,3337,3339,3340,3343,3344,3347],{},"Dispatching through the bus exercises the handler, its dependencies, and the automatic\n",[503,3338,1977],{}," retry together — and the retry, living in the wiring rather than your handler, can\nonly be observed this way. Direct dispatch outside an HTTP request requires ",[503,3341,3342],{},"app.context.run(...)"," to\nopen the ambient ",[503,3345,3346],{},"Context"," frame; an HTTP request opens it automatically.",[1271,3349,3351],{"id":3350},"assert-side-effects-through-a-shared-sink","Assert side effects through a shared sink",[499,3353,3354,3355,3358],{},"CQRS and event handlers route by class identity, so spying on a handler instance would miss whether the\nwiring actually reached it. Assert the ",[951,3356,3357],{},"observable effect"," instead: have the handler write to a small\nshared provider, dispatch the message over the real bus, then read the provider back off the same app\nhandle. There's one instance per token, so the provider you assert is the one the handler wrote to.",[499,3360,3361,3362,3365],{},"The CQRS example uses an ",[503,3363,3364],{},"AuditLog"," provider that an interceptor records into around every command:",[508,3367,3370],{"className":510,"code":3368,"filename":3369,"language":513,"meta":514,"style":514},"import { CommandBus } from \"@heximon\u002Fcqrs\";\nimport { createTestApp } from \"@heximon\u002Ftesting\";\nimport { AuditLog } from \"..\u002Fsrc\u002Fusers\u002Faudit-log\";\nimport { CreateUserCommand } from \"..\u002Fsrc\u002Fusers\u002Fcommands\u002Fcreate-user.command\";\nimport { UserId } from \"..\u002Fsrc\u002Fusers\u002Fuser\";\n\ntest(\"the app-wide interceptor records a before+after audit entry around each command\", async () => {\n  await using app = await createTestApp();\n  const commandBus = await app.get(CommandBus);\n  const auditLog = await app.get(AuditLog); \u002F\u002F the SAME instance the interceptor records into\n\n  auditLog.clear();\n\n  \u002F\u002F Direct bus dispatch needs an open Context frame — HTTP requests open it for you.\n  await app.context.run(async () => {\n    await commandBus.execute(\n      new CreateUserCommand(UserId.from(\"u-audit\"), \"Erin\", \"erin@example.com\"),\n    );\n  });\n\n  \u002F\u002F The around-chain interceptor ran for real — proven by the sink, not a spy.\n  expect(auditLog.entries()).toEqual([\n    { command: \"CreateUserCommand\", phase: \"before\" },\n    { command: \"CreateUserCommand\", phase: \"after\" },\n  ]);\n});\n","audit.test.ts",[503,3371,3372,3392,3412,3434,3454,3474,3478,3501,3517,3541,3570,3574,3588,3592,3597,3621,3633,3681,3687,3695,3699,3704,3727,3759,3788,3795],{"__ignoreMap":514},[518,3373,3374,3376,3378,3380,3382,3384,3386,3388,3390],{"class":520,"line":521},[518,3375,532],{"class":531},[518,3377,536],{"class":535},[518,3379,2919],{"class":539},[518,3381,549],{"class":535},[518,3383,552],{"class":531},[518,3385,555],{"class":535},[518,3387,2933],{"class":558},[518,3389,562],{"class":535},[518,3391,565],{"class":535},[518,3393,3394,3396,3398,3400,3402,3404,3406,3408,3410],{"class":520,"line":528},[518,3395,532],{"class":531},[518,3397,536],{"class":535},[518,3399,2049],{"class":539},[518,3401,549],{"class":535},[518,3403,552],{"class":531},[518,3405,555],{"class":535},[518,3407,2008],{"class":558},[518,3409,562],{"class":535},[518,3411,565],{"class":535},[518,3413,3414,3416,3418,3421,3423,3425,3427,3430,3432],{"class":520,"line":568},[518,3415,532],{"class":531},[518,3417,536],{"class":535},[518,3419,3420],{"class":539}," AuditLog",[518,3422,549],{"class":535},[518,3424,552],{"class":531},[518,3426,555],{"class":535},[518,3428,3429],{"class":558},"..\u002Fsrc\u002Fusers\u002Faudit-log",[518,3431,562],{"class":535},[518,3433,565],{"class":535},[518,3435,3436,3438,3440,3442,3444,3446,3448,3450,3452],{"class":520,"line":591},[518,3437,532],{"class":531},[518,3439,536],{"class":535},[518,3441,1329],{"class":539},[518,3443,549],{"class":535},[518,3445,552],{"class":531},[518,3447,555],{"class":535},[518,3449,1338],{"class":558},[518,3451,562],{"class":535},[518,3453,565],{"class":535},[518,3455,3456,3458,3460,3462,3464,3466,3468,3470,3472],{"class":520,"line":598},[518,3457,532],{"class":531},[518,3459,536],{"class":535},[518,3461,1373],{"class":539},[518,3463,549],{"class":535},[518,3465,552],{"class":531},[518,3467,555],{"class":535},[518,3469,1382],{"class":558},[518,3471,562],{"class":535},[518,3473,565],{"class":535},[518,3475,3476],{"class":520,"line":630},[518,3477,595],{"emptyLinePlaceholder":594},[518,3479,3480,3482,3484,3486,3489,3491,3493,3495,3497,3499],{"class":520,"line":653},[518,3481,602],{"class":601},[518,3483,605],{"class":539},[518,3485,562],{"class":535},[518,3487,3488],{"class":558},"the app-wide interceptor records a before+after audit entry around each command",[518,3490,562],{"class":535},[518,3492,543],{"class":535},[518,3494,618],{"class":617},[518,3496,621],{"class":535},[518,3498,624],{"class":617},[518,3500,627],{"class":535},[518,3502,3503,3505,3507,3509,3511,3513,3515],{"class":520,"line":678},[518,3504,2137],{"class":617},[518,3506,2140],{"class":539},[518,3508,639],{"class":535},[518,3510,663],{"class":531},[518,3512,2049],{"class":601},[518,3514,648],{"class":647},[518,3516,565],{"class":535},[518,3518,3519,3521,3523,3525,3527,3529,3531,3533,3535,3537,3539],{"class":520,"line":707},[518,3520,633],{"class":617},[518,3522,3097],{"class":539},[518,3524,639],{"class":535},[518,3526,663],{"class":531},[518,3528,2140],{"class":539},[518,3530,668],{"class":535},[518,3532,2171],{"class":601},[518,3534,605],{"class":647},[518,3536,3112],{"class":539},[518,3538,689],{"class":647},[518,3540,565],{"class":535},[518,3542,3543,3545,3548,3550,3552,3554,3556,3558,3560,3562,3564,3567],{"class":520,"line":751},[518,3544,633],{"class":617},[518,3546,3547],{"class":539}," auditLog",[518,3549,639],{"class":535},[518,3551,663],{"class":531},[518,3553,2140],{"class":539},[518,3555,668],{"class":535},[518,3557,2171],{"class":601},[518,3559,605],{"class":647},[518,3561,3364],{"class":539},[518,3563,689],{"class":647},[518,3565,3566],{"class":535},";",[518,3568,3569],{"class":524}," \u002F\u002F the SAME instance the interceptor records into\n",[518,3571,3572],{"class":520,"line":761},[518,3573,595],{"emptyLinePlaceholder":594},[518,3575,3576,3579,3581,3584,3586],{"class":520,"line":766},[518,3577,3578],{"class":539},"  auditLog",[518,3580,668],{"class":535},[518,3582,3583],{"class":601},"clear",[518,3585,648],{"class":647},[518,3587,565],{"class":535},[518,3589,3590],{"class":520,"line":790},[518,3591,595],{"emptyLinePlaceholder":594},[518,3593,3594],{"class":520,"line":807},[518,3595,3596],{"class":524},"  \u002F\u002F Direct bus dispatch needs an open Context frame — HTTP requests open it for you.\n",[518,3598,3599,3601,3603,3605,3607,3609,3611,3613,3615,3617,3619],{"class":520,"line":877},[518,3600,3170],{"class":531},[518,3602,2140],{"class":539},[518,3604,668],{"class":535},[518,3606,3177],{"class":539},[518,3608,668],{"class":535},[518,3610,3182],{"class":601},[518,3612,605],{"class":647},[518,3614,2553],{"class":617},[518,3616,621],{"class":535},[518,3618,624],{"class":617},[518,3620,627],{"class":535},[518,3622,3623,3625,3627,3629,3631],{"class":520,"line":912},[518,3624,1179],{"class":531},[518,3626,3097],{"class":539},[518,3628,668],{"class":535},[518,3630,2899],{"class":601},[518,3632,1237],{"class":647},[518,3634,3635,3638,3640,3642,3644,3646,3648,3650,3652,3655,3657,3659,3661,3663,3666,3668,3670,3672,3675,3677,3679],{"class":520,"line":2286},[518,3636,3637],{"class":535},"      new",[518,3639,1329],{"class":601},[518,3641,605],{"class":647},[518,3643,1513],{"class":539},[518,3645,668],{"class":535},[518,3647,1518],{"class":601},[518,3649,605],{"class":647},[518,3651,562],{"class":535},[518,3653,3654],{"class":558},"u-audit",[518,3656,562],{"class":535},[518,3658,689],{"class":647},[518,3660,543],{"class":535},[518,3662,555],{"class":535},[518,3664,3665],{"class":558},"Erin",[518,3667,562],{"class":535},[518,3669,543],{"class":535},[518,3671,555],{"class":535},[518,3673,3674],{"class":558},"erin@example.com",[518,3676,562],{"class":535},[518,3678,689],{"class":647},[518,3680,1245],{"class":535},[518,3682,3683,3685],{"class":520,"line":2291},[518,3684,1250],{"class":647},[518,3686,565],{"class":535},[518,3688,3689,3691,3693],{"class":520,"line":2330},[518,3690,1257],{"class":535},[518,3692,689],{"class":647},[518,3694,565],{"class":535},[518,3696,3697],{"class":520,"line":2335},[518,3698,595],{"emptyLinePlaceholder":594},[518,3700,3701],{"class":520,"line":2365},[518,3702,3703],{"class":524},"  \u002F\u002F The around-chain interceptor ran for real — proven by the sink, not a spy.\n",[518,3705,3706,3708,3710,3713,3715,3718,3720,3722,3724],{"class":520,"line":2395},[518,3707,681],{"class":601},[518,3709,605],{"class":647},[518,3711,3712],{"class":539},"auditLog",[518,3714,668],{"class":535},[518,3716,3717],{"class":601},"entries",[518,3719,2200],{"class":647},[518,3721,668],{"class":535},[518,3723,837],{"class":601},[518,3725,3726],{"class":647},"([\n",[518,3728,3729,3732,3735,3737,3739,3742,3744,3746,3749,3751,3753,3755,3757],{"class":520,"line":2798},[518,3730,3731],{"class":535},"    {",[518,3733,3734],{"class":647}," command",[518,3736,848],{"class":535},[518,3738,555],{"class":535},[518,3740,3741],{"class":558},"CreateUserCommand",[518,3743,562],{"class":535},[518,3745,543],{"class":535},[518,3747,3748],{"class":647}," phase",[518,3750,848],{"class":535},[518,3752,555],{"class":535},[518,3754,2411],{"class":558},[518,3756,562],{"class":535},[518,3758,2731],{"class":535},[518,3760,3761,3763,3765,3767,3769,3771,3773,3775,3777,3779,3781,3784,3786],{"class":520,"line":2803},[518,3762,3731],{"class":535},[518,3764,3734],{"class":647},[518,3766,848],{"class":535},[518,3768,555],{"class":535},[518,3770,3741],{"class":558},[518,3772,562],{"class":535},[518,3774,543],{"class":535},[518,3776,3748],{"class":647},[518,3778,848],{"class":535},[518,3780,555],{"class":535},[518,3782,3783],{"class":558},"after",[518,3785,562],{"class":535},[518,3787,2731],{"class":535},[518,3789,3790,3793],{"class":520,"line":2831},[518,3791,3792],{"class":647},"  ])",[518,3794,565],{"class":535},[518,3796,3797,3799,3801],{"class":520,"line":2860},[518,3798,754],{"class":535},[518,3800,689],{"class":539},[518,3802,565],{"class":535},[499,3804,3805,3806,3809,3810,3813,3814,3817],{},"Import the command, query, and provider classes ",[951,3807,3808],{},"statically"," (never via ",[503,3811,3812],{},"await import(...)","). The bus\ndispatches by class identity, so a statically imported class resolves to the same ",[503,3815,3816],{},"src\u002F"," module the\ncompiler wired — their identities line up where a dynamic import's would not.",[1271,3819,3821],{"id":3820},"swap-a-real-dependency-for-a-fake-with-overrides","Swap a real dependency for a fake with overrides",[499,3823,3824,3825,3828,3829,3831,3832,3834],{},"An override substitutes a fake for a real provider, keyed by class identity. ",[951,3826,3827],{},"It replaces the DI token\neverywhere it is injected"," — same-module construction, cross-module constructor inputs, dispatched\nhandlers, and direct ",[503,3830,981],{},". ",[503,3833,999],{}," compiles in a dedicated test wiring mode that\ngives the override full reach, so you can reason about it simply: the fake stands in for the real\nprovider at every injection site.",[499,3836,3837,3840,3841,3844,3845,3848,3849,3851],{},[951,3838,3839],{},"What overrides can reach:"," any DI token — a service, a bus, a controller, or a token another provider\ntakes as a ",[951,3842,3843],{},"constructor argument",". A controller is resolved at dispatch time, so overriding it means\nthe fake's methods handle every route the controller owns. The pattern that follows swaps\n",[503,3846,3847],{},"UsersController"," for a fake whose ",[503,3850,671],{}," returns a fixed roster, proving the override takes effect at\ndispatch time:",[508,3853,3856],{"className":510,"code":3854,"filename":3855,"language":513,"meta":514,"style":514},"import { createTestClient } from \"@heximon\u002Fhttp\u002Ftesting\";\nimport { createTestApp } from \"@heximon\u002Ftesting\";\nimport { expect, test } from \"vitest\";\nimport { UsersController } from \"..\u002Fsrc\u002Fusers\u002Fusers.controller\";\nimport { type User } from \"..\u002Fsrc\u002Fusers\u002Fusers.repository\";\n\ntest(\"overriding a controller makes its dispatched route serve the fake\", async () => {\n  \u002F\u002F A controller fake whose `list` returns a fixed roster — substituted via `createTestApp({ overrides })`.\n  class FakeUsersController {\n    public async list(): Promise\u003CUser[]> {\n      return [{ id: \"a1\", name: \"Anna\", email: \"anna@example.com\" }];\n    }\n  }\n\n  await using app = await createTestApp({\n    overrides: [{ provide: UsersController, useValue: new FakeUsersController() as unknown as UsersController }],\n  });\n  const client = createTestClient(app);\n\n  const response = await client.request(new Request(\"http:\u002F\u002Flocalhost\u002Fusers\"));\n\n  \u002F\u002F The controller token is resolved at dispatch via app.get — the override-reachable seam — so the route\n  \u002F\u002F serves only the fake's roster.\n  expect(await response.json()).toEqual([{ id: \"a1\", name: \"Anna\", email: \"anna@example.com\" }]);\n});\n","test\u002Foverrides.test.ts",[503,3857,3858,3878,3898,3922,3944,3967,3971,3994,3999,4009,4039,4092,4097,4102,4106,4123,4170,4178,4196,4200,4234,4238,4243,4248,4314],{"__ignoreMap":514},[518,3859,3860,3862,3864,3866,3868,3870,3872,3874,3876],{"class":520,"line":521},[518,3861,532],{"class":531},[518,3863,536],{"class":535},[518,3865,2027],{"class":539},[518,3867,549],{"class":535},[518,3869,552],{"class":531},[518,3871,555],{"class":535},[518,3873,2036],{"class":558},[518,3875,562],{"class":535},[518,3877,565],{"class":535},[518,3879,3880,3882,3884,3886,3888,3890,3892,3894,3896],{"class":520,"line":528},[518,3881,532],{"class":531},[518,3883,536],{"class":535},[518,3885,2049],{"class":539},[518,3887,549],{"class":535},[518,3889,552],{"class":531},[518,3891,555],{"class":535},[518,3893,2008],{"class":558},[518,3895,562],{"class":535},[518,3897,565],{"class":535},[518,3899,3900,3902,3904,3906,3908,3910,3912,3914,3916,3918,3920],{"class":520,"line":568},[518,3901,532],{"class":531},[518,3903,536],{"class":535},[518,3905,540],{"class":539},[518,3907,543],{"class":535},[518,3909,546],{"class":539},[518,3911,549],{"class":535},[518,3913,552],{"class":531},[518,3915,555],{"class":535},[518,3917,559],{"class":558},[518,3919,562],{"class":535},[518,3921,565],{"class":535},[518,3923,3924,3926,3928,3931,3933,3935,3937,3940,3942],{"class":520,"line":591},[518,3925,532],{"class":531},[518,3927,536],{"class":535},[518,3929,3930],{"class":539}," UsersController",[518,3932,549],{"class":535},[518,3934,552],{"class":531},[518,3936,555],{"class":535},[518,3938,3939],{"class":558},"..\u002Fsrc\u002Fusers\u002Fusers.controller",[518,3941,562],{"class":535},[518,3943,565],{"class":535},[518,3945,3946,3948,3950,3952,3955,3957,3959,3961,3963,3965],{"class":520,"line":598},[518,3947,532],{"class":531},[518,3949,536],{"class":535},[518,3951,2430],{"class":531},[518,3953,3954],{"class":539}," User",[518,3956,549],{"class":535},[518,3958,552],{"class":531},[518,3960,555],{"class":535},[518,3962,584],{"class":558},[518,3964,562],{"class":535},[518,3966,565],{"class":535},[518,3968,3969],{"class":520,"line":630},[518,3970,595],{"emptyLinePlaceholder":594},[518,3972,3973,3975,3977,3979,3982,3984,3986,3988,3990,3992],{"class":520,"line":653},[518,3974,602],{"class":601},[518,3976,605],{"class":539},[518,3978,562],{"class":535},[518,3980,3981],{"class":558},"overriding a controller makes its dispatched route serve the fake",[518,3983,562],{"class":535},[518,3985,543],{"class":535},[518,3987,618],{"class":617},[518,3989,621],{"class":535},[518,3991,624],{"class":617},[518,3993,627],{"class":535},[518,3995,3996],{"class":520,"line":678},[518,3997,3998],{"class":524},"  \u002F\u002F A controller fake whose `list` returns a fixed roster — substituted via `createTestApp({ overrides })`.\n",[518,4000,4001,4004,4007],{"class":520,"line":707},[518,4002,4003],{"class":617},"  class",[518,4005,4006],{"class":1484}," FakeUsersController",[518,4008,627],{"class":535},[518,4010,4011,4014,4016,4019,4022,4025,4028,4031,4034,4037],{"class":520,"line":751},[518,4012,4013],{"class":617},"    public",[518,4015,618],{"class":617},[518,4017,4018],{"class":647}," list",[518,4020,4021],{"class":535},"():",[518,4023,4024],{"class":1484}," Promise",[518,4026,4027],{"class":535},"\u003C",[518,4029,4030],{"class":1484},"User",[518,4032,4033],{"class":647},"[]",[518,4035,4036],{"class":535},">",[518,4038,627],{"class":535},[518,4040,4041,4044,4047,4049,4051,4053,4055,4058,4060,4062,4064,4066,4068,4071,4073,4075,4077,4079,4081,4084,4086,4088,4090],{"class":520,"line":761},[518,4042,4043],{"class":531},"      return",[518,4045,4046],{"class":647}," [",[518,4048,842],{"class":535},[518,4050,845],{"class":647},[518,4052,848],{"class":535},[518,4054,555],{"class":535},[518,4056,4057],{"class":558},"a1",[518,4059,562],{"class":535},[518,4061,543],{"class":535},[518,4063,859],{"class":647},[518,4065,848],{"class":535},[518,4067,555],{"class":535},[518,4069,4070],{"class":558},"Anna",[518,4072,562],{"class":535},[518,4074,543],{"class":535},[518,4076,1211],{"class":647},[518,4078,848],{"class":535},[518,4080,555],{"class":535},[518,4082,4083],{"class":558},"anna@example.com",[518,4085,562],{"class":535},[518,4087,549],{"class":535},[518,4089,722],{"class":647},[518,4091,565],{"class":535},[518,4093,4094],{"class":520,"line":766},[518,4095,4096],{"class":535},"    }\n",[518,4098,4099],{"class":520,"line":790},[518,4100,4101],{"class":535},"  }\n",[518,4103,4104],{"class":520,"line":807},[518,4105,595],{"emptyLinePlaceholder":594},[518,4107,4108,4110,4112,4114,4116,4118,4120],{"class":520,"line":877},[518,4109,2137],{"class":617},[518,4111,2140],{"class":539},[518,4113,639],{"class":535},[518,4115,663],{"class":531},[518,4117,2049],{"class":601},[518,4119,605],{"class":647},[518,4121,4122],{"class":535},"{\n",[518,4124,4125,4128,4130,4132,4134,4137,4139,4141,4143,4146,4148,4150,4152,4154,4157,4160,4162,4164,4166,4168],{"class":520,"line":912},[518,4126,4127],{"class":647},"    overrides",[518,4129,848],{"class":535},[518,4131,4046],{"class":647},[518,4133,842],{"class":535},[518,4135,4136],{"class":647}," provide",[518,4138,848],{"class":535},[518,4140,3930],{"class":539},[518,4142,543],{"class":535},[518,4144,4145],{"class":647}," useValue",[518,4147,848],{"class":535},[518,4149,642],{"class":535},[518,4151,4006],{"class":601},[518,4153,1457],{"class":647},[518,4155,4156],{"class":531},"as",[518,4158,4159],{"class":1484}," unknown",[518,4161,1481],{"class":531},[518,4163,3930],{"class":1484},[518,4165,549],{"class":535},[518,4167,722],{"class":647},[518,4169,1245],{"class":535},[518,4171,4172,4174,4176],{"class":520,"line":2286},[518,4173,1257],{"class":535},[518,4175,689],{"class":647},[518,4177,565],{"class":535},[518,4179,4180,4182,4184,4186,4188,4190,4192,4194],{"class":520,"line":2291},[518,4181,633],{"class":617},[518,4183,2270],{"class":539},[518,4185,639],{"class":535},[518,4187,2027],{"class":601},[518,4189,605],{"class":647},[518,4191,2279],{"class":539},[518,4193,689],{"class":647},[518,4195,565],{"class":535},[518,4197,4198],{"class":520,"line":2330},[518,4199,595],{"emptyLinePlaceholder":594},[518,4201,4202,4204,4206,4208,4210,4212,4214,4216,4218,4220,4222,4224,4226,4228,4230,4232],{"class":520,"line":2335},[518,4203,633],{"class":617},[518,4205,2296],{"class":539},[518,4207,639],{"class":535},[518,4209,663],{"class":531},[518,4211,2270],{"class":539},[518,4213,668],{"class":535},[518,4215,2307],{"class":601},[518,4217,605],{"class":647},[518,4219,505],{"class":535},[518,4221,2314],{"class":601},[518,4223,605],{"class":647},[518,4225,562],{"class":535},[518,4227,2321],{"class":558},[518,4229,562],{"class":535},[518,4231,832],{"class":647},[518,4233,565],{"class":535},[518,4235,4236],{"class":520,"line":2365},[518,4237,595],{"emptyLinePlaceholder":594},[518,4239,4240],{"class":520,"line":2395},[518,4241,4242],{"class":524},"  \u002F\u002F The controller token is resolved at dispatch via app.get — the override-reachable seam — so the route\n",[518,4244,4245],{"class":520,"line":2798},[518,4246,4247],{"class":524},"  \u002F\u002F serves only the fake's roster.\n",[518,4249,4250,4252,4254,4256,4258,4260,4262,4264,4266,4268,4271,4273,4275,4277,4279,4281,4283,4285,4287,4289,4291,4293,4295,4297,4299,4301,4303,4305,4307,4309,4312],{"class":520,"line":2803},[518,4251,681],{"class":601},[518,4253,605],{"class":647},[518,4255,814],{"class":531},[518,4257,2296],{"class":539},[518,4259,668],{"class":535},[518,4261,2378],{"class":601},[518,4263,2200],{"class":647},[518,4265,668],{"class":535},[518,4267,837],{"class":601},[518,4269,4270],{"class":647},"([",[518,4272,842],{"class":535},[518,4274,845],{"class":647},[518,4276,848],{"class":535},[518,4278,555],{"class":535},[518,4280,4057],{"class":558},[518,4282,562],{"class":535},[518,4284,543],{"class":535},[518,4286,859],{"class":647},[518,4288,848],{"class":535},[518,4290,555],{"class":535},[518,4292,4070],{"class":558},[518,4294,562],{"class":535},[518,4296,543],{"class":535},[518,4298,1211],{"class":647},[518,4300,848],{"class":535},[518,4302,555],{"class":535},[518,4304,4083],{"class":558},[518,4306,562],{"class":535},[518,4308,549],{"class":535},[518,4310,4311],{"class":647},"])",[518,4313,565],{"class":535},[518,4315,4316,4318,4320],{"class":520,"line":2831},[518,4317,754],{"class":535},[518,4319,689],{"class":539},[518,4321,565],{"class":535},[499,4323,4324,4327,4328,4331,4332,4335,4336,4339],{},[951,4325,4326],{},"One boundary is out of reach: a precompiled package's internals."," An imported ",[951,4329,4330],{},"precompiled"," package (a library-mode boundary) is overridable\nonly at its declared seams — its ",[503,4333,4334],{},"requires"," and ",[503,4337,4338],{},"exports"," — never its internals, which were wired at\nthat package's own build time. Your app's own source has no such limit: every token at every site is\noverridable. To override a package's internals, test that package in its own suite.",[499,4341,4342,4343,4346,4347,4350,4351,4354,4355,4357],{},"Each override is ",[503,4344,4345],{},"{ provide: Token, useValue }"," (a ready-made instance), ",[503,4348,4349],{},"{ provide: Token, useClass }","\n(a no-arg class the graph constructs once and memoizes), or ",[503,4352,4353],{},"{ provide: Token, useFactory }"," (a factory\ngiven the request ",[503,4356,3346],{},", built once and memoized — for a fake that needs the ambient context, like a\ndatabase).",[499,4359,4360,4361,4364,4365,4369,4370,668],{},"Prefer fakes over mocks for anything with real behavior — an in-memory store, a fixed clock —\nsince they read clearly in the assertion and don't break when an unrelated call is added; reach for\n",[503,4362,4363],{},"vi.fn()"," when you specifically need to assert ",[4366,4367,4368],"em",{},"how"," a collaborator was called. The full reference — every\noverride form, database isolation, and cross-service topology — is on\n",[2881,4371,116],{"href":117},[1271,4373,4375],{"id":4374},"test-a-contract-self-client-with-clienttransportmock","Test a contract self-client with ClientTransport.mock",[499,4377,4378,4379,4382,4383,4386,4387,2005,4389,4392,4393,4396,4397,4400],{},"A contract is also a typed client — ",[503,4380,4381],{},"new SomeApi(transport)"," — and you can test the client-side logic\n(URL assembly, body serialization, argument marshalling, response validation) without a running server by\nwiring it to a ",[503,4384,4385],{},"ClientTransport.mock",". Import ",[503,4388,4385],{},[503,4390,4391],{},"@heximon\u002Fclient"," and pass a\n",[503,4394,4395],{},"\"METHOD \u002Fpath\""," → ",[503,4398,4399],{},"ClientResponse"," map:",[508,4402,4405],{"className":510,"code":4403,"filename":4404,"language":513,"meta":514,"style":514},"import { Contract, Route } from \"@heximon\u002Fcontract\";\nimport { SchemaObject } from \"@heximon\u002Fschema\";\nimport { ClientTransport } from \"@heximon\u002Fclient\";\nimport * as v from \"valibot\";\nimport { expect, test } from \"vitest\";\n\nclass SkuParams extends SchemaObject({ sku: v.string() }) {}\nclass NewProduct extends SchemaObject({ name: v.string() }) {}\nclass Product extends SchemaObject({ sku: v.string(), name: v.string() }) {}\nclass NotFound extends SchemaObject({ reason: v.string() }) {}\n\nclass ProductsApi extends Contract({\n  prefix: \"\u002Fapi\u002Fproducts\",\n  routes: {\n    find: Route.get(\"\u002F:sku\").pathParams(SkuParams).responses({ 200: Product, 404: NotFound }),\n    create: Route.post(\"\u002F\").body(NewProduct).responses({ 201: Product }),\n  },\n}) {}\n\ntest(\"a 2xx caller round-trips through the canned map and returns the success body\", async () => {\n  const api = new ProductsApi(\n    ClientTransport.mock({\n      \"GET \u002Fapi\u002Fproducts\u002Fabc\": { status: 200, headers: {}, body: { sku: \"abc\", name: \"Widget\" } },\n    }),\n  );\n\n  const product = await api.client.find({ params: { sku: \"abc\" } });\n\n  expect(product).toEqual({ sku: \"abc\", name: \"Widget\" });\n});\n","products-client.test.ts",[503,4406,4407,4434,4456,4477,4500,4524,4528,4568,4601,4648,4682,4686,4701,4717,4726,4790,4845,4850,4858,4862,4885,4900,4914,4980,4988,4994,4998,5050,5055,5103],{"__ignoreMap":514},[518,4408,4409,4411,4413,4416,4418,4421,4423,4425,4427,4430,4432],{"class":520,"line":521},[518,4410,532],{"class":531},[518,4412,536],{"class":535},[518,4414,4415],{"class":539}," Contract",[518,4417,543],{"class":535},[518,4419,4420],{"class":539}," Route",[518,4422,549],{"class":535},[518,4424,552],{"class":531},[518,4426,555],{"class":535},[518,4428,4429],{"class":558},"@heximon\u002Fcontract",[518,4431,562],{"class":535},[518,4433,565],{"class":535},[518,4435,4436,4438,4440,4443,4445,4447,4449,4452,4454],{"class":520,"line":528},[518,4437,532],{"class":531},[518,4439,536],{"class":535},[518,4441,4442],{"class":539}," SchemaObject",[518,4444,549],{"class":535},[518,4446,552],{"class":531},[518,4448,555],{"class":535},[518,4450,4451],{"class":558},"@heximon\u002Fschema",[518,4453,562],{"class":535},[518,4455,565],{"class":535},[518,4457,4458,4460,4462,4465,4467,4469,4471,4473,4475],{"class":520,"line":568},[518,4459,532],{"class":531},[518,4461,536],{"class":535},[518,4463,4464],{"class":539}," ClientTransport",[518,4466,549],{"class":535},[518,4468,552],{"class":531},[518,4470,555],{"class":535},[518,4472,4391],{"class":558},[518,4474,562],{"class":535},[518,4476,565],{"class":535},[518,4478,4479,4481,4484,4486,4489,4491,4493,4496,4498],{"class":520,"line":591},[518,4480,532],{"class":531},[518,4482,4483],{"class":535}," *",[518,4485,1481],{"class":531},[518,4487,4488],{"class":539}," v ",[518,4490,1518],{"class":531},[518,4492,555],{"class":535},[518,4494,4495],{"class":558},"valibot",[518,4497,562],{"class":535},[518,4499,565],{"class":535},[518,4501,4502,4504,4506,4508,4510,4512,4514,4516,4518,4520,4522],{"class":520,"line":598},[518,4503,532],{"class":531},[518,4505,536],{"class":535},[518,4507,540],{"class":539},[518,4509,543],{"class":535},[518,4511,546],{"class":539},[518,4513,549],{"class":535},[518,4515,552],{"class":531},[518,4517,555],{"class":535},[518,4519,559],{"class":558},[518,4521,562],{"class":535},[518,4523,565],{"class":535},[518,4525,4526],{"class":520,"line":630},[518,4527,595],{"emptyLinePlaceholder":594},[518,4529,4530,4533,4536,4539,4541,4543,4545,4548,4550,4553,4555,4558,4560,4562,4565],{"class":520,"line":653},[518,4531,4532],{"class":617},"class",[518,4534,4535],{"class":1484}," SkuParams",[518,4537,4538],{"class":617}," extends",[518,4540,4442],{"class":601},[518,4542,605],{"class":539},[518,4544,842],{"class":535},[518,4546,4547],{"class":647}," sku",[518,4549,848],{"class":535},[518,4551,4552],{"class":539}," v",[518,4554,668],{"class":535},[518,4556,4557],{"class":601},"string",[518,4559,1457],{"class":539},[518,4561,754],{"class":535},[518,4563,4564],{"class":539},") ",[518,4566,4567],{"class":535},"{}\n",[518,4569,4570,4572,4575,4577,4579,4581,4583,4585,4587,4589,4591,4593,4595,4597,4599],{"class":520,"line":678},[518,4571,4532],{"class":617},[518,4573,4574],{"class":1484}," NewProduct",[518,4576,4538],{"class":617},[518,4578,4442],{"class":601},[518,4580,605],{"class":539},[518,4582,842],{"class":535},[518,4584,859],{"class":647},[518,4586,848],{"class":535},[518,4588,4552],{"class":539},[518,4590,668],{"class":535},[518,4592,4557],{"class":601},[518,4594,1457],{"class":539},[518,4596,754],{"class":535},[518,4598,4564],{"class":539},[518,4600,4567],{"class":535},[518,4602,4603,4605,4608,4610,4612,4614,4616,4618,4620,4622,4624,4626,4628,4630,4632,4634,4636,4638,4640,4642,4644,4646],{"class":520,"line":707},[518,4604,4532],{"class":617},[518,4606,4607],{"class":1484}," Product",[518,4609,4538],{"class":617},[518,4611,4442],{"class":601},[518,4613,605],{"class":539},[518,4615,842],{"class":535},[518,4617,4547],{"class":647},[518,4619,848],{"class":535},[518,4621,4552],{"class":539},[518,4623,668],{"class":535},[518,4625,4557],{"class":601},[518,4627,648],{"class":539},[518,4629,543],{"class":535},[518,4631,859],{"class":647},[518,4633,848],{"class":535},[518,4635,4552],{"class":539},[518,4637,668],{"class":535},[518,4639,4557],{"class":601},[518,4641,1457],{"class":539},[518,4643,754],{"class":535},[518,4645,4564],{"class":539},[518,4647,4567],{"class":535},[518,4649,4650,4652,4655,4657,4659,4661,4663,4666,4668,4670,4672,4674,4676,4678,4680],{"class":520,"line":751},[518,4651,4532],{"class":617},[518,4653,4654],{"class":1484}," NotFound",[518,4656,4538],{"class":617},[518,4658,4442],{"class":601},[518,4660,605],{"class":539},[518,4662,842],{"class":535},[518,4664,4665],{"class":647}," reason",[518,4667,848],{"class":535},[518,4669,4552],{"class":539},[518,4671,668],{"class":535},[518,4673,4557],{"class":601},[518,4675,1457],{"class":539},[518,4677,754],{"class":535},[518,4679,4564],{"class":539},[518,4681,4567],{"class":535},[518,4683,4684],{"class":520,"line":761},[518,4685,595],{"emptyLinePlaceholder":594},[518,4687,4688,4690,4693,4695,4697,4699],{"class":520,"line":766},[518,4689,4532],{"class":617},[518,4691,4692],{"class":1484}," ProductsApi",[518,4694,4538],{"class":617},[518,4696,4415],{"class":601},[518,4698,605],{"class":539},[518,4700,4122],{"class":535},[518,4702,4703,4706,4708,4710,4713,4715],{"class":520,"line":790},[518,4704,4705],{"class":647},"  prefix",[518,4707,848],{"class":535},[518,4709,555],{"class":535},[518,4711,4712],{"class":558},"\u002Fapi\u002Fproducts",[518,4714,562],{"class":535},[518,4716,1245],{"class":535},[518,4718,4719,4722,4724],{"class":520,"line":807},[518,4720,4721],{"class":647},"  routes",[518,4723,848],{"class":535},[518,4725,627],{"class":535},[518,4727,4728,4731,4733,4735,4737,4739,4741,4743,4746,4748,4750,4752,4755,4758,4760,4763,4765,4767,4770,4772,4774,4776,4779,4781,4784,4786,4788],{"class":520,"line":877},[518,4729,4730],{"class":647},"    find",[518,4732,848],{"class":535},[518,4734,4420],{"class":539},[518,4736,668],{"class":535},[518,4738,2171],{"class":601},[518,4740,605],{"class":539},[518,4742,562],{"class":535},[518,4744,4745],{"class":558},"\u002F:sku",[518,4747,562],{"class":535},[518,4749,689],{"class":539},[518,4751,668],{"class":535},[518,4753,4754],{"class":601},"pathParams",[518,4756,4757],{"class":539},"(SkuParams)",[518,4759,668],{"class":535},[518,4761,4762],{"class":601},"responses",[518,4764,605],{"class":539},[518,4766,842],{"class":535},[518,4768,4769],{"class":699}," 200",[518,4771,848],{"class":535},[518,4773,4607],{"class":539},[518,4775,543],{"class":535},[518,4777,4778],{"class":699}," 404",[518,4780,848],{"class":535},[518,4782,4783],{"class":539}," NotFound ",[518,4785,754],{"class":535},[518,4787,689],{"class":539},[518,4789,1245],{"class":535},[518,4791,4792,4795,4797,4799,4801,4804,4806,4808,4811,4813,4815,4817,4820,4823,4825,4827,4829,4831,4834,4836,4839,4841,4843],{"class":520,"line":912},[518,4793,4794],{"class":647},"    create",[518,4796,848],{"class":535},[518,4798,4420],{"class":539},[518,4800,668],{"class":535},[518,4802,4803],{"class":601},"post",[518,4805,605],{"class":539},[518,4807,562],{"class":535},[518,4809,4810],{"class":558},"\u002F",[518,4812,562],{"class":535},[518,4814,689],{"class":539},[518,4816,668],{"class":535},[518,4818,4819],{"class":601},"body",[518,4821,4822],{"class":539},"(NewProduct)",[518,4824,668],{"class":535},[518,4826,4762],{"class":601},[518,4828,605],{"class":539},[518,4830,842],{"class":535},[518,4832,4833],{"class":699}," 201",[518,4835,848],{"class":535},[518,4837,4838],{"class":539}," Product ",[518,4840,754],{"class":535},[518,4842,689],{"class":539},[518,4844,1245],{"class":535},[518,4846,4847],{"class":520,"line":2286},[518,4848,4849],{"class":535},"  },\n",[518,4851,4852,4854,4856],{"class":520,"line":2291},[518,4853,754],{"class":535},[518,4855,4564],{"class":539},[518,4857,4567],{"class":535},[518,4859,4860],{"class":520,"line":2330},[518,4861,595],{"emptyLinePlaceholder":594},[518,4863,4864,4866,4868,4870,4873,4875,4877,4879,4881,4883],{"class":520,"line":2335},[518,4865,602],{"class":601},[518,4867,605],{"class":539},[518,4869,562],{"class":535},[518,4871,4872],{"class":558},"a 2xx caller round-trips through the canned map and returns the success body",[518,4874,562],{"class":535},[518,4876,543],{"class":535},[518,4878,618],{"class":617},[518,4880,621],{"class":535},[518,4882,624],{"class":617},[518,4884,627],{"class":535},[518,4886,4887,4889,4892,4894,4896,4898],{"class":520,"line":2365},[518,4888,633],{"class":617},[518,4890,4891],{"class":539}," api",[518,4893,639],{"class":535},[518,4895,642],{"class":535},[518,4897,4692],{"class":601},[518,4899,1237],{"class":647},[518,4901,4902,4905,4907,4910,4912],{"class":520,"line":2395},[518,4903,4904],{"class":539},"    ClientTransport",[518,4906,668],{"class":535},[518,4908,4909],{"class":601},"mock",[518,4911,605],{"class":647},[518,4913,4122],{"class":535},[518,4915,4916,4919,4922,4924,4926,4928,4931,4933,4935,4937,4940,4942,4945,4948,4950,4952,4954,4956,4958,4961,4963,4965,4967,4969,4971,4974,4976,4978],{"class":520,"line":2798},[518,4917,4918],{"class":535},"      \"",[518,4920,4921],{"class":647},"GET \u002Fapi\u002Fproducts\u002Fabc",[518,4923,562],{"class":535},[518,4925,848],{"class":535},[518,4927,536],{"class":535},[518,4929,4930],{"class":647}," status",[518,4932,848],{"class":535},[518,4934,4769],{"class":699},[518,4936,543],{"class":535},[518,4938,4939],{"class":647}," headers",[518,4941,848],{"class":535},[518,4943,4944],{"class":535}," {},",[518,4946,4947],{"class":647}," body",[518,4949,848],{"class":535},[518,4951,536],{"class":535},[518,4953,4547],{"class":647},[518,4955,848],{"class":535},[518,4957,555],{"class":535},[518,4959,4960],{"class":558},"abc",[518,4962,562],{"class":535},[518,4964,543],{"class":535},[518,4966,859],{"class":647},[518,4968,848],{"class":535},[518,4970,555],{"class":535},[518,4972,4973],{"class":558},"Widget",[518,4975,562],{"class":535},[518,4977,549],{"class":535},[518,4979,2731],{"class":535},[518,4981,4982,4984,4986],{"class":520,"line":2803},[518,4983,2784],{"class":535},[518,4985,689],{"class":647},[518,4987,1245],{"class":535},[518,4989,4990,4992],{"class":520,"line":2831},[518,4991,2793],{"class":647},[518,4993,565],{"class":535},[518,4995,4996],{"class":520,"line":2860},[518,4997,595],{"emptyLinePlaceholder":594},[518,4999,5001,5003,5006,5008,5010,5012,5014,5016,5018,5021,5023,5025,5028,5030,5032,5034,5036,5038,5040,5042,5044,5046,5048],{"class":520,"line":5000},27,[518,5002,633],{"class":617},[518,5004,5005],{"class":539}," product",[518,5007,639],{"class":535},[518,5009,663],{"class":531},[518,5011,4891],{"class":539},[518,5013,668],{"class":535},[518,5015,2872],{"class":539},[518,5017,668],{"class":535},[518,5019,5020],{"class":601},"find",[518,5022,605],{"class":647},[518,5024,842],{"class":535},[518,5026,5027],{"class":647}," params",[518,5029,848],{"class":535},[518,5031,536],{"class":535},[518,5033,4547],{"class":647},[518,5035,848],{"class":535},[518,5037,555],{"class":535},[518,5039,4960],{"class":558},[518,5041,562],{"class":535},[518,5043,549],{"class":535},[518,5045,549],{"class":535},[518,5047,689],{"class":647},[518,5049,565],{"class":535},[518,5051,5053],{"class":520,"line":5052},28,[518,5054,595],{"emptyLinePlaceholder":594},[518,5056,5058,5060,5062,5065,5067,5069,5071,5073,5075,5077,5079,5081,5083,5085,5087,5089,5091,5093,5095,5097,5099,5101],{"class":520,"line":5057},29,[518,5059,681],{"class":601},[518,5061,605],{"class":647},[518,5063,5064],{"class":539},"product",[518,5066,689],{"class":647},[518,5068,668],{"class":535},[518,5070,837],{"class":601},[518,5072,605],{"class":647},[518,5074,842],{"class":535},[518,5076,4547],{"class":647},[518,5078,848],{"class":535},[518,5080,555],{"class":535},[518,5082,4960],{"class":558},[518,5084,562],{"class":535},[518,5086,543],{"class":535},[518,5088,859],{"class":647},[518,5090,848],{"class":535},[518,5092,555],{"class":535},[518,5094,4973],{"class":558},[518,5096,562],{"class":535},[518,5098,549],{"class":535},[518,5100,689],{"class":647},[518,5102,565],{"class":535},[518,5104,5106,5108,5110],{"class":520,"line":5105},30,[518,5107,754],{"class":535},[518,5109,689],{"class":539},[518,5111,565],{"class":535},[499,5113,5114,5115,5117,5118,5121,5122,5124,5125,5128,5129,5132],{},"The mock key is ",[503,5116,4395],{}," — the contract's prefix is already folded into the path by the client,\nso the key includes the full path. ",[503,5119,5120],{},"api.client.find(...)"," (the ",[503,5123,1022],{}," caller) throws a ",[503,5126,5127],{},"ContractError","\non a non-2xx; ",[503,5130,5131],{},"api.raw(key, args)"," never throws and returns the full discriminated union instead — use it\nwhen you specifically need to assert error-status handling:",[508,5134,5136],{"className":510,"code":5135,"filename":4404,"language":513,"meta":514,"style":514},"test(\"raw() returns a non-2xx result without throwing\", async () => {\n  const api = new ProductsApi(\n    ClientTransport.mock({\n      \"GET \u002Fapi\u002Fproducts\u002Fgone\": { status: 404, headers: {}, body: { reason: \"gone\" } },\n    }),\n  );\n\n  const result = await api.raw(\"find\", { params: { sku: \"gone\" } });\n\n  expect(result.status).toBe(404);\n  if (result.status === 404) {\n    expect(result.body).toEqual({ reason: \"gone\" });\n  }\n});\n",[503,5137,5138,5161,5175,5187,5235,5243,5249,5253,5307,5311,5339,5361,5399,5403],{"__ignoreMap":514},[518,5139,5140,5142,5144,5146,5149,5151,5153,5155,5157,5159],{"class":520,"line":521},[518,5141,602],{"class":601},[518,5143,605],{"class":539},[518,5145,562],{"class":535},[518,5147,5148],{"class":558},"raw() returns a non-2xx result without throwing",[518,5150,562],{"class":535},[518,5152,543],{"class":535},[518,5154,618],{"class":617},[518,5156,621],{"class":535},[518,5158,624],{"class":617},[518,5160,627],{"class":535},[518,5162,5163,5165,5167,5169,5171,5173],{"class":520,"line":528},[518,5164,633],{"class":617},[518,5166,4891],{"class":539},[518,5168,639],{"class":535},[518,5170,642],{"class":535},[518,5172,4692],{"class":601},[518,5174,1237],{"class":647},[518,5176,5177,5179,5181,5183,5185],{"class":520,"line":568},[518,5178,4904],{"class":539},[518,5180,668],{"class":535},[518,5182,4909],{"class":601},[518,5184,605],{"class":647},[518,5186,4122],{"class":535},[518,5188,5189,5191,5194,5196,5198,5200,5202,5204,5206,5208,5210,5212,5214,5216,5218,5220,5222,5224,5226,5229,5231,5233],{"class":520,"line":591},[518,5190,4918],{"class":535},[518,5192,5193],{"class":647},"GET \u002Fapi\u002Fproducts\u002Fgone",[518,5195,562],{"class":535},[518,5197,848],{"class":535},[518,5199,536],{"class":535},[518,5201,4930],{"class":647},[518,5203,848],{"class":535},[518,5205,4778],{"class":699},[518,5207,543],{"class":535},[518,5209,4939],{"class":647},[518,5211,848],{"class":535},[518,5213,4944],{"class":535},[518,5215,4947],{"class":647},[518,5217,848],{"class":535},[518,5219,536],{"class":535},[518,5221,4665],{"class":647},[518,5223,848],{"class":535},[518,5225,555],{"class":535},[518,5227,5228],{"class":558},"gone",[518,5230,562],{"class":535},[518,5232,549],{"class":535},[518,5234,2731],{"class":535},[518,5236,5237,5239,5241],{"class":520,"line":598},[518,5238,2784],{"class":535},[518,5240,689],{"class":647},[518,5242,1245],{"class":535},[518,5244,5245,5247],{"class":520,"line":630},[518,5246,2793],{"class":647},[518,5248,565],{"class":535},[518,5250,5251],{"class":520,"line":653},[518,5252,595],{"emptyLinePlaceholder":594},[518,5254,5255,5257,5260,5262,5264,5266,5268,5271,5273,5275,5277,5279,5281,5283,5285,5287,5289,5291,5293,5295,5297,5299,5301,5303,5305],{"class":520,"line":678},[518,5256,633],{"class":617},[518,5258,5259],{"class":539}," result",[518,5261,639],{"class":535},[518,5263,663],{"class":531},[518,5265,4891],{"class":539},[518,5267,668],{"class":535},[518,5269,5270],{"class":601},"raw",[518,5272,605],{"class":647},[518,5274,562],{"class":535},[518,5276,5020],{"class":558},[518,5278,562],{"class":535},[518,5280,543],{"class":535},[518,5282,536],{"class":535},[518,5284,5027],{"class":647},[518,5286,848],{"class":535},[518,5288,536],{"class":535},[518,5290,4547],{"class":647},[518,5292,848],{"class":535},[518,5294,555],{"class":535},[518,5296,5228],{"class":558},[518,5298,562],{"class":535},[518,5300,549],{"class":535},[518,5302,549],{"class":535},[518,5304,689],{"class":647},[518,5306,565],{"class":535},[518,5308,5309],{"class":520,"line":707},[518,5310,595],{"emptyLinePlaceholder":594},[518,5312,5313,5315,5317,5320,5322,5324,5326,5328,5330,5332,5335,5337],{"class":520,"line":751},[518,5314,681],{"class":601},[518,5316,605],{"class":647},[518,5318,5319],{"class":539},"result",[518,5321,668],{"class":535},[518,5323,2347],{"class":539},[518,5325,689],{"class":647},[518,5327,668],{"class":535},[518,5329,735],{"class":601},[518,5331,605],{"class":647},[518,5333,5334],{"class":699},"404",[518,5336,689],{"class":647},[518,5338,565],{"class":535},[518,5340,5341,5344,5347,5349,5351,5353,5355,5357,5359],{"class":520,"line":761},[518,5342,5343],{"class":531},"  if",[518,5345,5346],{"class":647}," (",[518,5348,5319],{"class":539},[518,5350,668],{"class":535},[518,5352,2347],{"class":539},[518,5354,3299],{"class":535},[518,5356,4778],{"class":699},[518,5358,4564],{"class":647},[518,5360,4122],{"class":535},[518,5362,5363,5365,5367,5369,5371,5373,5375,5377,5379,5381,5383,5385,5387,5389,5391,5393,5395,5397],{"class":520,"line":766},[518,5364,3268],{"class":601},[518,5366,605],{"class":647},[518,5368,5319],{"class":539},[518,5370,668],{"class":535},[518,5372,4819],{"class":539},[518,5374,689],{"class":647},[518,5376,668],{"class":535},[518,5378,837],{"class":601},[518,5380,605],{"class":647},[518,5382,842],{"class":535},[518,5384,4665],{"class":647},[518,5386,848],{"class":535},[518,5388,555],{"class":535},[518,5390,5228],{"class":558},[518,5392,562],{"class":535},[518,5394,549],{"class":535},[518,5396,689],{"class":647},[518,5398,565],{"class":535},[518,5400,5401],{"class":520,"line":790},[518,5402,4101],{"class":535},[518,5404,5405,5407,5409],{"class":520,"line":807},[518,5406,754],{"class":535},[518,5408,689],{"class":539},[518,5410,565],{"class":535},[1271,5412,5414],{"id":5413},"run-the-tests","Run the tests",[499,5416,5417,5418,5424,5425,5428,5429,5431,5432,5434],{},"Tests run on ",[2881,5419,5423],{"href":5420,"rel":5421},"https:\u002F\u002Fvitest.dev",[5422],"nofollow","Vitest"," through the ",[503,5426,5427],{},"vp test"," task. Group cases with ",[503,5430,1111],{},", write\neach with ",[503,5433,602],{},", and assert HTTP status before body so a failing status explains the response you got.",[5436,5437,5438,5453,5468,5482],"code-group",{},[508,5439,5444],{"className":5440,"code":5441,"filename":5442,"language":5443,"meta":514,"style":514},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm test\n","pnpm","bash",[503,5445,5446],{"__ignoreMap":514},[518,5447,5448,5450],{"class":520,"line":521},[518,5449,5442],{"class":1484},[518,5451,5452],{"class":558}," test\n",[508,5454,5457],{"className":5440,"code":5455,"filename":5456,"language":5443,"meta":514,"style":514},"npm run test\n","npm",[503,5458,5459],{"__ignoreMap":514},[518,5460,5461,5463,5466],{"class":520,"line":521},[518,5462,5456],{"class":1484},[518,5464,5465],{"class":558}," run",[518,5467,5452],{"class":558},[508,5469,5472],{"className":5440,"code":5470,"filename":5471,"language":5443,"meta":514,"style":514},"yarn run test\n","yarn",[503,5473,5474],{"__ignoreMap":514},[518,5475,5476,5478,5480],{"class":520,"line":521},[518,5477,5471],{"class":1484},[518,5479,5465],{"class":558},[518,5481,5452],{"class":558},[508,5483,5486],{"className":5440,"code":5484,"filename":5485,"language":5443,"meta":514,"style":514},"bun run test\n","bun",[503,5487,5488],{"__ignoreMap":514},[518,5489,5490,5492,5494],{"class":520,"line":521},[518,5491,5485],{"class":1484},[518,5493,5465],{"class":558},[518,5495,5452],{"class":558},[499,5497,5498,5501,5502,5505,5506,5508,5509,5511],{},[503,5499,5500],{},"pnpm test"," resolves the ",[503,5503,5504],{},"@heximon\u002F*"," packages from source, so you never rebuild a class before\ntesting it. When using ",[503,5507,999],{},", the app is compiled fresh for each test run — no dev server\nprerequisite, no stale ",[503,5510,2012],{}," directory.",[1271,5513,5515],{"id":5514},"next-steps","Next steps",[5517,5518,5519,5532,5537,5548,5557,5567,5582],"ul",{},[5520,5521,5522,5524,5525,4335,5527,5529,5530,668],"li",{},[2881,5523,116],{"href":117}," — ",[503,5526,999],{},[503,5528,1991],{}," in full:\nevery override form, database isolation, contract-mode registration, multi-app isolation, eager init,\nand configuring plugins via ",[503,5531,2886],{},[5520,5533,5534,5536],{},[2881,5535,57],{"href":58}," — the routes, middleware, and error filters your HTTP tests exercise.",[5520,5538,5539,5541,5542,5544,5545,5547],{},[2881,5540,233],{"href":234}," — the ",[503,5543,3112],{}," \u002F ",[503,5546,3138],{}," you dispatch through, and the retry a bus test surfaces.",[5520,5549,5550,5524,5553,5556],{},[2881,5551,5552],{"href":54},"Modules",[503,5554,5555],{},"providers"," and the import graph that decide which tokens a provider can inject.",[5520,5558,5559,5566],{},[2881,5560,5563],{"href":5561,"rel":5562},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL02-http-validation",[5422],[951,5564,5565],{},"L02 — HTTP validation","\n— two feature modules with an in-process end-to-end test that boots the real server and proves routing,\nvalidation, and the error filters that map domain errors to RFC 9457 responses.",[5520,5568,5569,5576,5577,5544,5579,5581],{},[2881,5570,5573],{"href":5571,"rel":5572},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL05-cqrs",[5422],[951,5574,5575],{},"L05 — CQRS commands & queries","\n— bus-dispatch tests that drive ",[503,5578,3112],{},[503,5580,3138],{}," directly and prove the 3-attempt concurrency retry.",[5520,5583,5584,5591],{},[2881,5585,5588],{"href":5586,"rel":5587},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fflagship",[5422],[951,5589,5590],{},"Example — Flagship","\n— a full register → login → create → complete flow tested end-to-end, with a fake email transport capturing the domain-event notification.",[5593,5594,5595],"style",{},"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}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":514,"searchDepth":528,"depth":528,"links":5597},[5598,5599,5600,5601,5602,5603,5604,5605],{"id":1273,"depth":528,"text":1274},{"id":1981,"depth":528,"text":1982},{"id":2889,"depth":528,"text":2890},{"id":3350,"depth":528,"text":3351},{"id":3820,"depth":528,"text":3821},{"id":4374,"depth":528,"text":4375},{"id":5413,"depth":528,"text":5414},{"id":5514,"depth":528,"text":5515},"Unit-test providers and handlers as plain classes with constructor-injected fakes, then reach for createTestApp and createTestClient when you need the real compiled wiring — routes, middleware, validation, error filters, and bus dispatch.","md",null,{},{"icon":114},{"title":111,"description":5606},"_gusBAIxVbEUNDiikPKKP4w-_0Am8dAfiMzAQqjidtc",[5614,5616],{"title":106,"path":107,"stem":108,"description":5615,"icon":109,"children":-1},"Throw an error and get a clean response — the HeximonError family, ErrorFilter mapping, and the RFC 9457 problem+json envelope.",{"title":116,"path":117,"stem":118,"description":5617,"icon":119,"children":-1},"createTestApp, TestApp, TestAppOptions, createTestClient, eagerInit, context.run, provider overrides, database isolation, contract-mode registration, multi-app isolation, heximon.config.ts plugin precedence",1783300761903]