@voltro/cli 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/CHANGELOG.md +1801 -0
  2. package/bin/nodeEnvironment.d.mts +30 -0
  3. package/bin/nodeEnvironment.mjs +158 -0
  4. package/bin/voltro.mjs +69 -5
  5. package/dist/addCommand-BNeoeSxe.js +124 -0
  6. package/dist/addCommand-aXSQveak.js +2 -0
  7. package/dist/agentsMd-BTchIZku.js +2 -0
  8. package/dist/agentsMd-mhQMF1bx.js +254 -0
  9. package/dist/apiBuild-BICVGnEC.js +2 -0
  10. package/dist/{apiBuild-h9VHtnlw.js → apiBuild-DZF_f0_I.js} +46 -46
  11. package/dist/appPort-B_HpJ_ck.js +48 -0
  12. package/dist/baselineCommand-C2ClWZN3.js +2 -0
  13. package/dist/baselineCommand-DIttzO8A.js +227 -0
  14. package/dist/bin.js +71 -28
  15. package/dist/build-CE7Ca9gm.js +711 -0
  16. package/dist/cacheCommand-DA4OH9xt.js +42 -0
  17. package/dist/capabilitiesCommand-nq_pz5xd.js +123 -0
  18. package/dist/checkCommand-Dv8r9tGO.js +231 -0
  19. package/dist/checkCommand-YZDmkAGd.js +2 -0
  20. package/dist/{cliArgs-qdZSElM3.js → cliArgs-D4p8n7EE.js} +12 -1
  21. package/dist/cliError-BmdYnghb.js +10 -0
  22. package/dist/cliOutput-D1tSBoRM.js +15 -0
  23. package/dist/{cliRuntime-Oh517vCV.js → cliRuntime-Dh7UDinH.js} +20 -20
  24. package/dist/cloudClient-DWL-Hw_T.js +67 -0
  25. package/dist/cloudCmd-Cvv5HGaZ.js +364 -0
  26. package/dist/clusterCmd-CNXKlcvD.js +54 -0
  27. package/dist/codegen-CYM3Zqrf.js +605 -0
  28. package/dist/codegen-ChBi_hVa.js +2 -0
  29. package/dist/codegenCommand-DC6w2tNZ.js +30 -0
  30. package/dist/codemodRunner-DRRqXR74.js +5243 -0
  31. package/dist/commandRunner-BLAEFLjp.js +47 -0
  32. package/dist/commands-gutsz-Ac.js +808 -0
  33. package/dist/connectionConfig-UFlIEiys.js +66 -0
  34. package/dist/dashboardCommand-3YG8p-UA.js +25 -0
  35. package/dist/dataCommand-qL0r7fPO.js +535 -0
  36. package/dist/dataProfile-dW-PsfLB.js +15 -0
  37. package/dist/{dbCommand-DTLKAfbA.js → dbCommand-B6X0FZbq.js} +551 -401
  38. package/dist/dbCommand-CpdKLeQq.js +2 -0
  39. package/dist/{dev-C_P8FLSx.js → dev-CerMd0mW.js} +3122 -3129
  40. package/dist/dev-CoG-ZPx8.js +3 -0
  41. package/dist/devActivity-Dx_3nnGv.js +100 -0
  42. package/dist/devActivity.js +1 -1
  43. package/dist/dialectDriver-CgXnDfec.js +39 -0
  44. package/dist/discover-C9XKJDco.js +25 -0
  45. package/dist/doctorCommand-BvqGBwNG.js +2 -0
  46. package/dist/{checkCommand-xGhRFFg2.js → doctorCommand-CnDXQxfa.js} +520 -1278
  47. package/dist/dormancyCommand-Dszo57d6.js +69 -0
  48. package/dist/e2eCmd-BRabZww-.js +147 -0
  49. package/dist/embeddingsCommand-C0sKVRo1.js +73 -0
  50. package/dist/envCommand-DPgdV1Bq.js +60 -0
  51. package/dist/evalCommand-6RUfPen4.js +118 -0
  52. package/dist/evolveCommand-DHpkgjgH.js +281 -0
  53. package/dist/fileTaxonomy-CJfgOllU.js +457 -0
  54. package/dist/frameworkTableAssembly-BGHmck-x.js +2 -0
  55. package/dist/{frameworkTableAssembly-BwIrO5nv.js → frameworkTableAssembly-DkkP6BgC.js} +184 -148
  56. package/dist/generateCommand-oibemh97.js +147 -0
  57. package/dist/index.d.ts +45 -0
  58. package/dist/index.js +4 -3
  59. package/dist/infoCommand-BJw9nLUR.js +60 -0
  60. package/dist/{inspect-BUUjt773.js → inspect-CBqFtAKA.js} +82 -40
  61. package/dist/inspect-C_T_WGvl.js +2 -0
  62. package/dist/inspectCmd-Bppy-GGw.js +224 -0
  63. package/dist/inspectFetch-Cm8_wVvp.js +151 -0
  64. package/dist/inspectMetrics-CfdKLh6t.js +72 -0
  65. package/dist/loadEnv-D9nEOClM.js +44 -0
  66. package/dist/logFileSink-C_D2wRN1.js +105 -0
  67. package/dist/logsCmd-CCca3KRZ.js +260 -0
  68. package/dist/manifestBuild-ChsKAhmn.js +2 -0
  69. package/dist/{manifestBuild-BLrVuSlM.js → manifestBuild-sxpwdKY1.js} +1 -1
  70. package/dist/metaCommands-7MJfZ5cf.js +196 -0
  71. package/dist/migrate-CBwOt_iV.js +83 -0
  72. package/dist/mssqlClusterPatch-_4cE_nun.js +44 -0
  73. package/dist/newCommand-COWOJ1_E.js +156 -0
  74. package/dist/nodeEnvironment-cGFAj1J8.js +28 -0
  75. package/dist/packageCommand-Cug_3Ogl.js +271 -0
  76. package/dist/pageConvention-cEiRxdab.js +5 -0
  77. package/dist/privacyCommand-C-Df56U_.js +146 -0
  78. package/dist/projectScaffold-DmzEKHib.js +2 -0
  79. package/dist/projectScaffold-LMMtaavR.js +814 -0
  80. package/dist/renderModeScan-D7J1B7Kw.js +105 -0
  81. package/dist/renderProfile-1OWWAAtx.js +81 -0
  82. package/dist/runtimeRegistry-DMeKfTHP.js +81 -0
  83. package/dist/runtimeTrace-CRxalXTs.js +91 -0
  84. package/dist/scheduleCmd--jksTrf6.js +69 -0
  85. package/dist/scheduleManifestCmd-D2x0CTTY.js +249 -0
  86. package/dist/schemaIr-UJybUUZW.js +103 -0
  87. package/dist/{sdkgen-C81QIkiL.js → sdkgen-CYJscZC7.js} +111 -209
  88. package/dist/seedRunner-TFHHiToI.js +329 -0
  89. package/dist/serveCommand-B_isw7q4.js +1647 -0
  90. package/dist/serveCommand-DOvbgRnQ.js +2 -0
  91. package/dist/serveEntry.js +5 -5
  92. package/dist/serverlessCommand-CfJZy6dS.js +482 -0
  93. package/dist/start-9LiUOfES.js +1087 -0
  94. package/dist/start-B-9Nsp-S.js +3 -0
  95. package/dist/startEntry.js +2 -2
  96. package/dist/staticCommand-Dr2M6tpU.js +304 -0
  97. package/dist/storageCommand-Co6NfLqN.js +42 -0
  98. package/dist/templates-De8IR5-c.js +102 -0
  99. package/dist/test-CI6iDsYc.js +115 -0
  100. package/dist/tracesCmd-CkEZQrtt.js +232 -0
  101. package/dist/tsconfigPaths-BWXBWgcl.js +107 -0
  102. package/dist/tsxLoader-EuXmSJ1K.js +51 -0
  103. package/dist/typecheckCommand-BlsWiCNq.js +61 -0
  104. package/dist/updateCommand-Bkptutss.js +585 -0
  105. package/dist/updateCommand-us1_hdIC.js +2 -0
  106. package/dist/{inspectMetrics-1xzTKAFx.js → webDev-CBYvPqQr.js} +975 -1559
  107. package/dist/webDev-Cg-fFiyd2.js +2 -0
  108. package/dist/webhookDiscovery-CrGAfhIG.js +2 -0
  109. package/dist/webhookDiscovery-D7VaeMlz.js +51 -0
  110. package/dist/webhooksCommand-CID96Rga.js +267 -0
  111. package/dist/workflowsCmd-D1VTmLMY.js +608 -0
  112. package/package.json +179 -17
  113. package/templates/AGENTS.core.md +58 -3
  114. package/templates/AGENTS.md +64 -7
  115. package/templates/agent-docs/_index.md +6 -4
  116. package/templates/agent-docs/_manifest.json +22 -5
  117. package/templates/agent-docs/ai.md +370 -0
  118. package/templates/agent-docs/authentication.md +265 -31
  119. package/templates/agent-docs/caching.md +6 -0
  120. package/templates/agent-docs/cli.md +794 -50
  121. package/templates/agent-docs/data.md +550 -11
  122. package/templates/agent-docs/database/migrations.md +174 -25
  123. package/templates/agent-docs/database/misc.md +156 -40
  124. package/templates/agent-docs/database/querying.md +19 -1
  125. package/templates/agent-docs/database/scaling.md +60 -0
  126. package/templates/agent-docs/database/schema.md +1 -0
  127. package/templates/agent-docs/database/seedsdialects.md +208 -19
  128. package/templates/agent-docs/database/transactions.md +68 -0
  129. package/templates/agent-docs/deployment.md +69 -3
  130. package/templates/agent-docs/introduction.md +87 -16
  131. package/templates/agent-docs/local-first-mobile.md +79 -4
  132. package/templates/agent-docs/multi-tenancy.md +95 -20
  133. package/templates/agent-docs/observability.md +58 -3
  134. package/templates/agent-docs/plugins/ai-flows.md +161 -2
  135. package/templates/agent-docs/plugins/analytics-postgres.md +1 -1
  136. package/templates/agent-docs/plugins/audit.md +37 -1
  137. package/templates/agent-docs/plugins/auth-social.md +143 -0
  138. package/templates/agent-docs/plugins/auth-workos.md +4 -2
  139. package/templates/agent-docs/plugins/auth.md +131 -6
  140. package/templates/agent-docs/plugins/billing.md +132 -15
  141. package/templates/agent-docs/plugins/cdc-out.md +46 -7
  142. package/templates/agent-docs/plugins/clickhouse.md +1 -1
  143. package/templates/agent-docs/plugins/duckdb.md +1 -1
  144. package/templates/agent-docs/plugins/flags.md +132 -0
  145. package/templates/agent-docs/plugins/governance.md +105 -7
  146. package/templates/agent-docs/plugins/multitenancy.md +9 -4
  147. package/templates/agent-docs/plugins/presence.md +13 -2
  148. package/templates/agent-docs/plugins/ratelimit.md +9 -0
  149. package/templates/agent-docs/plugins/search.md +157 -6
  150. package/templates/agent-docs/plugins/sso-saml.md +47 -8
  151. package/templates/agent-docs/plugins/webhooks.md +105 -0
  152. package/templates/agent-docs/plugins.md +150 -18
  153. package/templates/agent-docs/reference.md +60 -3
  154. package/templates/agent-docs/releases.md +1117 -0
  155. package/templates/agent-docs/routing.md +43 -25
  156. package/templates/agent-docs/scheduling.md +10 -0
  157. package/templates/agent-docs/schema-driven-ui.md +92 -12
  158. package/templates/agent-docs/security.md +426 -0
  159. package/templates/agent-docs/templates/apibackends.md +87 -18
  160. package/templates/agent-docs/templates/appshells.md +32 -14
  161. package/templates/agent-docs/templates/overview.md +13 -8
  162. package/templates/agent-docs/testing.md +211 -14
  163. package/templates/agent-docs/whats-new.md +1700 -104
  164. package/templates/agent-docs/workflows.md +130 -14
  165. package/templates/apps/api-ai/actions/summarize.action.ts +11 -0
  166. package/templates/apps/api-ai/package.json +8 -7
  167. package/templates/apps/api-auth/actions/me.action.ts +13 -0
  168. package/templates/apps/api-auth/package.json +9 -8
  169. package/templates/apps/api-backend/mutations/notes.create.mutation.ts +9 -0
  170. package/templates/apps/api-backend/package.json +12 -8
  171. package/templates/apps/api-backend/queries/notes.query.ts +30 -8
  172. package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +14 -0
  173. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +8 -0
  174. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +10 -0
  175. package/templates/apps/api-backend-deactivation/package.json +8 -7
  176. package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +17 -0
  177. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +9 -0
  178. package/templates/apps/api-backend-mail/package.json +9 -8
  179. package/templates/apps/api-backend-mail/queries/notes.query.ts +30 -8
  180. package/templates/apps/api-backend-mariadb/.env.example +14 -0
  181. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +9 -0
  182. package/templates/apps/api-backend-mariadb/package.json +10 -9
  183. package/templates/apps/api-backend-mariadb/queries/notes.query.ts +30 -8
  184. package/templates/apps/api-backend-sqlite/.env.example +14 -0
  185. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +9 -0
  186. package/templates/apps/api-backend-sqlite/package.json +9 -8
  187. package/templates/apps/api-backend-sqlite/queries/notes.query.ts +30 -8
  188. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +13 -0
  189. package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +12 -0
  190. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +9 -0
  191. package/templates/apps/api-backend-storage/package.json +9 -8
  192. package/templates/apps/api-backend-storage/queries/notes.query.ts +30 -8
  193. package/templates/apps/api-cms/actions/content.get.action.ts +7 -0
  194. package/templates/apps/api-cms/actions/content.types.action.ts +6 -0
  195. package/templates/apps/api-cms/actions/me.action.ts +13 -0
  196. package/templates/apps/api-cms/app.config.ts +19 -0
  197. package/templates/apps/api-cms/authz.ts +63 -0
  198. package/templates/apps/api-cms/mutations/content.publish.mutation.ts +10 -0
  199. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +10 -0
  200. package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +5 -0
  201. package/templates/apps/api-cms/package.json +11 -10
  202. package/templates/apps/api-cms/queries/content.list.query.ts +23 -7
  203. package/templates/apps/api-cms/tests/accessDecisions.test.ts +121 -0
  204. package/templates/apps/api-cms/tests/content.descriptors.test.ts +8 -4
  205. package/templates/apps/api-collab/mutations/documents.create.mutation.ts +8 -0
  206. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +13 -0
  207. package/templates/apps/api-collab/package.json +9 -8
  208. package/templates/apps/api-collab/queries/documents.query.ts +19 -7
  209. package/templates/apps/api-data-advanced/package.json +9 -8
  210. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +12 -0
  211. package/templates/apps/api-data-advanced/queries/books.search.query.ts +9 -0
  212. package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +17 -0
  213. package/templates/apps/api-durable/mutations/orders.place.mutation.ts +9 -0
  214. package/templates/apps/api-durable/package.json +9 -8
  215. package/templates/apps/api-feature-flags/actions/notes.export.action.ts +16 -0
  216. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +12 -0
  217. package/templates/apps/api-feature-flags/package.json +10 -9
  218. package/templates/apps/api-governance/README.md +30 -8
  219. package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -1
  220. package/templates/apps/api-governance/actions/profiles.get.action.ts +29 -4
  221. package/templates/apps/api-governance/database/schema.ts +16 -4
  222. package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +12 -0
  223. package/templates/apps/api-governance/package.json +9 -8
  224. package/templates/apps/api-kv/actions/sync.pull.action.ts +15 -0
  225. package/templates/apps/api-kv/actions/sync.reset.action.ts +13 -0
  226. package/templates/apps/api-kv/actions/sync.status.action.ts +7 -0
  227. package/templates/apps/api-kv/package.json +9 -8
  228. package/templates/apps/api-kv/queries/events.list.query.ts +19 -8
  229. package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +11 -0
  230. package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +13 -0
  231. package/templates/apps/api-moderation/package.json +9 -8
  232. package/templates/apps/api-observability/mutations/notes.create.mutation.ts +8 -0
  233. package/templates/apps/api-observability/package.json +9 -8
  234. package/templates/apps/api-observability/queries/notes.list.query.ts +13 -0
  235. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +14 -0
  236. package/templates/apps/api-ratelimit/package.json +9 -8
  237. package/templates/apps/api-rbac/package.json +9 -8
  238. package/templates/apps/api-rest/package.json +8 -7
  239. package/templates/apps/api-saas/mutations/projects.create.mutation.ts +13 -0
  240. package/templates/apps/api-saas/package.json +12 -11
  241. package/templates/apps/api-saas/queries/projects.list.query.ts +11 -0
  242. package/templates/apps/api-saas-starter/actions/me.action.ts +13 -0
  243. package/templates/apps/api-saas-starter/app.config.ts +19 -0
  244. package/templates/apps/api-saas-starter/authz.ts +75 -0
  245. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +10 -0
  246. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +9 -0
  247. package/templates/apps/api-saas-starter/package.json +15 -11
  248. package/templates/apps/api-saas-starter/queries/invites.list.query.ts +19 -8
  249. package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -7
  250. package/templates/apps/api-saas-starter/tests/accessDecisions.test.ts +135 -0
  251. package/templates/apps/api-search/mutations/articles.create.mutation.ts +14 -0
  252. package/templates/apps/api-search/package.json +9 -8
  253. package/templates/apps/api-search/queries/articles.list.query.ts +21 -8
  254. package/templates/apps/api-status/README.md +10 -3
  255. package/templates/apps/api-status/app.config.ts +8 -3
  256. package/templates/apps/api-status/authz.ts +5 -3
  257. package/templates/apps/api-status/package.json +9 -8
  258. package/templates/apps/api-status/queries/components.list.query.ts +14 -6
  259. package/templates/apps/api-status/queries/incidents.live.query.ts +23 -10
  260. package/templates/apps/api-status/queries/updates.list.query.ts +16 -9
  261. package/templates/apps/api-status/tests/status.test.ts +9 -1
  262. package/templates/apps/api-versioning/actions/documents.asOf.action.ts +12 -0
  263. package/templates/apps/api-versioning/actions/documents.history.action.ts +13 -0
  264. package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +9 -0
  265. package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +12 -0
  266. package/templates/apps/api-versioning/package.json +9 -8
  267. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +16 -0
  268. package/templates/apps/api-webhooks/package.json +10 -9
  269. package/templates/apps/api-webhooks/queries/orders.list.query.ts +10 -0
  270. package/templates/apps/changelog/package.json +8 -6
  271. package/templates/apps/edge-functions/package.json +2 -2
  272. package/templates/apps/frontend-admin/package.json +10 -8
  273. package/templates/apps/frontend-admin/src/lib/admin.ts +20 -9
  274. package/templates/apps/frontend-admin/src/locales/de.ts +11 -1
  275. package/templates/apps/frontend-admin/src/locales/en.ts +13 -1
  276. package/templates/apps/frontend-admin/src/pages/admin/[entity]/page.tsx +65 -22
  277. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +130 -23
  278. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +3 -2
  279. package/templates/apps/frontend-admin/src/pages/admin/page.test.tsx +19 -2
  280. package/templates/apps/frontend-admin/src/pages/admin/page.tsx +9 -4
  281. package/templates/apps/frontend-app/app.config.ts +4 -3
  282. package/templates/apps/frontend-app/package.json +11 -8
  283. package/templates/apps/frontend-app/src/lib/api.ts +25 -0
  284. package/templates/apps/frontend-app/src/pages/page.test.tsx +130 -82
  285. package/templates/apps/frontend-app/src/pages/page.tsx +14 -18
  286. package/templates/apps/frontend-auth/package.json +10 -8
  287. package/templates/apps/frontend-blank/package.json +9 -7
  288. package/templates/apps/frontend-cms/package.json +11 -9
  289. package/templates/apps/frontend-collab/package.json +12 -9
  290. package/templates/apps/frontend-collab/src/pages/page.test.tsx +122 -78
  291. package/templates/apps/frontend-contact/package.json +9 -7
  292. package/templates/apps/frontend-dashboard/package.json +9 -7
  293. package/templates/apps/frontend-docs/package.json +9 -7
  294. package/templates/apps/frontend-i18n/package.json +8 -6
  295. package/templates/apps/frontend-landing/package.json +9 -7
  296. package/templates/apps/frontend-portal/package.json +10 -8
  297. package/templates/apps/frontend-saas/app.config.ts +10 -6
  298. package/templates/apps/frontend-saas/package.json +10 -8
  299. package/templates/apps/frontend-saas/src/lib/api.ts +27 -32
  300. package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +7 -8
  301. package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +27 -3
  302. package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +4 -4
  303. package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +3 -4
  304. package/templates/apps/frontend-spa/package.json +9 -7
  305. package/templates/apps/frontend-ssr/package.json +9 -7
  306. package/templates/apps/frontend-ssr-api/package.json +10 -8
  307. package/templates/apps/frontend-static-blog/package.json +8 -6
  308. package/templates/apps/frontend-status/package.json +10 -8
  309. package/templates/apps/mobile-app/README.md +1 -0
  310. package/templates/apps/mobile-app/package.json +4 -2
  311. package/templates/apps/mobile-app/src/app/index.tsx +22 -12
  312. package/templates/apps/mobile-app/src/app/orders/[id].tsx +1 -1
  313. package/templates/apps/mobile-app/src/lib/api.ts +34 -0
  314. package/templates/apps/mobile-app/voltro.mobile.ts +4 -2
  315. package/templates/baselines/bare/.env.example +14 -0
  316. package/templates/baselines/bare/baseline.json +4 -4
  317. package/templates/baselines/compose/.env.example +14 -0
  318. package/templates/baselines/compose/README.md +1 -1
  319. package/templates/baselines/compose/baseline.json +5 -5
  320. package/templates/baselines/compose-mariadb/.env.example +14 -0
  321. package/templates/baselines/compose-mariadb/README.md +1 -1
  322. package/templates/baselines/compose-mariadb/baseline.json +5 -5
  323. package/templates/baselines/helm/.env.example +14 -0
  324. package/templates/baselines/helm/baseline.json +4 -4
  325. package/dist/apiBuild-C-x9YacA.js +0 -2
  326. package/dist/checkCommand-DRovTKza.js +0 -2
  327. package/dist/commands-CJfepbm4.js +0 -11541
  328. package/dist/dbCommand-b1gum4td.js +0 -2
  329. package/dist/dev-iiMtlkfs.js +0 -3
  330. package/dist/devActivity-BhIu6ncs.js +0 -159
  331. package/dist/frameworkTableAssembly-D-EebUQX.js +0 -2
  332. package/dist/inspect-mmBuRXmy.js +0 -2
  333. package/dist/manifestBuild-Dj8Jjoto.js +0 -2
  334. package/dist/seedRunner-Bqxgp7HZ.js +0 -230
  335. package/dist/serveCommand-DdaM4Hup.js +0 -1608
  336. package/dist/start-C0koT0UO.js +0 -1084
  337. /package/templates/apps/api-ai/actions/{summarize.action.server.tsx → summarize.action.server.ts} +0 -0
@@ -1,26 +1,24 @@
1
- import { i as e, n as t, r as n, s as r, t as i } from "./seedRunner-Bqxgp7HZ.js";
2
- import { n as a } from "./appModuleLoader-C9r9mxZt.js";
3
- import { n as o } from "./frameworkTableAssembly-BwIrO5nv.js";
4
- import { b as s } from "./fileConventions-Cof68_BL.js";
5
- import { a as c, n as l, t as u } from "./cliArgs-qdZSElM3.js";
6
- import { basename as d, join as f, relative as p, resolve as m } from "node:path";
7
- import { pathToFileURL as h } from "node:url";
8
- import { Effect as g } from "effect";
9
- import { createLogger as _ } from "@voltro/logger";
10
- import { promises as v, writeSync as y } from "node:fs";
11
- import { InMemoryDataStore as b, makeFieldCipher as ee } from "@voltro/runtime";
12
- import { SqlClient as x } from "@effect/sql";
13
- import { actorsTable as te, frameworkTables as S, isEncrypted as C, isMigrationDefinition as ne, quoteIdent as re, registerCoreTables as ie } from "@voltro/database";
14
- import { createHash as ae } from "node:crypto";
15
- import { DEFAULT_CDC_CHANNEL as oe, applyPlan as se, applySchema as w, assessRollingDeployGate as ce, declaredSnapshot as le, destructiveScope as ue, detectReactiveTriggerDrift as de, fingerprintSchema as fe, ignoreTablesFromEnv as T, introspectSchema as pe, pendingFileMigrationIds as me, planMigrations as E, reactiveTriggerRepairSql as he, rollbackFileBasedMigration as ge, rollingDeployUnsafeOps as _e, runFileBasedMigrations as ve, shortFingerprint as D, squashMigrationPlans as ye, unblockLossy as be } from "@voltro/database/sql";
16
- //#region src/cliError.ts
17
- var O = class extends Error {
18
- isCliError = !0;
19
- code;
20
- constructor(e, t = 1) {
21
- super(e), this.name = "CliError", this.code = t;
22
- }
23
- }, xe = (e) => typeof e == "object" && !!e && e.isCliError === !0, Se = (e) => typeof e != "string", Ce = (e, t, n, r) => {
1
+ import { n as e, r as t } from "./nodeEnvironment-cGFAj1J8.js";
2
+ import { t as n } from "./cliError-BmdYnghb.js";
3
+ import { n as r } from "./appModuleLoader-C9r9mxZt.js";
4
+ import { a as i, i as a, n as o, t as s } from "./cliArgs-D4p8n7EE.js";
5
+ import { r as c } from "./dialectDriver-CgXnDfec.js";
6
+ import { a as l } from "./connectionConfig-UFlIEiys.js";
7
+ import { i as u, n as d, r as f, s as p, t as m } from "./seedRunner-TFHHiToI.js";
8
+ import { n as h, o as g, y as _ } from "./frameworkTableAssembly-DkkP6BgC.js";
9
+ import { b as v, x as y } from "./fileConventions-Cof68_BL.js";
10
+ import { basename as b, join as x, relative as S, resolve as C } from "node:path";
11
+ import { promises as w, writeSync as ee } from "node:fs";
12
+ import { pathToFileURL as T } from "node:url";
13
+ import { createLogger as te } from "@voltro/logger";
14
+ import { Effect as E } from "effect";
15
+ import { SqlClient as D } from "@effect/sql";
16
+ import { DEFAULT_CDC_CHANNEL as ne, applyPlan as re, applySchema as O, assessRollingDeployGate as k, branchRehearsalExitCode as ie, declaredSnapshot as A, destructiveScope as ae, fingerprintSchema as oe, formatBranchRehearsal as se, ignoreTablesFromEnv as j, introspectSchema as ce, pendingFileMigrationIds as le, planMigrations as M, recordUpToDate as ue, rehearseMigrationOnBranch as de, rollbackFileBasedMigration as fe, rollingDeployUnsafeOps as pe, runFileBasedMigrations as me, shortFingerprint as N, squashMigrationPlans as he, unblockLossy as ge } from "@voltro/database/sql";
17
+ import { actorsTable as _e, branchNamespaceName as ve, frameworkTables as P, isEncrypted as F, isMigrationDefinition as ye, makeNamespaceBranchExecutor as be, provisionBranch as xe, quoteIdent as Se, registerCoreTables as Ce, resolveBranchMechanism as we, teardownBranch as Te } from "@voltro/database";
18
+ import { InMemoryDataStore as Ee, makeFieldCipher as De } from "@voltro/runtime";
19
+ import { createHash as Oe } from "node:crypto";
20
+ //#region src/adoptPlan.ts
21
+ var ke = (e) => typeof e != "string", Ae = (e, t, n, r) => {
24
22
  let i = [], a = new Map(t.map((e) => [e.name, e])), o = new Map(n.map((e) => [e.name, e])), s = new Set(e.leaveUnset ?? []);
25
23
  r > 0 && i.push({
26
24
  kind: "target-not-empty",
@@ -37,7 +35,7 @@ var O = class extends Error {
37
35
  });
38
36
  continue;
39
37
  }
40
- if (Se(n)) {
38
+ if (ke(n)) {
41
39
  c.push({
42
40
  target: t,
43
41
  source: n.expr,
@@ -80,23 +78,23 @@ var O = class extends Error {
80
78
  remintIds: f,
81
79
  fatal: i.some((e) => e.fatal)
82
80
  };
83
- }, we = (e, t) => [
81
+ }, je = (e, t) => [
84
82
  `back up '${e.from}' to a restorable dump`,
85
83
  `copy rows: INSERT INTO ${e.into} (${t.assignments.map((e) => e.target).join(", ")}) SELECT … FROM ${e.from}`,
86
84
  ...t.remintIds ? ["record old id → new id in a translation table", `rewrite every reference to '${e.from}', JSON columns included`] : [],
87
85
  "verify: row counts match and a sample round-trips",
88
86
  `drop '${e.from}' — LAST, and only after the verify`
89
- ], Te = (e, t, n) => {
87
+ ], Me = (e, t, n) => {
90
88
  let r = [`adopt · ${e.from} (${n} row(s)) → ${e.into}`, ""];
91
89
  for (let e of t.assignments) r.push(` ${e.target.padEnd(24)} ← ${e.raw ? `${e.source} (raw)` : e.source}`);
92
90
  t.problems.length > 0 && r.push("");
93
91
  for (let e of t.problems) r.push(` ${e.fatal ? "✗" : "⚠"} ${e.detail}`);
94
92
  if (r.push(""), t.fatal) return r.push(" REFUSED — fix the problems above. Nothing was written."), r;
95
93
  r.push(" would run, in this order:");
96
- for (let [n, i] of we(e, t).entries()) r.push(` ${n + 1}. ${i}`);
94
+ for (let [n, i] of je(e, t).entries()) r.push(` ${n + 1}. ${i}`);
97
95
  return r;
98
- }, Ee = (e) => e === "mysql" || e === "mariadb" ? (e) => `\`${e}\`` : e === "mssql" ? (e) => `[${e}]` : (e) => `"${e}"`, De = (e) => `${e}__adopt_snapshot`, Oe = (e, t, n, r, i) => {
99
- let a = Ee(n), o = De(e.from), s = t.assignments.map((e) => e.target), c = t.assignments.map((e) => e.raw ? e.source : a(e.source));
96
+ }, Ne = (e) => e === "mysql" || e === "mariadb" ? (e) => `\`${e}\`` : e === "mssql" ? (e) => `[${e}]` : (e) => `"${e}"`, Pe = (e) => `${e}__adopt_snapshot`, Fe = (e, t, n, r, i) => {
97
+ let a = Ne(n), o = Pe(e.from), s = t.assignments.map((e) => e.target), c = t.assignments.map((e) => e.raw ? e.source : a(e.source));
100
98
  return i !== void 0 && (s.unshift(r), c.unshift(i)), {
101
99
  snapshot: n === "mssql" ? `SELECT * INTO ${a(o)} FROM ${a(e.from)}` : `CREATE TABLE ${a(o)} AS SELECT * FROM ${a(e.from)}`,
102
100
  copy: `INSERT INTO ${a(e.into)} (${s.map(a).join(", ")}) SELECT ${c.join(", ")} FROM ${a(e.from)}`,
@@ -106,18 +104,18 @@ var O = class extends Error {
106
104
  drop: `DROP TABLE ${a(e.from)}`,
107
105
  dropSnapshot: `DROP TABLE ${a(o)}`
108
106
  };
109
- }, ke = (e) => {
107
+ }, Ie = (e) => {
110
108
  let t = e[0];
111
109
  if (t === void 0) return 0;
112
110
  let n = t.n ?? t.N ?? Object.values(t)[0];
113
111
  return Number(n ?? 0);
114
- }, Ae = async (e, t, n, r, i, a, o = {}) => {
112
+ }, Le = async (e, t, n, r, i, a, o = {}) => {
115
113
  if (t.fatal) throw Error("adopt: the plan was refused — nothing was run");
116
- let s = Oe(e, t, n, r, i), c = De(e.from), l = ke(await a(s.verifySource));
114
+ let s = Fe(e, t, n, r, i), c = Pe(e.from), l = Ie(await a(s.verifySource));
117
115
  await a(s.snapshot);
118
116
  for (let e of s.translations) await a(e);
119
117
  await a(s.copy);
120
- let u = ke(await a(s.verifyTarget));
118
+ let u = Ie(await a(s.verifyTarget));
121
119
  return u === l ? o.keepSource === !0 ? {
122
120
  copied: u,
123
121
  sourceRows: l,
@@ -137,7 +135,7 @@ var O = class extends Error {
137
135
  snapshotTable: c,
138
136
  sourceDropped: !1
139
137
  };
140
- }, k = [
138
+ }, I = [
141
139
  "token",
142
140
  "secret",
143
141
  "password",
@@ -146,7 +144,7 @@ var O = class extends Error {
146
144
  "credential",
147
145
  "privatekey",
148
146
  "private_key"
149
- ], je = [
147
+ ], Re = [
150
148
  {
151
149
  table: "_voltro_audit_log",
152
150
  column: "subject"
@@ -191,7 +189,7 @@ var O = class extends Error {
191
189
  table: "_voltro_row_history",
192
190
  column: "subjectId"
193
191
  }
194
- ], Me = (e, t) => {
192
+ ], ze = (e, t) => {
195
193
  switch (t) {
196
194
  case "postgres": return `LOWER(CAST(${e} AS text))`;
197
195
  case "mysql":
@@ -200,17 +198,17 @@ var O = class extends Error {
200
198
  case "sqlite":
201
199
  case "turso": return `LOWER(CAST(${e} AS TEXT))`;
202
200
  }
203
- }, A = (e, t, n = k) => n.map((n) => `${Me(e, t)} LIKE '%${n}%'`).join("\n OR "), Ne = ["_omitted", "__redacted"], Pe = (e, t) => {
201
+ }, Be = (e, t, n = I) => n.map((n) => `${ze(e, t)} LIKE '%${n}%'`).join("\n OR "), Ve = ["_omitted", "__redacted"], He = (e, t) => {
204
202
  let n = e.toLowerCase();
205
203
  return t.some((e) => n.includes(e));
206
- }, j = (e, t = []) => {
204
+ }, Ue = (e, t = []) => {
207
205
  if (Array.isArray(e)) {
208
- for (let n of e) j(n, t);
206
+ for (let n of e) Ue(n, t);
209
207
  return t;
210
208
  }
211
- if (typeof e == "object" && e) for (let [n, r] of Object.entries(e)) t.push(n), j(r, t);
209
+ if (typeof e == "object" && e) for (let [n, r] of Object.entries(e)) t.push(n), Ue(r, t);
212
210
  return t;
213
- }, M = (e) => Array.isArray(e) ? e.map(M) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ne.includes(e) ? null : M(t)])) : e, Fe = (e, t = k) => {
211
+ }, We = (e) => Array.isArray(e) ? e.map(We) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Ve.includes(e) ? null : We(t)])) : e, Ge = (e, t = I) => {
214
212
  let n;
215
213
  try {
216
214
  n = JSON.parse(e);
@@ -222,33 +220,33 @@ var O = class extends Error {
222
220
  };
223
221
  }
224
222
  return {
225
- asKey: j(n).some((e) => Pe(e, t)),
226
- redactionMarkerOnly: !Pe(JSON.stringify(M(n)) ?? "", t),
223
+ asKey: Ue(n).some((e) => He(e, t)),
224
+ redactionMarkerOnly: !He(JSON.stringify(We(n)) ?? "", t),
227
225
  undecidable: !1
228
226
  };
229
- }, Ie = (e) => ({
227
+ }, Ke = (e) => ({
230
228
  examined: e.length,
231
229
  asKey: e.filter((e) => e.asKey).length,
232
230
  redactionMarkerOnly: e.filter((e) => e.redactionMarkerOnly && !e.asKey).length,
233
231
  undecidable: e.filter((e) => e.undecidable).length
234
- }), N = (e) => {
232
+ }), L = (e) => {
235
233
  let t = e.classification;
236
234
  return t === void 0 || e.hits === void 0 || e.hits === 0 ? !1 : t.examined === e.hits && t.undecidable === 0 && t.asKey === 0 && t.redactionMarkerOnly === e.hits;
237
- }, Le = (e, t, n, r) => {
238
- let i = `WHERE ${A(t, n)}`, a = Me(t, n).replace(/^LOWER\((.*)\)$/s, "$1");
235
+ }, qe = (e, t, n, r) => {
236
+ let i = `WHERE ${Be(t, n)}`, a = ze(t, n).replace(/^LOWER\((.*)\)$/s, "$1");
239
237
  return n === "mssql" ? `SELECT TOP (${r}) ${a} AS v FROM ${e}\n ${i}` : `SELECT ${a} AS v FROM ${e}\n ${i}\n LIMIT ${r}`;
240
- }, Re = async (e, t, n, r, i) => (await g.runPromise(e.unsafe(Le(t, n, r, i)))).map((e) => {
238
+ }, Je = async (e, t, n, r, i) => (await E.runPromise(e.unsafe(qe(t, n, r, i)))).map((e) => {
241
239
  let t = Object.values(e)[0];
242
240
  return typeof t == "string" ? t : JSON.stringify(t ?? null);
243
- }), P = async (e, t) => {
244
- let n = await g.runPromise(e.unsafe(t));
241
+ }), Ye = async (e, t) => {
242
+ let n = await E.runPromise(e.unsafe(t));
245
243
  return Number(Object.values(n[0] ?? { n: 0 })[0] ?? 0);
246
- }, ze = async (e, t, n, r) => {
244
+ }, Xe = async (e, t, n, r) => {
247
245
  let i = [];
248
246
  for (let a of n) {
249
247
  let n = r(a.table), o;
250
248
  try {
251
- o = await P(e, `SELECT COUNT(*) AS n FROM ${n}`);
249
+ o = await Ye(e, `SELECT COUNT(*) AS n FROM ${n}`);
252
250
  } catch {
253
251
  i.push({
254
252
  table: a.table,
@@ -260,9 +258,9 @@ var O = class extends Error {
260
258
  continue;
261
259
  }
262
260
  try {
263
- let s = await P(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${A(r(a.column), t)}`), c = [];
264
- if (s > 0) for (let i of k) try {
265
- let o = await P(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${A(r(a.column), t, [i])}`);
261
+ let s = await Ye(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Be(r(a.column), t)}`), c = [];
262
+ if (s > 0) for (let i of I) try {
263
+ let o = await Ye(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Be(r(a.column), t, [i])}`);
266
264
  o > 0 && c.push({
267
265
  needle: i,
268
266
  rows: o
@@ -270,7 +268,7 @@ var O = class extends Error {
270
268
  } catch {}
271
269
  let l;
272
270
  if (s > 0) try {
273
- l = Ie((await Re(e, n, r(a.column), t, 500)).map((e) => Fe(e)));
271
+ l = Ke((await Je(e, n, r(a.column), t, 500)).map((e) => Ge(e)));
274
272
  } catch {}
275
273
  i.push({
276
274
  table: a.table,
@@ -291,8 +289,8 @@ var O = class extends Error {
291
289
  }
292
290
  }
293
291
  return i;
294
- }, Be = (e, t) => {
295
- let n = k.length, r = [`credential scan · dialect ${t}`, ""], i = /* @__PURE__ */ new Set();
292
+ }, Ze = (e, t) => {
293
+ let n = I.length, r = [`credential scan · dialect ${t}`, ""], i = /* @__PURE__ */ new Set();
296
294
  for (let t of e) {
297
295
  if (t.unavailable === "column") {
298
296
  r.push(` · ${t.table}.${t.column} — column is not present on this deployment (${t.scanned} row(s) exist but this column was not scanned)`);
@@ -306,34 +304,34 @@ var O = class extends Error {
306
304
  r.push(` · ${t.table} — table is EMPTY (0 rows scanned; this is not a clean bill of health)`);
307
305
  continue;
308
306
  }
309
- let e = N(t), n = (t.hits ?? 0) === 0 ? "✓" : e ? "~" : "✗";
307
+ let e = L(t), n = (t.hits ?? 0) === 0 ? "✓" : e ? "~" : "✗";
310
308
  r.push(` ${n} ${t.table}.${t.column} — ${t.hits} of ${t.scanned} row(s) contain a credential-shaped NAME (anywhere in the value)`), (t.matchedNeedles?.length ?? 0) > 0 && r.push(` matched (rows per needle, may overlap): ${t.matchedNeedles.map((e) => `${e.needle} (${e.rows})`).join(", ")}`);
311
309
  let a = t.classification;
312
- a !== void 0 && (r.push(` examined ${a.examined} of ${t.hits} matched row(s)${a.examined < (t.hits ?? 0) ? " (capped at 500)" : ""}: ${a.asKey} as a JSON KEY, ${a.redactionMarkerOnly} only inside a redaction marker${a.undecidable > 0 ? `, ${a.undecidable} not parseable as JSON` : ""}`), e && r.push(` EXPLAINED — every match is \`${Ne.join("` / `")}\`, the framework's own`, " record that a `.sensitive()` column was left OUT. Nothing to purge, nothing to rotate."));
310
+ a !== void 0 && (r.push(` examined ${a.examined} of ${t.hits} matched row(s)${a.examined < (t.hits ?? 0) ? " (capped at 500)" : ""}: ${a.asKey} as a JSON KEY, ${a.redactionMarkerOnly} only inside a redaction marker${a.undecidable > 0 ? `, ${a.undecidable} not parseable as JSON` : ""}`), e && r.push(` EXPLAINED — every match is \`${Ve.join("` / `")}\`, the framework's own`, " record that a `.sensitive()` column was left OUT. Nothing to purge, nothing to rotate."));
313
311
  }
314
- let a = e.reduce((e, t) => e + (N(t) ? 0 : t.hits ?? 0), 0), o = e.reduce((e, t) => e + (N(t) ? t.hits ?? 0 : 0), 0);
312
+ let a = e.reduce((e, t) => e + (L(t) ? 0 : t.hits ?? 0), 0), o = e.reduce((e, t) => e + (L(t) ? t.hits ?? 0 : 0), 0);
315
313
  return r.push(""), o > 0 && r.push(` ${o} row(s) matched only the framework's own redaction markers and are NOT findings.`), a > 0 ? r.push(` ${a} row(s) carry something credential-shaped.`, " Purge them AND rotate the credentials — assume anything written to a log", " table has been read. Then stop putting the credential on the Subject:", " `connectionCredentials(...)` keeps it in the framework vault.") : e.every((e) => e.scanned === void 0 || e.scanned === 0 || e.unavailable !== void 0) ? r.push(" NOTHING WAS SCANNED. This run proves nothing about your data.") : r.push(" No credential-shaped keys found in the rows that exist."), r.push("", ` These are NAME heuristics (${n} of them), not proof. A credential in a`, " column whose key is not credential-shaped — `keyValue`, `pat`, `authz` —", " is invisible here. A clean run means \"no credential-shaped NAME found\",", " which is not the same as \"no credential\".", "", " Run this on EVERY environment. A dev database is not a sample of production."), r.join("\n");
316
- }, Ve = (e) => e.some((e) => (e.hits ?? 0) > 0 && !N(e)) ? 1 : e.every((e) => e.unavailable !== void 0 || e.scanned === void 0 || e.scanned === 0) ? 2 : 0, F = /\.migration\.ts$/, I = async (e, t) => {
314
+ }, Qe = (e) => e.some((e) => (e.hits ?? 0) > 0 && !L(e)) ? 1 : e.every((e) => e.unavailable !== void 0 || e.scanned === void 0 || e.scanned === 0) ? 2 : 0, $e = /\.migration\.ts$/, R = async (e, t) => {
317
315
  let n = [];
318
316
  for (let r of e) {
319
317
  let e;
320
318
  try {
321
- e = await import(h(r).href);
319
+ e = await import(T(r).href);
322
320
  } catch (e) {
323
321
  t.warn("migration: failed to import", { file: r }, e);
324
322
  continue;
325
323
  }
326
- let i = (e.default && ne(e.default) ? e.default : void 0) ?? Object.values(e).find(ne);
324
+ let i = (e.default && ye(e.default) ? e.default : void 0) ?? Object.values(e).find(ye);
327
325
  if (!i) {
328
326
  t.warn("migration: no defineMigration export", { file: r });
329
327
  continue;
330
328
  }
331
- i.id !== d(r).replace(/\.migration\.ts$/, "") && t.warn("migration: id does not match filename — id wins for ordering, but rename the file for clarity", {
329
+ i.id !== b(r).replace(/\.migration\.ts$/, "") && t.warn("migration: id does not match filename — id wins for ordering, but rename the file for clarity", {
332
330
  file: r,
333
331
  idInFile: i.id,
334
- idFromFile: d(r).replace(/\.migration\.ts$/, "")
332
+ idFromFile: b(r).replace(/\.migration\.ts$/, "")
335
333
  });
336
- let a = await v.readFile(r, "utf8").catch(() => ""), o = ae("sha256").update(a).digest("hex").slice(0, 16);
334
+ let a = await w.readFile(r, "utf8").catch(() => ""), o = Oe("sha256").update(a).digest("hex").slice(0, 16);
337
335
  n.push({
338
336
  file: r,
339
337
  definition: i,
@@ -341,14 +339,14 @@ var O = class extends Error {
341
339
  });
342
340
  }
343
341
  return [...n].sort((e, t) => e.definition.id < t.definition.id ? -1 : 1);
344
- }, L = (e) => {
342
+ }, et = (e) => {
345
343
  let t = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), n = t === "memory" ? "postgres" : t;
346
- return g.runPromise(w(S, n).pipe(g.provide(e)));
347
- }, R = (e) => g.runPromise(g.gen(function* () {
348
- let e = yield* (yield* x.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(g.orElseSucceed(() => []));
344
+ return E.runPromise(O(P, n).pipe(E.provide(e)));
345
+ }, tt = (e) => E.runPromise(E.gen(function* () {
346
+ let e = yield* (yield* D.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(E.orElseSucceed(() => []));
349
347
  return new Map(e.map((e) => [e.id, e]));
350
- }).pipe(g.provide(e))), z = (e, t) => g.runPromise(g.gen(function* () {
351
- yield* (yield* x.SqlClient)`
348
+ }).pipe(E.provide(e))), z = (e, t) => E.runPromise(E.gen(function* () {
349
+ yield* (yield* D.SqlClient)`
352
350
  INSERT INTO "_voltro_migrations"
353
351
  (id, name, hash, status, "appliedAt", "durationMs", "errorMessage", "errorStack")
354
352
  VALUES
@@ -363,14 +361,14 @@ var O = class extends Error {
363
361
  "errorStack" = EXCLUDED."errorStack",
364
362
  "updatedAt" = now()
365
363
  `;
366
- }).pipe(g.provide(e))), He = async (e, t, n) => {
364
+ }).pipe(E.provide(e))), nt = async (e, t, n) => {
367
365
  if (e.length === 0) return {
368
366
  applied: [],
369
367
  failed: null,
370
368
  skipped: []
371
369
  };
372
- await L(t);
373
- let r = await R(t), i = [], a = [], o = null;
370
+ await et(t);
371
+ let r = await tt(t), i = [], a = [], o = null;
374
372
  for (let s of e) {
375
373
  let e = r.get(s.definition.id);
376
374
  if (e && e.status === "applied") {
@@ -405,7 +403,7 @@ var O = class extends Error {
405
403
  for (let e of s.definition.steps) {
406
404
  let n = Date.now();
407
405
  try {
408
- await g.runPromise(e.apply.pipe(g.provide(t))), l.push({
406
+ await E.runPromise(e.apply.pipe(E.provide(t))), l.push({
409
407
  stepName: e.name,
410
408
  status: "applied",
411
409
  durationMs: Date.now() - n
@@ -471,9 +469,9 @@ var O = class extends Error {
471
469
  failed: o,
472
470
  skipped: a
473
471
  };
474
- }, Ue = async (e, t, n, r = {}) => {
475
- await L(t);
476
- let i = await R(t), a = e.filter((e) => i.get(e.definition.id)?.status === "applied");
472
+ }, rt = async (e, t, n, r = {}) => {
473
+ await et(t);
474
+ let i = await tt(t), a = e.filter((e) => i.get(e.definition.id)?.status === "applied");
477
475
  if (a.length === 0) return n.info("migration: nothing to roll back"), {
478
476
  applied: [],
479
477
  failed: null,
@@ -491,7 +489,7 @@ var O = class extends Error {
491
489
  for (let n = e.definition.steps.length - 1; n >= 0; n--) {
492
490
  let o = e.definition.steps[n], s = Date.now();
493
491
  try {
494
- await g.runPromise(o.undo.pipe(g.provide(t))), i.push({
492
+ await E.runPromise(o.undo.pipe(E.provide(t))), i.push({
495
493
  stepName: o.name,
496
494
  status: "applied",
497
495
  durationMs: Date.now() - s
@@ -542,9 +540,9 @@ var O = class extends Error {
542
540
  failed: c,
543
541
  skipped: []
544
542
  };
545
- }, We = async (e, t) => {
546
- await L(t);
547
- let n = await R(t);
543
+ }, it = async (e, t) => {
544
+ await et(t);
545
+ let n = await tt(t);
548
546
  return e.map((e) => {
549
547
  let t = n.get(e.definition.id);
550
548
  return t ? {
@@ -561,7 +559,7 @@ var O = class extends Error {
561
559
  hashMatches: !0
562
560
  };
563
561
  });
564
- }, Ge = (e) => {
562
+ }, at = (e) => {
565
563
  if (!e.failed) return "";
566
564
  let t = e.failed, n = [
567
565
  `✗ Migration failed: ${t.migrationId} / step '${t.error?.stepName ?? "?"}'`,
@@ -574,22 +572,22 @@ var O = class extends Error {
574
572
  ""
575
573
  ];
576
574
  return e.applied.length > 0 && n.unshift("", `(${e.applied.length} migration(s) applied successfully before the failure.)`), n.join("\n");
577
- }, Ke = (e) => {
575
+ }, ot = (e) => {
578
576
  let t = e.split(".");
579
577
  if (t.length !== 2 || !t[0] || !t[1]) throw Error(`voltro db encrypt-column: expected <table>.<column>, got "${e}"`);
580
578
  return {
581
579
  table: t[0],
582
580
  column: t[1]
583
581
  };
584
- }, qe = (e) => 49 + 4 * Math.ceil(e / 3), Je = (e, t) => {
585
- let n = qe(e);
582
+ }, st = (e) => 49 + 4 * Math.ceil(e / 3), ct = (e, t) => {
583
+ let n = st(e);
586
584
  return {
587
585
  longestPlaintextBytes: e,
588
586
  longestCiphertext: n,
589
587
  declaredMaxLength: t,
590
588
  fits: t === void 0 || n <= t
591
589
  };
592
- }, Ye = (e, t) => `${e.table}.${e.column} is too narrow: its longest value is ${t.longestPlaintextBytes} byte(s), which encrypts to ${t.longestCiphertext} characters, and the column is declared as ${t.declaredMaxLength}. Widen it first (\`.maxLength(${t.longestCiphertext})\` or more, then \`voltro db apply\`) and run this again. Nothing was written.`, Xe = (e, t) => {
590
+ }, lt = (e, t) => `${e.table}.${e.column} is too narrow: its longest value is ${t.longestPlaintextBytes} byte(s), which encrypts to ${t.longestCiphertext} characters, and the column is declared as ${t.declaredMaxLength}. Widen it first (\`.maxLength(${t.longestCiphertext})\` or more, then \`voltro db apply\`) and run this again. Nothing was written.`, ut = (e, t) => {
593
591
  let n = t ? "would encrypt" : "encrypted";
594
592
  return [
595
593
  ` ${e.table}.${e.column}`,
@@ -598,10 +596,10 @@ var O = class extends Error {
598
596
  ` null / empty ${e.empty}`,
599
597
  ` ${n.padEnd(18)} ${e.encrypted}`
600
598
  ].join("\n");
601
- }, Ze = (e, t, n) => {
599
+ }, dt = (e, t, n) => {
602
600
  if (e == null) return;
603
601
  let r = typeof e == "string" ? e : String(e);
604
- if (r === "" || C(r)) return;
602
+ if (r === "" || F(r)) return;
605
603
  let i = t.encrypt(r), a;
606
604
  try {
607
605
  a = t.decrypt(i);
@@ -610,13 +608,13 @@ var O = class extends Error {
610
608
  }
611
609
  if (a !== r) throw Error(`${n.table}.${n.column}: round-trip mismatch — the cipher did not return what it was given. Nothing was written.`);
612
610
  return i;
613
- }, Qe = (e) => Buffer.byteLength(e, "utf8"), $e = (e, t) => {
611
+ }, ft = (e) => Buffer.byteLength(e, "utf8"), pt = (e, t) => {
614
612
  if (e !== void 0) try {
615
613
  return t.decrypt(e), !0;
616
614
  } catch {
617
615
  return !1;
618
616
  }
619
- }, et = (e, t) => `${e.table}.${e.column} already holds values encrypted with a DIFFERENT key than ${t} — the active key cannot decrypt them. Continuing would encrypt the remaining rows under a second key, and the column would then be readable with neither key alone. Nothing was written. Point ${t} at the key the existing rows were written with.`, tt = (e) => [
617
+ }, mt = (e, t) => `${e.table}.${e.column} already holds values encrypted with a DIFFERENT key than ${t} — the active key cannot decrypt them. Continuing would encrypt the remaining rows under a second key, and the column would then be readable with neither key alone. Nothing was written. Point ${t} at the key the existing rows were written with.`, ht = (e) => [
620
618
  "",
621
619
  " NEXT — this converted the rows that exist. New writes are still plaintext",
622
620
  " until the column carries the modifier:",
@@ -626,7 +624,7 @@ var O = class extends Error {
626
624
  " Order does not matter: a read returns a non-ciphertext value unchanged, so",
627
625
  " the column may hold a mix while you deploy. Run this again afterwards to",
628
626
  " catch anything written in between — it skips what is already encrypted."
629
- ].join("\n"), B = _({ scope: "voltro:db" }), nt = /* @__PURE__ */ new Set([
627
+ ].join("\n"), B = te({ scope: "voltro:db" }), gt = /* @__PURE__ */ new Set([
630
628
  "node_modules",
631
629
  "dist",
632
630
  "build",
@@ -636,46 +634,50 @@ var O = class extends Error {
636
634
  ".git"
637
635
  ]), V = async (e, t) => {
638
636
  let n = [], r = async (e) => {
639
- let i = await v.readdir(e, { withFileTypes: !0 }).catch(() => []);
637
+ let i = await w.readdir(e, { withFileTypes: !0 }).catch(() => []);
640
638
  for (let a of i) {
641
- if (nt.has(a.name)) continue;
642
- let i = f(e, a.name);
639
+ if (gt.has(a.name)) continue;
640
+ let i = x(e, a.name);
643
641
  a.isDirectory() ? await r(i) : a.isFile() && t.test(a.name) && n.push(i);
644
642
  }
645
643
  };
646
644
  return await r(e), n;
647
- }, H = (e) => m(e.find((e) => !e.startsWith("-")) ?? process.cwd()), U = () => {
648
- let e = process.env.DB_MAX_CONNECTIONS ?? process.env.PG_MAX_CONNECTIONS, t = e !== void 0 && e !== "" ? Number(e) : NaN, n = Number.isInteger(t) && t > 0 ? { maxConnections: t } : {}, r = process.env.DB_SCHEMA, i = r && r.length > 0 ? { schema: r } : {}, a = process.env.DB_DIRECT_URL ?? process.env.DB_MIGRATE_URL ?? process.env.DB_URL ?? process.env.DB_PRIMARY_URL;
649
- return a ? {
650
- url: a,
651
- ...n,
652
- ...i
653
- } : {
654
- host: process.env.DB_HOST ?? process.env.PG_HOST ?? "localhost",
655
- port: Number(process.env.DB_PORT ?? process.env.PG_PORT ?? 5432),
656
- username: process.env.DB_USER ?? process.env.PG_USER ?? "app",
657
- password: process.env.DB_PASSWORD ?? process.env.PG_PASSWORD ?? "app",
658
- database: process.env.DB_DATABASE ?? process.env.PG_DATABASE ?? "app",
659
- ...n,
660
- ...i
661
- };
662
- }, rt = (e) => {
645
+ }, _t = [
646
+ "--against",
647
+ "--batch",
648
+ "--before",
649
+ "--id",
650
+ "--key-env",
651
+ "--lifecycle",
652
+ "--limit",
653
+ "--name",
654
+ "--note",
655
+ "--online-after",
656
+ "--plan",
657
+ "--pr",
658
+ "--prefer",
659
+ "--root",
660
+ "--seed",
661
+ "--store",
662
+ "--to",
663
+ "--token"
664
+ ], H = (e) => C(s(e, _t) ?? process.cwd()), U = () => l("migration"), vt = (e) => {
663
665
  let t = e;
664
666
  if (typeof t != "object" || !t) return !1;
665
667
  if (t.code === "ERR_OUT_OF_RANGE" || t.cause?.code === "ERR_OUT_OF_RANGE") return !0;
666
668
  let n = `${t.message ?? ""} ${t.cause?.message ?? ""} ${t.stack ?? ""}`;
667
669
  return /ERR_OUT_OF_RANGE|out of range/i.test(n) && /pg-protocol|parseDataRow|buffer-reader|BufferReader/i.test(n);
668
- }, it = "Live-DB introspection got a corrupt / misaligned response from the database. This happens when `voltro db plan` / `apply` / `drift` / `migrate` runs through a connection POOLER (Supabase Supavisor / PgBouncer) on a LARGE schema — the pooler mis-frames a big catalog response. The introspection already batches by table to keep responses small; if a batch still trips it:\n 1. Lower the batch: set `VOLTRO_INTROSPECT_BATCH` to a smaller number of tables (default 20 — try 5 or 1). This keeps `db plan` on the normal pooler, no direct connection needed.\n 2. Or use a DIRECT (non-pooler) connection: set `DB_DIRECT_URL` (or `DB_MIGRATE_URL`) to the direct database URL — the runtime keeps `DB_URL`, so only the migration path is affected. (Supabase: direct = `db.<project-ref>.supabase.co` [IPv6-only on newer projects]; pooler = `aws-0-<region>.pooler.supabase.com`.)", W = () => {
670
+ }, yt = "Live-DB introspection got a corrupt / misaligned response from the database. This happens when `voltro db plan` / `apply` / `drift` / `migrate` runs through a connection POOLER (Supabase Supavisor / PgBouncer) on a LARGE schema — the pooler mis-frames a big catalog response. The introspection already batches by table to keep responses small; if a batch still trips it:\n 1. Lower the batch: set `VOLTRO_INTROSPECT_BATCH` to a smaller number of tables (default 20 — try 5 or 1). This keeps `db plan` on the normal pooler, no direct connection needed.\n 2. Or use a DIRECT (non-pooler) connection: set `DB_DIRECT_URL` (or `DB_MIGRATE_URL`) to the direct database URL — the runtime keeps `DB_URL`, so only the migration path is affected. (Supabase: direct = `db.<project-ref>.supabase.co` [IPv6-only on newer projects]; pooler = `aws-0-<region>.pooler.supabase.com`.)", W = () => {
669
671
  let e = (process.env.DB_DIALECT ?? "postgres").toLowerCase();
670
- if (e === "memory") throw new O("voltro db: subcommands require a real dialect, not DB_DIALECT=memory.");
672
+ if (e === "memory") throw new n("voltro db: subcommands require a real dialect, not DB_DIALECT=memory.");
671
673
  return e;
672
- }, G = (e) => re(e, W()), K = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", q = async () => (await r(W())).makeSqlLayer(U()), at = async (e) => {
673
- let t = H(e), n = e.includes("--dry-run"), r = await I(await V(t, F), B);
674
+ }, G = (e) => Se(e, W()), K = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", q = async () => (await c(W())).makeSqlLayer(U()), bt = async (e) => {
675
+ let t = H(e), n = e.includes("--dry-run"), r = await R(await V(t, $e), B);
674
676
  if (r.length === 0) return B.info("no migrations found", { root: t }), 0;
675
677
  if (n) {
676
678
  let e = /* @__PURE__ */ new Set();
677
679
  try {
678
- let t = await We(r, await q());
680
+ let t = await it(r, await q());
679
681
  e = new Set(t.filter((e) => e.status === "applied").map((e) => e.id));
680
682
  } catch {
681
683
  B.warn("migrate --dry-run: could not read the migration ledger — showing ALL as pending");
@@ -686,116 +688,116 @@ var O = class extends Error {
686
688
  for (let e of t) console.log(` pending ${e.definition.id}`);
687
689
  return 0;
688
690
  }
689
- let i = await He(r, await q(), B);
690
- return i.failed ? (process.stderr.write(Ge(i) + "\n"), 1) : (B.info("migrate complete", {
691
+ let i = await nt(r, await q(), B);
692
+ return i.failed ? (process.stderr.write(at(i) + "\n"), 1) : (B.info("migrate complete", {
691
693
  applied: i.applied.length,
692
694
  skipped: i.skipped.length
693
695
  }), 0);
694
- }, ot = async (e) => {
695
- let t = H(e), n = l(e, "--to"), r = await I(await V(t, F), B);
696
+ }, xt = async (e) => {
697
+ let t = H(e), n = o(e, "--to"), r = await R(await V(t, $e), B);
696
698
  if (r.length === 0) return B.info("no migrations found", { root: t }), 0;
697
- let i = await Ue(r, await q(), B, n ? { to: n } : {});
698
- return i.failed ? (process.stderr.write(Ge(i) + "\n"), 1) : (B.info("rollback complete", { reverted: i.applied.length }), 0);
699
- }, st = async (e) => {
700
- let t = await I(await V(H(e), F), B);
699
+ let i = await rt(r, await q(), B, n ? { to: n } : {});
700
+ return i.failed ? (process.stderr.write(at(i) + "\n"), 1) : (B.info("rollback complete", { reverted: i.applied.length }), 0);
701
+ }, St = async (e) => {
702
+ let t = await R(await V(H(e), $e), B);
701
703
  if (t.length === 0) return console.log("no migrations found"), 0;
702
- let n = await We(t, await q());
704
+ let n = await it(t, await q());
703
705
  for (let e of n) {
704
706
  let t = e.status === "applied" ? "✓" : e.status === "failed" ? "✗" : e.status === "reverted" ? "↩" : "·", n = e.hashMatches ? "" : " (hash drift!)", r = e.appliedAt ? ` @ ${e.appliedAt.toISOString()}` : "";
705
707
  console.log(` ${t} ${e.id} [${e.status}] ${e.name}${r}${n}`);
706
708
  }
707
709
  return 0;
708
- }, ct = async (e) => {
709
- let t = (l(e, "--store") ?? process.env.DB_DIALECT ?? "postgres").toLowerCase();
710
+ }, Ct = async (e) => {
711
+ let t = (o(e, "--store") ?? process.env.DB_DIALECT ?? "postgres").toLowerCase();
710
712
  if (t === "memory") return B.warn("voltro db seed: using in-memory store (explicit opt-in via --store memory / DB_DIALECT=memory)"), B.warn(" rows written by this run will NOT persist beyond the process. set DB_DIALECT=postgres or unset to seed the real DB."), {
711
- store: new b(),
713
+ store: new Ee(),
712
714
  dispose: async () => {},
713
715
  dialectId: "memory"
714
716
  };
715
- let n = await r(t);
717
+ let n = await c(t);
716
718
  B.info(`voltro db seed: target store=${n.id} — rows will persist`);
717
- let i = await n.makeStore({
719
+ let r = await n.makeStore({
718
720
  sqlLayer: n.makeSqlLayer(U()),
719
721
  changeStrategy: "inline"
720
- }), a = i;
722
+ }), i = r;
721
723
  return {
722
- store: i,
724
+ store: r,
723
725
  dispose: async () => {
724
- typeof a.close == "function" && await a.close(5e3);
726
+ typeof i.close == "function" && await i.close(5e3);
725
727
  },
726
728
  dialectId: n.id
727
729
  };
728
- }, lt = async (r) => {
729
- let a = H(r), o = l(r, "--id"), s = l(r, "--lifecycle"), c = await t(await V(a, i), B);
730
- if (c.length === 0) return B.info("no seeds found", { root: a }), 0;
731
- let { store: u, dispose: d, dialectId: f } = await ct(r);
730
+ }, wt = async (e) => {
731
+ let t = H(e), n = o(e, "--id"), r = o(e, "--lifecycle"), i = await d(await V(t, y), B);
732
+ if (i.length === 0) return B.info("no seeds found", { root: t }), 0;
733
+ let { store: a, dispose: s, dialectId: c } = await Ct(e);
732
734
  try {
733
- return o ? +((await e(c, o, u, B)).status === "failed") : +((await n((s ? c.filter((e) => e.definition.lifecycle === s) : c.filter((e) => e.definition.lifecycle === "boot")).map((e) => ({
735
+ return n ? +((await u(i, n, a, B)).status === "failed") : +((await f((r ? i.filter((e) => e.definition.lifecycle === r) : i.filter((e) => e.definition.lifecycle === "boot")).map((e) => ({
734
736
  ...e,
735
737
  definition: {
736
738
  ...e.definition,
737
739
  lifecycle: "boot"
738
740
  }
739
- })), u, B, { force: !0 })).filter((e) => e.status === "failed").length > 0);
741
+ })), a, B, { force: !0 })).filter((e) => e.status === "failed").length > 0);
740
742
  } finally {
741
- await d().catch((e) => {
743
+ await s().catch((e) => {
742
744
  B.warn("voltro db seed: store dispose failed", { error: String(e) });
743
745
  });
744
746
  }
745
- }, ut = (e) => typeof e == "object" && !!e && "tableName" in e && "fields" in e && typeof e.tableName == "string", dt = async (e) => {
746
- let t = await V(e, s), n = [];
747
+ }, Tt = (e) => typeof e == "object" && !!e && "tableName" in e && "fields" in e && typeof e.tableName == "string", Et = async (e) => {
748
+ let t = await V(e, v), n = [];
747
749
  for (let r of t) {
748
750
  let t;
749
751
  try {
750
- t = await import(h(r).href);
752
+ t = await import(T(r).href);
751
753
  } catch (t) {
752
754
  B.warn("db: failed to import schema file", {
753
- file: p(e, r),
755
+ file: S(e, r),
754
756
  error: String(t)
755
757
  });
756
758
  continue;
757
759
  }
758
- for (let e of Object.values(t)) ut(e) && n.push(e);
760
+ for (let e of Object.values(t)) Tt(e) && n.push(e);
759
761
  }
760
762
  return n;
761
- }, ft = (e) => {
763
+ }, Dt = (e) => {
762
764
  let t = new Map(e.map((e) => [e.tableName, e]));
763
- t.has("actors") || t.set("actors", te);
765
+ t.has("actors") || t.set("actors", _e);
764
766
  let n = t.get("actors"), r = t.get("tenants");
765
- return ie({
767
+ return Ce({
766
768
  actors: () => n,
767
769
  ...r === void 0 ? {} : { tenants: () => r }
768
770
  }), [...t.values()];
769
- }, pt = (e) => {
771
+ }, Ot = (e) => {
770
772
  let t = /* @__PURE__ */ new Map();
771
773
  for (let n of e) {
772
774
  let e = n.tableName;
773
775
  e !== void 0 && !t.has(e) && t.set(e, n);
774
776
  }
775
777
  return [...t.values()];
776
- }, mt = (e) => {
777
- let t = ue(process.env.VOLTRO_DESTRUCTIVE_OK);
778
+ }, kt = (e) => {
779
+ let t = ae(process.env.VOLTRO_DESTRUCTIVE_OK);
778
780
  if (t === void 0 || !e.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy")) return {
779
781
  plan: e,
780
782
  acknowledged: !1
781
783
  };
782
- let n = be(e, t);
784
+ let n = ge(e, t);
783
785
  return {
784
786
  plan: n,
785
787
  acknowledged: !n.operations.some((e) => e.blocked)
786
788
  };
787
- }, J = async (e, t) => g.runPromise(t.pipe(g.provide(e))), Y = async (e) => {
789
+ }, J = async (e, t) => E.runPromise(t.pipe(E.provide(e))), Y = async (e) => {
788
790
  try {
789
- return await J(e, x.SqlClient.pipe(g.flatMap(pe)));
791
+ return await J(e, D.SqlClient.pipe(E.flatMap(ce)));
790
792
  } catch (e) {
791
793
  let t = String(e?.message ?? e);
792
- if (rt(e) || /connection error/i.test(t)) {
793
- let n = /* @__PURE__ */ Error(`${it}\n\nOriginal error: ${t}`);
794
+ if (vt(e) || /connection error/i.test(t)) {
795
+ let n = /* @__PURE__ */ Error(`${yt}\n\nOriginal error: ${t}`);
794
796
  throw n.cause = e, n;
795
797
  }
796
798
  throw e;
797
799
  }
798
- }, ht = {
800
+ }, At = {
799
801
  safe: "\x1B[32m✓\x1B[0m",
800
802
  "needs-default": "\x1B[32m⊕\x1B[0m",
801
803
  "needs-backfill": "\x1B[33m⊕\x1B[0m",
@@ -803,7 +805,7 @@ var O = class extends Error {
803
805
  lossy: "\x1B[31m✗\x1B[0m",
804
806
  "online-required": "\x1B[36m◷\x1B[0m",
805
807
  "multi-step": "\x1B[35m⇉\x1B[0m"
806
- }, gt = (e) => {
808
+ }, jt = (e) => {
807
809
  let t = e.op, n;
808
810
  switch (t.kind) {
809
811
  case "create-table":
@@ -867,9 +869,9 @@ var O = class extends Error {
867
869
  n = `ALTER TABLE ${t.table} DROP CHECK ${t.column}`;
868
870
  break;
869
871
  }
870
- let r = ht[e.classification], i = e.reason ? ` # ${e.reason}` : "", a = e.blocked ? `\n ! ${e.blocked.fix}` : "";
872
+ let r = At[e.classification], i = e.reason ? ` # ${e.reason}` : "", a = e.blocked ? `\n ! ${e.blocked.fix}` : "";
871
873
  return ` ${r} ${n}${i}${a}`;
872
- }, _t = async (e, t) => {
874
+ }, Mt = async (e, t) => {
873
875
  let n = e.operations.filter((e) => e.classification === "needs-default" && e.op.kind === "add-column");
874
876
  if (n.length === 0) return;
875
877
  let r = [];
@@ -878,7 +880,7 @@ var O = class extends Error {
878
880
  if (i === void 0 || a === void 0) continue;
879
881
  let o = 0;
880
882
  try {
881
- let e = await J(t, x.SqlClient.pipe(g.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${re(i, W())}`))));
883
+ let e = await J(t, D.SqlClient.pipe(E.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${Se(i, W())}`))));
882
884
  o = Number(Object.values(e[0] ?? { n: 0 })[0] ?? 0);
883
885
  } catch {
884
886
  continue;
@@ -890,187 +892,334 @@ var O = class extends Error {
890
892
  for (let e of r) console.log(e);
891
893
  console.log(" (the shape is correct either way — this is the VALUE a state diff cannot know)");
892
894
  }
893
- }, X = async (e, t) => {
895
+ }, Nt = async (e, t) => {
894
896
  if (W() !== "postgres") return;
895
- let n = oe, r;
897
+ let n = ne, r;
896
898
  try {
897
- r = await J(t, x.SqlClient.pipe(g.flatMap((t) => de(t, e, n))));
899
+ r = await J(t, D.SqlClient.pipe(E.flatMap((t) => p(t, e, n))));
898
900
  } catch {
899
901
  return;
900
902
  }
901
- let i = he({
902
- tables: e,
903
- dialect: "postgres",
904
- missing: r.missing,
905
- stale: r.stale,
906
- channel: n
903
+ let { drift: i, statements: a } = r;
904
+ if (a.length === 0) return;
905
+ B.info(i.missing.length + i.stale.length > 0 ? `db apply: installing change triggers on ${i.missing.length} table(s)` + (i.stale.length > 0 ? `, removing ${i.stale.length} stale one(s)` : "") + (i.functionOutdated ? ", replacing an outdated notify function" : "") : "db apply: replacing an outdated change-notify function (no table drift)");
906
+ let o = 0;
907
+ for (let e of a) await J(t, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(e)))), o += 1;
908
+ B.info(`db apply: change triggers converged (${o} statement(s))`, {
909
+ installed: i.missing.length,
910
+ removed: i.stale.length,
911
+ functionReplaced: i.functionOutdated
907
912
  });
908
- if (i.length === 0) return;
909
- B.info(`db apply: installing change triggers on ${r.missing.length} table(s)` + (r.stale.length > 0 ? `, removing ${r.stale.length} stale one(s)` : ""));
910
- let a = 0;
911
- for (let e of i) await J(t, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(e)))), a += 1;
912
- B.info(`db apply: change triggers converged (${a} statement(s))`, {
913
- installed: r.missing.length,
914
- removed: r.stale.length
915
- });
916
- }, Z = (e) => {
913
+ }, X = (e) => {
917
914
  let t = e.summary, n = e.operations.length;
918
915
  if (console.log(`\nschema diff: ${n} operation${n === 1 ? "" : "s"}, ${t.blocked} blocked\n`), n === 0) {
919
916
  console.log(" (schema is up to date)\n");
920
917
  return;
921
918
  }
922
- for (let t of e.operations) console.log(gt(t));
923
- console.log(), console.log(` safe: ${t.safe} needs-default: ${t.needsDefault} needs-backfill: ${t.needsBackfill}`), console.log(` rename: ${t.needsRenameAnnotation} lossy: ${t.lossy} blocked: ${t.blocked}`), console.log(` fingerprint: ${e.fromFingerprint.slice(0, 16)} → ${e.toFingerprint.slice(0, 16)}\n`), vt(e);
924
- }, vt = (e) => {
925
- let t = _e(e.operations);
919
+ for (let t of e.operations) console.log(jt(t));
920
+ console.log(), console.log(` safe: ${t.safe} needs-default: ${t.needsDefault} needs-backfill: ${t.needsBackfill}`), console.log(` rename: ${t.needsRenameAnnotation} lossy: ${t.lossy} blocked: ${t.blocked}`), console.log(` fingerprint: ${e.fromFingerprint.slice(0, 16)} → ${e.toFingerprint.slice(0, 16)}\n`), Pt(e);
921
+ }, Pt = (e) => {
922
+ let t = pe(e.operations);
926
923
  if (t.length !== 0) {
927
924
  console.log(` ⚠ ${t.length} operation(s) UNSAFE under a rolling deploy`), console.log(" (old + new instances overlap → old code breaks against the new schema):");
928
925
  for (let e of t) console.log(` • ${e.op.op.kind}: ${e.reason}`), console.log(` → ${e.remedy}`);
929
926
  console.log(" Deploy with a maintenance window / scale-to-zero, or split into"), console.log(" expand → deploy → contract. See docs: deployment/production-hardening.\n");
930
927
  }
931
- }, yt = (e, t) => {
932
- let n = ce({
928
+ }, Ft = (e, t) => {
929
+ let n = k({
933
930
  enabled: process.env.VOLTRO_ROLLING_DEPLOY === "1",
934
931
  forced: t.includes("--force"),
935
- unsafeCount: _e(e.operations).length
932
+ unsafeCount: pe(e.operations).length
936
933
  });
937
934
  return n.refuse ? (B.error(`db apply: ${n.message}`), !0) : (n.warnForced && B.warn(`db apply: ${n.message}`), !1);
938
- }, bt = (e) => {
939
- let t = l(e, "--online-after") ?? process.env.VOLTRO_ONLINE_THRESHOLD;
935
+ }, It = (e) => {
936
+ let t = o(e, "--online-after") ?? process.env.VOLTRO_ONLINE_THRESHOLD;
940
937
  if (t === void 0) return;
941
938
  let n = Number(t);
942
939
  if (!Number.isInteger(n) || n < 0) throw Error(`--online-after / VOLTRO_ONLINE_THRESHOLD must be a non-negative integer, got "${t}"`);
943
940
  return n;
944
- }, Q = async (e) => {
945
- let t = await dt(e);
941
+ }, Z = async (e) => {
942
+ let t = await Et(e);
946
943
  if (t.length === 0) return;
947
- let n = await o({ root: e });
948
- return ft(pt([
944
+ let n = await h({ root: e });
945
+ return Dt(Ot([
949
946
  ...t,
950
- ...S,
947
+ ...P,
951
948
  ...n
952
949
  ]));
953
- }, xt = async (e) => {
954
- let t = bt(e), n = H(e), r = await Q(n);
950
+ }, Q = async (e, t, n) => {
951
+ let r;
952
+ try {
953
+ await J(n, _(await g(e), (e, t) => {
954
+ B.info(`db apply: ${e}`, t ?? {});
955
+ }));
956
+ } catch (e) {
957
+ r = e;
958
+ }
959
+ return await Nt(t, n), r === void 0 ? 0 : (B.error("db apply: a plugin migration FAILED — the schema was applied, the plugin steps were not", { error: r instanceof Error ? r.message : String(r) }), 1);
960
+ }, Lt = async (e, t) => {
961
+ let n = { close: async () => {} }, r = await V(e, y);
962
+ if (r.length === 0) return n;
963
+ let i = await d(r, B), a = i.filter((e) => e.definition.lifecycle === "onSchemaChange");
964
+ if (a.length === 0) return n;
965
+ let { store: o, dispose: s } = await Ct(t), c = m(i, o, B.child("seeds"));
966
+ return B.info(`db apply: ${a.length} onSchemaChange seed(s) armed for this apply`, { ids: a.map((e) => e.definition.id) }), { close: async () => {
967
+ c(), await s().catch((e) => {
968
+ B.warn("db apply: seed store dispose failed", { error: String(e) });
969
+ });
970
+ } };
971
+ }, Rt = async (e) => {
972
+ let t = It(e), n = H(e), r = await Z(n);
955
973
  if (r === void 0) return B.warn("db plan: no schema files found", {
956
974
  root: n,
957
975
  hint: "looked for *.entity.ts / *.schema.ts / schema.ts"
958
976
  }), 1;
959
- let i = l(e, "--against");
977
+ let i = o(e, "--against");
960
978
  if (i) {
961
- let n = i, a = l(e, "--token") ?? process.env.VOLTRO_INSPECT_TOKEN, o = { accept: "application/json" };
962
- a && (o.authorization = `Bearer ${a}`);
979
+ let n = i, a = o(e, "--token") ?? process.env.VOLTRO_INSPECT_TOKEN, s = { accept: "application/json" };
980
+ a && (s.authorization = `Bearer ${a}`);
963
981
  try {
964
- let e = n.endsWith("/_voltro/inspect/migrations") ? n : `${n.replace(/\/+$/, "")}/_voltro/inspect/migrations`, i = await fetch(e, { headers: o });
982
+ let e = n.endsWith("/_voltro/inspect/migrations") ? n : `${n.replace(/\/+$/, "")}/_voltro/inspect/migrations`, i = await fetch(e, { headers: s });
965
983
  if (!i.ok) return B.error(`db plan --against: remote returned ${i.status}`, { url: e }), 1;
966
984
  let a = (await i.json()).drift?.liveSnapshot;
967
985
  if (!a) return B.error("db plan --against: remote inspect payload missing drift.liveSnapshot", { url: e }), 1;
968
- let s = E({
986
+ let o = M({
969
987
  declared: r,
970
988
  live: a,
971
989
  dialect: W(),
972
- ...T(),
990
+ ...j(),
973
991
  ...t === void 0 ? {} : { onlineAfter: t }
974
992
  });
975
- return console.log(`\n[--against ${e}] — diff vs remote live schema:\n`), Z(s), s.summary.blocked > 0 ? 2 : 0;
993
+ return console.log(`\n[--against ${e}] — diff vs remote live schema:\n`), X(o), o.summary.blocked > 0 ? 2 : 0;
976
994
  } catch (e) {
977
995
  return B.error(`db plan --against: ${e.message}`), 1;
978
996
  }
979
997
  }
980
- let a = E({
998
+ let a = M({
981
999
  declared: r,
982
1000
  live: await Y(await q()),
983
1001
  dialect: W(),
984
- ...T(),
1002
+ ...j(),
985
1003
  ...t === void 0 ? {} : { onlineAfter: t }
986
1004
  });
987
- return e.includes("--json") ? (y(1, `${JSON.stringify(a, null, 2)}\n`), a.summary.blocked > 0 ? 2 : 0) : (Z(a), a.summary.blocked > 0 ? 2 : 0);
988
- }, St = async (e, t, n) => {
1005
+ return e.includes("--json") ? (ee(1, `${JSON.stringify(a, null, 2)}\n`), a.summary.blocked > 0 ? 2 : 0) : (X(a), a.summary.blocked > 0 ? 2 : 0);
1006
+ }, $ = t, zt = async (e, t, n) => {
989
1007
  let r;
990
1008
  try {
991
- let t = await v.readFile(m(e), "utf8");
1009
+ let t = await w.readFile(C(e), "utf8");
992
1010
  r = JSON.parse(t);
993
1011
  } catch (t) {
994
1012
  return B.error(`db apply --plan: cannot read/parse plan file '${e}': ${t.message}`), 1;
995
1013
  }
996
1014
  if (!Array.isArray(r?.operations) || typeof r?.fromFingerprint != "string" || typeof r?.toFingerprint != "string") return B.error(`db apply --plan: '${e}' is not a valid plan file (expected the output of \`voltro db plan --json\`).`), 1;
997
- let i = await Q(n);
1015
+ let i = await Z(n);
998
1016
  if (i === void 0) return B.warn("db apply --plan: no schema files found", { root: n }), 1;
999
- let a = await q();
1000
- await J(a, w(S, W()));
1001
- let o = await J(a, x.SqlClient.pipe(g.flatMap((e) => me(e, n)))).catch(() => []);
1002
- if (o.length > 0) return B.error(`db apply --plan: refusing — ${o.length} pending file-based migration(s).`), console.error(` ${o.join("\n ")}`), console.error(""), console.error(" These perform the changes a state diff cannot infer, so they change the shape"), console.error(" this plan was computed against. Apply them and regenerate the plan:"), console.error(""), console.error(" voltro db files ."), console.error(" voltro db plan --json > plan.json"), console.error(" voltro db apply --plan plan.json"), 1;
1003
- let s = E({
1017
+ let a = await q(), s = await J(a, D.SqlClient.pipe(E.flatMap((e) => le(e, n)))).catch(() => []);
1018
+ if (s.length > 0) return B.error(`db apply --plan: refusing — ${s.length} pending file-based migration(s).`), console.error(` ${s.join("\n ")}`), console.error(""), console.error(" These perform the changes a state diff cannot infer, so they change the shape"), console.error(" this plan was computed against. Apply them and regenerate the plan:"), console.error(""), console.error(" voltro db files ."), console.error(" voltro db plan --json > plan.json"), console.error(" voltro db apply --plan plan.json"), 1;
1019
+ let c = M({
1004
1020
  declared: i,
1005
1021
  live: await Y(a),
1006
1022
  dialect: W(),
1007
- ...T()
1023
+ ...j()
1008
1024
  });
1009
- if (s.fromFingerprint !== r.fromFingerprint) return B.error("db apply --plan: refusing — the live schema has drifted since this plan was generated."), console.error(` plan.from=${r.fromFingerprint.slice(0, 16)} live=${s.fromFingerprint.slice(0, 16)}`), console.error(" Regenerate against the current live schema: `voltro db plan --json > plan.json`"), 2;
1010
- if (s.toFingerprint !== r.toFingerprint) return B.error("db apply --plan: refusing — the declared schema differs from what this plan targets."), console.error(` plan.to=${r.toFingerprint.slice(0, 16)} declared=${s.toFingerprint.slice(0, 16)}`), console.error(" The schema files changed since the plan was generated. Regenerate the plan."), 2;
1011
- let c = mt(s), u = c.plan;
1012
- if (u.summary.blocked > 0 && !c.acknowledged) return Z(u), B.error(`db apply --plan: refusing — ${s.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (B.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), B.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1013
- if (c.acknowledged && B.warn("db apply --plan: proceeding with acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)"), yt(u, t)) return 2;
1014
- if (u.operations.length === 0) return B.info("db apply --plan: schema is up to date — no DDL to apply (change triggers are reconciled separately below)"), await X(i, a), 0;
1015
- Z(u);
1016
- let d = (process.env.NODE_ENV ?? "dev").toLowerCase(), f = l(t, "--note"), p = await J(a, x.SqlClient.pipe(g.flatMap((e) => se(e, u, {
1025
+ if (c.fromFingerprint !== r.fromFingerprint) return B.error("db apply --plan: refusing — the live schema has drifted since this plan was generated."), console.error(` plan.from=${r.fromFingerprint.slice(0, 16)} live=${c.fromFingerprint.slice(0, 16)}`), console.error(" Regenerate against the current live schema: `voltro db plan --json > plan.json`"), 2;
1026
+ if (c.toFingerprint !== r.toFingerprint) return B.error("db apply --plan: refusing — the declared schema differs from what this plan targets."), console.error(` plan.to=${r.toFingerprint.slice(0, 16)} declared=${c.toFingerprint.slice(0, 16)}`), console.error(" The schema files changed since the plan was generated. Regenerate the plan."), 2;
1027
+ let l = kt(c), u = l.plan;
1028
+ if (u.summary.blocked > 0 && !l.acknowledged) return X(u), B.error(`db apply --plan: refusing — ${c.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (B.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), B.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1029
+ if (l.acknowledged && B.warn("db apply --plan: proceeding with acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)"), Ft(u, t)) return 2;
1030
+ if (u.operations.length === 0) {
1031
+ let e = await J(a, D.SqlClient.pipe(E.flatMap((e) => ue(e, u, {
1032
+ appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1033
+ environment: $(),
1034
+ source: "file"
1035
+ }))));
1036
+ return B.info(e === "recorded" ? `db apply --plan: schema is up to date — no DDL to apply, recorded fingerprint=${u.toFingerprint.slice(0, 16)} (change triggers are reconciled separately below)` : "db apply --plan: schema is up to date — no DDL to apply (change triggers are reconciled separately below)"), Q(n, i, a);
1037
+ }
1038
+ X(u);
1039
+ let d = o(t, "--note"), f = await J(a, D.SqlClient.pipe(E.flatMap((e) => re(e, u, {
1017
1040
  declared: i,
1018
1041
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1019
- environment: d === "production" ? "prod" : d === "staging" ? "staging" : "dev",
1042
+ environment: $(),
1020
1043
  source: "file",
1021
- ...f ? { notes: f } : {},
1022
- replan: () => g.promise(() => Y(a)).pipe(g.map((e) => E({
1044
+ ...d ? { notes: d } : {},
1045
+ replan: () => E.promise(() => Y(a)).pipe(E.map((e) => M({
1023
1046
  declared: i,
1024
1047
  live: e,
1025
1048
  dialect: W(),
1026
- ...T()
1049
+ ...j()
1027
1050
  })))
1028
1051
  }))));
1029
- return B.info(`db apply --plan: applied ${p.appliedOps} op(s) in ${p.durationMs}ms`, {
1030
- id: p.id,
1031
- fingerprint: p.fingerprint.slice(0, 16)
1032
- }), await X(i, a), 0;
1033
- }, Ct = async (e) => {
1034
- let t = H(e), n = bt(e), r = l(e, "--plan");
1035
- if (r) return St(r, e, t);
1036
- if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error("voltro db apply: refusing — auto-apply on prod is not allowed."), console.error("In production, schema changes go through `voltro db plan --json > plan.json`"), console.error("then `voltro db apply --plan plan.json` as an explicit step in your deploy pipeline."), 3;
1037
- let i = await Q(t);
1038
- if (i === void 0) return B.warn("db apply: no schema files found", { root: t }), 1;
1039
- let a = await q(), o = await Mt(t, a);
1040
- if ("failed" in o) return B.error("db apply: a file-based migration FAILED — the schema diff was NOT run"), console.error(o.failed), console.error("Fix the migration and re-run. `voltro db files` runs them alone."), 1;
1041
- await J(a, w(S, W()));
1042
- let s = E({
1043
- declared: i,
1044
- live: await Y(a),
1052
+ return B.info(`db apply --plan: applied ${f.appliedOps} op(s) in ${f.durationMs}ms`, {
1053
+ id: f.id,
1054
+ fingerprint: f.fingerprint.slice(0, 16)
1055
+ }), Q(n, i, a);
1056
+ }, Bt = async (e) => {
1057
+ let t = H(e), n = await Lt(t, e);
1058
+ try {
1059
+ return await Vt(e, t);
1060
+ } finally {
1061
+ await n.close();
1062
+ }
1063
+ }, Vt = async (t, n) => {
1064
+ let r = It(t), i = o(t, "--plan");
1065
+ if (i) return zt(i, t, n);
1066
+ if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error(`voltro db apply: refusing — auto-apply on prod is not allowed.${e()}`), console.error("In production, schema changes go through `voltro db plan --json > plan.json`"), console.error("then `voltro db apply --plan plan.json` as an explicit step in your deploy pipeline."), 3;
1067
+ let a = await Z(n);
1068
+ if (a === void 0) return B.warn("db apply: no schema files found", { root: n }), 1;
1069
+ let s = await q(), c = await rn(n, s);
1070
+ if ("failed" in c) return B.error("db apply: a file-based migration FAILED — the schema diff was NOT run"), console.error(c.failed), console.error("Fix the migration and re-run. `voltro db files` runs them alone."), 1;
1071
+ let l = M({
1072
+ declared: a,
1073
+ live: await Y(s),
1045
1074
  dialect: W(),
1046
- ...T(),
1047
- ...n === void 0 ? {} : { onlineAfter: n }
1075
+ ...j(),
1076
+ ...r === void 0 ? {} : { onlineAfter: r }
1048
1077
  });
1049
- Z(s), await _t(s, a);
1050
- let c = mt(s), u = c.plan;
1051
- if (u.summary.blocked > 0 && !c.acknowledged) return B.error(`db apply: refusing — ${u.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (B.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), B.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1052
- if (c.acknowledged && B.warn(`db apply: proceeding with ${s.summary.blocked} acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)`), yt(u, e)) return 2;
1053
- if (u.operations.length === 0) return B.info("db apply: schema is up to date — no DDL to apply (change triggers are reconciled separately below)"), await Ot(a), l(e, "--note") !== void 0 && (B.warn("db apply: --note was ignored — an empty plan writes no history row to attach it to."), console.error("To record that the CURRENT live schema is the accepted baseline, use `voltro db drift --accept`.")), await X(i, a), 0;
1054
- let d = l(e, "--note"), f = await J(a, x.SqlClient.pipe(g.flatMap((e) => se(e, u, {
1055
- declared: i,
1078
+ X(l), await Mt(l, s);
1079
+ let u = kt(l), d = u.plan;
1080
+ if (d.summary.blocked > 0 && !u.acknowledged) return B.error(`db apply: refusing — ${d.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (B.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), B.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1081
+ if (u.acknowledged && B.warn(`db apply: proceeding with ${l.summary.blocked} acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)`), Ft(d, t)) return 2;
1082
+ if (d.operations.length === 0) {
1083
+ B.info("db apply: schema is up to date no DDL to apply (change triggers are reconciled separately below)");
1084
+ let e = await J(s, D.SqlClient.pipe(E.flatMap((e) => ue(e, d, {
1085
+ appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:apply",
1086
+ environment: $(),
1087
+ source: "auto-diff"
1088
+ }))));
1089
+ return e === "recorded" && B.info(`db apply: recorded fingerprint=${d.toFingerprint.slice(0, 16)} (0 operations)`), await Qt(s), o(t, "--note") !== void 0 && e !== "recorded" && (B.warn("db apply: --note was ignored — this schema is already the latest recorded one, so there is no new history row to attach it to."), console.error("To record that the CURRENT live schema is the accepted baseline, use `voltro db drift --accept`.")), Q(n, a, s);
1090
+ }
1091
+ let f = o(t, "--note"), p = await J(s, D.SqlClient.pipe(E.flatMap((e) => re(e, d, {
1092
+ declared: a,
1056
1093
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user",
1057
- environment: (process.env.NODE_ENV ?? "dev").toLowerCase() === "staging" ? "staging" : "dev",
1094
+ environment: $(),
1058
1095
  source: "auto-diff",
1059
- ...d ? { notes: d } : {},
1060
- replan: () => g.promise(() => Y(a)).pipe(g.map((e) => E({
1061
- declared: i,
1096
+ ...f ? { notes: f } : {},
1097
+ replan: () => E.promise(() => Y(s)).pipe(E.map((e) => M({
1098
+ declared: a,
1062
1099
  live: e,
1063
1100
  dialect: W(),
1064
- ...T(),
1065
- ...n === void 0 ? {} : { onlineAfter: n }
1101
+ ...j(),
1102
+ ...r === void 0 ? {} : { onlineAfter: r }
1066
1103
  })))
1067
1104
  }))));
1068
- return B.info(`db apply: applied ${f.appliedOps} op(s) in ${f.durationMs}ms`, {
1069
- id: f.id,
1070
- fingerprint: f.fingerprint.slice(0, 16)
1071
- }), await X(i, a), 0;
1072
- }, wt = async (e) => {
1073
- let t = Math.max(1, Number(l(e, "--limit") ?? "20")), n = await J(await q(), x.SqlClient.pipe(g.flatMap((e) => e`
1105
+ return B.info(`db apply: applied ${p.appliedOps} op(s) in ${p.durationMs}ms`, {
1106
+ id: p.id,
1107
+ fingerprint: p.fingerprint.slice(0, 16)
1108
+ }), Q(n, a, s);
1109
+ }, Ht = (e) => {
1110
+ let t = [];
1111
+ for (let n of e.tables) for (let e of n.columns) {
1112
+ let r = e.references;
1113
+ r !== void 0 && t.push({
1114
+ table: n.name,
1115
+ column: e.name,
1116
+ targetTable: r.table,
1117
+ targetColumn: r.column,
1118
+ ...r.onDelete === void 0 ? {} : { onDelete: r.onDelete }
1119
+ });
1120
+ }
1121
+ return t;
1122
+ }, Ut = (e) => {
1123
+ let t = [];
1124
+ for (let n of e.tables) for (let e of n.indexes) e.expression !== !0 && e.name !== `${n.name}_pkey` && e.columns.length !== 0 && t.push({
1125
+ table: n.name,
1126
+ columns: e.columns,
1127
+ unique: e.unique,
1128
+ name: e.name
1129
+ });
1130
+ return t;
1131
+ }, Wt = (e, t) => {
1132
+ let n = (e) => JSON.stringify(e.op), r = new Set(e.operations.map(n)), i = new Set(t.operations.map(n)), a = [...t.operations.filter((e) => !r.has(n(e))), ...e.operations.filter((e) => !i.has(n(e)))];
1133
+ return {
1134
+ ...t,
1135
+ operations: a,
1136
+ summary: {
1137
+ ...t.summary,
1138
+ blocked: 0
1139
+ }
1140
+ };
1141
+ }, Gt = (e) => {
1142
+ if (e === void 0) return "empty";
1143
+ if (e === "empty" || e === "copy") return e;
1144
+ throw e === "fresh" ? new n("voltro db branch: --seed fresh is not implemented — the branch lifecycle has no executor step that runs boot seeds, so the branch would come up EMPTY while this reported it as seeded. Use --seed copy (the parent's rows) or --seed empty (schema only).") : new n(`voltro db branch: --seed must be one of empty|copy, got "${e}"`);
1145
+ }, Kt = (e) => {
1146
+ if (e !== void 0) {
1147
+ if (e === "namespace" || e === "neon-cow") return e;
1148
+ throw new n(`voltro db branch: --prefer must be one of namespace|neon-cow, got "${e}"`);
1149
+ }
1150
+ }, qt = async (e) => {
1151
+ let t = H(e), r = Gt(o(e, "--seed")), i = Kt(o(e, "--prefer")), a = e.includes("--keep"), s = e.includes("--json"), l = It(e), u = W();
1152
+ if (u !== "postgres") return B.error(`voltro db branch: not supported on '${u}'.`), console.error(" The branch PLAN is dialect-agnostic; the shipped namespace EXECUTOR is Postgres-only"), console.error(" (CREATE SCHEMA / CREATE TABLE … LIKE … INCLUDING ALL / \"-quoted identifiers)."), console.error(" MySQL, MariaDB, SQLite and SQL Server need their own BranchExecutor — see"), console.error(" makeNamespaceBranchExecutor in @voltro/database."), 1;
1153
+ let d = await Z(t);
1154
+ if (d === void 0) return B.warn("db branch: no schema files found", {
1155
+ root: t,
1156
+ hint: "looked for *.entity.ts / *.schema.ts / schema.ts"
1157
+ }), 1;
1158
+ let f = U(), p = we({
1159
+ seed: r,
1160
+ ...f.url === void 0 ? {} : { dbUrl: f.url },
1161
+ ...i === void 0 ? {} : { prefer: i }
1162
+ });
1163
+ if (p === "neon-cow") return B.error("voltro db branch: this connection resolves to the Neon copy-on-write mechanism, which the CLI cannot execute."), console.error(" A Neon CoW branch is a single call to Neon's branch REST API and needs a Neon API token;"), console.error(" the framework ships the PLAN, and the cloud control plane executes it."), console.error(" Re-run with `--prefer namespace` to rehearse on a schema-per-branch copy instead"), console.error(` (portable, no vendor API — it copies ${r === "copy" ? "every row" : "the schema only"}).`), 1;
1164
+ let m = f.schema ?? "public", h = o(e, "--name") ?? b(t), g = o(e, "--pr"), _ = g === void 0 ? 0 : Number(g);
1165
+ if (!Number.isInteger(_) || _ < 0) throw new n(`voltro db branch: --pr must be a non-negative integer, got "${String(g)}"`);
1166
+ let v = ve(h, _), y = await c(u), x = y.makeSqlLayer(f), S = y.makeSqlLayer({
1167
+ ...f,
1168
+ schema: v
1169
+ }), C = await Y(x), w = M({
1170
+ declared: d,
1171
+ live: C,
1172
+ dialect: u,
1173
+ ...j(),
1174
+ ...l === void 0 ? {} : { onlineAfter: l }
1175
+ }), T = C.tables.map((e) => e.name), te = Ht(C), ne = Ut(C), O = be({ run: (e) => J(x, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(e)), E.asVoid)) }), k = async () => M({
1176
+ declared: d,
1177
+ live: await Y(S),
1178
+ dialect: u,
1179
+ ...j(),
1180
+ ...l === void 0 ? {} : { onlineAfter: l }
1181
+ }), A = await de({
1182
+ branchId: v,
1183
+ mechanism: p,
1184
+ branchedTables: T.length,
1185
+ replayedForeignKeys: te.length,
1186
+ keep: a,
1187
+ log: (e) => {
1188
+ s || B.info(`db branch: ${e}`);
1189
+ },
1190
+ provision: async () => {
1191
+ await xe({
1192
+ appSlug: h,
1193
+ prNumber: _,
1194
+ seed: r,
1195
+ tableNames: T,
1196
+ parentNamespace: m,
1197
+ foreignKeys: te,
1198
+ indexNames: ne,
1199
+ prefer: "namespace",
1200
+ ...f.url === void 0 ? {} : { dbUrl: f.url }
1201
+ }, O);
1202
+ },
1203
+ fidelityPlan: async () => Wt(w, await k()),
1204
+ plan: k,
1205
+ apply: async (e) => {
1206
+ await J(S, D.SqlClient.pipe(E.flatMap((t) => re(t, e, {
1207
+ declared: d,
1208
+ appliedBy: "cli:db-branch",
1209
+ environment: $(),
1210
+ source: "auto-diff",
1211
+ notes: `migration rehearsal on branch ${v}`,
1212
+ replan: () => E.promise(k)
1213
+ }))));
1214
+ },
1215
+ replan: async () => await k(),
1216
+ teardown: async () => {
1217
+ await Te(v, "namespace", O);
1218
+ }
1219
+ });
1220
+ return s ? ee(1, `${JSON.stringify(A, null, 2)}\n`) : console.log(`\n${se(A)}\n`), ie(A);
1221
+ }, Jt = async (e) => {
1222
+ let t = Math.max(1, Number(o(e, "--limit") ?? "20")), n = await J(await q(), D.SqlClient.pipe(E.flatMap((e) => e`
1074
1223
  SELECT ${e("id")}, ${e("fingerprint")}, ${e("operations")},
1075
1224
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
1076
1225
  ${e("durationMs")}, ${e("notes")}, ${e("appliedAt")}
@@ -1083,20 +1232,20 @@ var O = class extends Error {
1083
1232
  for (let e of n) {
1084
1233
  let t = 0;
1085
1234
  try {
1086
- t = JSON.parse(kt(e.operations)).length;
1235
+ t = JSON.parse($t(e.operations)).length;
1087
1236
  } catch {}
1088
- console.log(` ${e.id} fp=${D(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${$(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1237
+ console.log(` ${e.id} fp=${N(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${en(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1089
1238
  }
1090
1239
  return console.log(), 0;
1091
- }, Tt = async (e) => {
1240
+ }, Yt = async (e) => {
1092
1241
  let t = e[0];
1093
1242
  if (!t) return console.error("voltro db restore-snapshot <plan-id>"), console.error(" Renames soft-dropped columns/tables from a plan back to their original names."), console.error(" Requires the plan to have been applied with VOLTRO_SOFT_DROP=1."), 2;
1094
- let n = await q(), r = await J(n, x.SqlClient.pipe(g.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1243
+ let n = await q(), r = await J(n, D.SqlClient.pipe(E.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1095
1244
  FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t}`)));
1096
1245
  if (r.length === 0) return console.error(`restore-snapshot: plan '${t}' not found`), 1;
1097
1246
  let i;
1098
1247
  try {
1099
- i = JSON.parse(kt(r[0].operations));
1248
+ i = JSON.parse($t(r[0].operations));
1100
1249
  } catch {
1101
1250
  return console.error(`restore-snapshot: plan '${t}' has corrupted operations JSON`), 1;
1102
1251
  }
@@ -1110,7 +1259,7 @@ var O = class extends Error {
1110
1259
  if (a.length === 0 && o.length === 0) return console.log(`restore-snapshot: plan '${t}' has no drop-column / drop-table ops to restore`), 0;
1111
1260
  let s = 0;
1112
1261
  for (let e of a) {
1113
- let t = await J(n, x.SqlClient.pipe(g.flatMap((t) => t`
1262
+ let t = await J(n, D.SqlClient.pipe(E.flatMap((t) => t`
1114
1263
  SELECT column_name FROM information_schema.columns
1115
1264
  WHERE ${t.unsafe(K(W()))}
1116
1265
  AND table_name = ${e.table}
@@ -1122,11 +1271,11 @@ var O = class extends Error {
1122
1271
  continue;
1123
1272
  }
1124
1273
  let r = t[0].column_name;
1125
- await J(n, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table)} RENAME COLUMN ${G(r)} TO ${G(e.column)}`)))), s++, console.log(` ↩ restored ${e.table}.${e.column} (from ${r})`);
1274
+ await J(n, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table)} RENAME COLUMN ${G(r)} TO ${G(e.column)}`)))), s++, console.log(` ↩ restored ${e.table}.${e.column} (from ${r})`);
1126
1275
  }
1127
1276
  let c = 0;
1128
1277
  for (let e of o) {
1129
- let t = await J(n, x.SqlClient.pipe(g.flatMap((t) => t`
1278
+ let t = await J(n, D.SqlClient.pipe(E.flatMap((t) => t`
1130
1279
  SELECT table_name FROM information_schema.tables
1131
1280
  WHERE ${t.unsafe(K(W()))}
1132
1281
  AND table_name LIKE ${e.table + "__dropped_%"}
@@ -1137,57 +1286,57 @@ var O = class extends Error {
1137
1286
  continue;
1138
1287
  }
1139
1288
  let r = t[0].table_name;
1140
- await J(n, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(`ALTER TABLE ${G(r)} RENAME TO ${G(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1289
+ await J(n, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(`ALTER TABLE ${G(r)} RENAME TO ${G(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1141
1290
  }
1142
1291
  return console.log(`\n✓ restored ${s} column(s) + ${c} table(s) from plan '${t}'\n`), 0;
1143
- }, Et = async (e) => {
1144
- let t = l(e, "--before");
1292
+ }, Xt = async (e) => {
1293
+ let t = o(e, "--before");
1145
1294
  if (!t) return console.error("voltro db gc-snapshots --before <date> [--dry-run]"), console.error(" Permanently drops soft-dropped columns/tables (<name>__dropped_<ts>) older than <date>."), console.error(" <date> is ISO — e.g. 2026-01-01 or 2026-01-01T00:00:00Z. NOT reversible."), 2;
1146
1295
  let n = t.replace(/[^0-9]/g, "");
1147
1296
  if (n.length < 8) return console.error(`gc-snapshots: --before must be at least a full date (YYYY-MM-DD), got "${t}"`), 2;
1148
- let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await q(), o = await J(a, x.SqlClient.pipe(g.flatMap((e) => e`
1297
+ let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await q(), s = await J(a, D.SqlClient.pipe(E.flatMap((e) => e`
1149
1298
  SELECT table_name, column_name FROM information_schema.columns
1150
1299
  WHERE ${e.unsafe(K(W()))} AND column_name LIKE ${"%__dropped_%"}
1151
- `))), s = await J(a, x.SqlClient.pipe(g.flatMap((e) => e`
1300
+ `))), c = await J(a, D.SqlClient.pipe(E.flatMap((e) => e`
1152
1301
  SELECT table_name FROM information_schema.tables
1153
1302
  WHERE ${e.unsafe(K(W()))} AND table_name LIKE ${"%__dropped_%"}
1154
- `))), c = (e) => {
1303
+ `))), l = (e) => {
1155
1304
  let t = /__dropped_(\d{14})$/.exec(e);
1156
1305
  return t ? t[1] : null;
1157
1306
  }, u = 0;
1158
- for (let e of o) {
1159
- let t = c(e.column_name);
1160
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await J(a, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table_name)} DROP COLUMN ${G(e.column_name)}`)))), u++);
1161
- }
1162
1307
  for (let e of s) {
1163
- let t = c(e.table_name);
1164
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await J(a, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(`DROP TABLE ${G(e.table_name)}`)))), u++);
1308
+ let t = l(e.column_name);
1309
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await J(a, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table_name)} DROP COLUMN ${G(e.column_name)}`)))), u++);
1310
+ }
1311
+ for (let e of c) {
1312
+ let t = l(e.table_name);
1313
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await J(a, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(`DROP TABLE ${G(e.table_name)}`)))), u++);
1165
1314
  }
1166
1315
  return console.log(`\n${i ? `[dry-run] ${u} snapshot(s) would be dropped` : `✓ dropped ${u} snapshot(s)`} (older than ${r}).\n`), 0;
1167
- }, Dt = async (e) => {
1168
- let t = l(e, "--before");
1316
+ }, Zt = async (e) => {
1317
+ let t = o(e, "--before");
1169
1318
  if (!t) return console.error("voltro db squash --before <iso-date> [--note \"<text>\"]"), 2;
1170
1319
  let n = t;
1171
1320
  if (Number.isNaN(new Date(n).getTime())) return console.error(`voltro db squash: --before '${n}' is not a valid ISO date`), 2;
1172
- let r = l(e, "--note"), i = H(e), a = await Q(i);
1321
+ let r = o(e, "--note"), i = H(e), a = await Z(i);
1173
1322
  if (a === void 0) return B.warn("db squash: no schema files found", { root: i }), 1;
1174
- let o = fe(le(a)), s = await q();
1323
+ let s = oe(A(a)), c = await q();
1175
1324
  try {
1176
- let e = await J(s, ye({
1325
+ let e = await J(c, he({
1177
1326
  before: n,
1178
- fingerprint: o,
1327
+ fingerprint: s,
1179
1328
  appliedBy: process.env.USER ?? "cli",
1180
- environment: process.env.NODE_ENV === "production" ? "prod" : "dev",
1329
+ environment: $(),
1181
1330
  ...r === void 0 ? {} : { note: r }
1182
1331
  }));
1183
- return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${D(e.snapshotFingerprint)}\n`), 0;
1332
+ return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${N(e.snapshotFingerprint)}\n`), 0;
1184
1333
  } catch (e) {
1185
1334
  return console.error(`squash refused: ${e.message}`), 1;
1186
1335
  }
1187
- }, Ot = async (e) => {
1336
+ }, Qt = async (e) => {
1188
1337
  try {
1189
- let t = fe(await Y(e));
1190
- await J(e, x.SqlClient.pipe(g.flatMap((e) => e`
1338
+ let t = oe(await Y(e));
1339
+ await J(e, D.SqlClient.pipe(E.flatMap((e) => e`
1191
1340
  UPDATE ${e("_voltro_migration_plans")}
1192
1341
  SET ${e("liveFingerprint")} = ${t}
1193
1342
  WHERE ${e("id")} = (
@@ -1199,7 +1348,7 @@ var O = class extends Error {
1199
1348
  AND ${e("liveFingerprint")} IS NULL
1200
1349
  `)));
1201
1350
  } catch {}
1202
- }, kt = (e) => typeof e == "string" ? e : e == null ? "" : JSON.stringify(e), $ = (e) => e instanceof Date ? e.toISOString() : String(e ?? ""), At = (e) => e === void 0 ? {
1351
+ }, $t = (e) => typeof e == "string" ? e : e == null ? "" : JSON.stringify(e), en = (e) => e instanceof Date ? e.toISOString() : String(e ?? ""), tn = (e) => e === void 0 ? {
1203
1352
  accept: !1,
1204
1353
  reason: "no-declared-schema"
1205
1354
  } : e > 0 ? {
@@ -1208,38 +1357,38 @@ var O = class extends Error {
1208
1357
  } : {
1209
1358
  accept: !0,
1210
1359
  reason: "converged"
1211
- }, jt = async (e) => {
1212
- let t = e.includes("--accept"), n = await q(), r = await J(n, x.SqlClient.pipe(g.flatMap((e) => e`
1360
+ }, nn = async (e) => {
1361
+ let t = e.includes("--accept"), n = await q(), r = await J(n, D.SqlClient.pipe(E.flatMap((e) => e`
1213
1362
  SELECT * FROM ${e("_voltro_migration_plans")}
1214
1363
  ORDER BY ${e("appliedAt")} DESC
1215
1364
  LIMIT 1
1216
- `))), i = await Y(n), a = fe(i);
1217
- if (r.length === 0) return B.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${D(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1365
+ `))), i = await Y(n), a = oe(i);
1366
+ if (r.length === 0) return B.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${N(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1218
1367
  let o = r[0];
1219
- if (o.liveFingerprint === null || o.liveFingerprint === void 0) return B.warn("db drift: no drift baseline recorded yet — cannot compare"), console.log(), console.log(` last applied: ${o.id} at ${$(o.appliedAt)}`), console.log(` live now: ${D(a)}`), console.log(), console.log("That row was written before the framework recorded a live-schema baseline,"), console.log("and the value it does carry is the DECLARED snapshot's hash — not comparable"), console.log("with a live one. Run `voltro db apply` once to establish the baseline (a no-op"), console.log("apply backfills it too); use `voltro db plan` meanwhile, which compares declared"), console.log("against live directly."), console.log(), console.log("Exit code 3 — NOT 0. \"Did not compare\" is not \"clean\", and a gate on the exit"), console.log("code has to be able to tell them apart."), 3;
1220
- if (o.liveFingerprint === a) return B.info(`db drift: live matches last applied (${D(a)})`), 0;
1368
+ if (o.liveFingerprint === null || o.liveFingerprint === void 0) return B.warn("db drift: no drift baseline recorded yet — cannot compare"), console.log(), console.log(` last applied: ${o.id} at ${en(o.appliedAt)}`), console.log(` live now: ${N(a)}`), console.log(), console.log("That row was written before the framework recorded a live-schema baseline,"), console.log("and the value it does carry is the DECLARED snapshot's hash — not comparable"), console.log("with a live one. Run `voltro db apply` once to establish the baseline (a no-op"), console.log("apply backfills it too); use `voltro db plan` meanwhile, which compares declared"), console.log("against live directly."), console.log(), console.log("Exit code 3 — NOT 0. \"Did not compare\" is not \"clean\", and a gate on the exit"), console.log("code has to be able to tell them apart."), 3;
1369
+ if (o.liveFingerprint === a) return B.info(`db drift: live matches last applied (${N(a)})`), 0;
1221
1370
  let s = await (async () => {
1222
1371
  try {
1223
- let t = await Q(H(e));
1224
- return t === void 0 ? void 0 : E({
1372
+ let t = await Z(H(e));
1373
+ return t === void 0 ? void 0 : M({
1225
1374
  declared: t,
1226
1375
  live: i,
1227
1376
  dialect: W(),
1228
- ...T()
1377
+ ...j()
1229
1378
  }).operations;
1230
1379
  } catch {
1231
1380
  return;
1232
1381
  }
1233
1382
  })();
1234
1383
  if (t) {
1235
- let e = At(s?.length);
1384
+ let e = tn(s?.length);
1236
1385
  if (e.reason === "no-declared-schema") return B.error("db drift --accept: no schema files found — cannot verify the live schema is current."), 1;
1237
1386
  if (!e.accept && s !== void 0) {
1238
1387
  B.error(`db drift --accept: refusing — ${s.length} operation(s) still pending against your declared schema.`), console.log();
1239
1388
  for (let e of s.slice(0, 10)) console.log(` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}`);
1240
1389
  return s.length > 10 && console.log(` … and ${s.length - 10} more`), console.log(), console.log("`--accept` records the CURRENT live schema as the applied baseline. It is for a"), console.log("change that already landed out of band and left the schema correct — not for one"), console.log("that has not landed. Run `voltro db apply` instead; it writes a real baseline."), 4;
1241
1390
  }
1242
- return await J(n, x.SqlClient.pipe(g.flatMap((e) => e`
1391
+ return await J(n, D.SqlClient.pipe(E.flatMap((e) => e`
1243
1392
  UPDATE ${e("_voltro_migration_plans")}
1244
1393
  SET ${e("liveFingerprint")} = ${a}
1245
1394
  WHERE ${e("id")} = (
@@ -1248,13 +1397,13 @@ var O = class extends Error {
1248
1397
  ORDER BY ${e("appliedAt")} DESC LIMIT 1
1249
1398
  ) AS ${e("newest")}
1250
1399
  )
1251
- `))), B.info(`db drift: accepted the live schema as the baseline (${D(a)})`), console.log(), console.log("`voltro db plan` reports 0 operations against this schema, so the live state already"), console.log("matches your declaration — only the ledger did not know. It does now."), console.log(), console.log("No history entry was invented: the latest row's baseline was updated in place,"), console.log("because no migration ran."), 0;
1400
+ `))), B.info(`db drift: accepted the live schema as the baseline (${N(a)})`), console.log(), console.log("`voltro db plan` reports 0 operations against this schema, so the live state already"), console.log("matches your declaration — only the ledger did not know. It does now."), console.log(), console.log("No history entry was invented: the latest row's baseline was updated in place,"), console.log("because no migration ran."), 0;
1252
1401
  }
1253
- return B.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${D(o.liveFingerprint)} at ${$(o.appliedAt)} (${o.id})`), console.log(` live now: ${D(a)}`), console.log(), console.log("Something changed the live schema after the last apply. This command can see"), console.log("THAT it changed, not what or who — the fingerprints are hashes, not a diff."), console.log(), s === void 0 ? (console.log("No schema files found here, so the declared side could not be compared."), console.log("Run `voltro db plan` from your project root for the actual difference."), 4) : s.length === 0 ? (console.log("Your DECLARED schema is already satisfied — `voltro db plan` reports 0 operations"), console.log("against this database. So the live schema is not wrong, only unrecorded: something"), console.log("applied a change without going through the planner (a hand-run ALTER, a DBA"), console.log("window, a restored dump), or it touched a table your code does not declare."), console.log(), console.log("If that was deliberate and the schema is right, record it:"), console.log(), console.log(" voltro db drift --accept"), console.log(), console.log("It updates the latest ledger row's baseline to the live schema and invents no"), console.log("history entry. Drift then measures from here."), 4) : (console.log(`\`voltro db plan\` reports ${s.length} operation(s) still pending against your`), console.log("declared schema, so this is not merely an unrecorded change — run it for the diff,"), console.log("then `voltro db apply`, which writes a fresh baseline of its own."), 4);
1254
- }, Mt = async (e, t) => {
1255
- let n = (process.env.NODE_ENV ?? "").toLowerCase() === "production" ? "prod" : (process.env.NODE_ENV ?? "").toLowerCase() === "staging" ? "staging" : "dev";
1402
+ return B.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${N(o.liveFingerprint)} at ${en(o.appliedAt)} (${o.id})`), console.log(` live now: ${N(a)}`), console.log(), console.log("Something changed the live schema after the last apply. This command can see"), console.log("THAT it changed, not what or who — the fingerprints are hashes, not a diff."), console.log(), s === void 0 ? (console.log("No schema files found here, so the declared side could not be compared."), console.log("Run `voltro db plan` from your project root for the actual difference."), 4) : s.length === 0 ? (console.log("Your DECLARED schema is already satisfied — `voltro db plan` reports 0 operations"), console.log("against this database. So the live schema is not wrong, only unrecorded: something"), console.log("applied a change without going through the planner (a hand-run ALTER, a DBA"), console.log("window, a restored dump), or it touched a table your code does not declare."), console.log(), console.log("If that was deliberate and the schema is right, record it:"), console.log(), console.log(" voltro db drift --accept"), console.log(), console.log("It updates the latest ledger row's baseline to the live schema and invents no"), console.log("history entry. Drift then measures from here."), 4) : (console.log(`\`voltro db plan\` reports ${s.length} operation(s) still pending against your`), console.log("declared schema, so this is not merely an unrecorded change — run it for the diff,"), console.log("then `voltro db apply`, which writes a fresh baseline of its own."), 4);
1403
+ }, rn = async (e, t) => {
1404
+ let n = $();
1256
1405
  try {
1257
- let r = await J(t, x.SqlClient.pipe(g.flatMap((t) => ve(t, {
1406
+ let r = await J(t, D.SqlClient.pipe(E.flatMap((t) => me(t, {
1258
1407
  projectRoot: e,
1259
1408
  env: n,
1260
1409
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
@@ -1263,10 +1412,10 @@ var O = class extends Error {
1263
1412
  } catch (e) {
1264
1413
  return { failed: e };
1265
1414
  }
1266
- }, Nt = async (e) => {
1267
- let t = H(e), n = await q(), r = (process.env.NODE_ENV ?? "").toLowerCase() === "production" ? "prod" : (process.env.NODE_ENV ?? "").toLowerCase() === "staging" ? "staging" : "dev";
1268
- await J(n, w(S, W()));
1269
- let i = await J(n, x.SqlClient.pipe(g.flatMap((e) => ve(e, {
1415
+ }, an = async (e) => {
1416
+ let t = H(e), n = await q(), r = $();
1417
+ await J(n, O(P, W()));
1418
+ let i = await J(n, D.SqlClient.pipe(E.flatMap((e) => me(e, {
1270
1419
  projectRoot: t,
1271
1420
  env: r,
1272
1421
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
@@ -1275,16 +1424,16 @@ var O = class extends Error {
1275
1424
  applied: i.applied.map((e) => `${e.id} (${e.durationMs}ms)`),
1276
1425
  skipped: i.skipped.length
1277
1426
  }), 0);
1278
- }, Pt = async (e) => {
1279
- let t = H(e), n = e.find((e) => !e.startsWith("--"));
1280
- if (!n) return B.error("voltro db rollback-file <migration-id>"), 2;
1281
- if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error("voltro db rollback-file: refusing on prod — schema rollback runs as an explicit deploy step."), 3;
1282
- let r = await J(await q(), x.SqlClient.pipe(g.flatMap((e) => ge(e, {
1283
- projectRoot: t,
1284
- id: n
1427
+ }, on = async (t) => {
1428
+ let n = H(t), r = s(t, _t);
1429
+ if (!r) return B.error("voltro db rollback-file <migration-id>"), 2;
1430
+ if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error("voltro db rollback-file: refusing on prod — schema rollback runs as an explicit deploy step." + e()), 3;
1431
+ let i = await J(await q(), D.SqlClient.pipe(E.flatMap((e) => fe(e, {
1432
+ projectRoot: n,
1433
+ id: r
1285
1434
  }))));
1286
- return B.info(`db rollback-file: rolled back ${r.id} in ${r.durationMs}ms`), 0;
1287
- }, Ft = () => {
1435
+ return B.info(`db rollback-file: rolled back ${i.id} in ${i.durationMs}ms`), 0;
1436
+ }, sn = () => {
1288
1437
  let e = /* @__PURE__ */ new Date();
1289
1438
  return [
1290
1439
  e.getUTCFullYear(),
@@ -1294,7 +1443,7 @@ var O = class extends Error {
1294
1443
  String(e.getUTCMinutes()).padStart(2, "0"),
1295
1444
  String(e.getUTCSeconds()).padStart(2, "0")
1296
1445
  ].join("");
1297
- }, It = (e) => e.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "migration", Lt = (e, t) => `import { defineMigration, SqlClient } from '@voltro/database'
1446
+ }, cn = (e) => e.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "migration", ln = (e, t) => `import { defineMigration, SqlClient } from '@voltro/database'
1298
1447
  import { Effect } from 'effect'
1299
1448
 
1300
1449
  // A hand-written migration. Reach for this when the DECLARATIVE differ can't
@@ -1326,99 +1475,100 @@ export default defineMigration({
1326
1475
  }),
1327
1476
  ],
1328
1477
  })
1329
- `, Rt = {
1330
- plan: xt,
1331
- apply: Ct,
1332
- plans: wt,
1333
- drift: jt,
1334
- files: Nt,
1335
- "rollback-file": Pt,
1336
- migrate: at,
1337
- rollback: ot,
1338
- status: st,
1339
- seed: lt,
1478
+ `, un = {
1479
+ plan: Rt,
1480
+ apply: Bt,
1481
+ branch: qt,
1482
+ plans: Jt,
1483
+ drift: nn,
1484
+ files: an,
1485
+ "rollback-file": on,
1486
+ migrate: bt,
1487
+ rollback: xt,
1488
+ status: St,
1489
+ seed: wt,
1340
1490
  generate: async (e) => {
1341
- let { value: t, rest: n } = c(e, "--root"), { value: r, rest: i } = c(n, "--name"), a = t ? m(t) : process.cwd(), o = It(r ?? u(i) ?? "migration"), s = `${Ft()}_${o}`, l = f(a, "migrations"), d = f(l, `${s}.migration.ts`);
1342
- return await v.mkdir(l, { recursive: !0 }), await v.writeFile(d, Lt(s, o), "utf8"), B.info(`created ${p(a, d)}`), console.error("Fill in the apply/undo steps, then run `voltro db migrate` (rollback with `voltro db rollback`)."), console.error("For a plain schema shape change you may not need this — `voltro db apply` diffs declared vs live."), 0;
1491
+ let { value: t, rest: n } = i(e, "--root"), { value: r, rest: a } = i(n, "--name"), o = t ? C(t) : process.cwd(), c = cn(r ?? s(a, []) ?? "migration"), l = `${sn()}_${c}`, u = x(o, "migrations"), d = x(u, `${l}.migration.ts`);
1492
+ return await w.mkdir(u, { recursive: !0 }), await w.writeFile(d, ln(l, c), "utf8"), B.info(`created ${S(o, d)}`), console.error("Fill in the apply/undo steps, then run `voltro db migrate` (rollback with `voltro db rollback`)."), console.error("For a plain schema shape change you may not need this — `voltro db apply` diffs declared vs live."), 0;
1343
1493
  },
1344
- squash: Dt,
1345
- "restore-snapshot": Tt,
1346
- "gc-snapshots": Et,
1494
+ squash: Zt,
1495
+ "restore-snapshot": Yt,
1496
+ "gc-snapshots": Xt,
1347
1497
  adopt: async (e) => {
1348
1498
  let t = (t) => {
1349
1499
  let n = e.indexOf(`--${t}`);
1350
1500
  return n === -1 ? void 0 : e[n + 1];
1351
- }, n = t("from"), r = t("into"), i = t("map");
1352
- if (n === void 0 || r === void 0 || i === void 0) return console.error("voltro db adopt --from <table> --into <table> --map <file.ts> [--apply] [--keep-source]"), console.error(" Dry run unless --apply. The map file default-exports { map, leaveUnset? }."), 1;
1353
- let o = (await a(m(process.cwd(), i))).default;
1354
- if (o?.map === void 0) return console.error(`voltro db adopt: ${i} must default-export { map: { <targetColumn>: <source> } }`), 1;
1501
+ }, n = t("from"), i = t("into"), a = t("map");
1502
+ if (n === void 0 || i === void 0 || a === void 0) return console.error("voltro db adopt --from <table> --into <table> --map <file.ts> [--apply] [--keep-source]"), console.error(" Dry run unless --apply. The map file default-exports { map, leaveUnset? }."), 1;
1503
+ let o = (await r(C(process.cwd(), a))).default;
1504
+ if (o?.map === void 0) return console.error(`voltro db adopt: ${a} must default-export { map: { <targetColumn>: <source> } }`), 1;
1355
1505
  let s = {
1356
1506
  from: n,
1357
- into: r,
1507
+ into: i,
1358
1508
  map: o.map,
1359
1509
  ...o.leaveUnset ? { leaveUnset: o.leaveUnset } : {}
1360
- }, c = W(), l = await q(), u = await J(l, x.SqlClient.pipe(g.flatMap(pe))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1510
+ }, c = W(), l = await q(), u = await J(l, D.SqlClient.pipe(E.flatMap(ce))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1361
1511
  name: e.name,
1362
1512
  nullable: e.nullable,
1363
1513
  hasDefault: e.defaultValue !== void 0 && e.defaultValue !== null
1364
- })), f = d(n), p = d(r);
1514
+ })), f = d(n), p = d(i);
1365
1515
  if (f === void 0) return console.error(`voltro db adopt: '${n}' does not exist in the database`), 1;
1366
- if (p === void 0) return console.error(`voltro db adopt: '${r}' does not exist in the database — boot once so the plugin's table is created`), 1;
1367
- let h = async (e) => await J(l, x.SqlClient.pipe(g.flatMap((t) => t.unsafe(e)))), _ = async (e) => Number(Object.values((await h(`SELECT COUNT(*) AS n FROM "${e}"`))[0] ?? { n: 0 })[0] ?? 0), v = Ce(s, f, p, await _(r));
1368
- for (let e of Te(s, v, await _(n))) console.log(e);
1369
- if (v.fatal) return 1;
1516
+ if (p === void 0) return console.error(`voltro db adopt: '${i}' does not exist in the database — boot once so the plugin's table is created`), 1;
1517
+ let m = async (e) => await J(l, D.SqlClient.pipe(E.flatMap((t) => t.unsafe(e)))), h = async (e) => Number(Object.values((await m(`SELECT COUNT(*) AS n FROM "${e}"`))[0] ?? { n: 0 })[0] ?? 0), g = Ae(s, f, p, await h(i));
1518
+ for (let e of Me(s, g, await h(n))) console.log(e);
1519
+ if (g.fatal) return 1;
1370
1520
  if (!e.includes("--apply")) return console.log(""), console.log(" (dry run — nothing written. Re-run with --apply.)"), 0;
1371
- let y = await Ae(s, v, c, "id", void 0, h, { keepSource: e.includes("--keep-source") });
1372
- return console.log(""), console.log(` copied ${y.copied}/${y.sourceRows} row(s)`), console.log(` snapshot: ${y.snapshotTable} — restore from here, then drop it yourself`), y.verified ? (console.log(y.sourceDropped ? ` dropped ${n}` : ` ${n} left in place (--keep-source)`), 0) : (console.error(" ✗ counts DIFFER — the source was NOT dropped. Compare the two tables before doing anything else."), 1);
1521
+ let _ = await Le(s, g, c, "id", void 0, m, { keepSource: e.includes("--keep-source") });
1522
+ return console.log(""), console.log(` copied ${_.copied}/${_.sourceRows} row(s)`), console.log(` snapshot: ${_.snapshotTable} — restore from here, then drop it yourself`), _.verified ? (console.log(_.sourceDropped ? ` dropped ${n}` : ` ${n} left in place (--keep-source)`), 0) : (console.error(" ✗ counts DIFFER — the source was NOT dropped. Compare the two tables before doing anything else."), 1);
1373
1523
  },
1374
1524
  "scan-credentials": async (e) => {
1375
- let t = W(), n = [];
1525
+ let t = W(), r = [];
1376
1526
  for (let t = 0; t < e.length; t += 1) {
1377
1527
  if (e[t] !== "--table") continue;
1378
- let r = e[t + 1];
1379
- if (r === void 0) throw new O("voltro db scan-credentials: --table needs a value");
1380
- let [i, a = "subject"] = r.split(":");
1381
- n.push({
1382
- table: i,
1383
- column: a
1528
+ let i = e[t + 1];
1529
+ if (i === void 0) throw new n("voltro db scan-credentials: --table needs a value");
1530
+ let [a, o = "subject"] = i.split(":");
1531
+ r.push({
1532
+ table: a,
1533
+ column: o
1384
1534
  });
1385
1535
  }
1386
- let r = [...je, ...n], i = await J(await q(), x.SqlClient.pipe(g.flatMap((e) => g.promise(() => ze(e, t, r, G)))));
1387
- return console.log(Be(i, t)), Ve(i);
1536
+ let i = [...Re, ...r], a = await J(await q(), D.SqlClient.pipe(E.flatMap((e) => E.promise(() => Xe(e, t, i, G)))));
1537
+ return console.log(Ze(a, t)), Qe(a);
1388
1538
  },
1389
1539
  "encrypt-column": async (e) => {
1390
- let t = W(), n = e.includes("--dry-run"), r = e.includes("--yes"), i = (t) => {
1540
+ let t = W(), r = e.includes("--dry-run"), i = e.includes("--yes"), o = (t) => {
1391
1541
  let n = e.indexOf(t);
1392
1542
  return n >= 0 ? e[n + 1] : void 0;
1393
- }, a = Math.max(1, Number(i("--batch") ?? 500)), o = i("--key-env") ?? "FIELD_ENCRYPTION_KEY", s = process.env[o];
1394
- if (!s) throw new O(`voltro db encrypt-column: ${o} is not set. It must be the SAME key your app runs with (\`governancePlugin({ fieldEncryption: { key } })\`) — encrypting with a different one produces rows the app cannot read. Use --key-env to name a different variable.`);
1395
- let c = ee(s), l = e.filter((e) => !e.startsWith("--") && e.includes(".")).map(Ke);
1396
- if (l.length === 0) throw new O("voltro db encrypt-column: name at least one <table>.<column>");
1397
- let u = await q(), d = [];
1398
- for (let e of l) {
1399
- let i = G(e.table), s = G(e.column), l = await J(u, x.SqlClient.pipe(g.flatMap((n) => g.promise(async () => {
1400
- let r = await g.runPromise(n.unsafe(`SELECT character_maximum_length AS n FROM information_schema.columns\n WHERE ${K(t)} AND table_name = '${e.table}' AND column_name = '${e.column}'`));
1401
- if (r.length === 0) throw new O(`voltro db encrypt-column: ${e.table}.${e.column} does not exist on this database`);
1402
- let i = Object.values(r[0])[0];
1403
- return i == null ? void 0 : Number(i);
1404
- })))), f = await J(u, x.SqlClient.pipe(g.flatMap((e) => g.promise(async () => await g.runPromise(e.unsafe(`SELECT ${G("id")} AS id, ${s} AS v FROM ${i}`)))))), p = 0;
1405
- for (let e of f) typeof e.v != "string" || C(e.v) || (p = Math.max(p, Qe(e.v)));
1406
- let m = Je(p, l);
1407
- if (!m.fits) return console.error(` ✗ ${Ye(e, m)}`), 1;
1408
- if ($e(f.map((e) => e.v).find((e) => typeof e == "string" && C(e)), c) === !1) return console.error(` ✗ ${et(e, o)}`), 1;
1409
- let h = f.filter((t) => Ze(t.v, c, e) !== void 0).length;
1410
- if (!n && !r) return console.error(` ✗ ${e.table}.${e.column}: ${h} row(s) would be rewritten in place. Re-run with --yes, or --dry-run to see the counts without writing.`), 1;
1543
+ }, s = Math.max(1, Number(o("--batch") ?? 500)), c = o("--key-env") ?? "FIELD_ENCRYPTION_KEY", l = process.env[c];
1544
+ if (!l) throw new n(`voltro db encrypt-column: ${c} is not set. It must be the SAME key your app runs with (\`governancePlugin({ fieldEncryption: { key } })\`) — encrypting with a different one produces rows the app cannot read. Use --key-env to name a different variable.`);
1545
+ let u = De(l), d = a(e, _t).filter((e) => e.includes(".")).map(ot);
1546
+ if (d.length === 0) throw new n("voltro db encrypt-column: name at least one <table>.<column>");
1547
+ let f = await q(), p = [];
1548
+ for (let e of d) {
1549
+ let a = G(e.table), o = G(e.column), l = await J(f, D.SqlClient.pipe(E.flatMap((r) => E.promise(async () => {
1550
+ let i = await E.runPromise(r.unsafe(`SELECT character_maximum_length AS n FROM information_schema.columns\n WHERE ${K(t)} AND table_name = '${e.table}' AND column_name = '${e.column}'`));
1551
+ if (i.length === 0) throw new n(`voltro db encrypt-column: ${e.table}.${e.column} does not exist on this database`);
1552
+ let a = Object.values(i[0])[0];
1553
+ return a == null ? void 0 : Number(a);
1554
+ })))), d = await J(f, D.SqlClient.pipe(E.flatMap((e) => E.promise(async () => await E.runPromise(e.unsafe(`SELECT ${G("id")} AS id, ${o} AS v FROM ${a}`)))))), m = 0;
1555
+ for (let e of d) typeof e.v != "string" || F(e.v) || (m = Math.max(m, ft(e.v)));
1556
+ let h = ct(m, l);
1557
+ if (!h.fits) return console.error(` ✗ ${lt(e, h)}`), 1;
1558
+ if (pt(d.map((e) => e.v).find((e) => typeof e == "string" && F(e)), u) === !1) return console.error(` ✗ ${mt(e, c)}`), 1;
1559
+ let g = d.filter((t) => dt(t.v, u, e) !== void 0).length;
1560
+ if (!r && !i) return console.error(` ✗ ${e.table}.${e.column}: ${g} row(s) would be rewritten in place. Re-run with --yes, or --dry-run to see the counts without writing.`), 1;
1411
1561
  let _ = 0, v = 0, y = 0, b = [];
1412
- for (let t of f) {
1562
+ for (let t of d) {
1413
1563
  if (t.v === null || t.v === void 0 || t.v === "") {
1414
1564
  v += 1;
1415
1565
  continue;
1416
1566
  }
1417
- if (typeof t.v == "string" && C(t.v)) {
1567
+ if (typeof t.v == "string" && F(t.v)) {
1418
1568
  _ += 1;
1419
1569
  continue;
1420
1570
  }
1421
- let n = Ze(t.v, c, e);
1571
+ let n = dt(t.v, u, e);
1422
1572
  if (n === void 0) {
1423
1573
  v += 1;
1424
1574
  continue;
@@ -1428,37 +1578,37 @@ export default defineMigration({
1428
1578
  value: n
1429
1579
  }), y += 1;
1430
1580
  }
1431
- if (!n && b.length > 0) for (let t = 0; t < b.length; t += a) {
1432
- let n = b.slice(t, t + a);
1433
- await J(u, x.SqlClient.pipe(g.flatMap((t) => g.promise(async () => {
1434
- for (let r of n) await g.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1581
+ if (!r && b.length > 0) for (let t = 0; t < b.length; t += s) {
1582
+ let n = b.slice(t, t + s);
1583
+ await J(f, D.SqlClient.pipe(E.flatMap((t) => E.promise(async () => {
1584
+ for (let r of n) await E.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1435
1585
  })))), B.info(`encrypt-column ${e.table}.${e.column}: ${Math.min(t + n.length, b.length)}/${b.length}`);
1436
1586
  }
1437
- d.push({
1587
+ p.push({
1438
1588
  table: e.table,
1439
1589
  column: e.column,
1440
- scanned: f.length,
1590
+ scanned: d.length,
1441
1591
  alreadyEncrypted: _,
1442
1592
  empty: v,
1443
1593
  encrypted: y
1444
1594
  });
1445
1595
  }
1446
- console.log(`field encryption · dialect ${t}${n ? " · DRY RUN, nothing written" : ""}`), console.log("");
1447
- for (let e of d) console.log(Xe(e, n));
1448
- return n || console.log(tt(l)), 0;
1596
+ console.log(`field encryption · dialect ${t}${r ? " · DRY RUN, nothing written" : ""}`), console.log("");
1597
+ for (let e of p) console.log(ut(e, r));
1598
+ return r || console.log(ht(d)), 0;
1449
1599
  }
1450
- }, zt = async (e) => {
1600
+ }, dn = async (e) => {
1451
1601
  let [t, ...n] = e;
1452
1602
  if (!t) {
1453
1603
  console.error("voltro db <subcommand> [args]"), console.error("subcommands:");
1454
- for (let e of Object.keys(Rt)) console.error(` ${e}`);
1604
+ for (let e of Object.keys(un)) console.error(` ${e}`);
1455
1605
  return 1;
1456
1606
  }
1457
- let r = Rt[t];
1607
+ let r = un[t];
1458
1608
  if (!r) return console.error(`voltro db: unknown subcommand '${t}'`), 2;
1459
1609
  (process.env.DB_DIRECT_URL !== void 0 || process.env.DB_MIGRATE_URL !== void 0) && B.info("using a DIRECT (non-pooler) connection for the db-command path (DB_DIRECT_URL/DB_MIGRATE_URL set)");
1460
1610
  let i = (e) => {
1461
- rt(e) ? B.error(it) : console.error(e), process.exit(1);
1611
+ vt(e) ? B.error(yt) : console.error(e), process.exit(1);
1462
1612
  };
1463
1613
  process.on("uncaughtException", i);
1464
1614
  try {
@@ -1468,4 +1618,4 @@ export default defineMigration({
1468
1618
  }
1469
1619
  };
1470
1620
  //#endregion
1471
- export { ft as a, O as c, At as i, xe as l, U as n, rt as o, dt as r, zt as s, it as t };
1621
+ export { Dt as a, tn as i, U as n, vt as o, Et as r, dn as s, yt as t };