@voltro/cli 0.55.0 → 0.56.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 (165) hide show
  1. package/CHANGELOG.md +497 -0
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/{apiBuild-CMvLJM_K.js → apiBuild-Bdaetr37.js} +119 -88
  4. package/dist/apiBuild-Vw1figjO.js +2 -0
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-S0QOzqPT.js → build-CI36wL4R.js} +337 -312
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-fbj9GDjN.js → checkCommand-CAwFXrxA.js} +6 -6
  9. package/dist/{checkCommand-DNkY5kwF.js → checkCommand-D0QV_zM_.js} +1 -1
  10. package/dist/{clusterCmd-DrVFCzSj.js → clusterCmd-CdLB1GkT.js} +1 -1
  11. package/dist/{codegen-SIepQtUl.js → codegen-Bth5lUTU.js} +2 -1
  12. package/dist/codegen-DbH7NbCR.js +2 -0
  13. package/dist/{codegenCommand-3TDJezom.js → codegenCommand-CidbQzbv.js} +10 -10
  14. package/dist/{codemodRunner-C2zxZUIw.js → codemodRunner-BlQPfjzA.js} +222 -0
  15. package/dist/{commands-BBYJ7Q3B.js → commands-CWjfThXv.js} +35 -35
  16. package/dist/{dashboardCommand-D2kmyCLL.js → dashboardCommand-BekcY5Ls.js} +3 -3
  17. package/dist/{dataCommand-BEPPQiTl.js → dataCommand-2pccgbIy.js} +3 -3
  18. package/dist/{dbCommand-DZTmOFT4.js → dbCommand-DpK_vQET.js} +457 -441
  19. package/dist/dbCommand-DrycGWWt.js +2 -0
  20. package/dist/{dev-DfVZaoys.js → dev-B9Gz0k85.js} +1 -1
  21. package/dist/{dev-Ca_A_S9v.js → dev-Dw263KPu.js} +2603 -2482
  22. package/dist/doctorCommand-BMWs6aVm.js +2 -0
  23. package/dist/{doctorCommand-CGZJK_4o.js → doctorCommand-aR_bFmIi.js} +353 -251
  24. package/dist/{dormancyCommand-DY2rYpTa.js → dormancyCommand-eXTQMbHU.js} +1 -1
  25. package/dist/{embeddingsCommand-BoCqZsgp.js → embeddingsCommand-CTmiQvwa.js} +1 -1
  26. package/dist/{envCommand-Bxy2fOjc.js → envCommand-BDUgV7EM.js} +12 -12
  27. package/dist/{evolveCommand-BsbZ-XDg.js → evolveCommand-YV8qW1LU.js} +2 -2
  28. package/dist/frameworkTableAssembly-CGNC0qr7.js +2 -0
  29. package/dist/{frameworkTableAssembly-Do-cf6RJ.js → frameworkTableAssembly-DNOFXfEQ.js} +92 -84
  30. package/dist/index.js +1 -1
  31. package/dist/{infoCommand-EmM3jPKD.js → infoCommand-BjVXpMlP.js} +1 -1
  32. package/dist/inspect-CNYvNXPU.js +1484 -0
  33. package/dist/inspect-S2rWy1Ys.js +2 -0
  34. package/dist/{inspectCmd-niF97fAq.js → inspectCmd-CP-G0sVK.js} +1 -1
  35. package/dist/{inspectFetch-EMuhTG_9.js → inspectFetch-BU1NyzxV.js} +36 -24
  36. package/dist/{inspectMetrics-CGF94puw.js → inspectMetrics-BY0Sjb2F.js} +19 -19
  37. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-BU8uCdys.js} +1 -1
  38. package/dist/{manifestBuild-DjX5MoXy.js → manifestBuild-CEkjfpwc.js} +1 -1
  39. package/dist/manifestBuild-DIa_s6u0.js +2 -0
  40. package/dist/{migrate-CGFZS-1a.js → migrate-SICulyz1.js} +2 -2
  41. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  42. package/dist/{probeCommand-Bs3iVBSL.js → probeCommand-6HxEkNDG.js} +2 -2
  43. package/dist/{runtimeTrace-C1BTpHGQ.js → runtimeTrace-DgYMc09E.js} +1 -1
  44. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  45. package/dist/{sdkgen-CXMwLg9n.js → sdkgen-PY-umd6O.js} +1 -1
  46. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  47. package/dist/serveCommand-BITS8Hpj.js +2 -0
  48. package/dist/{serveCommand-C7IrCD58.js → serveCommand-DIJ3ma76.js} +910 -870
  49. package/dist/serveEntry.js +1 -1
  50. package/dist/{start-EOV7s1NZ.js → start-B9NGB8gn.js} +575 -546
  51. package/dist/{start-DH7cat4-.js → start-BFQQkL1i.js} +1 -1
  52. package/dist/startEntry.js +1 -1
  53. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  54. package/dist/{test-DO27-x2P.js → test-jipIQ5Mx.js} +1 -1
  55. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-BWYDqMy6.js} +1 -1
  56. package/dist/{updateCommand-C_jN1w18.js → updateCommand-C9n_Z_oG.js} +8 -2
  57. package/dist/updateCommand-DsXEAHbd.js +2 -0
  58. package/dist/webDev-C2dRz9s5.js +2 -0
  59. package/dist/{webDev-B7vNj4Bq.js → webDev-C53hJdcL.js} +1240 -1271
  60. package/dist/{webhooksCommand-B1LVcyO3.js → webhooksCommand-uuPu8qQX.js} +1 -1
  61. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  62. package/package.json +55 -19
  63. package/templates/AGENTS.core.md +20 -1
  64. package/templates/AGENTS.md +21 -2
  65. package/templates/agent-docs/_index.md +1 -1
  66. package/templates/agent-docs/_manifest.json +1 -1
  67. package/templates/agent-docs/cli.md +122 -0
  68. package/templates/agent-docs/data.md +145 -5
  69. package/templates/agent-docs/database/scaling.md +40 -1
  70. package/templates/agent-docs/deployment.md +53 -1
  71. package/templates/agent-docs/internationalization.md +32 -0
  72. package/templates/agent-docs/local-first-mobile.md +9 -2
  73. package/templates/agent-docs/observability.md +227 -0
  74. package/templates/agent-docs/plugins/billing.md +15 -0
  75. package/templates/agent-docs/plugins/broadcast.md +2 -1
  76. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  77. package/templates/agent-docs/plugins/row-history.md +11 -0
  78. package/templates/agent-docs/plugins.md +19 -0
  79. package/templates/agent-docs/templates/appshells.md +3 -3
  80. package/templates/agent-docs/whats-new.md +432 -73
  81. package/templates/apps/api-ai/package.json +6 -6
  82. package/templates/apps/api-auth/package.json +8 -8
  83. package/templates/apps/api-backend/package.json +7 -7
  84. package/templates/apps/api-backend-deactivation/package.json +7 -7
  85. package/templates/apps/api-backend-mail/package.json +8 -8
  86. package/templates/apps/api-backend-mariadb/package.json +9 -9
  87. package/templates/apps/api-backend-sqlite/package.json +8 -8
  88. package/templates/apps/api-backend-storage/package.json +8 -8
  89. package/templates/apps/api-cms/package.json +9 -9
  90. package/templates/apps/api-collab/package.json +8 -8
  91. package/templates/apps/api-data-advanced/package.json +8 -8
  92. package/templates/apps/api-durable/package.json +8 -8
  93. package/templates/apps/api-feature-flags/package.json +9 -9
  94. package/templates/apps/api-governance/package.json +8 -8
  95. package/templates/apps/api-kv/package.json +8 -8
  96. package/templates/apps/api-moderation/package.json +8 -8
  97. package/templates/apps/api-observability/package.json +8 -8
  98. package/templates/apps/api-ratelimit/package.json +8 -8
  99. package/templates/apps/api-rbac/package.json +8 -8
  100. package/templates/apps/api-rest/package.json +7 -7
  101. package/templates/apps/api-row-history/package.json +8 -8
  102. package/templates/apps/api-saas/package.json +11 -11
  103. package/templates/apps/api-saas-starter/package.json +10 -10
  104. package/templates/apps/api-search/package.json +8 -8
  105. package/templates/apps/api-status/package.json +8 -8
  106. package/templates/apps/api-webhooks/package.json +9 -9
  107. package/templates/apps/changelog/package.json +7 -7
  108. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  109. package/templates/apps/edge-functions/package.json +2 -2
  110. package/templates/apps/frontend-admin/package.json +7 -8
  111. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  112. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  113. package/templates/apps/frontend-app/package.json +8 -9
  114. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  115. package/templates/apps/frontend-auth/package.json +7 -8
  116. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  117. package/templates/apps/frontend-blank/package.json +6 -7
  118. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  119. package/templates/apps/frontend-cms/package.json +8 -9
  120. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  121. package/templates/apps/frontend-collab/README.md +7 -2
  122. package/templates/apps/frontend-collab/package.json +9 -10
  123. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  124. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  125. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  126. package/templates/apps/frontend-contact/package.json +7 -7
  127. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  128. package/templates/apps/frontend-dashboard/package.json +6 -7
  129. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  130. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  131. package/templates/apps/frontend-docs/package.json +8 -8
  132. package/templates/apps/frontend-i18n/package.json +6 -6
  133. package/templates/apps/frontend-landing/package.json +7 -7
  134. package/templates/apps/frontend-portal/package.json +7 -8
  135. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  136. package/templates/apps/frontend-saas/package.json +7 -8
  137. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  138. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  139. package/templates/apps/frontend-spa/package.json +6 -7
  140. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  141. package/templates/apps/frontend-ssr/package.json +6 -7
  142. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  143. package/templates/apps/frontend-ssr-api/package.json +7 -8
  144. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  145. package/templates/apps/frontend-static-blog/package.json +8 -8
  146. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  147. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  148. package/templates/apps/frontend-status/package.json +7 -8
  149. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  150. package/templates/apps/mobile-app/package.json +4 -4
  151. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  152. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  153. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  154. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  155. package/dist/apiBuild-Cl0IDx8c.js +0 -2
  156. package/dist/codegen-CN6vMM4J.js +0 -2
  157. package/dist/dbCommand-BTyBGhIA.js +0 -2
  158. package/dist/doctorCommand-djmqEcDC.js +0 -2
  159. package/dist/frameworkTableAssembly-Df2Ymp2f.js +0 -2
  160. package/dist/inspect-DCqILJ1G.js +0 -1197
  161. package/dist/inspect-DGJwpOAb.js +0 -2
  162. package/dist/manifestBuild-CJ2zvPvT.js +0 -2
  163. package/dist/serveCommand-Cjt5S9hD.js +0 -2
  164. package/dist/updateCommand-nnFjDbl4.js +0 -2
  165. package/dist/webDev-1XpVnYkW.js +0 -2
@@ -2,25 +2,41 @@ import { n as e } from "./subcommandNames-CDzfEtKV.js";
2
2
  import { n as t, r as n } from "./nodeEnvironment-cGFAj1J8.js";
3
3
  import { t as r } from "./cliError-BmdYnghb.js";
4
4
  import { n as i } from "./appModuleLoader-C9r9mxZt.js";
5
- import { a, i as o, n as s, t as c } from "./cliArgs-D4p8n7EE.js";
6
- import { r as l } from "./dialectDriver-czCHYpeH.js";
7
- import { a as u } from "./connectionConfig-Bk9IC7D0.js";
8
- import { i as d, n as f, r as p, s as m, t as h } from "./seedRunner-Dgsiwk_e.js";
9
- import { g, n as _, s as v } from "./frameworkTableAssembly-Do-cf6RJ.js";
10
- import { C as y, S as b } from "./fileConventions-l-RIXbx8.js";
11
- import { r as x, t as S } from "./inspectGateHint-4LxkNtrz.js";
5
+ import { r as a, t as o } from "./inspectGateHint-4LxkNtrz.js";
6
+ import { a as s, i as c, n as l, t as u } from "./cliArgs-D4p8n7EE.js";
7
+ import { r as d } from "./dialectDriver-czCHYpeH.js";
8
+ import { a as f } from "./connectionConfig-Bk9IC7D0.js";
9
+ import { i as p, n as m, r as h, s as g, t as _ } from "./seedRunner-DISBKow-.js";
10
+ import { g as v, n as y, s as b } from "./frameworkTableAssembly-DNOFXfEQ.js";
11
+ import { C as x, S } from "./fileConventions-l-RIXbx8.js";
12
12
  import { basename as ee, join as C, relative as w, resolve as T } from "node:path";
13
13
  import { promises as E, writeSync as te } from "node:fs";
14
14
  import { pathToFileURL as D } from "node:url";
15
- import { createLogger as O, logFormat as k } from "@voltro/logger";
16
- import { actorsTable as ne, branchNamespaceName as re, decodeFieldValue as ie, encodeFieldValue as ae, frameworkTables as oe, isEncrypted as A, isMigrationDefinition as se, isRawEncoding as ce, makeNamespaceBranchExecutor as le, provisionBranch as ue, quoteIdent as de, registerCoreTables as fe, resolveBranchMechanism as pe, teardownBranch as me } from "@voltro/database";
17
- import { Effect as j } from "effect";
18
- import { SqlClient as M } from "@effect/sql";
19
- import { DEFAULT_CDC_CHANNEL as he, applyPlan as ge, applySchema as _e, assessRollingDeployGate as ve, branchRehearsalExitCode as ye, declaredSnapshot as be, destructiveScope as xe, fingerprintSchema as Se, formatBranchRehearsal as Ce, ignoreTablesFromEnv as N, introspectSchema as P, pendingFileMigrationIds as we, planMigrations as F, recordUpToDate as Te, rehearseMigrationOnBranch as Ee, rollbackFileBasedMigration as De, rollingDeployUnsafeOps as Oe, runFileBasedMigrations as ke, shortFingerprint as I, squashMigrationPlans as Ae, unblockLossy as je } from "@voltro/database/sql";
20
- import { InMemoryDataStore as Me, makeFieldCipher as Ne } from "@voltro/runtime";
21
- import { createHash as Pe } from "node:crypto";
22
- //#region src/adoptPlan.ts
23
- var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
15
+ import { createLogger as O, logFormat as ne } from "@voltro/logger";
16
+ import { actorsTable as re, branchNamespaceName as ie, decodeFieldValue as ae, encodeFieldValue as oe, frameworkTables as se, isEncrypted as k, isMigrationDefinition as ce, isRawEncoding as le, makeNamespaceBranchExecutor as ue, provisionBranch as de, quoteIdent as fe, registerCoreTables as pe, resolveBranchMechanism as me, teardownBranch as he } from "@voltro/database";
17
+ import { InMemoryDataStore as ge, makeFieldCipher as _e } from "@voltro/runtime";
18
+ import { Effect as A } from "effect";
19
+ import { SqlClient as j } from "@effect/sql";
20
+ import { DEFAULT_CDC_CHANNEL as ve, applyPlan as ye, applySchema as be, assessRollingDeployGate as xe, branchRehearsalExitCode as Se, declaredSnapshot as Ce, destructiveScope as we, fingerprintSchema as Te, formatBranchRehearsal as Ee, ignoreTablesFromEnv as M, introspectSchema as N, pendingFileMigrationIds as De, planMigrations as P, recordUpToDate as Oe, rehearseMigrationOnBranch as ke, rollbackFileBasedMigration as Ae, rollingDeployUnsafeOps as je, runFileBasedMigrations as Me, shortFingerprint as F, squashMigrationPlans as Ne, unblockLossy as Pe } from "@voltro/database/sql";
21
+ import { createHash as Fe } from "node:crypto";
22
+ //#region src/writeAllSync.ts
23
+ var Ie = (e) => {
24
+ let t = new Int32Array(new SharedArrayBuffer(4));
25
+ Atomics.wait(t, 0, 0, e);
26
+ }, Le = (e, t) => {
27
+ let n = Buffer.from(t, "utf8"), r = 0;
28
+ for (; r < n.length;) try {
29
+ r += te(e, n, r, n.length - r);
30
+ } catch (e) {
31
+ let t = e.code;
32
+ if (t === "EAGAIN") {
33
+ Ie(1);
34
+ continue;
35
+ }
36
+ if (t === "EPIPE") return;
37
+ throw e;
38
+ }
39
+ }, Re = (e) => typeof e != "string", ze = (e, t, n, r) => {
24
40
  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
41
  r > 0 && i.push({
26
42
  kind: "target-not-empty",
@@ -37,7 +53,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
37
53
  });
38
54
  continue;
39
55
  }
40
- if (Fe(n)) {
56
+ if (Re(n)) {
41
57
  c.push({
42
58
  target: t,
43
59
  source: n.expr,
@@ -80,23 +96,23 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
80
96
  remintIds: f,
81
97
  fatal: i.some((e) => e.fatal)
82
98
  };
83
- }, Le = (e, t) => [
99
+ }, Be = (e, t) => [
84
100
  `back up '${e.from}' to a restorable dump`,
85
101
  `copy rows: INSERT INTO ${e.into} (${t.assignments.map((e) => e.target).join(", ")}) SELECT … FROM ${e.from}`,
86
102
  ...t.remintIds ? ["record old id → new id in a translation table", `rewrite every reference to '${e.from}', JSON columns included`] : [],
87
103
  "verify: row counts match and a sample round-trips",
88
104
  `drop '${e.from}' — LAST, and only after the verify`
89
- ], Re = (e, t, n) => {
105
+ ], Ve = (e, t, n) => {
90
106
  let r = [`adopt · ${e.from} (${n} row(s)) → ${e.into}`, ""];
91
107
  for (let e of t.assignments) r.push(` ${e.target.padEnd(24)} ← ${e.raw ? `${e.source} (raw)` : e.source}`);
92
108
  t.problems.length > 0 && r.push("");
93
109
  for (let e of t.problems) r.push(` ${e.fatal ? "✗" : "⚠"} ${e.detail}`);
94
110
  if (r.push(""), t.fatal) return r.push(" REFUSED — fix the problems above. Nothing was written."), r;
95
111
  r.push(" would run, in this order:");
96
- for (let [n, i] of Le(e, t).entries()) r.push(` ${n + 1}. ${i}`);
112
+ for (let [n, i] of Be(e, t).entries()) r.push(` ${n + 1}. ${i}`);
97
113
  return r;
98
- }, ze = (e) => e === "mysql" || e === "mariadb" ? (e) => `\`${e}\`` : e === "mssql" ? (e) => `[${e}]` : (e) => `"${e}"`, Be = (e) => `${e}__adopt_snapshot`, Ve = (e, t, n, r, i) => {
99
- let a = ze(n), o = Be(e.from), s = t.assignments.map((e) => e.target), c = t.assignments.map((e) => e.raw ? e.source : a(e.source));
114
+ }, He = (e) => e === "mysql" || e === "mariadb" ? (e) => `\`${e}\`` : e === "mssql" ? (e) => `[${e}]` : (e) => `"${e}"`, Ue = (e) => `${e}__adopt_snapshot`, We = (e, t, n, r, i) => {
115
+ let a = He(n), o = Ue(e.from), s = t.assignments.map((e) => e.target), c = t.assignments.map((e) => e.raw ? e.source : a(e.source));
100
116
  return i !== void 0 && (s.unshift(r), c.unshift(i)), {
101
117
  snapshot: n === "mssql" ? `SELECT * INTO ${a(o)} FROM ${a(e.from)}` : `CREATE TABLE ${a(o)} AS SELECT * FROM ${a(e.from)}`,
102
118
  copy: `INSERT INTO ${a(e.into)} (${s.map(a).join(", ")}) SELECT ${c.join(", ")} FROM ${a(e.from)}`,
@@ -106,18 +122,18 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
106
122
  drop: `DROP TABLE ${a(e.from)}`,
107
123
  dropSnapshot: `DROP TABLE ${a(o)}`
108
124
  };
109
- }, He = (e) => {
125
+ }, Ge = (e) => {
110
126
  let t = e[0];
111
127
  if (t === void 0) return 0;
112
128
  let n = t.n ?? t.N ?? Object.values(t)[0];
113
129
  return Number(n ?? 0);
114
- }, Ue = async (e, t, n, r, i, a, o = {}) => {
130
+ }, Ke = async (e, t, n, r, i, a, o = {}) => {
115
131
  if (t.fatal) throw Error("adopt: the plan was refused — nothing was run");
116
- let s = Ve(e, t, n, r, i), c = Be(e.from), l = He(await a(s.verifySource));
132
+ let s = We(e, t, n, r, i), c = Ue(e.from), l = Ge(await a(s.verifySource));
117
133
  await a(s.snapshot);
118
134
  for (let e of s.translations) await a(e);
119
135
  await a(s.copy);
120
- let u = He(await a(s.verifyTarget));
136
+ let u = Ge(await a(s.verifyTarget));
121
137
  return u === l ? o.keepSource === !0 ? {
122
138
  copied: u,
123
139
  sourceRows: l,
@@ -137,7 +153,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
137
153
  snapshotTable: c,
138
154
  sourceDropped: !1
139
155
  };
140
- }, L = [
156
+ }, I = [
141
157
  "token",
142
158
  "secret",
143
159
  "password",
@@ -146,7 +162,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
146
162
  "credential",
147
163
  "privatekey",
148
164
  "private_key"
149
- ], We = [
165
+ ], qe = [
150
166
  {
151
167
  table: "_voltro_audit_log",
152
168
  column: "subject"
@@ -191,7 +207,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
191
207
  table: "_voltro_row_history",
192
208
  column: "subjectId"
193
209
  }
194
- ], Ge = (e, t) => {
210
+ ], Je = (e, t) => {
195
211
  switch (t) {
196
212
  case "postgres": return `LOWER(CAST(${e} AS text))`;
197
213
  case "mysql":
@@ -200,17 +216,17 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
200
216
  case "sqlite":
201
217
  case "turso": return `LOWER(CAST(${e} AS TEXT))`;
202
218
  }
203
- }, Ke = (e, t, n = L) => n.map((n) => `${Ge(e, t)} LIKE '%${n}%'`).join("\n OR "), qe = ["_omitted", "__redacted"], Je = (e, t) => {
219
+ }, Ye = (e, t, n = I) => n.map((n) => `${Je(e, t)} LIKE '%${n}%'`).join("\n OR "), Xe = ["_omitted", "__redacted"], Ze = (e, t) => {
204
220
  let n = e.toLowerCase();
205
221
  return t.some((e) => n.includes(e));
206
- }, Ye = (e, t = []) => {
222
+ }, Qe = (e, t = []) => {
207
223
  if (Array.isArray(e)) {
208
- for (let n of e) Ye(n, t);
224
+ for (let n of e) Qe(n, t);
209
225
  return t;
210
226
  }
211
- if (typeof e == "object" && e) for (let [n, r] of Object.entries(e)) t.push(n), Ye(r, t);
227
+ if (typeof e == "object" && e) for (let [n, r] of Object.entries(e)) t.push(n), Qe(r, t);
212
228
  return t;
213
- }, Xe = (e) => Array.isArray(e) ? e.map(Xe) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).map(([e, t]) => [e, qe.includes(e) ? null : Xe(t)])) : e, Ze = (e, t = L) => {
229
+ }, $e = (e) => Array.isArray(e) ? e.map($e) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).map(([e, t]) => [e, Xe.includes(e) ? null : $e(t)])) : e, et = (e, t = I) => {
214
230
  let n;
215
231
  try {
216
232
  n = JSON.parse(e);
@@ -222,33 +238,33 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
222
238
  };
223
239
  }
224
240
  return {
225
- asKey: Ye(n).some((e) => Je(e, t)),
226
- redactionMarkerOnly: !Je(JSON.stringify(Xe(n)) ?? "", t),
241
+ asKey: Qe(n).some((e) => Ze(e, t)),
242
+ redactionMarkerOnly: !Ze(JSON.stringify($e(n)) ?? "", t),
227
243
  undecidable: !1
228
244
  };
229
- }, Qe = (e) => ({
245
+ }, tt = (e) => ({
230
246
  examined: e.length,
231
247
  asKey: e.filter((e) => e.asKey).length,
232
248
  redactionMarkerOnly: e.filter((e) => e.redactionMarkerOnly && !e.asKey).length,
233
249
  undecidable: e.filter((e) => e.undecidable).length
234
- }), R = (e) => {
250
+ }), L = (e) => {
235
251
  let t = e.classification;
236
252
  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
- }, $e = (e, t, n, r) => {
238
- let i = `WHERE ${Ke(t, n)}`, a = Ge(t, n).replace(/^LOWER\((.*)\)$/s, "$1");
253
+ }, nt = (e, t, n, r) => {
254
+ let i = `WHERE ${Ye(t, n)}`, a = Je(t, n).replace(/^LOWER\((.*)\)$/s, "$1");
239
255
  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
- }, et = async (e, t, n, r, i) => (await j.runPromise(e.unsafe($e(t, n, r, i)))).map((e) => {
256
+ }, rt = async (e, t, n, r, i) => (await A.runPromise(e.unsafe(nt(t, n, r, i)))).map((e) => {
241
257
  let t = Object.values(e)[0];
242
258
  return typeof t == "string" ? t : JSON.stringify(t ?? null);
243
- }), tt = async (e, t) => {
244
- let n = await j.runPromise(e.unsafe(t));
259
+ }), it = async (e, t) => {
260
+ let n = await A.runPromise(e.unsafe(t));
245
261
  return Number(Object.values(n[0] ?? { n: 0 })[0] ?? 0);
246
- }, nt = async (e, t, n, r) => {
262
+ }, at = async (e, t, n, r) => {
247
263
  let i = [];
248
264
  for (let a of n) {
249
265
  let n = r(a.table), o;
250
266
  try {
251
- o = await tt(e, `SELECT COUNT(*) AS n FROM ${n}`);
267
+ o = await it(e, `SELECT COUNT(*) AS n FROM ${n}`);
252
268
  } catch {
253
269
  i.push({
254
270
  table: a.table,
@@ -260,9 +276,9 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
260
276
  continue;
261
277
  }
262
278
  try {
263
- let s = await tt(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Ke(r(a.column), t)}`), c = [];
264
- if (s > 0) for (let i of L) try {
265
- let o = await tt(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Ke(r(a.column), t, [i])}`);
279
+ let s = await it(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Ye(r(a.column), t)}`), c = [];
280
+ if (s > 0) for (let i of I) try {
281
+ let o = await it(e, `SELECT COUNT(*) AS n FROM ${n}\n WHERE ${Ye(r(a.column), t, [i])}`);
266
282
  o > 0 && c.push({
267
283
  needle: i,
268
284
  rows: o
@@ -270,7 +286,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
270
286
  } catch {}
271
287
  let l;
272
288
  if (s > 0) try {
273
- l = Qe((await et(e, n, r(a.column), t, 500)).map((e) => Ze(e)));
289
+ l = tt((await rt(e, n, r(a.column), t, 500)).map((e) => et(e)));
274
290
  } catch {}
275
291
  i.push({
276
292
  table: a.table,
@@ -291,8 +307,8 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
291
307
  }
292
308
  }
293
309
  return i;
294
- }, rt = (e, t) => {
295
- let n = L.length, r = [`credential scan · dialect ${t}`, ""], i = /* @__PURE__ */ new Set();
310
+ }, ot = (e, t) => {
311
+ let n = I.length, r = [`credential scan · dialect ${t}`, ""], i = /* @__PURE__ */ new Set();
296
312
  for (let t of e) {
297
313
  if (t.unavailable === "column") {
298
314
  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,14 +322,14 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
306
322
  r.push(` · ${t.table} — table is EMPTY (0 rows scanned; this is not a clean bill of health)`);
307
323
  continue;
308
324
  }
309
- let e = R(t), n = (t.hits ?? 0) === 0 ? "✓" : e ? "~" : "✗";
325
+ let e = L(t), n = (t.hits ?? 0) === 0 ? "✓" : e ? "~" : "✗";
310
326
  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
327
  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 \`${qe.join("` / `")}\`, the framework's own`, " record that a `.sensitive()` column was left OUT. Nothing to purge, nothing to rotate."));
328
+ 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 \`${Xe.join("` / `")}\`, the framework's own`, " record that a `.sensitive()` column was left OUT. Nothing to purge, nothing to rotate."));
313
329
  }
314
- let a = e.reduce((e, t) => e + (R(t) ? 0 : t.hits ?? 0), 0), o = e.reduce((e, t) => e + (R(t) ? t.hits ?? 0 : 0), 0);
330
+ 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
331
  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
- }, it = (e) => e.some((e) => (e.hits ?? 0) > 0 && !R(e)) ? 1 : e.every((e) => e.unavailable !== void 0 || e.scanned === void 0 || e.scanned === 0) ? 2 : 0, at = /\.migration\.ts$/, ot = async (e, t) => {
332
+ }, st = (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, ct = /\.migration\.ts$/, lt = async (e, t) => {
317
333
  let n = [];
318
334
  for (let r of e) {
319
335
  let e;
@@ -323,7 +339,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
323
339
  t.warn("migration: failed to import", { file: r }, e);
324
340
  continue;
325
341
  }
326
- let i = (e.default && se(e.default) ? e.default : void 0) ?? Object.values(e).find(se);
342
+ let i = (e.default && ce(e.default) ? e.default : void 0) ?? Object.values(e).find(ce);
327
343
  if (!i) {
328
344
  t.warn("migration: no defineMigration export", { file: r });
329
345
  continue;
@@ -333,7 +349,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
333
349
  idInFile: i.id,
334
350
  idFromFile: ee(r).replace(/\.migration\.ts$/, "")
335
351
  });
336
- let a = await E.readFile(r, "utf8").catch(() => ""), o = Pe("sha256").update(a).digest("hex").slice(0, 16);
352
+ let a = await E.readFile(r, "utf8").catch(() => ""), o = Fe("sha256").update(a).digest("hex").slice(0, 16);
337
353
  n.push({
338
354
  file: r,
339
355
  definition: i,
@@ -341,14 +357,14 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
341
357
  });
342
358
  }
343
359
  return [...n].sort((e, t) => e.definition.id < t.definition.id ? -1 : 1);
344
- }, st = async (e) => {
345
- let t = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), n = t === "memory" ? "postgres" : t, r = n, i = t === "memory" ? void 0 : await l(n).then((e) => e.retryFilter, () => void 0);
346
- return j.runPromise(_e(oe, r, void 0, i === void 0 ? {} : { retryFilter: i }).pipe(j.provide(e)));
347
- }, ct = (e) => j.runPromise(j.gen(function* () {
348
- let e = yield* (yield* M.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(j.orElseSucceed(() => []));
360
+ }, ut = async (e) => {
361
+ let t = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), n = t === "memory" ? "postgres" : t, r = n, i = t === "memory" ? void 0 : await d(n).then((e) => e.retryFilter, () => void 0);
362
+ return A.runPromise(be(se, r, void 0, i === void 0 ? {} : { retryFilter: i }).pipe(A.provide(e)));
363
+ }, dt = (e) => A.runPromise(A.gen(function* () {
364
+ let e = yield* (yield* j.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(A.orElseSucceed(() => []));
349
365
  return new Map(e.map((e) => [e.id, e]));
350
- }).pipe(j.provide(e))), z = (e, t) => j.runPromise(j.gen(function* () {
351
- yield* (yield* M.SqlClient)`
366
+ }).pipe(A.provide(e))), R = (e, t) => A.runPromise(A.gen(function* () {
367
+ yield* (yield* j.SqlClient)`
352
368
  INSERT INTO "_voltro_migrations"
353
369
  (id, name, hash, status, "appliedAt", "durationMs", "errorMessage", "errorStack")
354
370
  VALUES
@@ -363,14 +379,14 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
363
379
  "errorStack" = EXCLUDED."errorStack",
364
380
  "updatedAt" = now()
365
381
  `;
366
- }).pipe(j.provide(e))), lt = async (e, t, n) => {
382
+ }).pipe(A.provide(e))), ft = async (e, t, n) => {
367
383
  if (e.length === 0) return {
368
384
  applied: [],
369
385
  failed: null,
370
386
  skipped: []
371
387
  };
372
- await st(t);
373
- let r = await ct(t), i = [], a = [], o = null;
388
+ await ut(t);
389
+ let r = await dt(t), i = [], a = [], o = null;
374
390
  for (let s of e) {
375
391
  let e = r.get(s.definition.id);
376
392
  if (e && e.status === "applied") {
@@ -391,7 +407,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
391
407
  name: s.definition.name
392
408
  });
393
409
  let c = Date.now(), l = [];
394
- await z(t, {
410
+ await R(t, {
395
411
  id: s.definition.id,
396
412
  name: s.definition.name,
397
413
  hash: s.hash,
@@ -405,7 +421,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
405
421
  for (let e of s.definition.steps) {
406
422
  let n = Date.now();
407
423
  try {
408
- await j.runPromise(e.apply.pipe(j.provide(t))), l.push({
424
+ await A.runPromise(e.apply.pipe(A.provide(t))), l.push({
409
425
  stepName: e.name,
410
426
  status: "applied",
411
427
  durationMs: Date.now() - n
@@ -432,7 +448,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
432
448
  ...a.stack ? { stack: a.stack } : {}
433
449
  }
434
450
  };
435
- o = f, i.push(f), await z(t, {
451
+ o = f, i.push(f), await R(t, {
436
452
  id: s.definition.id,
437
453
  name: s.definition.name,
438
454
  hash: s.hash,
@@ -451,7 +467,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
451
467
  status: "applied",
452
468
  durationMs: Date.now() - c,
453
469
  steps: l
454
- }), await z(t, {
470
+ }), await R(t, {
455
471
  id: s.definition.id,
456
472
  name: s.definition.name,
457
473
  hash: s.hash,
@@ -471,9 +487,9 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
471
487
  failed: o,
472
488
  skipped: a
473
489
  };
474
- }, ut = async (e, t, n, r = {}) => {
475
- await st(t);
476
- let i = await ct(t), a = e.filter((e) => i.get(e.definition.id)?.status === "applied");
490
+ }, pt = async (e, t, n, r = {}) => {
491
+ await ut(t);
492
+ let i = await dt(t), a = e.filter((e) => i.get(e.definition.id)?.status === "applied");
477
493
  if (a.length === 0) return n.info("migration: nothing to roll back"), {
478
494
  applied: [],
479
495
  failed: null,
@@ -491,7 +507,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
491
507
  for (let n = e.definition.steps.length - 1; n >= 0; n--) {
492
508
  let o = e.definition.steps[n], s = Date.now();
493
509
  try {
494
- await j.runPromise(o.undo.pipe(j.provide(t))), i.push({
510
+ await A.runPromise(o.undo.pipe(A.provide(t))), i.push({
495
511
  stepName: o.name,
496
512
  status: "applied",
497
513
  durationMs: Date.now() - s
@@ -526,7 +542,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
526
542
  status: "applied",
527
543
  durationMs: Date.now() - r,
528
544
  steps: i
529
- }), await z(t, {
545
+ }), await R(t, {
530
546
  id: e.definition.id,
531
547
  name: e.definition.name,
532
548
  hash: e.hash,
@@ -542,9 +558,9 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
542
558
  failed: c,
543
559
  skipped: []
544
560
  };
545
- }, dt = async (e, t) => {
546
- await st(t);
547
- let n = await ct(t);
561
+ }, mt = async (e, t) => {
562
+ await ut(t);
563
+ let n = await dt(t);
548
564
  return e.map((e) => {
549
565
  let t = n.get(e.definition.id);
550
566
  return t ? {
@@ -561,7 +577,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
561
577
  hashMatches: !0
562
578
  };
563
579
  });
564
- }, ft = (e) => {
580
+ }, ht = (e) => {
565
581
  if (!e.failed) return "";
566
582
  let t = e.failed, n = [
567
583
  `✗ Migration failed: ${t.migrationId} / step '${t.error?.stepName ?? "?"}'`,
@@ -574,22 +590,22 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
574
590
  ""
575
591
  ];
576
592
  return e.applied.length > 0 && n.unshift("", `(${e.applied.length} migration(s) applied successfully before the failure.)`), n.join("\n");
577
- }, pt = (e) => {
593
+ }, gt = (e) => {
578
594
  let t = e.split(".");
579
595
  if (t.length !== 2 || !t[0] || !t[1]) throw Error(`voltro db encrypt-column: expected <table>.<column>, got "${e}"`);
580
596
  return {
581
597
  table: t[0],
582
598
  column: t[1]
583
599
  };
584
- }, mt = (e) => 49 + 4 * Math.ceil(e / 3), ht = (e, t) => {
585
- let n = mt(e);
600
+ }, _t = (e) => 49 + 4 * Math.ceil(e / 3), vt = (e, t) => {
601
+ let n = _t(e);
586
602
  return {
587
603
  longestPlaintextBytes: e,
588
604
  longestCiphertext: n,
589
605
  declaredMaxLength: t,
590
606
  fits: t === void 0 || n <= t
591
607
  };
592
- }, gt = (e, t) => `${e.table}.${e.column} is too narrow: its longest value encodes to ${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.`, _t = (e, t) => {
608
+ }, yt = (e, t) => `${e.table}.${e.column} is too narrow: its longest value encodes to ${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.`, bt = (e, t) => {
593
609
  let n = t ? "would encrypt" : "encrypted";
594
610
  return [
595
611
  ` ${e.table}.${e.column}`,
@@ -599,25 +615,25 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
599
615
  ` null / empty ${e.empty}`,
600
616
  ` ${n.padEnd(18)} ${e.encrypted}`
601
617
  ].join("\n");
602
- }, vt = (e, t, n) => {
618
+ }, xt = (e, t, n) => {
603
619
  if (e == null) return;
604
620
  let r = typeof e == "string" ? e : String(e);
605
- if (r === "" || A(r)) return;
606
- let i = ae(t, r), a;
621
+ if (r === "" || k(r)) return;
622
+ let i = oe(t, r), a;
607
623
  try {
608
- a = ie(t, i);
624
+ a = ae(t, i);
609
625
  } catch (e) {
610
626
  throw Error(`${n.table}.${n.column}: the value could not be read back the way the app reads it (${e.message ?? String(e)}). Nothing was written.`);
611
627
  }
612
628
  if (a !== r) throw Error(`${n.table}.${n.column}: round-trip mismatch — reading the encrypted value back did not return what it was given. Nothing was written.`);
613
629
  return i;
614
- }, yt = (e) => Buffer.byteLength(e, "utf8"), bt = (e) => yt(JSON.stringify(typeof e == "string" ? e : String(e))), xt = (e, t) => {
630
+ }, St = (e) => Buffer.byteLength(e, "utf8"), Ct = (e) => St(JSON.stringify(typeof e == "string" ? e : String(e))), wt = (e, t) => {
615
631
  if (e !== void 0) try {
616
632
  return t.decrypt(e), !0;
617
633
  } catch {
618
634
  return !1;
619
635
  }
620
- }, St = (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.`, Ct = (e) => [
636
+ }, Tt = (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.`, Et = (e) => [
621
637
  "",
622
638
  " NEXT — this converted the rows that exist. New writes are still plaintext",
623
639
  " until the column carries the modifier:",
@@ -627,25 +643,25 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
627
643
  " Order does not matter: a read returns a non-ciphertext value unchanged, so",
628
644
  " the column may hold a mix while you deploy. Run this again afterwards to",
629
645
  " catch anything written in between — it skips what is already encrypted."
630
- ].join("\n"), wt = (e, t, n) => {
631
- if (typeof e != "string" || !A(e)) return;
646
+ ].join("\n"), Dt = (e, t, n) => {
647
+ if (typeof e != "string" || !k(e)) return;
632
648
  let r;
633
649
  try {
634
- r = ce(t, e);
650
+ r = le(t, e);
635
651
  } catch {
636
652
  return;
637
653
  }
638
654
  if (r !== !0) return;
639
- let i = ie(t, e);
655
+ let i = ae(t, e);
640
656
  if (typeof i != "string") return;
641
- let a = ae(t, i);
642
- if (ie(t, a) !== i) throw Error(`${n.table}.${n.column}: re-encoding did not round-trip. Nothing was written.`);
657
+ let a = oe(t, i);
658
+ if (ae(t, a) !== i) throw Error(`${n.table}.${n.column}: re-encoding did not round-trip. Nothing was written.`);
643
659
  return a;
644
- }, Tt = (e, t, n) => e === "sqlite" ? `SELECT NULL AS n FROM pragma_table_info('${t.table}') WHERE name = '${t.column}'` : `SELECT character_maximum_length AS n FROM information_schema.columns\n WHERE ${n} AND table_name = '${t.table}' AND column_name = '${t.column}'`, Et = (e) => {
660
+ }, Ot = (e, t, n) => e === "sqlite" ? `SELECT NULL AS n FROM pragma_table_info('${t.table}') WHERE name = '${t.column}'` : `SELECT character_maximum_length AS n FROM information_schema.columns\n WHERE ${n} AND table_name = '${t.table}' AND column_name = '${t.column}'`, kt = (e) => {
645
661
  if (e == null) return;
646
662
  let t = Number(e);
647
663
  return Number.isFinite(t) && t >= 0 ? t : void 0;
648
- }, B = O({ scope: "voltro:db" }), Dt = /* @__PURE__ */ new Set([
664
+ }, z = O({ scope: "voltro:db" }), At = /* @__PURE__ */ new Set([
649
665
  "node_modules",
650
666
  "dist",
651
667
  "build",
@@ -653,17 +669,17 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
653
669
  ".vite",
654
670
  ".next",
655
671
  ".git"
656
- ]), V = async (e, t) => {
672
+ ]), B = async (e, t) => {
657
673
  let n = [], r = async (e) => {
658
674
  let i = await E.readdir(e, { withFileTypes: !0 }).catch(() => []);
659
675
  for (let a of i) {
660
- if (Dt.has(a.name)) continue;
676
+ if (At.has(a.name)) continue;
661
677
  let i = C(e, a.name);
662
678
  a.isDirectory() ? await r(i) : a.isFile() && t.test(a.name) && n.push(i);
663
679
  }
664
680
  };
665
681
  return await r(e), n;
666
- }, Ot = [
682
+ }, jt = [
667
683
  "--against",
668
684
  "--batch",
669
685
  "--before",
@@ -682,63 +698,63 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
682
698
  "--store",
683
699
  "--to",
684
700
  "--token"
685
- ], H = (e) => T(c(e, Ot) ?? process.cwd()), U = () => u("migration"), kt = (e) => {
701
+ ], V = (e) => T(u(e, jt) ?? process.cwd()), H = () => f("migration"), Mt = (e) => {
686
702
  let t = e;
687
703
  if (typeof t != "object" || !t) return !1;
688
704
  if (t.code === "ERR_OUT_OF_RANGE" || t.cause?.code === "ERR_OUT_OF_RANGE") return !0;
689
705
  let n = `${t.message ?? ""} ${t.cause?.message ?? ""} ${t.stack ?? ""}`;
690
706
  return /ERR_OUT_OF_RANGE|out of range/i.test(n) && /pg-protocol|parseDataRow|buffer-reader|BufferReader/i.test(n);
691
- }, At = "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 = () => {
707
+ }, Nt = "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`.)", U = () => {
692
708
  let e = (process.env.DB_DIALECT ?? "postgres").toLowerCase();
693
709
  if (e === "memory") throw new r("voltro db: subcommands require a real dialect, not DB_DIALECT=memory.");
694
710
  return e;
695
- }, G = (e) => de(e, W()), K = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", q = async () => (await l(W())).makeSqlLayer(U()), jt = async (e) => {
696
- let t = H(e), n = e.includes("--dry-run"), r = await ot(await V(t, at), B);
697
- if (r.length === 0) return B.info("no migrations found", { root: t }), 0;
711
+ }, W = (e) => fe(e, U()), G = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", K = async () => (await d(U())).makeSqlLayer(H()), Pt = async (e) => {
712
+ let t = V(e), n = e.includes("--dry-run"), r = await lt(await B(t, ct), z);
713
+ if (r.length === 0) return z.info("no migrations found", { root: t }), 0;
698
714
  if (n) {
699
715
  let e = /* @__PURE__ */ new Set();
700
716
  try {
701
- let t = await dt(r, await q());
717
+ let t = await mt(r, await K());
702
718
  e = new Set(t.filter((e) => e.status === "applied").map((e) => e.id));
703
719
  } catch {
704
- B.warn("migrate --dry-run: could not read the migration ledger — showing ALL as pending");
720
+ z.warn("migrate --dry-run: could not read the migration ledger — showing ALL as pending");
705
721
  }
706
722
  let t = r.filter((t) => !e.has(t.definition.id));
707
- if (t.length === 0) return B.info("migrate --dry-run: nothing pending — every migration is applied"), 0;
708
- B.info(`migrate --dry-run: ${t.length} pending (nothing applied)`);
723
+ if (t.length === 0) return z.info("migrate --dry-run: nothing pending — every migration is applied"), 0;
724
+ z.info(`migrate --dry-run: ${t.length} pending (nothing applied)`);
709
725
  for (let e of t) console.log(` pending ${e.definition.id}`);
710
726
  return 0;
711
727
  }
712
- let i = await lt(r, await q(), B);
713
- return i.failed ? (process.stderr.write(ft(i) + "\n"), 1) : (B.info("migrate complete", {
728
+ let i = await ft(r, await K(), z);
729
+ return i.failed ? (process.stderr.write(ht(i) + "\n"), 1) : (z.info("migrate complete", {
714
730
  applied: i.applied.length,
715
731
  skipped: i.skipped.length
716
732
  }), 0);
717
- }, Mt = async (e) => {
718
- let t = H(e), n = s(e, "--to"), r = await ot(await V(t, at), B);
719
- if (r.length === 0) return B.info("no migrations found", { root: t }), 0;
720
- let i = await ut(r, await q(), B, n ? { to: n } : {});
721
- return i.failed ? (process.stderr.write(ft(i) + "\n"), 1) : (B.info("rollback complete", { reverted: i.applied.length }), 0);
722
- }, Nt = async (e) => {
723
- let t = await ot(await V(H(e), at), B);
733
+ }, Ft = async (e) => {
734
+ let t = V(e), n = l(e, "--to"), r = await lt(await B(t, ct), z);
735
+ if (r.length === 0) return z.info("no migrations found", { root: t }), 0;
736
+ let i = await pt(r, await K(), z, n ? { to: n } : {});
737
+ return i.failed ? (process.stderr.write(ht(i) + "\n"), 1) : (z.info("rollback complete", { reverted: i.applied.length }), 0);
738
+ }, It = async (e) => {
739
+ let t = await lt(await B(V(e), ct), z);
724
740
  if (t.length === 0) return console.log("no migrations found"), 0;
725
- let n = await dt(t, await q());
741
+ let n = await mt(t, await K());
726
742
  for (let e of n) {
727
743
  let t = e.status === "applied" ? "✓" : e.status === "failed" ? "✗" : e.status === "reverted" ? "↩" : "·", n = e.hashMatches ? "" : " (hash drift!)", r = e.appliedAt ? ` @ ${e.appliedAt.toISOString()}` : "";
728
744
  console.log(` ${t} ${e.id} [${e.status}] ${e.name}${r}${n}`);
729
745
  }
730
746
  return 0;
731
- }, Pt = async (e) => {
732
- let t = (s(e, "--store") ?? process.env.DB_DIALECT ?? "postgres").toLowerCase();
733
- 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."), {
734
- store: new Me(),
747
+ }, Lt = async (e) => {
748
+ let t = (l(e, "--store") ?? process.env.DB_DIALECT ?? "postgres").toLowerCase();
749
+ if (t === "memory") return z.warn("voltro db seed: using in-memory store (explicit opt-in via --store memory / DB_DIALECT=memory)"), z.warn(" rows written by this run will NOT persist beyond the process. set DB_DIALECT=postgres or unset to seed the real DB."), {
750
+ store: new ge(),
735
751
  dispose: async () => {},
736
752
  dialectId: "memory"
737
753
  };
738
- let n = await l(t);
739
- B.info(`voltro db seed: target store=${n.id} — rows will persist`);
754
+ let n = await d(t);
755
+ z.info(`voltro db seed: target store=${n.id} — rows will persist`);
740
756
  let r = await n.makeStore({
741
- sqlLayer: n.makeSqlLayer(U()),
757
+ sqlLayer: n.makeSqlLayer(H()),
742
758
  changeStrategy: "inline"
743
759
  }), i = r;
744
760
  return {
@@ -748,79 +764,79 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
748
764
  },
749
765
  dialectId: n.id
750
766
  };
751
- }, Ft = async (e) => {
752
- let t = H(e), n = s(e, "--id"), r = s(e, "--lifecycle"), i = await V(t, y), a = await f(i, B);
753
- if (a.length === 0) return B.info("no seeds found", { root: t }), 0;
754
- let { store: o, dispose: c, dialectId: l } = await Pt(e);
767
+ }, Rt = async (e) => {
768
+ let t = V(e), n = l(e, "--id"), r = l(e, "--lifecycle"), i = await B(t, x), a = await m(i, z);
769
+ if (a.length === 0) return z.info("no seeds found", { root: t }), 0;
770
+ let { store: o, dispose: s, dialectId: c } = await Lt(e);
755
771
  try {
756
- if (n) return +((await d(a, n, o, B)).status === "failed");
772
+ if (n) return +((await p(a, n, o, z)).status === "failed");
757
773
  let e = r ? a.filter((e) => e.definition.lifecycle === r) : a.filter((e) => e.definition.lifecycle === "boot");
758
- return +((await p(e.map((e) => ({
774
+ return +((await h(e.map((e) => ({
759
775
  ...e,
760
776
  definition: {
761
777
  ...e.definition,
762
778
  lifecycle: "boot"
763
779
  }
764
- })), o, B, { force: !0 })).filter((e) => e.status === "failed").length > 0);
780
+ })), o, z, { force: !0 })).filter((e) => e.status === "failed").length > 0);
765
781
  } finally {
766
- await c().catch((e) => {
767
- B.warn("voltro db seed: store dispose failed", { error: String(e) });
782
+ await s().catch((e) => {
783
+ z.warn("voltro db seed: store dispose failed", { error: String(e) });
768
784
  });
769
785
  }
770
- }, It = (e) => typeof e == "object" && !!e && "tableName" in e && "fields" in e && typeof e.tableName == "string", Lt = async (e) => {
771
- let t = await V(e, b), n = [];
786
+ }, zt = (e) => typeof e == "object" && !!e && "tableName" in e && "fields" in e && typeof e.tableName == "string", Bt = async (e) => {
787
+ let t = await B(e, S), n = [];
772
788
  for (let r of t) {
773
789
  let t;
774
790
  try {
775
791
  t = await import(D(r).href);
776
792
  } catch (t) {
777
- B.warn("db: failed to import schema file", {
793
+ z.warn("db: failed to import schema file", {
778
794
  file: w(e, r),
779
795
  error: String(t)
780
796
  });
781
797
  continue;
782
798
  }
783
- for (let e of Object.values(t)) It(e) && n.push(e);
799
+ for (let e of Object.values(t)) zt(e) && n.push(e);
784
800
  }
785
801
  return n;
786
- }, Rt = (e) => {
802
+ }, Vt = (e) => {
787
803
  let t = new Map(e.map((e) => [e.tableName, e]));
788
- t.has("actors") || t.set("actors", ne);
804
+ t.has("actors") || t.set("actors", re);
789
805
  let n = t.get("actors"), r = t.get("tenants");
790
- return fe({
806
+ return pe({
791
807
  actors: () => n,
792
808
  ...r === void 0 ? {} : { tenants: () => r }
793
809
  }), [...t.values()];
794
- }, zt = (e) => {
810
+ }, Ht = (e) => {
795
811
  let t = /* @__PURE__ */ new Map();
796
812
  for (let n of e) {
797
813
  let e = n.tableName;
798
814
  e !== void 0 && !t.has(e) && t.set(e, n);
799
815
  }
800
816
  return [...t.values()];
801
- }, Bt = (e) => {
802
- let t = xe(process.env.VOLTRO_DESTRUCTIVE_OK);
817
+ }, Ut = (e) => {
818
+ let t = we(process.env.VOLTRO_DESTRUCTIVE_OK);
803
819
  if (t === void 0 || !e.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy")) return {
804
820
  plan: e,
805
821
  acknowledged: !1
806
822
  };
807
- let n = je(e, t);
823
+ let n = Pe(e, t);
808
824
  return {
809
825
  plan: n,
810
826
  acknowledged: !n.operations.some((e) => e.blocked)
811
827
  };
812
- }, J = async (e, t) => j.runPromise(t.pipe(j.provide(e))), Y = async (e) => {
828
+ }, q = async (e, t) => A.runPromise(t.pipe(A.provide(e))), J = async (e) => {
813
829
  try {
814
- return await J(e, M.SqlClient.pipe(j.flatMap(P)));
830
+ return await q(e, j.SqlClient.pipe(A.flatMap(N)));
815
831
  } catch (e) {
816
832
  let t = String(e?.message ?? e);
817
- if (kt(e) || /connection error/i.test(t)) {
818
- let n = /* @__PURE__ */ Error(`${At}\n\nOriginal error: ${t}`);
833
+ if (Mt(e) || /connection error/i.test(t)) {
834
+ let n = /* @__PURE__ */ Error(`${Nt}\n\nOriginal error: ${t}`);
819
835
  throw n.cause = e, n;
820
836
  }
821
837
  throw e;
822
838
  }
823
- }, Vt = {
839
+ }, Wt = {
824
840
  safe: "\x1B[32m✓\x1B[0m",
825
841
  "needs-default": "\x1B[32m⊕\x1B[0m",
826
842
  "needs-backfill": "\x1B[33m⊕\x1B[0m",
@@ -828,7 +844,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
828
844
  lossy: "\x1B[31m✗\x1B[0m",
829
845
  "online-required": "\x1B[36m◷\x1B[0m",
830
846
  "multi-step": "\x1B[35m⇉\x1B[0m"
831
- }, Ht = (e) => {
847
+ }, Gt = (e) => {
832
848
  let t = e.op, n;
833
849
  switch (t.kind) {
834
850
  case "create-table":
@@ -890,9 +906,9 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
890
906
  break;
891
907
  case "drop-check": n = `ALTER TABLE ${t.table} DROP CHECK ${t.column}`;
892
908
  }
893
- let r = Vt[e.classification], i = e.reason ? ` # ${e.reason}` : "", a = e.blocked ? `\n ! ${e.blocked.fix}` : "";
909
+ let r = Wt[e.classification], i = e.reason ? ` # ${e.reason}` : "", a = e.blocked ? `\n ! ${e.blocked.fix}` : "";
894
910
  return ` ${r} ${n}${i}${a}`;
895
- }, Ut = async (e, t) => {
911
+ }, Kt = async (e, t) => {
896
912
  let n = e.operations.filter((e) => e.classification === "needs-default" && e.op.kind === "add-column");
897
913
  if (n.length === 0) return;
898
914
  let r = [];
@@ -901,7 +917,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
901
917
  if (i === void 0 || a === void 0) continue;
902
918
  let o = 0;
903
919
  try {
904
- let e = await J(t, M.SqlClient.pipe(j.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${de(i, W())}`))));
920
+ let e = await q(t, j.SqlClient.pipe(A.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${fe(i, U())}`))));
905
921
  o = Number(Object.values(e[0] ?? { n: 0 })[0] ?? 0);
906
922
  } catch {
907
923
  continue;
@@ -913,28 +929,28 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
913
929
  for (let e of r) console.log(e);
914
930
  console.log(" (the shape is correct either way — this is the VALUE a state diff cannot know)");
915
931
  }
916
- }, Wt = async (e, t) => {
917
- if (W() !== "postgres") return;
918
- let n = he, r;
932
+ }, qt = async (e, t) => {
933
+ if (U() !== "postgres") return;
934
+ let n = ve, r;
919
935
  try {
920
- r = await J(t, M.SqlClient.pipe(j.flatMap((t) => m(t, e, n))));
936
+ r = await q(t, j.SqlClient.pipe(A.flatMap((t) => g(t, e, n))));
921
937
  } catch {
922
938
  return;
923
939
  }
924
940
  let { drift: i, statements: a } = r;
925
941
  if (a.length === 0) return;
926
- 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)");
942
+ z.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)");
927
943
  let o = 0;
928
- for (let e of a) await J(t, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(e)))), o += 1;
929
- B.info(`db apply: change triggers converged (${o} statement(s))`, {
944
+ for (let e of a) await q(t, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(e)))), o += 1;
945
+ z.info(`db apply: change triggers converged (${o} statement(s))`, {
930
946
  installed: i.missing.length,
931
947
  removed: i.stale.length,
932
948
  functionReplaced: i.functionOutdated
933
949
  });
934
- }, X = (e) => {
950
+ }, Y = (e) => {
935
951
  let t = e.summary, n = e.operations.length;
936
- if (k() === "json") {
937
- B.info(`schema diff: ${n} operation${n === 1 ? "" : "s"}, ${t.blocked} blocked${n === 0 ? " — schema is up to date" : ""}`, {
952
+ if (ne() === "json") {
953
+ z.info(`schema diff: ${n} operation${n === 1 ? "" : "s"}, ${t.blocked} blocked${n === 0 ? " — schema is up to date" : ""}`, {
938
954
  operations: n,
939
955
  blocked: t.blocked,
940
956
  safe: t.safe,
@@ -942,23 +958,23 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
942
958
  needsBackfill: t.needsBackfill,
943
959
  rename: t.needsRenameAnnotation,
944
960
  lossy: t.lossy,
945
- ops: e.operations.map((e) => Ht(e).trim()),
961
+ ops: e.operations.map((e) => Gt(e).trim()),
946
962
  fingerprintLive: e.fromFingerprint.slice(0, 16),
947
963
  fingerprintDeclared: e.toFingerprint.slice(0, 16)
948
- }), Gt(e);
964
+ }), Jt(e);
949
965
  return;
950
966
  }
951
967
  if (console.log(`\nschema diff: ${n} operation${n === 1 ? "" : "s"}, ${t.blocked} blocked\n`), n === 0) {
952
968
  console.log(" (schema is up to date)\n");
953
969
  return;
954
970
  }
955
- for (let t of e.operations) console.log(Ht(t));
956
- 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: live ${e.fromFingerprint.slice(0, 16)} · declared ${e.toFingerprint.slice(0, 16)}`), console.log(" (measured differently — a live hash never equals a declared one. The plan above is"), console.log(" what says whether they agree; these two are not meant to match.)\n"), Gt(e);
957
- }, Gt = (e) => {
958
- let t = Oe(e.operations);
971
+ for (let t of e.operations) console.log(Gt(t));
972
+ 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: live ${e.fromFingerprint.slice(0, 16)} · declared ${e.toFingerprint.slice(0, 16)}`), console.log(" (measured differently — a live hash never equals a declared one. The plan above is"), console.log(" what says whether they agree; these two are not meant to match.)\n"), Jt(e);
973
+ }, Jt = (e) => {
974
+ let t = je(e.operations);
959
975
  if (t.length !== 0) {
960
- if (k() === "json") {
961
- B.warn(`${t.length} operation(s) UNSAFE under a rolling deploy — old code breaks against the new schema`, {
976
+ if (ne() === "json") {
977
+ z.warn(`${t.length} operation(s) UNSAFE under a rolling deploy — old code breaks against the new schema`, {
962
978
  unsafe: t.map((e) => ({
963
979
  kind: e.op.op.kind,
964
980
  reason: e.reason,
@@ -972,204 +988,204 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
972
988
  for (let e of t) console.log(` • ${e.op.op.kind}: ${e.reason}`), console.log(` → ${e.remedy}`);
973
989
  console.log(" Deploy with a maintenance window / scale-to-zero, or split into"), console.log(" expand → deploy → contract. See docs: deployment/production-hardening.\n");
974
990
  }
975
- }, Kt = (e, t) => {
976
- let n = ve({
991
+ }, Yt = (e, t) => {
992
+ let n = xe({
977
993
  enabled: process.env.VOLTRO_ROLLING_DEPLOY === "1",
978
994
  forced: t.includes("--force"),
979
- unsafeCount: Oe(e.operations).length
995
+ unsafeCount: je(e.operations).length
980
996
  });
981
- return n.refuse ? (B.error(`db apply: ${n.message}`), !0) : (n.warnForced && B.warn(`db apply: ${n.message}`), !1);
982
- }, qt = (e) => {
983
- let t = s(e, "--online-after") ?? process.env.VOLTRO_ONLINE_THRESHOLD;
997
+ return n.refuse ? (z.error(`db apply: ${n.message}`), !0) : (n.warnForced && z.warn(`db apply: ${n.message}`), !1);
998
+ }, Xt = (e) => {
999
+ let t = l(e, "--online-after") ?? process.env.VOLTRO_ONLINE_THRESHOLD;
984
1000
  if (t === void 0) return;
985
1001
  let n = Number(t);
986
1002
  if (!Number.isInteger(n) || n < 0) throw Error(`--online-after / VOLTRO_ONLINE_THRESHOLD must be a non-negative integer, got "${t}"`);
987
1003
  return n;
988
- }, Z = async (e) => {
989
- let t = await Lt(e);
1004
+ }, X = async (e) => {
1005
+ let t = await Bt(e);
990
1006
  if (t.length === 0) return;
991
- let n = await _({ root: e });
992
- return Rt(zt([
1007
+ let n = await y({ root: e });
1008
+ return Vt(Ht([
993
1009
  ...t,
994
- ...oe,
1010
+ ...se,
995
1011
  ...n
996
1012
  ]));
997
- }, Q = async (e, t, n) => {
1013
+ }, Z = async (e, t, n) => {
998
1014
  let r;
999
1015
  try {
1000
- let t = await v(e);
1001
- await J(n, g(t, (e, t) => {
1002
- B.info(`db apply: ${e}`, t ?? {});
1016
+ let t = await b(e);
1017
+ await q(n, v(t, (e, t) => {
1018
+ z.info(`db apply: ${e}`, t ?? {});
1003
1019
  }));
1004
1020
  } catch (e) {
1005
1021
  r = e;
1006
1022
  }
1007
- return await Wt(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);
1008
- }, Jt = async (e, t) => {
1009
- let n = { close: async () => {} }, r = await V(e, y);
1023
+ return await qt(t, n), r === void 0 ? 0 : (z.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);
1024
+ }, Zt = async (e, t) => {
1025
+ let n = { close: async () => {} }, r = await B(e, x);
1010
1026
  if (r.length === 0) return n;
1011
- let i = await f(r, B), a = i.filter((e) => e.definition.lifecycle === "onSchemaChange");
1027
+ let i = await m(r, z), a = i.filter((e) => e.definition.lifecycle === "onSchemaChange");
1012
1028
  if (a.length === 0) return n;
1013
- let { store: o, dispose: s } = await Pt(t), c = h(i, o, B.child("seeds"));
1014
- return B.info(`db apply: ${a.length} onSchemaChange seed(s) armed for this apply`, { ids: a.map((e) => e.definition.id) }), { close: async () => {
1029
+ let { store: o, dispose: s } = await Lt(t), c = _(i, o, z.child("seeds"));
1030
+ return z.info(`db apply: ${a.length} onSchemaChange seed(s) armed for this apply`, { ids: a.map((e) => e.definition.id) }), { close: async () => {
1015
1031
  c(), await s().catch((e) => {
1016
- B.warn("db apply: seed store dispose failed", { error: String(e) });
1032
+ z.warn("db apply: seed store dispose failed", { error: String(e) });
1017
1033
  });
1018
1034
  } };
1019
- }, Yt = async (e) => {
1020
- let t = qt(e), n = H(e), r = await Z(n);
1021
- if (r === void 0) return B.warn("db plan: no schema files found", {
1035
+ }, Qt = async (e) => {
1036
+ let t = Xt(e), n = V(e), r = await X(n);
1037
+ if (r === void 0) return z.warn("db plan: no schema files found", {
1022
1038
  root: n,
1023
1039
  hint: "looked for *.entity.ts / *.schema.ts / schema.ts"
1024
1040
  }), 1;
1025
- let i = s(e, "--against");
1041
+ let i = l(e, "--against");
1026
1042
  if (i) {
1027
- let n = i, a = s(e, "--token") ?? process.env.VOLTRO_INSPECT_TOKEN, o = { accept: "application/json" };
1028
- a && (o.authorization = `Bearer ${a}`);
1043
+ let n = i, s = l(e, "--token") ?? process.env.VOLTRO_INSPECT_TOKEN, c = { accept: "application/json" };
1044
+ s && (c.authorization = `Bearer ${s}`);
1029
1045
  try {
1030
- let e = n.endsWith("/_voltro/inspect/migrations") ? n : `${n.replace(/\/+$/, "")}/_voltro/inspect/migrations`, i = await fetch(e, { headers: o });
1031
- if (!i.ok) return B.error(`db plan --against: remote returned ${i.status}`, { url: e }), x(i.status) && console.error(` ${S(i.status)}`), 1;
1032
- let a = (await i.json()).drift?.liveSnapshot;
1033
- if (!a) return B.error("db plan --against: remote inspect payload missing drift.liveSnapshot", { url: e }), 1;
1034
- let s = F({
1046
+ let e = n.endsWith("/_voltro/inspect/migrations") ? n : `${n.replace(/\/+$/, "")}/_voltro/inspect/migrations`, i = await fetch(e, { headers: c });
1047
+ if (!i.ok) return z.error(`db plan --against: remote returned ${i.status}`, { url: e }), a(i.status) && console.error(` ${o(i.status)}`), 1;
1048
+ let s = (await i.json()).drift?.liveSnapshot;
1049
+ if (!s) return z.error("db plan --against: remote inspect payload missing drift.liveSnapshot", { url: e }), 1;
1050
+ let l = P({
1035
1051
  declared: r,
1036
- live: a,
1037
- dialect: W(),
1038
- ...N(),
1052
+ live: s,
1053
+ dialect: U(),
1054
+ ...M(),
1039
1055
  ...t === void 0 ? {} : { onlineAfter: t }
1040
1056
  });
1041
- return console.log(`\n[--against ${e}] — diff vs remote live schema:\n`), X(s), s.summary.blocked > 0 ? 2 : 0;
1057
+ return console.log(`\n[--against ${e}] — diff vs remote live schema:\n`), Y(l), l.summary.blocked > 0 ? 2 : 0;
1042
1058
  } catch (e) {
1043
- return B.error(`db plan --against: ${e.message}`), 1;
1059
+ return z.error(`db plan --against: ${e.message}`), 1;
1044
1060
  }
1045
1061
  }
1046
- let a = await Y(await q()), o = F({
1062
+ let s = await J(await K()), c = P({
1047
1063
  declared: r,
1048
- live: a,
1049
- dialect: W(),
1050
- ...N(),
1064
+ live: s,
1065
+ dialect: U(),
1066
+ ...M(),
1051
1067
  ...t === void 0 ? {} : { onlineAfter: t }
1052
1068
  });
1053
- return e.includes("--json") ? (te(1, `${JSON.stringify(o, null, 2)}\n`), o.summary.blocked > 0 ? 2 : 0) : (X(o), o.summary.blocked > 0 ? 2 : 0);
1054
- }, $ = n, Xt = async (e, t, n) => {
1069
+ return e.includes("--json") ? (Le(1, `${JSON.stringify(c, null, 2)}\n`), c.summary.blocked > 0 ? 2 : 0) : (Y(c), c.summary.blocked > 0 ? 2 : 0);
1070
+ }, Q = n, $t = async (e, t, n) => {
1055
1071
  let r;
1056
1072
  try {
1057
1073
  let t = await E.readFile(T(e), "utf8");
1058
1074
  r = JSON.parse(t);
1059
1075
  } catch (t) {
1060
- return B.error(`db apply --plan: cannot read/parse plan file '${e}': ${t.message}`), 1;
1076
+ return z.error(`db apply --plan: cannot read/parse plan file '${e}': ${t.message}`), 1;
1061
1077
  }
1062
- 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;
1063
- let i = await Z(n);
1064
- if (i === void 0) return B.warn("db apply --plan: no schema files found", { root: n }), 1;
1065
- let a = await q(), o = await J(a, M.SqlClient.pipe(j.flatMap((e) => we(e, n)))).catch(() => []);
1066
- if (o.length > 0) return B.error(`db apply --plan: refusing — ${o.length} pending file-based migration(s).`, {
1078
+ if (!Array.isArray(r?.operations) || typeof r?.fromFingerprint != "string" || typeof r?.toFingerprint != "string") return z.error(`db apply --plan: '${e}' is not a valid plan file (expected the output of \`voltro db plan --json\`).`), 1;
1079
+ let i = await X(n);
1080
+ if (i === void 0) return z.warn("db apply --plan: no schema files found", { root: n }), 1;
1081
+ let a = await K(), o = await q(a, j.SqlClient.pipe(A.flatMap((e) => De(e, n)))).catch(() => []);
1082
+ if (o.length > 0) return z.error(`db apply --plan: refusing — ${o.length} pending file-based migration(s).`, {
1067
1083
  pending: o,
1068
1084
  why: "file migrations perform changes a state diff cannot infer, so they change the shape this plan was computed against",
1069
1085
  fix: "voltro db files . && voltro db plan --json > plan.json && voltro db apply --plan plan.json"
1070
1086
  }), 1;
1071
- let c = await Y(a), l = F({
1087
+ let s = await J(a), c = P({
1072
1088
  declared: i,
1073
- live: c,
1074
- dialect: W(),
1075
- ...N()
1089
+ live: s,
1090
+ dialect: U(),
1091
+ ...M()
1076
1092
  });
1077
- if (l.fromFingerprint !== r.fromFingerprint) return B.error("db apply --plan: refusing — the live schema has drifted since this plan was generated.", {
1093
+ if (c.fromFingerprint !== r.fromFingerprint) return z.error("db apply --plan: refusing — the live schema has drifted since this plan was generated.", {
1078
1094
  planFrom: r.fromFingerprint.slice(0, 16),
1079
- live: l.fromFingerprint.slice(0, 16),
1095
+ live: c.fromFingerprint.slice(0, 16),
1080
1096
  fix: "regenerate against the current live schema: voltro db plan --json > plan.json"
1081
1097
  }), 2;
1082
- if (l.toFingerprint !== r.toFingerprint) return B.error("db apply --plan: refusing — the declared schema differs from what this plan targets.", {
1098
+ if (c.toFingerprint !== r.toFingerprint) return z.error("db apply --plan: refusing — the declared schema differs from what this plan targets.", {
1083
1099
  planTo: r.toFingerprint.slice(0, 16),
1084
- declared: l.toFingerprint.slice(0, 16),
1100
+ declared: c.toFingerprint.slice(0, 16),
1085
1101
  fix: "the schema files changed since the plan was generated — regenerate the plan"
1086
1102
  }), 2;
1087
- let u = Bt(l), d = u.plan;
1088
- if (d.summary.blocked > 0 && !u.acknowledged) return X(d), B.error(`db apply --plan: refusing — ${l.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;
1089
- if (u.acknowledged && B.warn("db apply --plan: proceeding with acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)"), Kt(d, t)) return 2;
1103
+ let u = Ut(c), d = u.plan;
1104
+ if (d.summary.blocked > 0 && !u.acknowledged) return Y(d), z.error(`db apply --plan: refusing — ${c.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (z.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), z.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1105
+ if (u.acknowledged && z.warn("db apply --plan: proceeding with acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)"), Yt(d, t)) return 2;
1090
1106
  if (d.operations.length === 0) {
1091
- let e = await J(a, M.SqlClient.pipe(j.flatMap((e) => Te(e, d, {
1107
+ let e = await q(a, j.SqlClient.pipe(A.flatMap((e) => Oe(e, d, {
1092
1108
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1093
- environment: $(),
1109
+ environment: Q(),
1094
1110
  source: "file"
1095
1111
  }))));
1096
- return B.info(e === "recorded" ? `db apply --plan: schema is up to date — no DDL to apply, recorded fingerprint=${d.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);
1112
+ return z.info(e === "recorded" ? `db apply --plan: schema is up to date — no DDL to apply, recorded fingerprint=${d.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)"), Z(n, i, a);
1097
1113
  }
1098
- X(d);
1099
- let f = s(t, "--note"), p = await J(a, M.SqlClient.pipe(j.flatMap((e) => ge(e, d, {
1114
+ Y(d);
1115
+ let f = l(t, "--note"), p = await q(a, j.SqlClient.pipe(A.flatMap((e) => ye(e, d, {
1100
1116
  declared: i,
1101
1117
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1102
- environment: $(),
1118
+ environment: Q(),
1103
1119
  source: "file",
1104
1120
  ...f ? { notes: f } : {},
1105
- replan: (e) => P(e).pipe(j.map((e) => F({
1121
+ replan: (e) => N(e).pipe(A.map((e) => P({
1106
1122
  declared: i,
1107
1123
  live: e,
1108
- dialect: W(),
1109
- ...N()
1124
+ dialect: U(),
1125
+ ...M()
1110
1126
  })))
1111
1127
  }))));
1112
- return B.info(`db apply --plan: applied ${p.appliedOps} op(s) in ${p.durationMs}ms`, {
1128
+ return z.info(`db apply --plan: applied ${p.appliedOps} op(s) in ${p.durationMs}ms`, {
1113
1129
  id: p.id,
1114
1130
  fingerprint: p.fingerprint.slice(0, 16)
1115
- }), Q(n, i, a);
1116
- }, Zt = async (e) => {
1117
- let t = H(e), n = await Jt(t, e);
1131
+ }), Z(n, i, a);
1132
+ }, en = async (e) => {
1133
+ let t = V(e), n = await Zt(t, e);
1118
1134
  try {
1119
- return await Qt(e, t);
1135
+ return await tn(e, t);
1120
1136
  } finally {
1121
1137
  await n.close();
1122
1138
  }
1123
- }, Qt = async (e, n) => {
1124
- let r = qt(e), i = s(e, "--plan");
1125
- if (i) return Xt(i, e, n);
1126
- if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error(`voltro db apply: refusing — auto-apply on prod is not allowed.${t()}`, { fix: "in production, schema changes go through `voltro db plan --json > plan.json`, then `voltro db apply --plan plan.json` as an explicit deploy step" }), 3;
1127
- let a = await Z(n);
1128
- if (a === void 0) return B.warn("db apply: no schema files found", { root: n }), 1;
1129
- let o = await q(), c = await hn(n, o);
1130
- if ("failed" in c) return B.error("db apply: a file-based migration FAILED — the schema diff was NOT run", {
1131
- failed: c.failed,
1139
+ }, tn = async (e, n) => {
1140
+ let r = Xt(e), i = l(e, "--plan");
1141
+ if (i) return $t(i, e, n);
1142
+ if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return z.error(`voltro db apply: refusing — auto-apply on prod is not allowed.${t()}`, { fix: "in production, schema changes go through `voltro db plan --json > plan.json`, then `voltro db apply --plan plan.json` as an explicit deploy step" }), 3;
1143
+ let a = await X(n);
1144
+ if (a === void 0) return z.warn("db apply: no schema files found", { root: n }), 1;
1145
+ let o = await K(), s = await vn(n, o);
1146
+ if ("failed" in s) return z.error("db apply: a file-based migration FAILED — the schema diff was NOT run", {
1147
+ failed: s.failed,
1132
1148
  fix: "fix the migration and re-run; `voltro db files` runs them alone"
1133
1149
  }), 1;
1134
- let l = await Y(o), u = F({
1150
+ let c = await J(o), u = P({
1135
1151
  declared: a,
1136
- live: l,
1137
- dialect: W(),
1138
- ...N(),
1152
+ live: c,
1153
+ dialect: U(),
1154
+ ...M(),
1139
1155
  ...r === void 0 ? {} : { onlineAfter: r }
1140
1156
  });
1141
- X(u), await Ut(u, o);
1142
- let d = Bt(u), f = d.plan;
1143
- if (f.summary.blocked > 0 && !d.acknowledged) return B.error(`db apply: refusing — ${f.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;
1144
- if (d.acknowledged && B.warn(`db apply: proceeding with ${u.summary.blocked} acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)`), Kt(f, e)) return 2;
1157
+ Y(u), await Kt(u, o);
1158
+ let d = Ut(u), f = d.plan;
1159
+ if (f.summary.blocked > 0 && !d.acknowledged) return z.error(`db apply: refusing — ${f.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (z.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), z.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1160
+ if (d.acknowledged && z.warn(`db apply: proceeding with ${u.summary.blocked} acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)`), Yt(f, e)) return 2;
1145
1161
  if (f.operations.length === 0) {
1146
- B.info("db apply: schema is up to date — no DDL to apply (change triggers are reconciled separately below)");
1147
- let t = await J(o, M.SqlClient.pipe(j.flatMap((e) => Te(e, f, {
1162
+ z.info("db apply: schema is up to date — no DDL to apply (change triggers are reconciled separately below)");
1163
+ let t = await q(o, j.SqlClient.pipe(A.flatMap((e) => Oe(e, f, {
1148
1164
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:apply",
1149
- environment: $(),
1165
+ environment: Q(),
1150
1166
  source: "auto-diff"
1151
1167
  }))));
1152
- return t === "recorded" && B.info(`db apply: recorded fingerprint=${f.toFingerprint.slice(0, 16)} (0 operations)`), await un(o), s(e, "--note") !== void 0 && t !== "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.", { hint: "to record the CURRENT live schema as the accepted baseline, use `voltro db drift --accept`" }), Q(n, a, o);
1168
+ return t === "recorded" && z.info(`db apply: recorded fingerprint=${f.toFingerprint.slice(0, 16)} (0 operations)`), await pn(o), l(e, "--note") !== void 0 && t !== "recorded" && z.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.", { hint: "to record the CURRENT live schema as the accepted baseline, use `voltro db drift --accept`" }), Z(n, a, o);
1153
1169
  }
1154
- let p = s(e, "--note"), m = await J(o, M.SqlClient.pipe(j.flatMap((e) => ge(e, f, {
1170
+ let p = l(e, "--note"), m = await q(o, j.SqlClient.pipe(A.flatMap((e) => ye(e, f, {
1155
1171
  declared: a,
1156
1172
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user",
1157
- environment: $(),
1173
+ environment: Q(),
1158
1174
  source: "auto-diff",
1159
1175
  ...p ? { notes: p } : {},
1160
- replan: (e) => P(e).pipe(j.map((e) => F({
1176
+ replan: (e) => N(e).pipe(A.map((e) => P({
1161
1177
  declared: a,
1162
1178
  live: e,
1163
- dialect: W(),
1164
- ...N(),
1179
+ dialect: U(),
1180
+ ...M(),
1165
1181
  ...r === void 0 ? {} : { onlineAfter: r }
1166
1182
  })))
1167
1183
  }))));
1168
- return B.info(`db apply: applied ${m.appliedOps} op(s) in ${m.durationMs}ms`, {
1184
+ return z.info(`db apply: applied ${m.appliedOps} op(s) in ${m.durationMs}ms`, {
1169
1185
  id: m.id,
1170
1186
  fingerprint: m.fingerprint.slice(0, 16)
1171
- }), Q(n, a, o);
1172
- }, $t = (e) => {
1187
+ }), Z(n, a, o);
1188
+ }, nn = (e) => {
1173
1189
  let t = [];
1174
1190
  for (let n of e.tables) for (let e of n.columns) {
1175
1191
  let r = e.references;
@@ -1182,7 +1198,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1182
1198
  });
1183
1199
  }
1184
1200
  return t;
1185
- }, en = (e) => {
1201
+ }, rn = (e) => {
1186
1202
  let t = [];
1187
1203
  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({
1188
1204
  table: n.name,
@@ -1191,7 +1207,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1191
1207
  name: e.name
1192
1208
  });
1193
1209
  return t;
1194
- }, tn = (e, t) => {
1210
+ }, an = (e, t) => {
1195
1211
  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)))];
1196
1212
  return {
1197
1213
  ...t,
@@ -1201,57 +1217,57 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1201
1217
  blocked: 0
1202
1218
  }
1203
1219
  };
1204
- }, nn = (e) => {
1220
+ }, on = (e) => {
1205
1221
  if (e === void 0) return "empty";
1206
1222
  if (e === "empty" || e === "copy") return e;
1207
1223
  throw e === "fresh" ? new r("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 r(`voltro db branch: --seed must be one of empty|copy, got "${e}"`);
1208
- }, rn = (e) => {
1224
+ }, sn = (e) => {
1209
1225
  if (e !== void 0) {
1210
1226
  if (e === "namespace" || e === "neon-cow") return e;
1211
1227
  throw new r(`voltro db branch: --prefer must be one of namespace|neon-cow, got "${e}"`);
1212
1228
  }
1213
- }, an = async (e) => {
1214
- let t = H(e), n = nn(s(e, "--seed")), i = rn(s(e, "--prefer")), a = e.includes("--keep"), o = e.includes("--json"), c = qt(e), u = W();
1215
- 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;
1216
- let d = await Z(t);
1217
- if (d === void 0) return B.warn("db branch: no schema files found", {
1229
+ }, cn = async (e) => {
1230
+ let t = V(e), n = on(l(e, "--seed")), i = sn(l(e, "--prefer")), a = e.includes("--keep"), o = e.includes("--json"), s = Xt(e), c = U();
1231
+ if (c !== "postgres") return z.error(`voltro db branch: not supported on '${c}'.`), 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;
1232
+ let u = await X(t);
1233
+ if (u === void 0) return z.warn("db branch: no schema files found", {
1218
1234
  root: t,
1219
1235
  hint: "looked for *.entity.ts / *.schema.ts / schema.ts"
1220
1236
  }), 1;
1221
- let f = U(), p = pe({
1237
+ let f = H(), p = me({
1222
1238
  seed: n,
1223
1239
  ...f.url === void 0 ? {} : { dbUrl: f.url },
1224
1240
  ...i === void 0 ? {} : { prefer: i }
1225
1241
  });
1226
- 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 ${n === "copy" ? "every row" : "the schema only"}).`), 1;
1227
- let m = f.schema ?? "public", h = s(e, "--name") ?? ee(t), g = s(e, "--pr"), _ = g === void 0 ? 0 : Number(g);
1242
+ if (p === "neon-cow") return z.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 ${n === "copy" ? "every row" : "the schema only"}).`), 1;
1243
+ let m = f.schema ?? "public", h = l(e, "--name") ?? ee(t), g = l(e, "--pr"), _ = g === void 0 ? 0 : Number(g);
1228
1244
  if (!Number.isInteger(_) || _ < 0) throw new r(`voltro db branch: --pr must be a non-negative integer, got "${String(g)}"`);
1229
- let v = re(h, _), y = await l(u), b = y.makeSqlLayer(f), x = y.makeSqlLayer({
1245
+ let v = ie(h, _), y = await d(c), b = y.makeSqlLayer(f), x = y.makeSqlLayer({
1230
1246
  ...f,
1231
1247
  schema: v
1232
- }), S = await Y(b), C = F({
1233
- declared: d,
1248
+ }), S = await J(b), C = P({
1249
+ declared: u,
1234
1250
  live: S,
1235
- dialect: u,
1236
- ...N(),
1237
- ...c === void 0 ? {} : { onlineAfter: c }
1238
- }), w = S.tables.map((e) => e.name), T = $t(S), E = en(S), D = le({ run: (e) => J(b, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(e)), j.asVoid)) }), O = async () => F({
1239
- declared: d,
1240
- live: await Y(x),
1241
- dialect: u,
1242
- ...N(),
1243
- ...c === void 0 ? {} : { onlineAfter: c }
1244
- }), k = await Ee({
1251
+ dialect: c,
1252
+ ...M(),
1253
+ ...s === void 0 ? {} : { onlineAfter: s }
1254
+ }), w = S.tables.map((e) => e.name), T = nn(S), E = rn(S), te = ue({ run: (e) => q(b, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(e)), A.asVoid)) }), D = async () => P({
1255
+ declared: u,
1256
+ live: await J(x),
1257
+ dialect: c,
1258
+ ...M(),
1259
+ ...s === void 0 ? {} : { onlineAfter: s }
1260
+ }), O = await ke({
1245
1261
  branchId: v,
1246
1262
  mechanism: p,
1247
1263
  branchedTables: w.length,
1248
1264
  replayedForeignKeys: T.length,
1249
1265
  keep: a,
1250
1266
  log: (e) => {
1251
- o || B.info(`db branch: ${e}`);
1267
+ o || z.info(`db branch: ${e}`);
1252
1268
  },
1253
1269
  provision: async () => {
1254
- await ue({
1270
+ await de({
1255
1271
  appSlug: h,
1256
1272
  prNumber: _,
1257
1273
  seed: n,
@@ -1261,28 +1277,28 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1261
1277
  indexNames: E,
1262
1278
  prefer: "namespace",
1263
1279
  ...f.url === void 0 ? {} : { dbUrl: f.url }
1264
- }, D);
1280
+ }, te);
1265
1281
  },
1266
- fidelityPlan: async () => tn(C, await O()),
1267
- plan: O,
1282
+ fidelityPlan: async () => an(C, await D()),
1283
+ plan: D,
1268
1284
  apply: async (e) => {
1269
- await J(x, M.SqlClient.pipe(j.flatMap((t) => ge(t, e, {
1270
- declared: d,
1285
+ await q(x, j.SqlClient.pipe(A.flatMap((t) => ye(t, e, {
1286
+ declared: u,
1271
1287
  appliedBy: "cli:db-branch",
1272
- environment: $(),
1288
+ environment: Q(),
1273
1289
  source: "auto-diff",
1274
1290
  notes: `migration rehearsal on branch ${v}`,
1275
- replan: () => j.promise(O)
1291
+ replan: () => A.promise(D)
1276
1292
  }))));
1277
1293
  },
1278
- replan: async () => await O(),
1294
+ replan: async () => await D(),
1279
1295
  teardown: async () => {
1280
- await me(v, "namespace", D);
1296
+ await he(v, "namespace", te);
1281
1297
  }
1282
1298
  });
1283
- return o ? te(1, `${JSON.stringify(k, null, 2)}\n`) : console.log(`\n${Ce(k)}\n`), ye(k);
1284
- }, on = async (e) => {
1285
- let t = Math.max(1, Number(s(e, "--limit") ?? "20")), n = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => e`
1299
+ return o ? Le(1, `${JSON.stringify(O, null, 2)}\n`) : console.log(`\n${Ee(O)}\n`), Se(O);
1300
+ }, ln = async (e) => {
1301
+ let t = Math.max(1, Number(l(e, "--limit") ?? "20")), n = await q(await K(), j.SqlClient.pipe(A.flatMap((e) => e`
1286
1302
  SELECT ${e("id")}, ${e("fingerprint")}, ${e("operations")},
1287
1303
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
1288
1304
  ${e("durationMs")}, ${e("notes")}, ${e("appliedAt")}
@@ -1290,25 +1306,25 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1290
1306
  ORDER BY ${e("appliedAt")} DESC
1291
1307
  LIMIT ${t}
1292
1308
  `)));
1293
- if (n.length === 0) return B.info("db plans: no planner-based migrations applied yet"), console.log("Run `voltro db apply` after a schema change to start a plan history."), 0;
1309
+ if (n.length === 0) return z.info("db plans: no planner-based migrations applied yet"), console.log("Run `voltro db apply` after a schema change to start a plan history."), 0;
1294
1310
  console.log(`\n${n.length} plan${n.length === 1 ? "" : "s"} (newest first):\n`);
1295
1311
  for (let e of n) {
1296
1312
  let t = 0;
1297
1313
  try {
1298
- t = JSON.parse(dn(e.operations)).length;
1314
+ t = JSON.parse(mn(e.operations)).length;
1299
1315
  } catch {}
1300
- console.log(` ${e.id} fp=${I(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${fn(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1316
+ console.log(` ${e.id} fp=${F(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${hn(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1301
1317
  }
1302
1318
  return console.log(), 0;
1303
- }, sn = async (e) => {
1319
+ }, un = async (e) => {
1304
1320
  let t = e[0];
1305
1321
  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;
1306
- let n = await q(), r = await J(n, M.SqlClient.pipe(j.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1322
+ let n = await K(), r = await q(n, j.SqlClient.pipe(A.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1307
1323
  FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t}`)));
1308
1324
  if (r.length === 0) return console.error(`restore-snapshot: plan '${t}' not found`), 1;
1309
1325
  let i;
1310
1326
  try {
1311
- i = JSON.parse(dn(r[0].operations));
1327
+ i = JSON.parse(mn(r[0].operations));
1312
1328
  } catch {
1313
1329
  return console.error(`restore-snapshot: plan '${t}' has corrupted operations JSON`), 1;
1314
1330
  }
@@ -1322,9 +1338,9 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1322
1338
  if (a.length === 0 && o.length === 0) return console.log(`restore-snapshot: plan '${t}' has no drop-column / drop-table ops to restore`), 0;
1323
1339
  let s = 0;
1324
1340
  for (let e of a) {
1325
- let t = await J(n, M.SqlClient.pipe(j.flatMap((t) => t`
1341
+ let t = await q(n, j.SqlClient.pipe(A.flatMap((t) => t`
1326
1342
  SELECT column_name FROM information_schema.columns
1327
- WHERE ${t.unsafe(K(W()))}
1343
+ WHERE ${t.unsafe(G(U()))}
1328
1344
  AND table_name = ${e.table}
1329
1345
  AND column_name LIKE ${e.column + "__dropped_%"}
1330
1346
  ORDER BY column_name DESC LIMIT 1
@@ -1334,13 +1350,13 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1334
1350
  continue;
1335
1351
  }
1336
1352
  let r = t[0].column_name;
1337
- await J(n, M.SqlClient.pipe(j.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})`);
1353
+ await q(n, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(`ALTER TABLE ${W(e.table)} RENAME COLUMN ${W(r)} TO ${W(e.column)}`)))), s++, console.log(` ↩ restored ${e.table}.${e.column} (from ${r})`);
1338
1354
  }
1339
1355
  let c = 0;
1340
1356
  for (let e of o) {
1341
- let t = await J(n, M.SqlClient.pipe(j.flatMap((t) => t`
1357
+ let t = await q(n, j.SqlClient.pipe(A.flatMap((t) => t`
1342
1358
  SELECT table_name FROM information_schema.tables
1343
- WHERE ${t.unsafe(K(W()))}
1359
+ WHERE ${t.unsafe(G(U()))}
1344
1360
  AND table_name LIKE ${e.table + "__dropped_%"}
1345
1361
  ORDER BY table_name DESC LIMIT 1
1346
1362
  `)));
@@ -1349,57 +1365,57 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1349
1365
  continue;
1350
1366
  }
1351
1367
  let r = t[0].table_name;
1352
- await J(n, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`ALTER TABLE ${G(r)} RENAME TO ${G(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1368
+ await q(n, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(`ALTER TABLE ${W(r)} RENAME TO ${W(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1353
1369
  }
1354
1370
  return console.log(`\n✓ restored ${s} column(s) + ${c} table(s) from plan '${t}'\n`), 0;
1355
- }, cn = async (e) => {
1356
- let t = s(e, "--before");
1371
+ }, dn = async (e) => {
1372
+ let t = l(e, "--before");
1357
1373
  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;
1358
1374
  let n = t.replace(/[^0-9]/g, "");
1359
1375
  if (n.length < 8) return console.error(`gc-snapshots: --before must be at least a full date (YYYY-MM-DD), got "${t}"`), 2;
1360
- let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await q(), o = await J(a, M.SqlClient.pipe(j.flatMap((e) => e`
1376
+ let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await K(), o = await q(a, j.SqlClient.pipe(A.flatMap((e) => e`
1361
1377
  SELECT table_name, column_name FROM information_schema.columns
1362
- WHERE ${e.unsafe(K(W()))} AND column_name LIKE ${"%__dropped_%"}
1363
- `))), c = await J(a, M.SqlClient.pipe(j.flatMap((e) => e`
1378
+ WHERE ${e.unsafe(G(U()))} AND column_name LIKE ${"%__dropped_%"}
1379
+ `))), s = await q(a, j.SqlClient.pipe(A.flatMap((e) => e`
1364
1380
  SELECT table_name FROM information_schema.tables
1365
- WHERE ${e.unsafe(K(W()))} AND table_name LIKE ${"%__dropped_%"}
1366
- `))), l = (e) => {
1381
+ WHERE ${e.unsafe(G(U()))} AND table_name LIKE ${"%__dropped_%"}
1382
+ `))), c = (e) => {
1367
1383
  let t = /__dropped_(\d{14})$/.exec(e);
1368
1384
  return t ? t[1] : null;
1369
1385
  }, u = 0;
1370
1386
  for (let e of o) {
1371
- let t = l(e.column_name);
1372
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await J(a, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table_name)} DROP COLUMN ${G(e.column_name)}`)))), u++);
1387
+ let t = c(e.column_name);
1388
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await q(a, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(`ALTER TABLE ${W(e.table_name)} DROP COLUMN ${W(e.column_name)}`)))), u++);
1373
1389
  }
1374
- for (let e of c) {
1375
- let t = l(e.table_name);
1376
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await J(a, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`DROP TABLE ${G(e.table_name)}`)))), u++);
1390
+ for (let e of s) {
1391
+ let t = c(e.table_name);
1392
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await q(a, j.SqlClient.pipe(A.flatMap((t) => t.unsafe(`DROP TABLE ${W(e.table_name)}`)))), u++);
1377
1393
  }
1378
1394
  return console.log(`\n${i ? `[dry-run] ${u} snapshot(s) would be dropped` : `✓ dropped ${u} snapshot(s)`} (older than ${r}).\n`), 0;
1379
- }, ln = async (e) => {
1380
- let t = s(e, "--before");
1395
+ }, fn = async (e) => {
1396
+ let t = l(e, "--before");
1381
1397
  if (!t) return console.error("voltro db squash --before <iso-date> [--note \"<text>\"]"), 2;
1382
1398
  let n = t;
1383
1399
  if (Number.isNaN(new Date(n).getTime())) return console.error(`voltro db squash: --before '${n}' is not a valid ISO date`), 2;
1384
- let r = s(e, "--note"), i = H(e), a = await Z(i);
1385
- if (a === void 0) return B.warn("db squash: no schema files found", { root: i }), 1;
1386
- let o = Se(be(a)), c = await q();
1400
+ let r = l(e, "--note"), i = V(e), a = await X(i);
1401
+ if (a === void 0) return z.warn("db squash: no schema files found", { root: i }), 1;
1402
+ let o = Te(Ce(a)), s = await K();
1387
1403
  try {
1388
- let e = await J(c, Ae({
1404
+ let e = await q(s, Ne({
1389
1405
  before: n,
1390
1406
  fingerprint: o,
1391
1407
  appliedBy: process.env.USER ?? "cli",
1392
- environment: $(),
1408
+ environment: Q(),
1393
1409
  ...r === void 0 ? {} : { note: r }
1394
1410
  }));
1395
- return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${I(e.snapshotFingerprint)}\n`), 0;
1411
+ return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${F(e.snapshotFingerprint)}\n`), 0;
1396
1412
  } catch (e) {
1397
1413
  return console.error(`squash refused: ${e.message}`), 1;
1398
1414
  }
1399
- }, un = async (e) => {
1415
+ }, pn = async (e) => {
1400
1416
  try {
1401
- let t = await Y(e), n = Se(t);
1402
- await J(e, M.SqlClient.pipe(j.flatMap((e) => e`
1417
+ let t = await J(e), n = Te(t);
1418
+ await q(e, j.SqlClient.pipe(A.flatMap((e) => e`
1403
1419
  UPDATE ${e("_voltro_migration_plans")}
1404
1420
  SET ${e("liveFingerprint")} = ${n}
1405
1421
  WHERE ${e("id")} = (
@@ -1411,7 +1427,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1411
1427
  AND ${e("liveFingerprint")} IS NULL
1412
1428
  `)));
1413
1429
  } catch {}
1414
- }, dn = (e) => typeof e == "string" ? e : e == null ? "" : JSON.stringify(e), fn = (e) => e instanceof Date ? e.toISOString() : String(e ?? ""), pn = (e) => e === void 0 ? {
1430
+ }, mn = (e) => typeof e == "string" ? e : e == null ? "" : JSON.stringify(e), hn = (e) => e instanceof Date ? e.toISOString() : String(e ?? ""), gn = (e) => e === void 0 ? {
1415
1431
  accept: !1,
1416
1432
  reason: "no-declared-schema"
1417
1433
  } : e > 0 ? {
@@ -1420,38 +1436,38 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1420
1436
  } : {
1421
1437
  accept: !0,
1422
1438
  reason: "converged"
1423
- }, mn = async (e) => {
1424
- let t = e.includes("--accept"), n = await q(), r = await J(n, M.SqlClient.pipe(j.flatMap((e) => e`
1439
+ }, _n = async (e) => {
1440
+ let t = e.includes("--accept"), n = await K(), r = await q(n, j.SqlClient.pipe(A.flatMap((e) => e`
1425
1441
  SELECT * FROM ${e("_voltro_migration_plans")}
1426
1442
  ORDER BY ${e("appliedAt")} DESC
1427
1443
  LIMIT 1
1428
- `))), i = await Y(n), a = Se(i);
1429
- if (r.length === 0) return B.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${I(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1444
+ `))), i = await J(n), a = Te(i);
1445
+ if (r.length === 0) return z.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${F(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1430
1446
  let o = r[0];
1431
- 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 ${fn(o.appliedAt)}`), console.log(` live now: ${I(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;
1432
- if (o.liveFingerprint === a) return B.info(`db drift: live matches last applied (${I(a)})`), 0;
1447
+ if (o.liveFingerprint === null || o.liveFingerprint === void 0) return z.warn("db drift: no drift baseline recorded yet — cannot compare"), console.log(), console.log(` last applied: ${o.id} at ${hn(o.appliedAt)}`), console.log(` live now: ${F(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;
1448
+ if (o.liveFingerprint === a) return z.info(`db drift: live matches last applied (${F(a)})`), 0;
1433
1449
  let s = await (async () => {
1434
1450
  try {
1435
- let t = await Z(H(e));
1436
- return t === void 0 ? void 0 : F({
1451
+ let t = await X(V(e));
1452
+ return t === void 0 ? void 0 : P({
1437
1453
  declared: t,
1438
1454
  live: i,
1439
- dialect: W(),
1440
- ...N()
1455
+ dialect: U(),
1456
+ ...M()
1441
1457
  }).operations;
1442
1458
  } catch {
1443
1459
  return;
1444
1460
  }
1445
1461
  })();
1446
1462
  if (t) {
1447
- let e = pn(s?.length);
1448
- if (e.reason === "no-declared-schema") return B.error("db drift --accept: no schema files found — cannot verify the live schema is current."), 1;
1463
+ let e = gn(s?.length);
1464
+ if (e.reason === "no-declared-schema") return z.error("db drift --accept: no schema files found — cannot verify the live schema is current."), 1;
1449
1465
  if (!e.accept && s !== void 0) {
1450
- B.error(`db drift --accept: refusing — ${s.length} operation(s) still pending against your declared schema.`), console.log();
1466
+ z.error(`db drift --accept: refusing — ${s.length} operation(s) still pending against your declared schema.`), console.log();
1451
1467
  for (let e of s.slice(0, 10)) console.log(` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}`);
1452
1468
  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;
1453
1469
  }
1454
- return await J(n, M.SqlClient.pipe(j.flatMap((e) => e`
1470
+ return await q(n, j.SqlClient.pipe(A.flatMap((e) => e`
1455
1471
  UPDATE ${e("_voltro_migration_plans")}
1456
1472
  SET ${e("liveFingerprint")} = ${a}
1457
1473
  WHERE ${e("id")} = (
@@ -1460,43 +1476,43 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1460
1476
  ORDER BY ${e("appliedAt")} DESC LIMIT 1
1461
1477
  ) AS ${e("newest")}
1462
1478
  )
1463
- `))), B.info(`db drift: accepted the live schema as the baseline (${I(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;
1479
+ `))), z.info(`db drift: accepted the live schema as the baseline (${F(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;
1464
1480
  }
1465
- return B.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${I(o.liveFingerprint)} at ${fn(o.appliedAt)} (${o.id})`), console.log(` live now: ${I(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);
1466
- }, hn = async (e, t) => {
1467
- let n = $();
1481
+ return z.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${F(o.liveFingerprint)} at ${hn(o.appliedAt)} (${o.id})`), console.log(` live now: ${F(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);
1482
+ }, vn = async (e, t) => {
1483
+ let n = Q();
1468
1484
  try {
1469
- let r = await J(t, M.SqlClient.pipe(j.flatMap((t) => ke(t, {
1485
+ let r = await q(t, j.SqlClient.pipe(A.flatMap((t) => Me(t, {
1470
1486
  projectRoot: e,
1471
1487
  env: n,
1472
1488
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
1473
1489
  }))));
1474
- return r.applied.length > 0 && B.info(`db apply: applied ${r.applied.length} pending file-based migration(s) first`, { applied: r.applied.map((e) => `${e.id} (${e.durationMs}ms)`) }), { applied: r.applied.length };
1490
+ return r.applied.length > 0 && z.info(`db apply: applied ${r.applied.length} pending file-based migration(s) first`, { applied: r.applied.map((e) => `${e.id} (${e.durationMs}ms)`) }), { applied: r.applied.length };
1475
1491
  } catch (e) {
1476
1492
  return { failed: e };
1477
1493
  }
1478
- }, gn = async (e) => {
1479
- let t = H(e), n = await q(), r = $();
1480
- await J(n, _e(oe, W(), void 0, { retryFilter: (await l(W())).retryFilter }));
1481
- let i = await J(n, M.SqlClient.pipe(j.flatMap((e) => ke(e, {
1494
+ }, yn = async (e) => {
1495
+ let t = V(e), n = await K(), r = Q();
1496
+ await q(n, be(se, U(), void 0, { retryFilter: (await d(U())).retryFilter }));
1497
+ let i = await q(n, j.SqlClient.pipe(A.flatMap((e) => Me(e, {
1482
1498
  projectRoot: t,
1483
1499
  env: r,
1484
1500
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
1485
1501
  }))));
1486
- return i.applied.length === 0 ? (B.info(`db files: no pending file-based migrations (${i.skipped.length} already applied)`), 0) : (B.info(`db files: applied ${i.applied.length} migration(s)`, {
1502
+ return i.applied.length === 0 ? (z.info(`db files: no pending file-based migrations (${i.skipped.length} already applied)`), 0) : (z.info(`db files: applied ${i.applied.length} migration(s)`, {
1487
1503
  applied: i.applied.map((e) => `${e.id} (${e.durationMs}ms)`),
1488
1504
  skipped: i.skipped.length
1489
1505
  }), 0);
1490
- }, _n = async (e) => {
1491
- let n = H(e), r = c(e, Ot);
1492
- if (!r) return B.error("voltro db rollback-file <migration-id>"), 2;
1493
- 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." + t()), 3;
1494
- let i = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => De(e, {
1506
+ }, bn = async (e) => {
1507
+ let n = V(e), r = u(e, jt);
1508
+ if (!r) return z.error("voltro db rollback-file <migration-id>"), 2;
1509
+ if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return z.error("voltro db rollback-file: refusing on prod — schema rollback runs as an explicit deploy step." + t()), 3;
1510
+ let i = await q(await K(), j.SqlClient.pipe(A.flatMap((e) => Ae(e, {
1495
1511
  projectRoot: n,
1496
1512
  id: r
1497
1513
  }))));
1498
- return B.info(`db rollback-file: rolled back ${i.id} in ${i.durationMs}ms`), 0;
1499
- }, vn = () => {
1514
+ return z.info(`db rollback-file: rolled back ${i.id} in ${i.durationMs}ms`), 0;
1515
+ }, xn = () => {
1500
1516
  let e = /* @__PURE__ */ new Date();
1501
1517
  return [
1502
1518
  e.getUTCFullYear(),
@@ -1506,7 +1522,7 @@ var Fe = (e) => typeof e != "string", Ie = (e, t, n, r) => {
1506
1522
  String(e.getUTCMinutes()).padStart(2, "0"),
1507
1523
  String(e.getUTCSeconds()).padStart(2, "0")
1508
1524
  ].join("");
1509
- }, yn = (e) => e.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "migration", bn = (e, t) => `import { defineMigration, SqlClient } from '@voltro/database'
1525
+ }, Sn = (e) => e.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "migration", Cn = (e, t) => `import { defineMigration, SqlClient } from '@voltro/database'
1510
1526
  import { Effect } from 'effect'
1511
1527
 
1512
1528
  // A hand-written migration. Reach for this when the DECLARATIVE differ can't
@@ -1538,25 +1554,25 @@ export default defineMigration({
1538
1554
  }),
1539
1555
  ],
1540
1556
  })
1541
- `, xn = {
1542
- plan: Yt,
1543
- apply: Zt,
1544
- branch: an,
1545
- plans: on,
1546
- drift: mn,
1547
- files: gn,
1548
- "rollback-file": _n,
1549
- migrate: jt,
1550
- rollback: Mt,
1551
- status: Nt,
1552
- seed: Ft,
1557
+ `, $ = {
1558
+ plan: Qt,
1559
+ apply: en,
1560
+ branch: cn,
1561
+ plans: ln,
1562
+ drift: _n,
1563
+ files: yn,
1564
+ "rollback-file": bn,
1565
+ migrate: Pt,
1566
+ rollback: Ft,
1567
+ status: It,
1568
+ seed: Rt,
1553
1569
  generate: async (e) => {
1554
- let { value: t, rest: n } = a(e, "--root"), { value: r, rest: i } = a(n, "--name"), o = t ? T(t) : process.cwd(), s = yn(r ?? c(i, []) ?? "migration"), l = `${vn()}_${s}`, u = C(o, "migrations"), d = C(u, `${l}.migration.ts`);
1555
- return await E.mkdir(u, { recursive: !0 }), await E.writeFile(d, bn(l, s), "utf8"), B.info(`created ${w(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;
1570
+ let { value: t, rest: n } = s(e, "--root"), { value: r, rest: i } = s(n, "--name"), a = t ? T(t) : process.cwd(), o = Sn(r ?? u(i, []) ?? "migration"), c = `${xn()}_${o}`, l = C(a, "migrations"), d = C(l, `${c}.migration.ts`);
1571
+ return await E.mkdir(l, { recursive: !0 }), await E.writeFile(d, Cn(c, o), "utf8"), z.info(`created ${w(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;
1556
1572
  },
1557
- squash: ln,
1558
- "restore-snapshot": sn,
1559
- "gc-snapshots": cn,
1573
+ squash: fn,
1574
+ "restore-snapshot": un,
1575
+ "gc-snapshots": dn,
1560
1576
  adopt: async (e) => {
1561
1577
  let t = (t) => {
1562
1578
  let n = e.indexOf(`--${t}`);
@@ -1570,22 +1586,22 @@ export default defineMigration({
1570
1586
  into: r,
1571
1587
  map: o.map,
1572
1588
  ...o.leaveUnset ? { leaveUnset: o.leaveUnset } : {}
1573
- }, c = W(), l = await q(), u = await J(l, M.SqlClient.pipe(j.flatMap(P))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1589
+ }, c = U(), l = await K(), u = await q(l, j.SqlClient.pipe(A.flatMap(N))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1574
1590
  name: e.name,
1575
1591
  nullable: e.nullable,
1576
1592
  hasDefault: e.defaultValue !== void 0 && e.defaultValue !== null
1577
1593
  })), f = d(n), p = d(r);
1578
1594
  if (f === void 0) return console.error(`voltro db adopt: '${n}' does not exist in the database`), 1;
1579
1595
  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;
1580
- let m = async (e) => await J(l, M.SqlClient.pipe(j.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 = Ie(s, f, p, await h(r));
1581
- for (let e of Re(s, g, await h(n))) console.log(e);
1596
+ let m = async (e) => await q(l, j.SqlClient.pipe(A.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 = ze(s, f, p, await h(r));
1597
+ for (let e of Ve(s, g, await h(n))) console.log(e);
1582
1598
  if (g.fatal) return 1;
1583
1599
  if (!e.includes("--apply")) return console.log(""), console.log(" (dry run — nothing written. Re-run with --apply.)"), 0;
1584
- let _ = await Ue(s, g, c, "id", void 0, m, { keepSource: e.includes("--keep-source") });
1600
+ let _ = await Ke(s, g, c, "id", void 0, m, { keepSource: e.includes("--keep-source") });
1585
1601
  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);
1586
1602
  },
1587
1603
  "scan-credentials": async (e) => {
1588
- let t = W(), n = [];
1604
+ let t = U(), n = [];
1589
1605
  for (let t = 0; t < e.length; t += 1) {
1590
1606
  if (e[t] !== "--table") continue;
1591
1607
  let i = e[t + 1];
@@ -1596,29 +1612,29 @@ export default defineMigration({
1596
1612
  column: o
1597
1613
  });
1598
1614
  }
1599
- let i = [...We, ...n], a = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => j.promise(() => nt(e, t, i, G)))));
1600
- return console.log(rt(a, t)), it(a);
1615
+ let i = [...qe, ...n], a = await q(await K(), j.SqlClient.pipe(A.flatMap((e) => A.promise(() => at(e, t, i, W)))));
1616
+ return console.log(ot(a, t)), st(a);
1601
1617
  },
1602
1618
  "encrypt-column": async (e) => {
1603
- let t = W(), n = e.includes("--dry-run"), i = e.includes("--yes"), a = (t) => {
1619
+ let t = U(), n = e.includes("--dry-run"), i = e.includes("--yes"), a = (t) => {
1604
1620
  let n = e.indexOf(t);
1605
1621
  return n >= 0 ? e[n + 1] : void 0;
1606
- }, s = Math.max(1, Number(a("--batch") ?? 500)), c = a("--key-env") ?? "FIELD_ENCRYPTION_KEY", l = process.env[c];
1607
- if (!l) throw new r(`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.`);
1608
- let u = Ne(l), d = o(e, Ot).filter((e) => e.includes(".")).map(pt);
1622
+ }, o = Math.max(1, Number(a("--batch") ?? 500)), s = a("--key-env") ?? "FIELD_ENCRYPTION_KEY", l = process.env[s];
1623
+ if (!l) throw new r(`voltro db encrypt-column: ${s} 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.`);
1624
+ let u = _e(l), d = c(e, jt).filter((e) => e.includes(".")).map(gt);
1609
1625
  if (d.length === 0) throw new r("voltro db encrypt-column: name at least one <table>.<column>");
1610
- let f = await q(), p = [];
1626
+ let f = await K(), p = [];
1611
1627
  for (let e of d) {
1612
- let a = G(e.table), o = G(e.column), l = await J(f, M.SqlClient.pipe(j.flatMap((n) => j.promise(async () => {
1613
- let i = await j.runPromise(n.unsafe(Tt(t, e, K(t))));
1628
+ let a = W(e.table), c = W(e.column), l = await q(f, j.SqlClient.pipe(A.flatMap((n) => A.promise(async () => {
1629
+ let i = await A.runPromise(n.unsafe(Ot(t, e, G(t))));
1614
1630
  if (i.length === 0) throw new r(`voltro db encrypt-column: ${e.table}.${e.column} does not exist on this database`);
1615
- return Et(Object.values(i[0])[0]);
1616
- })))), d = await J(f, M.SqlClient.pipe(j.flatMap((e) => j.promise(async () => await j.runPromise(e.unsafe(`SELECT ${G("id")} AS id, ${o} AS v FROM ${a}`)))))), m = 0;
1617
- for (let e of d) typeof e.v != "string" || A(e.v) || (m = Math.max(m, bt(e.v)));
1618
- let h = ht(m, l);
1619
- if (!h.fits) return console.error(` ✗ ${gt(e, h)}`), 1;
1620
- if (xt(d.map((e) => e.v).find((e) => typeof e == "string" && A(e)), u) === !1) return console.error(` ✗ ${St(e, c)}`), 1;
1621
- let g = d.filter((t) => vt(t.v, u, e) !== void 0 || wt(t.v, u, e) !== void 0).length;
1631
+ return kt(Object.values(i[0])[0]);
1632
+ })))), d = await q(f, j.SqlClient.pipe(A.flatMap((e) => A.promise(async () => await A.runPromise(e.unsafe(`SELECT ${W("id")} AS id, ${c} AS v FROM ${a}`)))))), m = 0;
1633
+ for (let e of d) typeof e.v != "string" || k(e.v) || (m = Math.max(m, Ct(e.v)));
1634
+ let h = vt(m, l);
1635
+ if (!h.fits) return console.error(` ✗ ${yt(e, h)}`), 1;
1636
+ if (wt(d.map((e) => e.v).find((e) => typeof e == "string" && k(e)), u) === !1) return console.error(` ✗ ${Tt(e, s)}`), 1;
1637
+ let g = d.filter((t) => xt(t.v, u, e) !== void 0 || Dt(t.v, u, e) !== void 0).length;
1622
1638
  if (!n && !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;
1623
1639
  let _ = 0, v = 0, y = 0, b = 0, x = [];
1624
1640
  for (let t of d) {
@@ -1626,8 +1642,8 @@ export default defineMigration({
1626
1642
  y += 1;
1627
1643
  continue;
1628
1644
  }
1629
- if (typeof t.v == "string" && A(t.v)) {
1630
- let n = wt(t.v, u, e);
1645
+ if (typeof t.v == "string" && k(t.v)) {
1646
+ let n = Dt(t.v, u, e);
1631
1647
  if (n === void 0) {
1632
1648
  _ += 1;
1633
1649
  continue;
@@ -1638,7 +1654,7 @@ export default defineMigration({
1638
1654
  }), v += 1;
1639
1655
  continue;
1640
1656
  }
1641
- let n = vt(t.v, u, e);
1657
+ let n = xt(t.v, u, e);
1642
1658
  if (n === void 0) {
1643
1659
  y += 1;
1644
1660
  continue;
@@ -1648,11 +1664,11 @@ export default defineMigration({
1648
1664
  value: n
1649
1665
  }), b += 1;
1650
1666
  }
1651
- if (!n && x.length > 0) for (let t = 0; t < x.length; t += s) {
1652
- let n = x.slice(t, t + s);
1653
- await J(f, M.SqlClient.pipe(j.flatMap((t) => j.promise(async () => {
1654
- for (let r of n) await j.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1655
- })))), B.info(`encrypt-column ${e.table}.${e.column}: ${Math.min(t + n.length, x.length)}/${x.length}`);
1667
+ if (!n && x.length > 0) for (let t = 0; t < x.length; t += o) {
1668
+ let n = x.slice(t, t + o);
1669
+ await q(f, j.SqlClient.pipe(A.flatMap((t) => A.promise(async () => {
1670
+ for (let r of n) await A.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1671
+ })))), z.info(`encrypt-column ${e.table}.${e.column}: ${Math.min(t + n.length, x.length)}/${x.length}`);
1656
1672
  }
1657
1673
  p.push({
1658
1674
  table: e.table,
@@ -1665,21 +1681,21 @@ export default defineMigration({
1665
1681
  });
1666
1682
  }
1667
1683
  console.log(`field encryption · dialect ${t}${n ? " · DRY RUN, nothing written" : ""}`), console.log("");
1668
- for (let e of p) console.log(_t(e, n));
1669
- return n || console.log(Ct(d)), 0;
1684
+ for (let e of p) console.log(bt(e, n));
1685
+ return n || console.log(Et(d)), 0;
1670
1686
  }
1671
- }, Sn = (e) => Object.prototype.hasOwnProperty.call(xn, e), Cn = async (t) => {
1687
+ }, wn = (e) => Object.prototype.hasOwnProperty.call($, e), Tn = async (t) => {
1672
1688
  let [n, ...r] = t;
1673
1689
  if (!n) {
1674
1690
  console.error("voltro db <subcommand> [args]"), console.error("subcommands:");
1675
- for (let e of Object.keys(xn)) console.error(` ${e}`);
1691
+ for (let e of Object.keys($)) console.error(` ${e}`);
1676
1692
  return 1;
1677
1693
  }
1678
- if (!Sn(n)) return console.error(`voltro db: unknown subcommand '${n}'`), console.error(` known: ${e.join(", ")}`), 2;
1679
- let i = xn[n];
1680
- (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)");
1694
+ if (!wn(n)) return console.error(`voltro db: unknown subcommand '${n}'`), console.error(` known: ${e.join(", ")}`), 2;
1695
+ let i = $[n];
1696
+ (process.env.DB_DIRECT_URL !== void 0 || process.env.DB_MIGRATE_URL !== void 0) && z.info("using a DIRECT (non-pooler) connection for the db-command path (DB_DIRECT_URL/DB_MIGRATE_URL set)");
1681
1697
  let a = (e) => {
1682
- kt(e) ? B.error(At) : console.error(e), process.exit(1);
1698
+ Mt(e) ? z.error(Nt) : console.error(e), process.exit(1);
1683
1699
  };
1684
1700
  process.on("uncaughtException", a);
1685
1701
  try {
@@ -1689,4 +1705,4 @@ export default defineMigration({
1689
1705
  }
1690
1706
  };
1691
1707
  //#endregion
1692
- export { Rt as a, Cn as c, pn as i, U as n, kt as o, Lt as r, X as s, At as t };
1708
+ export { Vt as a, Tn as c, gn as i, H as n, Mt as o, Bt as r, Y as s, Nt as t };