[{"data":1,"prerenderedAt":2943},["ShallowReactive",2],{"navigation_docs":3,"-docs-essentials-migrations":493,"-docs-essentials-migrations-surround":2938},[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":92,"body":495,"description":2931,"extension":2932,"links":2933,"meta":2934,"navigation":2935,"path":93,"seo":2936,"stem":94,"__hash__":2937},"docs\u002Fdocs\u002F02.essentials\u002F09.migrations.md",{"type":496,"value":497,"toc":2921},"minimark",[498,530,557,562,569,601,612,645,648,714,747,993,1017,1021,1041,1144,1163,1406,1419,1430,1579,1606,1610,1644,1671,2136,2146,2166,2170,2176,2212,2232,2236,2239,2305,2309,2323,2332,2353,2357,2367,2761,2779,2829,2842,2846,2917],[499,500,501,502,506,507,511,512,515,516,519,520,523,524,529],"p",{},"Migrations split into two jobs Heximon keeps deliberately separate. ",[503,504,505],"strong",{},"Generating"," the SQL is the stock ",[508,509,510],"code",{},"drizzle-kit generate"," CLI's work — it diffs your schema and writes ",[508,513,514],{},".sql"," files; Heximon ships no schema-diff tooling because the upstream tool already does it well. ",[503,517,518],{},"Applying"," those files at runtime is an injectable ",[508,521,522],{},"MigrationRunner"," you wire like any other provider. Both read the same ",[525,526,528],"a",{"href":527},"\u002Fdocs\u002Fessentials\u002Fpersistence#author-the-unified-config","unified config",", so schema paths, credentials, and the output folder live in exactly one place.",[499,531,532,533,538,539,541,542,541,545,548,549,552,553,556],{},"This page covers that config-and-runner mechanism directly. The ",[525,534,535],{"href":371},[508,536,537],{},"heximon migrations"," CLI command wraps the same ",[508,540,510],{},"\u002F",[508,543,544],{},"push",[508,546,547],{},"studio"," calls shown below — it auto-detects your unified config(s) and loads the right ",[508,550,551],{},".env"," overlay for you, so you don't have to remember the ",[508,554,555],{},"--config"," flag.",[558,559,561],"h2",{"id":560},"generate-migrations","Generate migrations",[499,563,564,565,568],{},"Your config object is a valid stock drizzle-kit ",[508,566,567],{},"Config",", so the upstream CLI consumes it directly — no wrapper, no jiti patch. Every time you change a schema file, regenerate:",[570,571,577],"pre",{"className":572,"code":573,"filename":574,"language":575,"meta":576,"style":576},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpx drizzle-kit generate --config .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts\n","terminal","bash","",[508,578,579],{"__ignoreMap":576},[580,581,584,588,592,595,598],"span",{"class":582,"line":583},"line",1,[580,585,587],{"class":586},"sBMFI","pnpx",[580,589,591],{"class":590},"sfazB"," drizzle-kit",[580,593,594],{"class":590}," generate",[580,596,597],{"class":590}," --config",[580,599,600],{"class":590}," .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts\n",[499,602,603,604,607,608,611],{},"That writes a new migration folder into the config's ",[508,605,606],{},"out"," directory plus a ",[508,609,610],{},"meta\u002F"," snapshot. The other upstream commands take the same flag:",[570,613,615],{"className":572,"code":614,"filename":574,"language":575,"meta":576,"style":576},"pnpx drizzle-kit push   --config .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts\npnpx drizzle-kit studio --config .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts\n",[508,616,617,631],{"__ignoreMap":576},[580,618,619,621,623,626,629],{"class":582,"line":583},[580,620,587],{"class":586},[580,622,591],{"class":590},[580,624,625],{"class":590}," push",[580,627,628],{"class":590},"   --config",[580,630,600],{"class":590},[580,632,634,636,638,641,643],{"class":582,"line":633},2,[580,635,587],{"class":586},[580,637,591],{"class":590},[580,639,640],{"class":590}," studio",[580,642,597],{"class":590},[580,644,600],{"class":590},[499,646,647],{},"Wire generation into your scripts so it's one command:",[570,649,654],{"className":650,"code":651,"filename":652,"language":653,"meta":576,"style":576},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"scripts\": {\n    \"db:generate\": \"drizzle-kit generate --config .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts\"\n  }\n}\n","package.json","json",[508,655,656,662,680,702,708],{"__ignoreMap":576},[580,657,658],{"class":582,"line":583},[580,659,661],{"class":660},"sMK4o","{\n",[580,663,664,667,671,674,677],{"class":582,"line":633},[580,665,666],{"class":660},"  \"",[580,668,670],{"class":669},"spNyl","scripts",[580,672,673],{"class":660},"\"",[580,675,676],{"class":660},":",[580,678,679],{"class":660}," {\n",[580,681,683,686,689,691,693,696,699],{"class":582,"line":682},3,[580,684,685],{"class":660},"    \"",[580,687,688],{"class":586},"db:generate",[580,690,673],{"class":660},[580,692,676],{"class":660},[580,694,695],{"class":660}," \"",[580,697,698],{"class":590},"drizzle-kit generate --config .\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts",[580,700,701],{"class":660},"\"\n",[580,703,705],{"class":582,"line":704},4,[580,706,707],{"class":660},"  }\n",[580,709,711],{"class":582,"line":710},5,[580,712,713],{"class":660},"}\n",[499,715,716,717,719,720,723,724,727,728,731,732,735,736,738,739,743,744,746],{},"The ",[508,718,606],{}," directory is the same path the runner reads from — the unified config ",[503,721,722],{},"is"," the migration config.\n",[508,725,726],{},"DrizzleLibSQLConfig"," (and its pg\u002Fmysql2 twins) implements ",[508,729,730],{},"MigrationConfig"," by deriving ",[508,733,734],{},"migrationsFolder","\nfrom ",[508,737,606],{},", so the one config object drives drizzle-kit ",[740,741,742],"em",{},"and"," the runtime runner. In the example app ",[508,745,606],{},"\nis resolved to an absolute path so the runner reads the right folder from any working directory:",[570,748,753],{"className":749,"code":750,"filename":751,"language":752,"meta":576,"style":576},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const migrationsFolder = join(dirname(fileURLToPath(import.meta.url)), \"..\u002F..\u002Fdatabase\u002Fmigrations\");\n\nexport const databaseConfig = new DrizzleLibSQLConfig(schema, relations, {\n  dialect: \"sqlite\",\n  schema: \".\u002Fsrc\u002Fdatabase\u002Fschema.ts\",\n  out: migrationsFolder, \u002F\u002F drizzle-kit writes here; the runner reads here (via migrationsFolder)\n  get url(): string {\n    return process.env[\"DATABASE_URL\"] ?? \"file::memory:?cache=shared\";\n  },\n});\n\nexport default databaseConfig;\n","src\u002Fdatabase\u002Fdatabase.config.ts","ts",[508,754,755,815,821,852,870,886,903,920,959,965,975,980],{"__ignoreMap":576},[580,756,757,760,764,767,771,774,777,779,782,784,788,791,794,796,799,802,804,807,809,812],{"class":582,"line":583},[580,758,759],{"class":669},"const",[580,761,763],{"class":762},"sTEyZ"," migrationsFolder ",[580,765,766],{"class":660},"=",[580,768,770],{"class":769},"s2Zo4"," join",[580,772,773],{"class":762},"(",[580,775,776],{"class":769},"dirname",[580,778,773],{"class":762},[580,780,781],{"class":769},"fileURLToPath",[580,783,773],{"class":762},[580,785,787],{"class":786},"s7zQu","import",[580,789,790],{"class":660},".",[580,792,793],{"class":762},"meta",[580,795,790],{"class":660},[580,797,798],{"class":762},"url))",[580,800,801],{"class":660},",",[580,803,695],{"class":660},[580,805,806],{"class":590},"..\u002F..\u002Fdatabase\u002Fmigrations",[580,808,673],{"class":660},[580,810,811],{"class":762},")",[580,813,814],{"class":660},";\n",[580,816,817],{"class":582,"line":633},[580,818,820],{"emptyLinePlaceholder":819},true,"\n",[580,822,823,826,829,832,834,837,840,843,845,848,850],{"class":582,"line":682},[580,824,825],{"class":786},"export",[580,827,828],{"class":669}," const",[580,830,831],{"class":762}," databaseConfig ",[580,833,766],{"class":660},[580,835,836],{"class":660}," new",[580,838,839],{"class":769}," DrizzleLibSQLConfig",[580,841,842],{"class":762},"(schema",[580,844,801],{"class":660},[580,846,847],{"class":762}," relations",[580,849,801],{"class":660},[580,851,679],{"class":660},[580,853,854,858,860,862,865,867],{"class":582,"line":704},[580,855,857],{"class":856},"swJcz","  dialect",[580,859,676],{"class":660},[580,861,695],{"class":660},[580,863,864],{"class":590},"sqlite",[580,866,673],{"class":660},[580,868,869],{"class":660},",\n",[580,871,872,875,877,879,882,884],{"class":582,"line":710},[580,873,874],{"class":856},"  schema",[580,876,676],{"class":660},[580,878,695],{"class":660},[580,880,881],{"class":590},".\u002Fsrc\u002Fdatabase\u002Fschema.ts",[580,883,673],{"class":660},[580,885,869],{"class":660},[580,887,889,892,894,897,899],{"class":582,"line":888},6,[580,890,891],{"class":856},"  out",[580,893,676],{"class":660},[580,895,896],{"class":762}," migrationsFolder",[580,898,801],{"class":660},[580,900,902],{"class":901},"sHwdD"," \u002F\u002F drizzle-kit writes here; the runner reads here (via migrationsFolder)\n",[580,904,906,909,912,915,918],{"class":582,"line":905},7,[580,907,908],{"class":669},"  get",[580,910,911],{"class":856}," url",[580,913,914],{"class":660},"():",[580,916,917],{"class":586}," string",[580,919,679],{"class":660},[580,921,923,926,929,931,934,937,939,942,944,947,950,952,955,957],{"class":582,"line":922},8,[580,924,925],{"class":786},"    return",[580,927,928],{"class":762}," process",[580,930,790],{"class":660},[580,932,933],{"class":762},"env",[580,935,936],{"class":856},"[",[580,938,673],{"class":660},[580,940,941],{"class":590},"DATABASE_URL",[580,943,673],{"class":660},[580,945,946],{"class":856},"] ",[580,948,949],{"class":660},"??",[580,951,695],{"class":660},[580,953,954],{"class":590},"file::memory:?cache=shared",[580,956,673],{"class":660},[580,958,814],{"class":660},[580,960,962],{"class":582,"line":961},9,[580,963,964],{"class":660},"  },\n",[580,966,968,971,973],{"class":582,"line":967},10,[580,969,970],{"class":660},"}",[580,972,811],{"class":762},[580,974,814],{"class":660},[580,976,978],{"class":582,"line":977},11,[580,979,820],{"emptyLinePlaceholder":819},[580,981,983,985,988,991],{"class":582,"line":982},12,[580,984,825],{"class":786},[580,986,987],{"class":786}," default",[580,989,990],{"class":762}," databaseConfig",[580,992,814],{"class":660},[994,995,997,998,1001,1002,1005,1006,1009,1010,1013,1014,790],"callout",{"type":996},"info","The config file needs a ",[508,999,1000],{},"default export"," so ",[508,1003,1004],{},"drizzle-kit --config"," can load it — ",[508,1007,1008],{},"export default databaseConfig",". The same instance is imported by name by the runtime ",[508,1011,1012],{},"useFactory"," provider, so the CLI and the running app can never drift. See ",[525,1015,1016],{"href":527},"Database wiring",[558,1018,1020],{"id":1019},"apply-migrations-on-boot","Apply migrations on boot",[499,1022,1023,1024,1026,1027,1030,1031,1034,1035,1034,1038,676],{},"The runner implements the ",[508,1025,522],{}," contract from ",[508,1028,1029],{},"@heximon\u002Fpersistence"," — ",[508,1032,1033],{},"apply"," \u002F ",[508,1036,1037],{},"status",[508,1039,1040],{},"rollback",[570,1042,1045],{"className":749,"code":1043,"filename":1044,"language":752,"meta":576,"style":576},"abstract class MigrationRunner {\n  abstract apply(): Promise\u003Creadonly string[]>;      \u002F\u002F pending migrations, in id order\n  abstract status(): Promise\u003Creadonly MigrationStatusEntry[]>;\n  abstract rollback(): Promise\u003Cstring | undefined>;  \u002F\u002F forward-only dialects reject this\n}\n","MigrationRunner contract",[508,1046,1047,1060,1090,1113,1140],{"__ignoreMap":576},[580,1048,1049,1052,1055,1058],{"class":582,"line":583},[580,1050,1051],{"class":669},"abstract",[580,1053,1054],{"class":669}," class",[580,1056,1057],{"class":586}," MigrationRunner",[580,1059,679],{"class":660},[580,1061,1062,1065,1068,1070,1073,1076,1079,1081,1084,1087],{"class":582,"line":633},[580,1063,1064],{"class":669},"  abstract",[580,1066,1067],{"class":856}," apply",[580,1069,914],{"class":660},[580,1071,1072],{"class":586}," Promise",[580,1074,1075],{"class":660},"\u003C",[580,1077,1078],{"class":669},"readonly",[580,1080,917],{"class":586},[580,1082,1083],{"class":762},"[]",[580,1085,1086],{"class":660},">;",[580,1088,1089],{"class":901},"      \u002F\u002F pending migrations, in id order\n",[580,1091,1092,1094,1097,1099,1101,1103,1105,1108,1110],{"class":582,"line":682},[580,1093,1064],{"class":669},[580,1095,1096],{"class":856}," status",[580,1098,914],{"class":660},[580,1100,1072],{"class":586},[580,1102,1075],{"class":660},[580,1104,1078],{"class":669},[580,1106,1107],{"class":586}," MigrationStatusEntry",[580,1109,1083],{"class":762},[580,1111,1112],{"class":660},">;\n",[580,1114,1115,1117,1120,1122,1124,1126,1129,1132,1135,1137],{"class":582,"line":704},[580,1116,1064],{"class":669},[580,1118,1119],{"class":856}," rollback",[580,1121,914],{"class":660},[580,1123,1072],{"class":586},[580,1125,1075],{"class":660},[580,1127,1128],{"class":586},"string",[580,1130,1131],{"class":660}," |",[580,1133,1134],{"class":586}," undefined",[580,1136,1086],{"class":660},[580,1138,1139],{"class":901},"  \u002F\u002F forward-only dialects reject this\n",[580,1141,1142],{"class":582,"line":710},[580,1143,713],{"class":660},[499,1145,1146,1147,1150,1151,1154,1155,1158,1159,1162],{},"Drive it from a ",[508,1148,1149],{},"Task",". A task is an ordinary injectable — ",[508,1152,1153],{},"extends Task\u003C...>"," is the discovery base, and its constructor declares the runner as a dependency, resolved by class identity. You run it through the ",[508,1156,1157],{},"TaskManager",", which resolves the task and invokes it inside ",[508,1160,1161],{},"Context.run"," — so a migrate step is a one-line call at startup or in a deploy script:",[570,1164,1167],{"className":749,"code":1165,"filename":1166,"language":752,"meta":576,"style":576},"import { Task, type TaskResult } from \"@heximon\u002Fruntime\";\nimport { MigrationRunner } from \"@heximon\u002Fpersistence\";\n\nexport class MigrateTask extends Task\u003Cstring> {\n  public constructor(private readonly runner: MigrationRunner) {\n    super();\n  }\n\n  public override async run(): Promise\u003CTaskResult\u003Cstring>> {\n    const applied = await this.runner.apply(); \u002F\u002F idempotent — a re-run applies nothing new\n    return { result: `Applied ${applied.length} migration(s).` };\n  }\n}\n","src\u002Fdatabase\u002Fmigrate.task.ts",[508,1168,1169,1202,1222,1226,1249,1277,1287,1291,1295,1326,1358,1397,1401],{"__ignoreMap":576},[580,1170,1171,1173,1176,1179,1181,1184,1187,1190,1193,1195,1198,1200],{"class":582,"line":583},[580,1172,787],{"class":786},[580,1174,1175],{"class":660}," {",[580,1177,1178],{"class":762}," Task",[580,1180,801],{"class":660},[580,1182,1183],{"class":786}," type",[580,1185,1186],{"class":762}," TaskResult",[580,1188,1189],{"class":660}," }",[580,1191,1192],{"class":786}," from",[580,1194,695],{"class":660},[580,1196,1197],{"class":590},"@heximon\u002Fruntime",[580,1199,673],{"class":660},[580,1201,814],{"class":660},[580,1203,1204,1206,1208,1210,1212,1214,1216,1218,1220],{"class":582,"line":633},[580,1205,787],{"class":786},[580,1207,1175],{"class":660},[580,1209,1057],{"class":762},[580,1211,1189],{"class":660},[580,1213,1192],{"class":786},[580,1215,695],{"class":660},[580,1217,1029],{"class":590},[580,1219,673],{"class":660},[580,1221,814],{"class":660},[580,1223,1224],{"class":582,"line":682},[580,1225,820],{"emptyLinePlaceholder":819},[580,1227,1228,1230,1232,1235,1238,1240,1242,1244,1247],{"class":582,"line":704},[580,1229,825],{"class":786},[580,1231,1054],{"class":669},[580,1233,1234],{"class":586}," MigrateTask",[580,1236,1237],{"class":669}," extends",[580,1239,1178],{"class":586},[580,1241,1075],{"class":660},[580,1243,1128],{"class":586},[580,1245,1246],{"class":660},">",[580,1248,679],{"class":660},[580,1250,1251,1254,1257,1259,1262,1265,1269,1271,1273,1275],{"class":582,"line":710},[580,1252,1253],{"class":669},"  public",[580,1255,1256],{"class":669}," constructor",[580,1258,773],{"class":660},[580,1260,1261],{"class":669},"private",[580,1263,1264],{"class":669}," readonly",[580,1266,1268],{"class":1267},"sHdIc"," runner",[580,1270,676],{"class":660},[580,1272,1057],{"class":586},[580,1274,811],{"class":660},[580,1276,679],{"class":660},[580,1278,1279,1282,1285],{"class":582,"line":888},[580,1280,1281],{"class":762},"    super",[580,1283,1284],{"class":856},"()",[580,1286,814],{"class":660},[580,1288,1289],{"class":582,"line":905},[580,1290,707],{"class":660},[580,1292,1293],{"class":582,"line":922},[580,1294,820],{"emptyLinePlaceholder":819},[580,1296,1297,1299,1302,1305,1308,1310,1312,1314,1317,1319,1321,1324],{"class":582,"line":961},[580,1298,1253],{"class":669},[580,1300,1301],{"class":669}," override",[580,1303,1304],{"class":669}," async",[580,1306,1307],{"class":856}," run",[580,1309,914],{"class":660},[580,1311,1072],{"class":586},[580,1313,1075],{"class":660},[580,1315,1316],{"class":586},"TaskResult",[580,1318,1075],{"class":660},[580,1320,1128],{"class":586},[580,1322,1323],{"class":660},">>",[580,1325,679],{"class":660},[580,1327,1328,1331,1334,1337,1340,1343,1346,1348,1350,1352,1355],{"class":582,"line":967},[580,1329,1330],{"class":669},"    const",[580,1332,1333],{"class":762}," applied",[580,1335,1336],{"class":660}," =",[580,1338,1339],{"class":786}," await",[580,1341,1342],{"class":660}," this.",[580,1344,1345],{"class":762},"runner",[580,1347,790],{"class":660},[580,1349,1033],{"class":769},[580,1351,1284],{"class":856},[580,1353,1354],{"class":660},";",[580,1356,1357],{"class":901}," \u002F\u002F idempotent — a re-run applies nothing new\n",[580,1359,1360,1362,1364,1367,1369,1372,1375,1378,1381,1383,1386,1388,1391,1394],{"class":582,"line":977},[580,1361,925],{"class":786},[580,1363,1175],{"class":660},[580,1365,1366],{"class":856}," result",[580,1368,676],{"class":660},[580,1370,1371],{"class":660}," `",[580,1373,1374],{"class":590},"Applied ",[580,1376,1377],{"class":660},"${",[580,1379,1380],{"class":762},"applied",[580,1382,790],{"class":660},[580,1384,1385],{"class":762},"length",[580,1387,970],{"class":660},[580,1389,1390],{"class":590}," migration(s).",[580,1392,1393],{"class":660},"`",[580,1395,1396],{"class":660}," };\n",[580,1398,1399],{"class":582,"line":982},[580,1400,707],{"class":660},[580,1402,1404],{"class":582,"line":1403},13,[580,1405,713],{"class":660},[499,1407,1408,1411,1412,1415,1416,1418],{},[508,1409,1410],{},"apply()"," is idempotent on purpose: it reads its bookkeeping table, applies only the pending migrations in ",[508,1413,1414],{},"id"," order, and returns their ids. A second run returns ",[508,1417,1083],{}," and leaves the schema untouched — so it's safe to run on every start, with no \"first run\" branch to maintain.",[499,1420,1421,1422,1425,1426,1429],{},"The module runs it for you: a ",[508,1423,1424],{},"Module"," can implement ",[508,1427,1428],{},"OnInit"," and inject the task, so migrations apply the first time the module is constructed — automatically before any request, with no manual call:",[570,1431,1434],{"className":749,"code":1432,"filename":1433,"language":752,"meta":576,"style":576},"export class DatabaseModule\n  extends Module({ providers: [\u002F* … see below … *\u002F] })\n  implements OnInit\n{\n  public constructor(private readonly migrateTask: MigrateTask) {\n    super();\n  }\n\n  public async onInit(): Promise\u003Cvoid> {\n    await this.migrateTask.run(); \u002F\u002F idempotent — safe on every boot\n  }\n}\n","src\u002Fdatabase\u002Fdatabase.module.ts — auto-migrate on boot",[508,1435,1436,1445,1476,1484,1488,1511,1519,1523,1527,1549,1571,1575],{"__ignoreMap":576},[580,1437,1438,1440,1442],{"class":582,"line":583},[580,1439,825],{"class":786},[580,1441,1054],{"class":669},[580,1443,1444],{"class":586}," DatabaseModule\n",[580,1446,1447,1450,1453,1455,1458,1461,1463,1466,1469,1471,1473],{"class":582,"line":633},[580,1448,1449],{"class":669},"  extends",[580,1451,1452],{"class":769}," Module",[580,1454,773],{"class":762},[580,1456,1457],{"class":660},"{",[580,1459,1460],{"class":856}," providers",[580,1462,676],{"class":660},[580,1464,1465],{"class":762}," [",[580,1467,1468],{"class":901},"\u002F* … see below … *\u002F",[580,1470,946],{"class":762},[580,1472,970],{"class":660},[580,1474,1475],{"class":762},")\n",[580,1477,1478,1481],{"class":582,"line":682},[580,1479,1480],{"class":669},"  implements",[580,1482,1483],{"class":586}," OnInit\n",[580,1485,1486],{"class":582,"line":704},[580,1487,661],{"class":660},[580,1489,1490,1492,1494,1496,1498,1500,1503,1505,1507,1509],{"class":582,"line":710},[580,1491,1253],{"class":669},[580,1493,1256],{"class":669},[580,1495,773],{"class":660},[580,1497,1261],{"class":669},[580,1499,1264],{"class":669},[580,1501,1502],{"class":1267}," migrateTask",[580,1504,676],{"class":660},[580,1506,1234],{"class":586},[580,1508,811],{"class":660},[580,1510,679],{"class":660},[580,1512,1513,1515,1517],{"class":582,"line":888},[580,1514,1281],{"class":762},[580,1516,1284],{"class":856},[580,1518,814],{"class":660},[580,1520,1521],{"class":582,"line":905},[580,1522,707],{"class":660},[580,1524,1525],{"class":582,"line":922},[580,1526,820],{"emptyLinePlaceholder":819},[580,1528,1529,1531,1533,1536,1538,1540,1542,1545,1547],{"class":582,"line":961},[580,1530,1253],{"class":669},[580,1532,1304],{"class":669},[580,1534,1535],{"class":856}," onInit",[580,1537,914],{"class":660},[580,1539,1072],{"class":586},[580,1541,1075],{"class":660},[580,1543,1544],{"class":586},"void",[580,1546,1246],{"class":660},[580,1548,679],{"class":660},[580,1550,1551,1554,1556,1559,1561,1564,1566,1568],{"class":582,"line":967},[580,1552,1553],{"class":786},"    await",[580,1555,1342],{"class":660},[580,1557,1558],{"class":762},"migrateTask",[580,1560,790],{"class":660},[580,1562,1563],{"class":769},"run",[580,1565,1284],{"class":856},[580,1567,1354],{"class":660},[580,1569,1570],{"class":901}," \u002F\u002F idempotent — safe on every boot\n",[580,1572,1573],{"class":582,"line":977},[580,1574,707],{"class":660},[580,1576,1577],{"class":582,"line":982},[580,1578,713],{"class":660},[994,1580,1582,1588,1589,1591,1592,1595,1596,1599,1600,1602,1603,1605],{"type":1581},"warning",[503,1583,1584,1587],{},[508,1585,1586],{},"onInit"," auto-migrate races across multiple instances."," A rolling deploy or a serverless cold-start\nfan-out can boot several instances at once, each calling ",[508,1590,1410],{}," against the same bookkeeping table —\nconcurrent ",[508,1593,1594],{},"migrate"," runs can conflict or double-apply. In production, apply migrations once, before\ntraffic shifts, with a dedicated deploy step instead: ",[508,1597,1598],{},"heximon deploy --migrate"," (see\n",[525,1601,370],{"href":371},") or a CI job that calls the runner directly. Keep ",[508,1604,1586],{},"\nauto-migrate for local development, where there's only ever one instance.",[558,1607,1609],{"id":1608},"bind-the-runner-and-its-config","Bind the runner and its config",[499,1611,1612,1613,1616,1617,1619,1620,1625,1626,1628,1629,1632,1633,1636,1637,1639,1640,1643],{},"One config value, one DI token. The unified ",[508,1614,1615],{},"databaseConfig"," is a plain imported value; because ",[508,1618,726],{}," ",[503,1621,1622,1623],{},"implements ",[508,1624,730],{},", it's bound under the abstract, non-generic ",[508,1627,730],{}," token the runner reads. The database factory does ",[503,1630,1631],{},"not"," inject it — it ",[503,1634,1635],{},"closes over"," the same imported value. There is no ",[508,1638,726],{}," DI token: the config is a static value, not a dependency to resolve, and a ",[740,1641,1642],{},"generic"," class makes a misleading token (resolution is by class identity; type arguments are erased).",[499,1645,1646,1649,1650,1653,1654,1656,1657,1660,1661,1663,1664,1666,1667,1670],{},[508,1647,1648],{},"DrizzleLibSQLMigrationRunner","'s constructor takes the concrete ",[508,1651,1652],{},"AppDatabase"," and the abstract ",[508,1655,730],{}," — both plain DI tokens the compiler resolves by class identity — so it's a ",[503,1658,1659],{},"bare provider",": list the class directly, no ",[508,1662,1012],{}," wrapper needed. Injecting the abstract ",[508,1665,522],{}," anywhere in the module (here, ",[508,1668,1669],{},"MigrateTask","'s constructor) then resolves straight through to this concrete runner:",[570,1672,1675],{"className":749,"code":1673,"filename":1674,"language":752,"meta":576,"style":576},"import { Context, Module, type OnInit } from \"@heximon\u002Fruntime\";\nimport { MigrationConfig, MigrationRunner } from \"@heximon\u002Fpersistence\";\nimport { DrizzleLibSQLMigrationRunner } from \"@heximon\u002Fdrizzle\u002Flibsql\";\nimport { AppDatabase } from \".\u002Fapp-database\";\nimport { databaseConfig } from \".\u002Fdatabase.config\";\nimport { MigrateTask } from \".\u002Fmigrate.task\";\n\nexport class DatabaseModule\n  extends Module({\n    providers: [\n      \u002F\u002F The unified config value, bound to the abstract migration-config token the runner reads. The\n      \u002F\u002F database factory closes over the same imported value — no DrizzleLibSQLConfig DI token.\n      { provide: MigrationConfig, useValue: databaseConfig },\n      {\n        provide: AppDatabase,\n        \u002F\u002F `AppDatabase` is an empty subclass; it inherits the `(config, context)` constructor. The factory\n        \u002F\u002F closes over the imported `databaseConfig` (not a DI token) — the argument a bare class provider\n        \u002F\u002F couldn't supply; the inherited `onShutdown` is detected on the result either way.\n        useFactory: (context: Context): AppDatabase => new AppDatabase(databaseConfig, context),\n      },\n      \u002F\u002F A bare listing: both constructor parameters (AppDatabase, MigrationConfig) are DI tokens, so no\n      \u002F\u002F useFactory wrapper is needed.\n      DrizzleLibSQLMigrationRunner,\n      MigrateTask,\n    ],\n    exports: [AppDatabase, MigrationRunner, MigrateTask],\n  })\n  implements OnInit\n{\n  public constructor(private readonly migrateTask: MigrateTask) {\n    super();\n  }\n\n  public async onInit(): Promise\u003Cvoid> {\n    await this.migrateTask.run();\n  }\n}\n","src\u002Fdatabase\u002Fdatabase.module.ts",[508,1676,1677,1709,1734,1756,1778,1799,1820,1824,1832,1842,1852,1857,1862,1886,1892,1904,1910,1916,1922,1962,1968,1974,1980,1988,1996,2004,2026,2034,2041,2046,2069,2078,2083,2088,2109,2126,2131],{"__ignoreMap":576},[580,1678,1679,1681,1683,1686,1688,1690,1692,1694,1697,1699,1701,1703,1705,1707],{"class":582,"line":583},[580,1680,787],{"class":786},[580,1682,1175],{"class":660},[580,1684,1685],{"class":762}," Context",[580,1687,801],{"class":660},[580,1689,1452],{"class":762},[580,1691,801],{"class":660},[580,1693,1183],{"class":786},[580,1695,1696],{"class":762}," OnInit",[580,1698,1189],{"class":660},[580,1700,1192],{"class":786},[580,1702,695],{"class":660},[580,1704,1197],{"class":590},[580,1706,673],{"class":660},[580,1708,814],{"class":660},[580,1710,1711,1713,1715,1718,1720,1722,1724,1726,1728,1730,1732],{"class":582,"line":633},[580,1712,787],{"class":786},[580,1714,1175],{"class":660},[580,1716,1717],{"class":762}," MigrationConfig",[580,1719,801],{"class":660},[580,1721,1057],{"class":762},[580,1723,1189],{"class":660},[580,1725,1192],{"class":786},[580,1727,695],{"class":660},[580,1729,1029],{"class":590},[580,1731,673],{"class":660},[580,1733,814],{"class":660},[580,1735,1736,1738,1740,1743,1745,1747,1749,1752,1754],{"class":582,"line":682},[580,1737,787],{"class":786},[580,1739,1175],{"class":660},[580,1741,1742],{"class":762}," DrizzleLibSQLMigrationRunner",[580,1744,1189],{"class":660},[580,1746,1192],{"class":786},[580,1748,695],{"class":660},[580,1750,1751],{"class":590},"@heximon\u002Fdrizzle\u002Flibsql",[580,1753,673],{"class":660},[580,1755,814],{"class":660},[580,1757,1758,1760,1762,1765,1767,1769,1771,1774,1776],{"class":582,"line":704},[580,1759,787],{"class":786},[580,1761,1175],{"class":660},[580,1763,1764],{"class":762}," AppDatabase",[580,1766,1189],{"class":660},[580,1768,1192],{"class":786},[580,1770,695],{"class":660},[580,1772,1773],{"class":590},".\u002Fapp-database",[580,1775,673],{"class":660},[580,1777,814],{"class":660},[580,1779,1780,1782,1784,1786,1788,1790,1792,1795,1797],{"class":582,"line":710},[580,1781,787],{"class":786},[580,1783,1175],{"class":660},[580,1785,990],{"class":762},[580,1787,1189],{"class":660},[580,1789,1192],{"class":786},[580,1791,695],{"class":660},[580,1793,1794],{"class":590},".\u002Fdatabase.config",[580,1796,673],{"class":660},[580,1798,814],{"class":660},[580,1800,1801,1803,1805,1807,1809,1811,1813,1816,1818],{"class":582,"line":888},[580,1802,787],{"class":786},[580,1804,1175],{"class":660},[580,1806,1234],{"class":762},[580,1808,1189],{"class":660},[580,1810,1192],{"class":786},[580,1812,695],{"class":660},[580,1814,1815],{"class":590},".\u002Fmigrate.task",[580,1817,673],{"class":660},[580,1819,814],{"class":660},[580,1821,1822],{"class":582,"line":905},[580,1823,820],{"emptyLinePlaceholder":819},[580,1825,1826,1828,1830],{"class":582,"line":922},[580,1827,825],{"class":786},[580,1829,1054],{"class":669},[580,1831,1444],{"class":586},[580,1833,1834,1836,1838,1840],{"class":582,"line":961},[580,1835,1449],{"class":669},[580,1837,1452],{"class":769},[580,1839,773],{"class":762},[580,1841,661],{"class":660},[580,1843,1844,1847,1849],{"class":582,"line":967},[580,1845,1846],{"class":856},"    providers",[580,1848,676],{"class":660},[580,1850,1851],{"class":762}," [\n",[580,1853,1854],{"class":582,"line":977},[580,1855,1856],{"class":901},"      \u002F\u002F The unified config value, bound to the abstract migration-config token the runner reads. The\n",[580,1858,1859],{"class":582,"line":982},[580,1860,1861],{"class":901},"      \u002F\u002F database factory closes over the same imported value — no DrizzleLibSQLConfig DI token.\n",[580,1863,1864,1867,1870,1872,1874,1876,1879,1881,1883],{"class":582,"line":1403},[580,1865,1866],{"class":660},"      {",[580,1868,1869],{"class":856}," provide",[580,1871,676],{"class":660},[580,1873,1717],{"class":762},[580,1875,801],{"class":660},[580,1877,1878],{"class":856}," useValue",[580,1880,676],{"class":660},[580,1882,831],{"class":762},[580,1884,1885],{"class":660},"},\n",[580,1887,1889],{"class":582,"line":1888},14,[580,1890,1891],{"class":660},"      {\n",[580,1893,1895,1898,1900,1902],{"class":582,"line":1894},15,[580,1896,1897],{"class":856},"        provide",[580,1899,676],{"class":660},[580,1901,1764],{"class":762},[580,1903,869],{"class":660},[580,1905,1907],{"class":582,"line":1906},16,[580,1908,1909],{"class":901},"        \u002F\u002F `AppDatabase` is an empty subclass; it inherits the `(config, context)` constructor. The factory\n",[580,1911,1913],{"class":582,"line":1912},17,[580,1914,1915],{"class":901},"        \u002F\u002F closes over the imported `databaseConfig` (not a DI token) — the argument a bare class provider\n",[580,1917,1919],{"class":582,"line":1918},18,[580,1920,1921],{"class":901},"        \u002F\u002F couldn't supply; the inherited `onShutdown` is detected on the result either way.\n",[580,1923,1925,1928,1930,1933,1936,1938,1940,1943,1945,1948,1950,1952,1955,1957,1960],{"class":582,"line":1924},19,[580,1926,1927],{"class":769},"        useFactory",[580,1929,676],{"class":660},[580,1931,1932],{"class":660}," (",[580,1934,1935],{"class":1267},"context",[580,1937,676],{"class":660},[580,1939,1685],{"class":586},[580,1941,1942],{"class":660},"):",[580,1944,1764],{"class":586},[580,1946,1947],{"class":669}," =>",[580,1949,836],{"class":660},[580,1951,1764],{"class":769},[580,1953,1954],{"class":762},"(databaseConfig",[580,1956,801],{"class":660},[580,1958,1959],{"class":762}," context)",[580,1961,869],{"class":660},[580,1963,1965],{"class":582,"line":1964},20,[580,1966,1967],{"class":660},"      },\n",[580,1969,1971],{"class":582,"line":1970},21,[580,1972,1973],{"class":901},"      \u002F\u002F A bare listing: both constructor parameters (AppDatabase, MigrationConfig) are DI tokens, so no\n",[580,1975,1977],{"class":582,"line":1976},22,[580,1978,1979],{"class":901},"      \u002F\u002F useFactory wrapper is needed.\n",[580,1981,1983,1986],{"class":582,"line":1982},23,[580,1984,1985],{"class":762},"      DrizzleLibSQLMigrationRunner",[580,1987,869],{"class":660},[580,1989,1991,1994],{"class":582,"line":1990},24,[580,1992,1993],{"class":762},"      MigrateTask",[580,1995,869],{"class":660},[580,1997,1999,2002],{"class":582,"line":1998},25,[580,2000,2001],{"class":762},"    ]",[580,2003,869],{"class":660},[580,2005,2007,2010,2012,2015,2017,2019,2021,2024],{"class":582,"line":2006},26,[580,2008,2009],{"class":856},"    exports",[580,2011,676],{"class":660},[580,2013,2014],{"class":762}," [AppDatabase",[580,2016,801],{"class":660},[580,2018,1057],{"class":762},[580,2020,801],{"class":660},[580,2022,2023],{"class":762}," MigrateTask]",[580,2025,869],{"class":660},[580,2027,2029,2032],{"class":582,"line":2028},27,[580,2030,2031],{"class":660},"  }",[580,2033,1475],{"class":762},[580,2035,2037,2039],{"class":582,"line":2036},28,[580,2038,1480],{"class":669},[580,2040,1483],{"class":586},[580,2042,2044],{"class":582,"line":2043},29,[580,2045,661],{"class":660},[580,2047,2049,2051,2053,2055,2057,2059,2061,2063,2065,2067],{"class":582,"line":2048},30,[580,2050,1253],{"class":669},[580,2052,1256],{"class":669},[580,2054,773],{"class":660},[580,2056,1261],{"class":669},[580,2058,1264],{"class":669},[580,2060,1502],{"class":1267},[580,2062,676],{"class":660},[580,2064,1234],{"class":586},[580,2066,811],{"class":660},[580,2068,679],{"class":660},[580,2070,2072,2074,2076],{"class":582,"line":2071},31,[580,2073,1281],{"class":762},[580,2075,1284],{"class":856},[580,2077,814],{"class":660},[580,2079,2081],{"class":582,"line":2080},32,[580,2082,707],{"class":660},[580,2084,2086],{"class":582,"line":2085},33,[580,2087,820],{"emptyLinePlaceholder":819},[580,2089,2091,2093,2095,2097,2099,2101,2103,2105,2107],{"class":582,"line":2090},34,[580,2092,1253],{"class":669},[580,2094,1304],{"class":669},[580,2096,1535],{"class":856},[580,2098,914],{"class":660},[580,2100,1072],{"class":586},[580,2102,1075],{"class":660},[580,2104,1544],{"class":586},[580,2106,1246],{"class":660},[580,2108,679],{"class":660},[580,2110,2112,2114,2116,2118,2120,2122,2124],{"class":582,"line":2111},35,[580,2113,1553],{"class":786},[580,2115,1342],{"class":660},[580,2117,1558],{"class":762},[580,2119,790],{"class":660},[580,2121,1563],{"class":769},[580,2123,1284],{"class":856},[580,2125,814],{"class":660},[580,2127,2129],{"class":582,"line":2128},36,[580,2130,707],{"class":660},[580,2132,2134],{"class":582,"line":2133},37,[580,2135,713],{"class":660},[499,2137,2138,2139,2142,2143,2145],{},"This works the same way for the PostgreSQL and MySQL2 runners — every dialect runner's constructor takes\nconcrete, DI-resolvable parameters, so a bare listing is enough. The one exception is\n",[508,2140,2141],{},"DrizzleDurableSQLiteMigrationRunner"," (the Cloudflare Durable Object dialect): its second constructor\nparameter is bundled migration data, not a class, so it still needs a ",[508,2144,1012],{}," provider to supply that\nargument.",[499,2147,2148,2150,2151,2154,2155,2158,2159,2162,2163,790],{},[508,2149,1652],{}," is the app's ",[503,2152,2153],{},"named database subclass"," — the DI token the repository injects — typed against the schema. Its body is empty: it inherits the ",[508,2156,2157],{},"(config, context)"," constructor, so ",[508,2160,2161],{},"new AppDatabase(config, context)"," opens a libsql client from the config and builds the ORM over this app's schema + relations. See ",[525,2164,1016],{"href":2165},"\u002Fdocs\u002Fessentials\u002Fpersistence#inject-the-one-shared-instance",[558,2167,2169],{"id":2168},"check-status","Check status",[499,2171,2172,2175],{},[508,2173,2174],{},"status()"," reports every known migration as applied or pending — handy in CI or a health check, where you want to fail loudly if a deploy left migrations unapplied:",[570,2177,2179],{"className":749,"code":2178,"filename":1037,"language":752,"meta":576,"style":576},"const entries = await runner.status();\n\u002F\u002F [ { id: \"20240101000000_create_tasks\",  applied: true },\n\u002F\u002F   { id: \"20240102000000_create_labels\", applied: false } ]\n",[508,2180,2181,2202,2207],{"__ignoreMap":576},[580,2182,2183,2185,2188,2190,2192,2194,2196,2198,2200],{"class":582,"line":583},[580,2184,759],{"class":669},[580,2186,2187],{"class":762}," entries ",[580,2189,766],{"class":660},[580,2191,1339],{"class":786},[580,2193,1268],{"class":762},[580,2195,790],{"class":660},[580,2197,1037],{"class":769},[580,2199,1284],{"class":762},[580,2201,814],{"class":660},[580,2203,2204],{"class":582,"line":633},[580,2205,2206],{"class":901},"\u002F\u002F [ { id: \"20240101000000_create_tasks\",  applied: true },\n",[580,2208,2209],{"class":582,"line":682},[580,2210,2211],{"class":901},"\u002F\u002F   { id: \"20240102000000_create_labels\", applied: false } ]\n",[994,2213,2214,1619,2217,2219,2220,2223,2224,2227,2228,2231],{"type":1581},[503,2215,2216],{},"Drizzle migrations are forward-only.",[508,2218,510],{}," writes no ",[508,2221,2222],{},"down"," SQL, so ",[508,2225,2226],{},"rollback()"," rejects rather than guessing at a reverse — calling it throws a ",[508,2229,2230],{},"forward-only"," error. To undo a change, generate a new forward migration that reverses it; that keeps your history linear and replayable instead of leaving the schema in a state no migration describes.",[558,2233,2235],{"id":2234},"switch-dialects","Switch dialects",[499,2237,2238],{},"The shape is identical across dialects — swap the config class, the runner, and the generate command; only the imports change:",[2240,2241,2242,2258],"table",{},[2243,2244,2245],"thead",{},[2246,2247,2248,2253,2255],"tr",{},[2249,2250,2252],"th",{"align":2251},"left","Dialect",[2249,2254,567],{"align":2251},[2249,2256,2257],{"align":2251},"Runner",[2259,2260,2261,2275,2290],"tbody",{},[2246,2262,2263,2267,2271],{},[2264,2265,2266],"td",{"align":2251},"LibSQL \u002F Turso",[2264,2268,2269],{"align":2251},[508,2270,726],{},[2264,2272,2273],{"align":2251},[508,2274,1648],{},[2246,2276,2277,2280,2285],{},[2264,2278,2279],{"align":2251},"PostgreSQL",[2264,2281,2282],{"align":2251},[508,2283,2284],{},"DrizzlePgConfig",[2264,2286,2287],{"align":2251},[508,2288,2289],{},"DrizzlePgMigrationRunner",[2246,2291,2292,2295,2300],{},[2264,2293,2294],{"align":2251},"MySQL2",[2264,2296,2297],{"align":2251},[508,2298,2299],{},"DrizzleMySQL2Config",[2264,2301,2302],{"align":2251},[508,2303,2304],{},"DrizzleMySQL2MigrationRunner",[558,2306,2308],{"id":2307},"migration-files-layout","Migration files layout",[499,2310,716,2311,1034,2313,2315,2316,2319,2320,2322],{},[508,2312,606],{},[508,2314,734],{}," follows drizzle-kit v1's own layout — one folder per migration, named ",[508,2317,2318],{},"YYYYMMDDHHmmss_\u003Cname>",", plus a ",[508,2321,610],{}," snapshot directory:",[570,2324,2330],{"className":2325,"code":2327,"filename":2328,"language":2329,"meta":576},[2326],"language-text","migrations\u002F\n├── 20240101000000_create_tasks\u002F\n│   └── migration.sql\n├── 20240102000000_create_labels\u002F\n│   └── migration.sql\n└── meta\u002F\n    ├── _journal.json\n    └── 0000_snapshot.json\n","migrations","text",[508,2331,2327],{"__ignoreMap":576},[499,2333,2334,2335,2338,2339,2341,2342,2344,2345,2348,2349,2352],{},"The timestamp prefix (",[508,2336,2337],{},"YYYYMMDDHHmmss",") is generated by ",[508,2340,510],{}," and is required — the runner\nparses the first 14 characters as a timestamp to determine apply order. Commit every file. The ",[508,2343,610],{},"\nsnapshots are what ",[508,2346,2347],{},"drizzle-kit"," diffs your current schema against to produce the next migration; delete them\nand the next ",[508,2350,2351],{},"generate"," re-emits the whole schema from scratch.",[558,2354,2356],{"id":2355},"seeding-fixture-data","Seeding fixture data",[499,2358,2359,2360,2362,2363,2366],{},"Seeding is a plain ",[508,2361,1149],{}," that injects a repository and calls the aggregate factory directly — no\nabstract ",[508,2364,2365],{},"Seeder"," base, no third-party seed library:",[570,2368,2371],{"className":749,"code":2369,"filename":2370,"language":752,"meta":576,"style":576},"import { Task, type TaskResult, uuid } from \"@heximon\u002Fruntime\";\nimport { User, type UserId } from \"..\u002Fusers\u002Fuser.entity\";\nimport { UserRepository } from \"..\u002Fusers\u002Fuser.repository\";\n\nexport class SeedTask extends Task\u003Cstring> {\n  public constructor(private readonly users: UserRepository) {\n    super();\n  }\n\n  public override async run(): Promise\u003CTaskResult\u003Cstring>> {\n    const fixtures = [\n      { name: \"Alice Example\", email: \"alice@example.com\" },\n      { name: \"Bob Example\", email: \"bob@example.com\" },\n    ];\n    for (const fixture of fixtures) {\n      const user = User.create(uuid.v7\u003CUserId>(), fixture);\n      await this.users.save(user);\n    }\n    return { result: `Seeded ${fixtures.length} fixture(s).` };\n  }\n}\n","src\u002Fdatabase\u002Fseed.task.ts",[508,2372,2373,2404,2433,2455,2459,2480,2503,2511,2515,2519,2545,2556,2589,2619,2625,2647,2691,2715,2720,2753,2757],{"__ignoreMap":576},[580,2374,2375,2377,2379,2381,2383,2385,2387,2389,2392,2394,2396,2398,2400,2402],{"class":582,"line":583},[580,2376,787],{"class":786},[580,2378,1175],{"class":660},[580,2380,1178],{"class":762},[580,2382,801],{"class":660},[580,2384,1183],{"class":786},[580,2386,1186],{"class":762},[580,2388,801],{"class":660},[580,2390,2391],{"class":762}," uuid",[580,2393,1189],{"class":660},[580,2395,1192],{"class":786},[580,2397,695],{"class":660},[580,2399,1197],{"class":590},[580,2401,673],{"class":660},[580,2403,814],{"class":660},[580,2405,2406,2408,2410,2413,2415,2417,2420,2422,2424,2426,2429,2431],{"class":582,"line":633},[580,2407,787],{"class":786},[580,2409,1175],{"class":660},[580,2411,2412],{"class":762}," User",[580,2414,801],{"class":660},[580,2416,1183],{"class":786},[580,2418,2419],{"class":762}," UserId",[580,2421,1189],{"class":660},[580,2423,1192],{"class":786},[580,2425,695],{"class":660},[580,2427,2428],{"class":590},"..\u002Fusers\u002Fuser.entity",[580,2430,673],{"class":660},[580,2432,814],{"class":660},[580,2434,2435,2437,2439,2442,2444,2446,2448,2451,2453],{"class":582,"line":682},[580,2436,787],{"class":786},[580,2438,1175],{"class":660},[580,2440,2441],{"class":762}," UserRepository",[580,2443,1189],{"class":660},[580,2445,1192],{"class":786},[580,2447,695],{"class":660},[580,2449,2450],{"class":590},"..\u002Fusers\u002Fuser.repository",[580,2452,673],{"class":660},[580,2454,814],{"class":660},[580,2456,2457],{"class":582,"line":704},[580,2458,820],{"emptyLinePlaceholder":819},[580,2460,2461,2463,2465,2468,2470,2472,2474,2476,2478],{"class":582,"line":710},[580,2462,825],{"class":786},[580,2464,1054],{"class":669},[580,2466,2467],{"class":586}," SeedTask",[580,2469,1237],{"class":669},[580,2471,1178],{"class":586},[580,2473,1075],{"class":660},[580,2475,1128],{"class":586},[580,2477,1246],{"class":660},[580,2479,679],{"class":660},[580,2481,2482,2484,2486,2488,2490,2492,2495,2497,2499,2501],{"class":582,"line":888},[580,2483,1253],{"class":669},[580,2485,1256],{"class":669},[580,2487,773],{"class":660},[580,2489,1261],{"class":669},[580,2491,1264],{"class":669},[580,2493,2494],{"class":1267}," users",[580,2496,676],{"class":660},[580,2498,2441],{"class":586},[580,2500,811],{"class":660},[580,2502,679],{"class":660},[580,2504,2505,2507,2509],{"class":582,"line":905},[580,2506,1281],{"class":762},[580,2508,1284],{"class":856},[580,2510,814],{"class":660},[580,2512,2513],{"class":582,"line":922},[580,2514,707],{"class":660},[580,2516,2517],{"class":582,"line":961},[580,2518,820],{"emptyLinePlaceholder":819},[580,2520,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543],{"class":582,"line":967},[580,2522,1253],{"class":669},[580,2524,1301],{"class":669},[580,2526,1304],{"class":669},[580,2528,1307],{"class":856},[580,2530,914],{"class":660},[580,2532,1072],{"class":586},[580,2534,1075],{"class":660},[580,2536,1316],{"class":586},[580,2538,1075],{"class":660},[580,2540,1128],{"class":586},[580,2542,1323],{"class":660},[580,2544,679],{"class":660},[580,2546,2547,2549,2552,2554],{"class":582,"line":977},[580,2548,1330],{"class":669},[580,2550,2551],{"class":762}," fixtures",[580,2553,1336],{"class":660},[580,2555,1851],{"class":856},[580,2557,2558,2560,2563,2565,2567,2570,2572,2574,2577,2579,2581,2584,2586],{"class":582,"line":982},[580,2559,1866],{"class":660},[580,2561,2562],{"class":856}," name",[580,2564,676],{"class":660},[580,2566,695],{"class":660},[580,2568,2569],{"class":590},"Alice Example",[580,2571,673],{"class":660},[580,2573,801],{"class":660},[580,2575,2576],{"class":856}," email",[580,2578,676],{"class":660},[580,2580,695],{"class":660},[580,2582,2583],{"class":590},"alice@example.com",[580,2585,673],{"class":660},[580,2587,2588],{"class":660}," },\n",[580,2590,2591,2593,2595,2597,2599,2602,2604,2606,2608,2610,2612,2615,2617],{"class":582,"line":1403},[580,2592,1866],{"class":660},[580,2594,2562],{"class":856},[580,2596,676],{"class":660},[580,2598,695],{"class":660},[580,2600,2601],{"class":590},"Bob Example",[580,2603,673],{"class":660},[580,2605,801],{"class":660},[580,2607,2576],{"class":856},[580,2609,676],{"class":660},[580,2611,695],{"class":660},[580,2613,2614],{"class":590},"bob@example.com",[580,2616,673],{"class":660},[580,2618,2588],{"class":660},[580,2620,2621,2623],{"class":582,"line":1888},[580,2622,2001],{"class":856},[580,2624,814],{"class":660},[580,2626,2627,2630,2632,2634,2637,2640,2642,2645],{"class":582,"line":1894},[580,2628,2629],{"class":786},"    for",[580,2631,1932],{"class":856},[580,2633,759],{"class":669},[580,2635,2636],{"class":762}," fixture",[580,2638,2639],{"class":660}," of",[580,2641,2551],{"class":762},[580,2643,2644],{"class":856},") ",[580,2646,661],{"class":660},[580,2648,2649,2652,2655,2657,2659,2661,2664,2666,2669,2671,2674,2676,2679,2681,2683,2685,2687,2689],{"class":582,"line":1906},[580,2650,2651],{"class":669},"      const",[580,2653,2654],{"class":762}," user",[580,2656,1336],{"class":660},[580,2658,2412],{"class":762},[580,2660,790],{"class":660},[580,2662,2663],{"class":769},"create",[580,2665,773],{"class":856},[580,2667,2668],{"class":762},"uuid",[580,2670,790],{"class":660},[580,2672,2673],{"class":769},"v7",[580,2675,1075],{"class":660},[580,2677,2678],{"class":586},"UserId",[580,2680,1246],{"class":660},[580,2682,1284],{"class":856},[580,2684,801],{"class":660},[580,2686,2636],{"class":762},[580,2688,811],{"class":856},[580,2690,814],{"class":660},[580,2692,2693,2696,2698,2701,2703,2706,2708,2711,2713],{"class":582,"line":1912},[580,2694,2695],{"class":786},"      await",[580,2697,1342],{"class":660},[580,2699,2700],{"class":762},"users",[580,2702,790],{"class":660},[580,2704,2705],{"class":769},"save",[580,2707,773],{"class":856},[580,2709,2710],{"class":762},"user",[580,2712,811],{"class":856},[580,2714,814],{"class":660},[580,2716,2717],{"class":582,"line":1918},[580,2718,2719],{"class":660},"    }\n",[580,2721,2722,2724,2726,2728,2730,2732,2735,2737,2740,2742,2744,2746,2749,2751],{"class":582,"line":1924},[580,2723,925],{"class":786},[580,2725,1175],{"class":660},[580,2727,1366],{"class":856},[580,2729,676],{"class":660},[580,2731,1371],{"class":660},[580,2733,2734],{"class":590},"Seeded ",[580,2736,1377],{"class":660},[580,2738,2739],{"class":762},"fixtures",[580,2741,790],{"class":660},[580,2743,1385],{"class":762},[580,2745,970],{"class":660},[580,2747,2748],{"class":590}," fixture(s).",[580,2750,1393],{"class":660},[580,2752,1396],{"class":660},[580,2754,2755],{"class":582,"line":1964},[580,2756,707],{"class":660},[580,2758,2759],{"class":582,"line":1970},[580,2760,713],{"class":660},[499,2762,2763,2764,2767,2768,2771,2772,2774,2775,2778],{},"Wire ",[508,2765,2766],{},"SeedTask"," as a plain provider in the module that owns the repository it injects (here ",[508,2769,2770],{},"UserModule","),\nand run it via the ",[508,2773,1157],{},". Migrations have already applied at boot (",[508,2776,2777],{},"DatabaseModule.onInit","), so the\nschema is ready — seeding is the only explicit step:",[570,2780,2783],{"className":749,"code":2781,"filename":2782,"language":752,"meta":576,"style":576},"const manager = await app.get(TaskManager);\nawait manager.run(SeedTask); \u002F\u002F the schema already exists (migrations ran on boot)\n","run order",[508,2784,2785,2809],{"__ignoreMap":576},[580,2786,2787,2789,2792,2794,2796,2799,2801,2804,2807],{"class":582,"line":583},[580,2788,759],{"class":669},[580,2790,2791],{"class":762}," manager ",[580,2793,766],{"class":660},[580,2795,1339],{"class":786},[580,2797,2798],{"class":762}," app",[580,2800,790],{"class":660},[580,2802,2803],{"class":769},"get",[580,2805,2806],{"class":762},"(TaskManager)",[580,2808,814],{"class":660},[580,2810,2811,2814,2817,2819,2821,2824,2826],{"class":582,"line":633},[580,2812,2813],{"class":786},"await",[580,2815,2816],{"class":762}," manager",[580,2818,790],{"class":660},[580,2820,1563],{"class":769},[580,2822,2823],{"class":762},"(SeedTask)",[580,2825,1354],{"class":660},[580,2827,2828],{"class":901}," \u002F\u002F the schema already exists (migrations ran on boot)\n",[994,2830,2831,2834,2835,2838,2839,2841],{"type":1581},[503,2832,2833],{},"Seeding is not idempotent."," Running the task twice inserts duplicate rows or throws a uniqueness-constraint\nerror (if the schema enforces it). Callers can clear the target table first, add a guard, or treat a\nconstraint error as a no-op. For bulk fake data, ",[508,2836,2837],{},"drizzle-seed"," (an optional upstream tool) is an\nalternative — the ",[508,2840,2766],{}," pattern is for small, deterministic, domain-rule-respecting fixture sets.",[558,2843,2845],{"id":2844},"see-also","See also",[2847,2848,2849,2858,2863,2874,2890,2904],"ul",{},[2850,2851,2852,2854,2855,2857],"li",{},[525,2853,1016],{"href":88}," — the ",[508,2856,1012],{}," provider and the unified config the CLI and runtime share.",[2850,2859,2860,2862],{},[525,2861,82],{"href":83}," — schemas, value-object columns, repositories, and relations.",[2850,2864,2865,2854,2868,2870,2871,2873],{},[525,2866,2867],{"href":88},"Persistence contracts",[508,2869,730],{}," and ",[508,2872,522],{}," tokens the runner implements.",[2850,2875,2876,2880,2881,541,2883,541,2885,2887,2888,556],{},[525,2877,2878],{"href":371},[508,2879,537],{}," — the CLI command that detects your unified config(s) and drives ",[508,2882,2351],{},[508,2884,544],{},[508,2886,547],{}," without the ",[508,2889,555],{},[2850,2891,2892,2900,2901,2903],{},[525,2893,2897],{"href":2894,"rel":2895},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL04-database",[2896],"nofollow",[503,2898,2899],{},"Example L04 — database"," — a CRUD API over a single SQLite table with the unified config ",[508,2902,2347],{}," and the runtime both read.",[2850,2905,2906,2913,2914,2916],{},[525,2907,2910],{"href":2908,"rel":2909},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL06-ddd",[2896],[503,2911,2912],{},"Example L06 — DDD"," — value-object columns, repositories, migrations applied on boot, and a ",[508,2915,2766],{}," for fixture data.",[2918,2919,2920],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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}",{"title":576,"searchDepth":633,"depth":633,"links":2922},[2923,2924,2925,2926,2927,2928,2929,2930],{"id":560,"depth":633,"text":561},{"id":1019,"depth":633,"text":1020},{"id":1608,"depth":633,"text":1609},{"id":2168,"depth":633,"text":2169},{"id":2234,"depth":633,"text":2235},{"id":2307,"depth":633,"text":2308},{"id":2355,"depth":633,"text":2356},{"id":2844,"depth":633,"text":2845},"Generate Drizzle migrations with stock drizzle-kit, then apply them with the injectable MigrationRunner, MigrationConfig, and a Task — one unified config drives both the CLI and the runtime.","md",null,{},{"icon":95},{"title":92,"description":2931},"AtsHcd2oWDZfIMZterQLQjYFMuKbn1UgROBpLWD-KiY",[2939,2941],{"title":87,"path":88,"stem":89,"description":2940,"icon":90,"children":-1},"A dialect-agnostic persistence boundary — the abstract Database surface, runInTransaction transactions, optimistic concurrency with ConcurrencyConflictError, MigrationRunner contracts, and how a concrete dialect plugs in via a useFactory provider.",{"title":97,"path":98,"stem":99,"description":2942,"icon":100,"children":-1},"Verify callers with JWT, hash passwords through the PasswordHashingAlgorithm port, read the request-scoped AuthContext, and list JWTAuthMiddleware directly in your app.",1783300761903]