@voltro/database 0.55.0 → 0.57.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.
package/dist/sql.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { $ as e, $t as t, Ht as n, Ut as r, a as i, at as a, c as o, d as s, en as c, et as l, g as u, h as d, i as f, it as p, o as m, r as h, s as g, tt as _, u as v, vt as y, wt as b, y as x } from "./frameworkLiveTables-CwDemhjW.js";
2
2
  import { Effect as S, Schedule as C } from "effect";
3
- import { createHash as ee } from "node:crypto";
4
- import { createLogger as te } from "@voltro/logger";
5
- import { SqlClient as w } from "@effect/sql";
6
- import { promises as ne } from "node:fs";
7
- import { join as re } from "node:path";
8
- import { pathToFileURL as ie } from "node:url";
3
+ import { createHash as w } from "node:crypto";
4
+ import { createLogger as T } from "@voltro/logger";
5
+ import { SqlClient as E } from "@effect/sql";
6
+ import { promises as ee } from "node:fs";
7
+ import { join as te } from "node:path";
8
+ import { pathToFileURL as ne } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var ae = (e, t, n, r = 400) => {
10
+ var re = (e, t, n, r = 400) => {
11
11
  let i = n, a = i.cause ?? {}, o = (e) => {
12
12
  let t = a[e];
13
13
  return t == null || t === "" ? void 0 : String(t);
@@ -38,21 +38,21 @@ var ae = (e, t, n, r = 400) => {
38
38
  let t = o(e);
39
39
  t !== void 0 && s.push(`db.${e}: ${t}`);
40
40
  }
41
- let c = oe(o("code"));
41
+ let c = ie(o("code"));
42
42
  return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
- }, oe = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, se = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, ce = (e) => e.replace(/"/g, "`"), le = (e) => typeof e == "string" ? e : e.name ?? String(e), ue = (e, t) => `_ua_${t}_${e}`.slice(0, 64), de = (e, t) => {
44
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(se)) return e;
43
+ }, ie = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, ae = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, oe = (e) => e.replace(/"/g, "`"), se = (e) => typeof e == "string" ? e : e.name ?? String(e), ce = (e, t) => `_ua_${t}_${e}`.slice(0, 64), le = (e, t) => {
44
+ if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(ae)) return e;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!se(t)) {
47
+ if (!ae(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = ce(t.where), o = [];
51
+ let a = oe(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = le(r);
53
+ let i = se(r);
54
54
  if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
55
- let s = ue(t.name, i);
55
+ let s = ce(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,73 +75,73 @@ var ae = (e, t, n, r = 400) => {
75
75
  appliedIndexes: r,
76
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
77
77
  };
78
- }, T = (e, t) => `${e}::${t}`, fe = (e, t) => {
78
+ }, D = (e, t) => `${e}::${t}`, ue = (e, t) => {
79
79
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
80
80
  n.add(e);
81
81
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
82
- for (let t of o) n.has(t.target) ? i.add(T(e, t.column)) : r.has(t.target) || a(t.target);
82
+ for (let t of o) n.has(t.target) ? i.add(D(e, t.column)) : r.has(t.target) || a(t.target);
83
83
  n.delete(e), r.add(e);
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, pe = 6322741009312437n, me = (e) => {
87
+ }, de = 6322741009312437n, fe = (e) => {
88
88
  let t = e?.trim();
89
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
90
- }, he = (e) => e?.schema === void 0 ? me(process.env.DB_SCHEMA) : me(e.schema), ge = 14695981039346656037n, _e = 1099511628211n, ve = 18446744073709551615n, ye = (e) => {
91
- let t = ge;
92
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * _e & ve;
90
+ }, pe = (e) => e?.schema === void 0 ? fe(process.env.DB_SCHEMA) : fe(e.schema), me = 14695981039346656037n, he = 1099511628211n, ge = 18446744073709551615n, _e = (e) => {
91
+ let t = me;
92
+ for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * he & ge;
93
93
  return t;
94
- }, be = (e) => {
95
- let t = me(e);
96
- return t === void 0 ? pe : ye(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
- }, E = (e) => {
98
- let t = `voltro_migration_${pe.toString(36)}`, n = me(e);
94
+ }, ve = (e) => {
95
+ let t = fe(e);
96
+ return t === void 0 ? de : _e(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
+ }, ye = (e) => {
98
+ let t = `voltro_migration_${de.toString(36)}`, n = fe(e);
99
99
  if (n === void 0) return t;
100
100
  let r = `${t}_${n}`;
101
- return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(ye(`voltro_migration_lock:${n}`) & ve).toString(16)}`;
102
- }, xe = 250, Se = () => {
101
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(_e(`voltro_migration_lock:${n}`) & ge).toString(16)}`;
102
+ }, be = 250, xe = () => {
103
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
104
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
105
- }, Ce = (e, t) => S.gen(function* () {
106
- let n = Se(), r = Date.now();
105
+ }, Se = (e, t) => S.gen(function* () {
106
+ let n = xe(), r = Date.now();
107
107
  for (;;) {
108
108
  if ((yield* e`
109
109
  SELECT pg_try_advisory_lock(${t.toString()}::bigint) AS got`)[0]?.got) return;
110
- Date.now() - r >= n && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(n / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* S.sleep(`${xe} millis`);
110
+ Date.now() - r >= n && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(n / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* S.sleep(`${be} millis`);
111
111
  }
112
- }), we = (e, t) => S.gen(function* () {
112
+ }), Ce = (e, t) => S.gen(function* () {
113
113
  yield* e`SELECT pg_advisory_unlock(${t.toString()}::bigint)`;
114
- }), Te = 30, Ee = (e, t) => S.gen(function* () {
114
+ }), we = 30, Te = (e, t) => S.gen(function* () {
115
115
  (yield* e`
116
- SELECT GET_LOCK(${t}, ${Te}) AS got`)[0]?.got !== 1 && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${Te}s (another migration is in progress, or a prior one left it held).`)));
117
- }), De = (e, t) => S.gen(function* () {
116
+ SELECT GET_LOCK(${t}, ${we}) AS got`)[0]?.got !== 1 && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${we}s (another migration is in progress, or a prior one left it held).`)));
117
+ }), Ee = (e, t) => S.gen(function* () {
118
118
  yield* e`SELECT RELEASE_LOCK(${t})`;
119
- }), Oe = 3e4, ke = (e, t) => S.gen(function* () {
119
+ }), De = 3e4, Oe = (e, t) => S.gen(function* () {
120
120
  let n = yield* e`
121
121
  DECLARE @res int;
122
122
  EXEC @res = sp_getapplock @Resource = ${t}, @LockMode = 'Exclusive',
123
- @LockOwner = 'Session', @LockTimeout = ${Oe};
123
+ @LockOwner = 'Session', @LockTimeout = ${De};
124
124
  SELECT @res AS res`;
125
125
  (n[0]?.res ?? -999) < 0 && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' (sp_getapplock returned ${n[0]?.res ?? "no row"}; another migration is in progress).`)));
126
- }), Ae = (e, t) => S.gen(function* () {
126
+ }), ke = (e, t) => S.gen(function* () {
127
127
  yield* e`EXEC sp_releaseapplock @Resource = ${t}, @LockOwner = 'Session'`;
128
- }), je = S.void, D = (e, t) => {
129
- let n = he(t);
128
+ }), Ae = S.void, je = (e, t) => {
129
+ let n = pe(t);
130
130
  return e.onDialectOrElse({
131
- mysql: () => Ee(e, E(n)),
132
- mssql: () => ke(e, E(n)),
133
- sqlite: () => je,
134
- orElse: () => Ce(e, be(n))
131
+ mysql: () => Te(e, ye(n)),
132
+ mssql: () => Oe(e, ye(n)),
133
+ sqlite: () => Ae,
134
+ orElse: () => Se(e, ve(n))
135
135
  });
136
136
  }, O = (e, t) => {
137
- let n = he(t);
137
+ let n = pe(t);
138
138
  return e.onDialectOrElse({
139
- mysql: () => De(e, E(n)),
140
- mssql: () => Ae(e, E(n)),
141
- sqlite: () => je,
142
- orElse: () => we(e, be(n))
139
+ mysql: () => Ee(e, ye(n)),
140
+ mssql: () => ke(e, ye(n)),
141
+ sqlite: () => Ae,
142
+ orElse: () => Ce(e, ve(n))
143
143
  });
144
- }, Me = (e, t, n) => S.acquireUseRelease(D(e, n), () => t, () => O(e, n).pipe(S.orDie)), Ne = (e) => e.onDialectOrElse({
144
+ }, Me = (e, t, n) => S.acquireUseRelease(je(e, n), () => t, () => O(e, n).pipe(S.orDie)), Ne = (e) => e.onDialectOrElse({
145
145
  pg: () => "postgres",
146
146
  mysql: () => "mysql",
147
147
  mssql: () => "mssql",
@@ -217,7 +217,7 @@ var ae = (e, t, n, r = 400) => {
217
217
  Object.keys(Pe);
218
218
  //#endregion
219
219
  //#region src/migrations/reactiveTriggerName.ts
220
- var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "framework_changes" ? `${qe}${e}` : `${qe}${t}_${e}`, Ye = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Xe = "voltro:notify:v2", Ze = te({ scope: "voltro:migrate" }), j = (e) => {
220
+ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "framework_changes" ? `${qe}${e}` : `${qe}${t}_${e}`, Ye = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Xe = "voltro:notify:v2", Ze = T({ scope: "voltro:migrate" }), j = (e) => {
221
221
  Ze.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
222
222
  }, M = (e, t) => {
223
223
  let n = e.type;
@@ -615,7 +615,7 @@ $$ LANGUAGE plpgsql;
615
615
  for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Je(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
616
616
  return r;
617
617
  }, mt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), ht = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), gt = (e) => {
618
- let t = new Map(e.map((e) => [e.tableName, e])), n = fe(e.map((e) => e.tableName), (e) => {
618
+ let t = new Map(e.map((e) => [e.tableName, e])), n = ue(e.map((e) => e.tableName), (e) => {
619
619
  let n = t.get(e);
620
620
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
621
621
  if (n.type !== "reference" || !n.references) return [];
@@ -626,7 +626,7 @@ $$ LANGUAGE plpgsql;
626
626
  }] : [];
627
627
  }) : [];
628
628
  }), r = [];
629
- for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(T(t.tableName, e)) && r.push({
629
+ for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(D(t.tableName, e)) && r.push({
630
630
  table: t.tableName,
631
631
  column: e,
632
632
  targetTable: i.references().tableName,
@@ -637,7 +637,7 @@ $$ LANGUAGE plpgsql;
637
637
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
638
638
  a.add(e.tableName);
639
639
  for (let [r, i] of Object.entries(e.fields)) {
640
- if (i.type !== "reference" || !i.references || n.has(T(e.tableName, r))) continue;
640
+ if (i.type !== "reference" || !i.references || n.has(D(e.tableName, r))) continue;
641
641
  let a = i.references();
642
642
  if (a.tableName === e.tableName) continue;
643
643
  let o = t.get(a.tableName);
@@ -712,7 +712,7 @@ BEGIN
712
712
  views: n
713
713
  };
714
714
  }, St = (e, t, n = A) => {
715
- let { tables: r, views: i } = xt(e), { sorted: a, cyclic: o } = gt(r.map((e) => de(e, t))), s = vt(o, t), c = [];
715
+ let { tables: r, views: i } = xt(e), { sorted: a, cyclic: o } = gt(r.map((e) => le(e, t))), s = vt(o, t), c = [];
716
716
  t === "postgres" && mt(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && ht(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
717
717
  let u = bt(a, t);
718
718
  u && c.push(u);
@@ -758,7 +758,7 @@ BEGIN
758
758
  for (let e of i) o.push(_t(e, t));
759
759
  return o.push(...lt(r, t, n)), o.join("\n\n") + "\n";
760
760
  }, Et = (e, t = "postgres", n = A, r = {}) => S.gen(function* () {
761
- let i = yield* w.SqlClient;
761
+ let i = yield* E.SqlClient;
762
762
  yield* Me(i, Nt(i, St(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
763
763
  }), Dt = (e, t) => {
764
764
  let n = t.cause ?? {};
@@ -781,17 +781,17 @@ BEGIN
781
781
  this.statement = e, this.error = t;
782
782
  }
783
783
  }, Mt = (e, t, n) => S.gen(function* () {
784
- let r = yield* w.SqlClient, i = n !== void 0 && Fe(t) === "per-operation";
784
+ let r = yield* E.SqlClient, i = n !== void 0 && Fe(t) === "per-operation";
785
785
  for (let a of Pt(e)) {
786
786
  process.env.VOLTRO_MIGRATE_DEBUG === "1" && Ze.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
787
787
  let e = r.unsafe(a).pipe(S.catchIf((e) => Dt(a, e), () => S.succeed([])), S.tapError((e) => S.sync(() => {
788
- Ze.error(ae("migrate: statement failed", a, e, 200));
788
+ Ze.error(re("migrate: statement failed", a, e, 200));
789
789
  })));
790
790
  yield* (i && n !== void 0 && Ot(a, t) ? e.pipe(S.retry(At((e) => n(e) === "retry"))) : e).pipe(S.mapError((e) => new jt(a, e)));
791
791
  }
792
792
  }), Nt = (e, t, n, r) => {
793
793
  let i = n === "turso" ? Mt(t, n, r) : e.withTransaction(Mt(t, n, r)), a = (e) => e instanceof jt ? e.error : e;
794
- return (r !== void 0 && Fe(n) === "plan-transactional" ? i.pipe(S.retry(At((e) => r(a(e)) === "retry"))) : i).pipe(S.orDieWith((e) => e instanceof jt ? Error(ae("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
794
+ return (r !== void 0 && Fe(n) === "plan-transactional" ? i.pipe(S.retry(At((e) => r(a(e)) === "retry"))) : i).pipe(S.orDieWith((e) => e instanceof jt ? Error(re("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
795
795
  }, Pt = (e) => {
796
796
  let t = [], n = "", r = !1;
797
797
  for (let i = 0; i < e.length; i++) {
@@ -810,7 +810,7 @@ BEGIN
810
810
  }, Ft = async (e, t, n = "postgres", r = {}) => {
811
811
  await S.runPromise(Et(e, n, void 0, r).pipe(S.provide(t)));
812
812
  }, It = (e, t, n = "postgres", r = {}) => S.gen(function* () {
813
- let i = wt(e, n, t), a = yield* w.SqlClient;
813
+ let i = wt(e, n, t), a = yield* E.SqlClient;
814
814
  yield* Me(a, Nt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
815
815
  }), Lt = async (e, t, n, r = "postgres", i = {}) => {
816
816
  await S.runPromise(It(e, t, r, i).pipe(S.provide(n))), await s({
@@ -819,7 +819,7 @@ BEGIN
819
819
  });
820
820
  }, Rt = async (e, t, n = "postgres", r = {}) => {
821
821
  await S.runPromise(S.gen(function* () {
822
- let t = Tt(e, n), i = yield* w.SqlClient;
822
+ let t = Tt(e, n), i = yield* E.SqlClient;
823
823
  yield* Me(i, Nt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
824
824
  }).pipe(S.provide(t)));
825
825
  }, zt = (e) => {
@@ -842,7 +842,7 @@ BEGIN
842
842
  indexes: Ht(e.indexes)
843
843
  })).sort((e, t) => e.name.localeCompare(t.name)), Wt = (e) => {
844
844
  let t = { tables: Ut(e.tables) }, n = JSON.stringify(zt(t));
845
- return ee("sha256").update(n).digest("hex");
845
+ return w("sha256").update(n).digest("hex");
846
846
  }, Gt = (e) => e.slice(0, 16), Kt = (e, t) => {
847
847
  let n = t.references ? {
848
848
  table: t.references().tableName,
@@ -956,7 +956,7 @@ BEGIN
956
956
  t.set(e.name, n.name);
957
957
  }
958
958
  }, I = (e, t) => {
959
- let n = e.filter((e) => !i(e.tableName)).map((e) => Jt(de(e, t)));
959
+ let n = e.filter((e) => !i(e.tableName)).map((e) => Jt(le(e, t)));
960
960
  return Yt(n), { tables: n };
961
961
  }, Xt = (e, t, n = A) => S.gen(function* () {
962
962
  let r = (yield* e`
@@ -1475,8 +1475,8 @@ BEGIN
1475
1475
  column: e.name,
1476
1476
  target: e.references.table
1477
1477
  }] : []) : [];
1478
- }, d = fe([...c], u), p = [];
1479
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(T(e.name, t.name)) || p.push(R({
1478
+ }, d = ue([...c], u), p = [];
1479
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(D(e.name, t.name)) || p.push(R({
1480
1480
  kind: "add-foreign-key",
1481
1481
  table: e.name,
1482
1482
  column: t.name,
@@ -1491,8 +1491,8 @@ BEGIN
1491
1491
  let n = a[t];
1492
1492
  if (n.op.kind !== "create-table") continue;
1493
1493
  let r = n.op;
1494
- if (!r.columns.some((e) => d.has(T(r.table, e.name)))) continue;
1495
- let i = r.columns.map((t) => d.has(T(r.table, t.name)) ? e(t) : t);
1494
+ if (!r.columns.some((e) => d.has(D(r.table, e.name)))) continue;
1495
+ let i = r.columns.map((t) => d.has(D(r.table, t.name)) ? e(t) : t);
1496
1496
  a[t] = {
1497
1497
  ...n,
1498
1498
  op: {
@@ -1512,7 +1512,7 @@ BEGIN
1512
1512
  let i = new Set(t).add(e), a = 0;
1513
1513
  for (let t of r.columns) {
1514
1514
  let n = t.references?.table;
1515
- n && n !== e && !d.has(T(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1515
+ n && n !== e && !d.has(D(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1516
1516
  }
1517
1517
  return g.set(e, a), a;
1518
1518
  }, v = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, y = (e) => {
@@ -1721,18 +1721,18 @@ BEGIN
1721
1721
  let t = v.get(e.table_name);
1722
1722
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1723
1723
  }
1724
- let ee = /* @__PURE__ */ new Map();
1724
+ let w = /* @__PURE__ */ new Map();
1725
1725
  for (let e of f) {
1726
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = ee.get(t);
1726
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = w.get(t);
1727
1727
  n || (n = {
1728
1728
  table: e.table_name,
1729
1729
  columns: []
1730
- }, ee.set(t, n)), n.columns.push({
1730
+ }, w.set(t, n)), n.columns.push({
1731
1731
  name: e.column_name,
1732
1732
  position: e.position
1733
1733
  });
1734
1734
  }
1735
- for (let [e, t] of ee) {
1735
+ for (let [e, t] of w) {
1736
1736
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1737
1737
  if (n.length === 1) {
1738
1738
  let e = y.get(t.table);
@@ -1757,7 +1757,7 @@ BEGIN
1757
1757
  let n = t.get(e.index_name);
1758
1758
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1759
1759
  }
1760
- let te = [];
1760
+ let T = [];
1761
1761
  for (let e of c) {
1762
1762
  let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = x.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1763
1763
  let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Fn(t.data_type, t.udt_name), c = a ? {
@@ -1802,14 +1802,14 @@ BEGIN
1802
1802
  unique: !0
1803
1803
  });
1804
1804
  let d = Number(e.row_count ?? 0);
1805
- te.push({
1805
+ T.push({
1806
1806
  name: e.table_name,
1807
1807
  columns: c,
1808
1808
  indexes: l,
1809
1809
  ...d > 0 ? { rowCount: d } : {}
1810
1810
  });
1811
1811
  }
1812
- return { tables: te };
1812
+ return { tables: T };
1813
1813
  });
1814
1814
  return (t > 0 ? e.withTransaction(n) : n).pipe(S.catchAll((e) => {
1815
1815
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
@@ -2567,9 +2567,9 @@ BEGIN
2567
2567
  };
2568
2568
  };
2569
2569
  }, X = (e, t, n, r = []) => e.unsafe(t).pipe(S.catchIf((e) => ar(e, r), () => S.void), S.tapError((e) => S.sync(() => {
2570
- process.stderr.write(ae(`applier: statement failed (op=${n})`, t, e, 400));
2570
+ process.stderr.write(re(`applier: statement failed (op=${n})`, t, e, 400));
2571
2571
  })), S.mapError((e) => {
2572
- let r = ae(`applier: statement failed (op=${n})`, t, e, 400).trim();
2572
+ let r = re(`applier: statement failed (op=${n})`, t, e, 400).trim();
2573
2573
  return Object.assign(e, { message: r });
2574
2574
  }), S.map(() => void 0)), Z = (e, t, n) => S.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : _(r, t)} FROM ${_(n, t)} WHERE 1=0`).pipe(S.as(!0), S.catchAll(() => S.succeed(!1))), Ai = (e, t) => S.gen(function* () {
2575
2575
  let n = I([Ie], t).tables[0];
@@ -2909,69 +2909,89 @@ BEGIN
2909
2909
  planned: e.planned
2910
2910
  }))
2911
2911
  });
2912
- }), zi = (e, t, n) => S.gen(function* () {
2912
+ }), zi = (e) => {
2913
+ let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
2914
+ return [
2915
+ t.kind,
2916
+ n("table"),
2917
+ n("column"),
2918
+ n("name"),
2919
+ n("to")
2920
+ ].join("\0");
2921
+ }, Bi = (e, t, n) => S.gen(function* () {
2913
2922
  let r = t.operations.filter((e) => e.blocked);
2914
2923
  if (r.length > 0) return yield* S.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2915
- yield* D(e, { schema: n.lockSchema });
2916
- let i = Date.now(), a = [], o = Ne(e), s = Fe(o) === "plan-transactional", c = s ? t.operations.filter((e) => e.classification !== "online-required") : [], l = s ? t.operations.filter((e) => e.classification === "online-required") : t.operations, u = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, d = l.map((e, t) => ({
2924
+ yield* je(e, { schema: n.lockSchema });
2925
+ let i = Date.now(), a = [], o = Ne(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => zi(e))), l = {
2926
+ ...s,
2927
+ operations: s.operations.map((e) => {
2928
+ if (!e.blocked || !c.has(zi(e))) return e;
2929
+ let { blocked: t, ...n } = e;
2930
+ return n;
2931
+ })
2932
+ };
2933
+ (l.operations.length !== t.operations.length || l.toFingerprint !== t.toFingerprint) && (yield* S.logInfo(`migration: re-planned under the lock — ${t.operations.length} operation(s) became ${l.operations.length}. Another writer changed the schema while this plan waited.`).pipe(S.annotateLogs({ scope: "voltro:migrate" })));
2934
+ let u = l.operations.filter((e) => e.blocked);
2935
+ if (u.length > 0) return yield* O(e, { schema: n.lockSchema }).pipe(S.orDie), yield* S.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — re-planning under the migration lock found ${u.length} blocked operation(s). Run \`voltro db plan\` to see the fixes.`));
2936
+ let d = Fe(o) === "plan-transactional", f = d ? l.operations.filter((e) => e.classification !== "online-required") : [], p = d ? l.operations.filter((e) => e.classification === "online-required") : l.operations, m = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, h = p.map((e, t) => ({
2917
2937
  index: t,
2918
2938
  planned: e
2919
- })), f = "fresh";
2939
+ })), g = "fresh";
2920
2940
  try {
2921
2941
  yield* Ai(e, o);
2922
- let r = yield* ji(e);
2923
- if (r.length > 0) {
2924
- let n = yield* Ri(e, o, t, r);
2925
- n.kind === "resume" ? (u = n.runId, d = n.ops, f = "resume") : (yield* S.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* Fi(e, n.runId));
2942
+ let t = yield* ji(e);
2943
+ if (t.length > 0) {
2944
+ let n = yield* Ri(e, o, l, t);
2945
+ n.kind === "resume" ? (m = n.runId, h = n.ops, g = "resume") : (yield* S.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* Fi(e, n.runId));
2926
2946
  }
2927
- f === "fresh" && d.length > 0 && (yield* Mi(e, u, t.toFingerprint, d)), c.length > 0 && (yield* e.withTransaction(S.gen(function* () {
2928
- let e = yield* w.SqlClient;
2929
- for (let t of c) a.push(yield* Li(e, t, n));
2947
+ g === "fresh" && h.length > 0 && (yield* Mi(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(S.gen(function* () {
2948
+ let e = yield* E.SqlClient;
2949
+ for (let t of f) a.push(yield* Li(e, t, n));
2930
2950
  })));
2931
- for (let { index: t, planned: r } of d) {
2932
- yield* Ni(e, u, t, "started");
2933
- let i = a.length, o = yield* Li(e, r, n, f).pipe(S.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${d.length + c.length} operation(s) applied before this one${c.length > 0 ? ` (${c.length} of them in a transaction)` : ""}.\n` + (s ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
2934
- a.push(o), yield* Ni(e, u, t, "applied", o.durationMs);
2951
+ for (let { index: t, planned: r } of h) {
2952
+ yield* Ni(e, m, t, "started");
2953
+ let i = a.length, o = yield* Li(e, r, n, g).pipe(S.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${h.length + f.length} operation(s) applied before this one${f.length > 0 ? ` (${f.length} of them in a transaction)` : ""}.\n` + (d ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
2954
+ a.push(o), yield* Ni(e, m, t, "applied", o.durationMs);
2935
2955
  }
2936
2956
  } finally {
2937
2957
  yield* O(e, { schema: n.lockSchema }).pipe(S.orDie);
2938
2958
  }
2939
- let p = yield* n.replan(e);
2940
- if (p.operations.length > 0) {
2941
- let e = p.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2942
- return yield* S.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${p.operations.length}:\n${e}${p.operations.length > 10 ? `\n … and ${p.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2959
+ let _ = yield* n.replan(e);
2960
+ if (_.operations.length > 0) {
2961
+ let e = _.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2962
+ return yield* S.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${l.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${_.operations.length}:\n${e}${_.operations.length > 10 ? `\n … and ${_.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2943
2963
  }
2944
- let m = a.filter((e) => e.status === "applied").length, h = Date.now() - i, g = u, _ = (/* @__PURE__ */ new Date()).toISOString(), y = yield* W(e, _), b = [...c, ...d.map((e) => e.planned)];
2964
+ let y = a.filter((e) => e.status === "applied").length, b = Date.now() - i, x = m, C = (/* @__PURE__ */ new Date()).toISOString(), w = yield* W(e, C), T = [...f, ...h.map((e) => e.planned)];
2945
2965
  yield* e`
2946
2966
  INSERT INTO ${e("_voltro_migration_plans")}
2947
2967
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
2948
2968
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
2949
2969
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
2950
2970
  VALUES
2951
- (${g}, ${t.toFingerprint}, ${p.fromFingerprint}, ${JSON.stringify(b)},
2971
+ (${x}, ${l.toFingerprint}, ${_.fromFingerprint}, ${JSON.stringify(T)},
2952
2972
  ${n.appliedBy}, ${n.environment}, ${n.source},
2953
- ${h}, ${y}, ${n.notes ?? null})
2954
- `, yield* Fi(e, u);
2955
- let x = [...new Set(b.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2956
- return yield* S.promise(() => v({ changedTables: x }).catch(() => {})), {
2957
- id: g,
2958
- appliedAt: _,
2959
- fingerprint: t.toFingerprint,
2960
- operations: b,
2973
+ ${b}, ${w}, ${n.notes ?? null})
2974
+ `, yield* Fi(e, m);
2975
+ let ee = [...new Set(T.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2976
+ return yield* S.promise(() => v({ changedTables: ee }).catch(() => {})), {
2977
+ id: x,
2978
+ appliedAt: C,
2979
+ fingerprint: l.toFingerprint,
2980
+ operations: T,
2961
2981
  appliedBy: n.appliedBy,
2962
2982
  environment: n.environment,
2963
- durationMs: h,
2964
- appliedOps: m,
2983
+ durationMs: b,
2984
+ appliedOps: y,
2965
2985
  source: n.source,
2966
2986
  ...n.notes ? { notes: n.notes } : {}
2967
2987
  };
2968
- }), Bi = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Vi = (e) => e`
2988
+ }), Vi = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Hi = (e) => e`
2969
2989
  SELECT fingerprint
2970
2990
  FROM _voltro_migration_plans
2971
2991
  ORDER BY ${e("appliedAt")} DESC
2972
2992
  LIMIT 1
2973
- `.pipe(S.map((e) => e.length > 0 ? e[0].fingerprint : void 0), S.catchAll(() => S.succeed(void 0))), Hi = (e, t, n) => S.gen(function* () {
2974
- if ((yield* Vi(e)) === t.toFingerprint) return "already-current";
2993
+ `.pipe(S.map((e) => e.length > 0 ? e[0].fingerprint : void 0), S.catchAll(() => S.succeed(void 0))), Ui = (e, t, n) => S.gen(function* () {
2994
+ if ((yield* Hi(e)) === t.toFingerprint) return "already-current";
2975
2995
  let r = `plan_${Date.now().toString(36)}`, i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2976
2996
  return yield* e`
2977
2997
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -2983,8 +3003,8 @@ BEGIN
2983
3003
  ${n.appliedBy}, ${n.environment}, ${n.source},
2984
3004
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
2985
3005
  `, "recorded";
2986
- }).pipe(S.catchAll(() => S.succeed("already-current"))), Ui = (e, t) => S.gen(function* () {
2987
- let n = Wt(I(t, Ne(e))), r = yield* Vi(e);
3006
+ }).pipe(S.catchAll(() => S.succeed("already-current"))), Wi = (e, t) => S.gen(function* () {
3007
+ let n = Wt(I(t, Ne(e))), r = yield* Hi(e);
2988
3008
  return r === n ? {
2989
3009
  kind: "up-to-date",
2990
3010
  fingerprint: n
@@ -2993,23 +3013,23 @@ BEGIN
2993
3013
  expected: n,
2994
3014
  ...r === void 0 ? {} : { actual: r }
2995
3015
  };
2996
- }), Wi = [
3016
+ }), Gi = [
2997
3017
  "pgeagertest_",
2998
3018
  "mig_e2e_",
2999
3019
  "mig_test_",
3000
3020
  "mysqleagertest_",
3001
3021
  "mssqleagertest_",
3002
3022
  "sqliteeagertest_"
3003
- ], Gi = (e) => Wi.some((t) => e.startsWith(t)), Ki = (e, t) => S.gen(function* () {
3023
+ ], Ki = (e) => Gi.some((t) => e.startsWith(t)), qi = (e, t) => S.gen(function* () {
3004
3024
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
3005
- let n = t.filter((e) => Gi(e.name)).map((e) => e.name);
3025
+ let n = t.filter((e) => Ki(e.name)).map((e) => e.name);
3006
3026
  if (n.length === 0) return [];
3007
3027
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(S.catchAll(() => S.void));
3008
3028
  return n;
3009
- }), qi = () => {
3029
+ }), Ji = () => {
3010
3030
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
3011
3031
  return e.length > 0 ? { ignoreTables: e } : {};
3012
- }, Ji = (e) => {
3032
+ }, Yi = (e) => {
3013
3033
  if (e === void 0) return;
3014
3034
  let t = e.trim();
3015
3035
  if (t === "") return;
@@ -3019,30 +3039,30 @@ BEGIN
3019
3039
  kind: "tables",
3020
3040
  tables: new Set(n)
3021
3041
  } : void 0;
3022
- }, Yi = (e) => typeof e.table == "string" ? e.table : void 0, Xi = (e, t = { kind: "all" }) => ({
3042
+ }, Xi = (e) => typeof e.table == "string" ? e.table : void 0, Zi = (e, t = { kind: "all" }) => ({
3023
3043
  ...e,
3024
3044
  operations: e.operations.map((e) => {
3025
3045
  if (!e.blocked || e.classification !== "lossy") return e;
3026
3046
  if (t?.kind === "tables") {
3027
- let n = Yi(e.op);
3047
+ let n = Xi(e.op);
3028
3048
  if (n === void 0 || !t.tables.has(n)) return e;
3029
3049
  }
3030
3050
  let { blocked: n, ...r } = e;
3031
3051
  return r;
3032
3052
  })
3033
- }), Zi = (e, t, n) => t === "postgres" ? Xt(e, n).pipe(S.flatMap((e) => {
3053
+ }), Qi = (e, t, n) => t === "postgres" ? Xt(e, n).pipe(S.flatMap((e) => {
3034
3054
  let t = Zt(e);
3035
3055
  return t === void 0 ? S.void : S.logWarning(`auto-migrate: ${t}`).pipe(S.annotateLogs({ scope: "voltro:migrate" }));
3036
- }), S.catchAll(() => S.void)) : S.void, Qi = (e, t, n) => S.gen(function* () {
3056
+ }), S.catchAll(() => S.void)) : S.void, $i = (e, t, n) => S.gen(function* () {
3037
3057
  let r = Ne(e), i = t;
3038
3058
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
3039
3059
  let t = Wt(I(i, r));
3040
- if ((yield* Vi(e)) === t) return yield* Zi(e, r, i), {
3060
+ if ((yield* Hi(e)) === t) return yield* Qi(e, r, i), {
3041
3061
  kind: "up-to-date",
3042
3062
  fingerprint: t
3043
3063
  };
3044
3064
  }
3045
- let a = yield* $n(e), o = yield* Ki(e, a.tables);
3065
+ let a = yield* $n(e), o = yield* qi(e, a.tables);
3046
3066
  o.length > 0 && (yield* S.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(S.annotateLogs({
3047
3067
  scope: "voltro:migrate",
3048
3068
  count: o.length
@@ -3051,16 +3071,16 @@ BEGIN
3051
3071
  declared: i,
3052
3072
  live: { tables: c(a.tables) },
3053
3073
  dialect: r,
3054
- ...qi()
3074
+ ...Ji()
3055
3075
  });
3056
3076
  if (l.summary.blocked > 0) {
3057
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Ji(process.env.VOLTRO_DESTRUCTIVE_OK);
3058
- if (t === void 0 || !e || (l = Xi(l, t), l.operations.some((e) => e.blocked))) return {
3077
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Yi(process.env.VOLTRO_DESTRUCTIVE_OK);
3078
+ if (t === void 0 || !e || (l = Zi(l, t), l.operations.some((e) => e.blocked))) return {
3059
3079
  kind: "refused-blocked",
3060
3080
  plan: l
3061
3081
  };
3062
3082
  }
3063
- return l.operations.length === 0 ? (yield* Hi(e, l, {
3083
+ return l.operations.length === 0 ? (yield* Ui(e, l, {
3064
3084
  appliedBy: n.appliedBy,
3065
3085
  environment: n.environment === "prod" ? "dev" : n.environment,
3066
3086
  source: "auto-diff"
@@ -3069,7 +3089,7 @@ BEGIN
3069
3089
  fingerprint: l.toFingerprint
3070
3090
  }) : {
3071
3091
  kind: "applied",
3072
- applied: yield* zi(e, l, {
3092
+ applied: yield* Bi(e, l, {
3073
3093
  declared: t,
3074
3094
  appliedBy: n.appliedBy,
3075
3095
  environment: n.environment === "prod" ? "dev" : n.environment,
@@ -3080,16 +3100,16 @@ BEGIN
3080
3100
  declared: i,
3081
3101
  live: { tables: c(t.tables) },
3082
3102
  dialect: r,
3083
- ...qi()
3103
+ ...Ji()
3084
3104
  });
3085
3105
  })
3086
3106
  }),
3087
3107
  plan: l
3088
3108
  };
3089
- }), $i = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? S.succeed({
3109
+ }), ea = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? S.succeed({
3090
3110
  kind: "skipped",
3091
3111
  reason: "VOLTRO_AUTO_MIGRATE=0"
3092
- }) : n.environment === "prod" ? Ui(e, t) : Qi(e, t, n), ea = (e, t) => {
3112
+ }) : n.environment === "prod" ? Wi(e, t) : $i(e, t, n), ta = (e, t) => {
3093
3113
  switch (e.kind) {
3094
3114
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
3095
3115
  case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${Gt(e.fingerprint)})`;
@@ -3099,7 +3119,7 @@ BEGIN
3099
3119
  }
3100
3120
  case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${Gt(e.expected)}` + (e.actual ? ` live=${Gt(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3101
3121
  case "refused-blocked": {
3102
- let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + Bi(e.plan), c = [""];
3122
+ let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + Vi(e.plan), c = [""];
3103
3123
  if (n > 0 && c.push(`${n} table(s) exist in the live DB but aren't in your declared schema.`, "This is usually one of three things:", " (a) You're iterating on the schema — the table file got renamed, moved, or temporarily commented out.", " → Restore the declaration. Your data stays intact.", " (b) You want to KEEP the table but NOT manage it with Voltro (a leftover from another tool —", " a Strapi/Rails/legacy migration artifact, or an externally-owned table).", ` → Set \`VOLTRO_DB_IGNORE_TABLES=${r.join(",")}\` (comma-separated).`, " The planner excludes those tables from the diff entirely — it never drops them, and they", " stop blocking your OTHER (additive) changes. This is the fix when a leftover freezes your schema.", " (c) You actually want to drop the table.", ` → Set \`VOLTRO_DESTRUCTIVE_OK=${r.join(",")}\` for ONE run — it acknowledges`, " the data loss for THOSE tables only; every other lossy op in this plan stays blocked.", " (`VOLTRO_DESTRUCTIVE_OK=1` acknowledges all of them, which is rarely what you mean.)", " There is deliberately no `dropped()` marker for a TABLE, unlike for a column: a", " dropped column leaves a slot worth documenting in the declaration, a dropped table", " leaves nothing — the marker would be a dead entry you must remember to delete.", " Soft-drop: set `VOLTRO_SOFT_DROP=1` alongside DESTRUCTIVE_OK to RENAME instead of DROP", " (data survives as `<name>__dropped_<ts>` for ~7d; restorable via `voltro db restore-snapshot`)."), i > 0 && c.push(`${i} required column(s) need a backfill strategy before adding to a populated table.`, " → Annotate the column: `.backfill(sql`<expr>`)` or `.backfill(row => <fn>)` or `.default(<value>)`.", " Existing rows get the backfill value; the column then lands as NOT NULL."), a > 0) {
3104
3124
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3105
3125
  for (let r of e.plan.operations) {
@@ -3116,7 +3136,7 @@ BEGIN
3116
3136
  return o > 0 && c.push(`${o} column(s) look like renames (one column gone + a new one of same shape appeared).`, " → On the NEW column add `.renamedFrom('<oldName>')` so the planner emits RENAME instead of DROP+ADD."), c.push("", "See `voltro db plan` for the full machine-readable diff."), s + "\n" + c.join("\n");
3117
3137
  }
3118
3138
  }
3119
- }, ta = /* @__PURE__ */ new Set([
3139
+ }, na = /* @__PURE__ */ new Set([
3120
3140
  "node_modules",
3121
3141
  "dist",
3122
3142
  "build",
@@ -3125,12 +3145,12 @@ BEGIN
3125
3145
  ".next",
3126
3146
  ".git",
3127
3147
  ".framework"
3128
- ]), na = async (e) => {
3148
+ ]), ra = async (e) => {
3129
3149
  let t = [], n = async (e) => {
3130
- let r = await ne.readdir(e, { withFileTypes: !0 }).catch(() => []);
3150
+ let r = await ee.readdir(e, { withFileTypes: !0 }).catch(() => []);
3131
3151
  for (let i of r) {
3132
- if (ta.has(i.name)) continue;
3133
- let r = re(e, i.name);
3152
+ if (na.has(i.name)) continue;
3153
+ let r = te(e, i.name);
3134
3154
  i.isDirectory() ? await n(r) : i.isFile() && m.test(i.name) && t.push(r);
3135
3155
  }
3136
3156
  };
@@ -3138,10 +3158,10 @@ BEGIN
3138
3158
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3139
3159
  return n.localeCompare(r);
3140
3160
  });
3141
- }, ra = async (e) => {
3161
+ }, ia = async (e) => {
3142
3162
  let t = [];
3143
3163
  for (let n of e) {
3144
- let e = (await import(ie(n).href)).default;
3164
+ let e = (await import(ne(n).href)).default;
3145
3165
  if (!g(e)) {
3146
3166
  process.stderr.write(`[voltro:migrate] ${n} has no default-exported \`migration(...)\` — skipped\n`);
3147
3167
  continue;
@@ -3152,11 +3172,11 @@ BEGIN
3152
3172
  });
3153
3173
  }
3154
3174
  return t;
3155
- }, ia = (e) => e`
3175
+ }, aa = (e) => e`
3156
3176
  SELECT ${e("id")}
3157
3177
  FROM ${e("_voltro_migration_plans")}
3158
3178
  WHERE ${e("source")} = 'file'
3159
- `.pipe(S.map((e) => e.map((e) => e.id)), S.catchAll(() => S.succeed([]))), aa = class extends Error {
3179
+ `.pipe(S.map((e) => e.map((e) => e.id)), S.catchAll(() => S.succeed([]))), oa = class extends Error {
3160
3180
  migrationId;
3161
3181
  file;
3162
3182
  cause;
@@ -3164,7 +3184,7 @@ BEGIN
3164
3184
  constructor(e, t, n) {
3165
3185
  super(`migration ${e}: up() SUCCEEDED but the ledger row could not be written.\n The change IS in the database. It is NOT recorded, so the next run would apply it AGAIN.\n Do not re-run ${t} until this is resolved.\n Cause: ${n instanceof Error ? n.message : String(n)}`), this.migrationId = e, this.file = t, this.cause = n, this.name = "FileMigrationLedgerError";
3166
3186
  }
3167
- }, oa = (e, t, n, r) => S.gen(function* () {
3187
+ }, sa = (e, t, n, r) => S.gen(function* () {
3168
3188
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3169
3189
  sql: e,
3170
3190
  log: {
@@ -3198,10 +3218,10 @@ BEGIN
3198
3218
  }])},
3199
3219
  ${r}, ${n}, ${"file"},
3200
3220
  ${c}, ${l}, ${t.migration.description})
3201
- `.pipe(S.mapError((e) => new aa(t.migration.id, t.file, e))), { durationMs: c };
3202
- }), sa = (e, t) => S.gen(function* () {
3221
+ `.pipe(S.mapError((e) => new oa(t.migration.id, t.file, e))), { durationMs: c };
3222
+ }), ca = (e, t) => S.gen(function* () {
3203
3223
  let n = yield* S.tryPromise({
3204
- try: () => na(re(t, "migrations")),
3224
+ try: () => ra(te(t, "migrations")),
3205
3225
  catch: (e) => e
3206
3226
  });
3207
3227
  if (n.length === 0) return {
@@ -3209,25 +3229,25 @@ BEGIN
3209
3229
  skipped: []
3210
3230
  };
3211
3231
  let r = yield* S.tryPromise({
3212
- try: () => ra(n),
3232
+ try: () => ia(n),
3213
3233
  catch: (e) => e
3214
3234
  });
3215
3235
  if (r.length === 0) return {
3216
3236
  pending: [],
3217
3237
  skipped: []
3218
3238
  };
3219
- let i = new Set(yield* ia(e));
3239
+ let i = new Set(yield* aa(e));
3220
3240
  return {
3221
3241
  pending: r.filter((e) => !i.has(e.migration.id)),
3222
3242
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3223
3243
  };
3224
- }), ca = (e, t) => sa(e, t).pipe(S.map((e) => e.pending.map((e) => e.migration.id))), la = (e, t) => S.gen(function* () {
3225
- let { pending: n, skipped: r } = yield* sa(e, t.projectRoot);
3244
+ }), la = (e, t) => ca(e, t).pipe(S.map((e) => e.pending.map((e) => e.migration.id))), ua = (e, t) => S.gen(function* () {
3245
+ let { pending: n, skipped: r } = yield* ca(e, t.projectRoot);
3226
3246
  if (n.length === 0) return {
3227
3247
  applied: [],
3228
3248
  skipped: r
3229
3249
  };
3230
- yield* D(e, { schema: t.lockSchema });
3250
+ yield* je(e, { schema: t.lockSchema });
3231
3251
  let i = [];
3232
3252
  try {
3233
3253
  for (let r of n) {
@@ -3236,7 +3256,7 @@ BEGIN
3236
3256
  id: r.migration.id,
3237
3257
  file: r.file
3238
3258
  }));
3239
- let { durationMs: n } = yield* oa(e, r, t.env, t.appliedBy);
3259
+ let { durationMs: n } = yield* sa(e, r, t.env, t.appliedBy);
3240
3260
  i.push({
3241
3261
  id: r.migration.id,
3242
3262
  durationMs: n
@@ -3253,22 +3273,22 @@ BEGIN
3253
3273
  applied: i,
3254
3274
  skipped: r
3255
3275
  };
3256
- }), ua = (e, t) => e`
3276
+ }), da = (e, t) => e`
3257
3277
  SELECT ${e("id")}
3258
3278
  FROM ${e("_voltro_migration_plans")}
3259
3279
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3260
3280
  LIMIT 1
3261
- `, da = (e, t) => S.gen(function* () {
3262
- if (!(yield* ua(e, t.id))[0]) return yield* S.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3281
+ `, fa = (e, t) => S.gen(function* () {
3282
+ if (!(yield* da(e, t.id))[0]) return yield* S.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3263
3283
  let n = yield* S.tryPromise({
3264
- try: () => na(re(t.projectRoot, "migrations")),
3284
+ try: () => ra(te(t.projectRoot, "migrations")),
3265
3285
  catch: (e) => e
3266
3286
  }), r = (yield* S.tryPromise({
3267
- try: () => ra(n),
3287
+ try: () => ia(n),
3268
3288
  catch: (e) => e
3269
3289
  })).find((e) => e.migration.id === t.id);
3270
3290
  if (!r) return yield* S.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3271
- yield* D(e, { schema: t.lockSchema });
3291
+ yield* je(e, { schema: t.lockSchema });
3272
3292
  let i = Date.now();
3273
3293
  try {
3274
3294
  let n = {
@@ -3297,8 +3317,8 @@ BEGIN
3297
3317
  } finally {
3298
3318
  yield* O(e, { schema: t.lockSchema }).pipe(S.orDie);
3299
3319
  }
3300
- }), fa = (e) => S.gen(function* () {
3301
- let t = yield* w.SqlClient, n = yield* t`
3320
+ }), pa = (e) => S.gen(function* () {
3321
+ let t = yield* E.SqlClient, n = yield* t`
3302
3322
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3303
3323
  WHERE source = 'auto-diff'
3304
3324
  AND squashedAt IS NULL
@@ -3342,7 +3362,7 @@ BEGIN
3342
3362
  snapshotFingerprint: e.fingerprint,
3343
3363
  snapshotId: i
3344
3364
  };
3345
- }), pa = { safe: !0 }, ma = (e) => {
3365
+ }), ma = { safe: !0 }, ha = (e) => {
3346
3366
  switch (e.kind) {
3347
3367
  case "drop-column": return {
3348
3368
  safe: !1,
@@ -3369,7 +3389,7 @@ BEGIN
3369
3389
  reason: `old instances read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
3370
3390
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3371
3391
  };
3372
- case "alter-column-nullability": return e.toNullable ? pa : {
3392
+ case "alter-column-nullability": return e.toNullable ? ma : {
3373
3393
  safe: !1,
3374
3394
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3375
3395
  remedy: `make code always write "${e.column}" and deploy that first; add NOT NULL in a LATER deploy (with a default to cover the gap)`
@@ -3399,12 +3419,12 @@ BEGIN
3399
3419
  case "drop-unique":
3400
3420
  case "drop-unique-composite":
3401
3421
  case "drop-foreign-key":
3402
- case "drop-check": return pa;
3422
+ case "drop-check": return ma;
3403
3423
  }
3404
- }, ha = (e) => {
3424
+ }, ga = (e) => {
3405
3425
  let t = [];
3406
3426
  for (let n of e) {
3407
- let e = ma(n.op);
3427
+ let e = ha(n.op);
3408
3428
  e.safe || t.push({
3409
3429
  op: n,
3410
3430
  reason: e.reason,
@@ -3412,7 +3432,7 @@ BEGIN
3412
3432
  });
3413
3433
  }
3414
3434
  return t;
3415
- }, ga = (e) => {
3435
+ }, _a = (e) => {
3416
3436
  if (!e.enabled || e.unsafeCount === 0) return {
3417
3437
  refuse: !1,
3418
3438
  warnForced: !1,
@@ -3428,18 +3448,18 @@ BEGIN
3428
3448
  warnForced: !1,
3429
3449
  message: `${t}. Old instances would break against the new schema mid-rollout. Split into expand → deploy → contract (see the ⚠ list above), deploy with no overlap (maintenance window / scale-to-zero), or pass --force to override.`
3430
3450
  };
3431
- }, _a = (e) => {
3451
+ }, va = (e) => {
3432
3452
  let t = e.table;
3433
3453
  if (typeof t == "string") return t;
3434
3454
  let n = e.from;
3435
3455
  return typeof n == "string" ? n : void 0;
3436
- }, va = (e) => ({
3456
+ }, ya = (e) => ({
3437
3457
  kind: e.op.kind,
3438
- table: _a(e.op),
3458
+ table: va(e.op),
3439
3459
  classification: e.classification,
3440
3460
  reason: e.reason,
3441
3461
  blockedFix: e.blocked?.fix
3442
- }), ya = (e) => e.operations.map(va), ba = async (e) => {
3462
+ }), ba = (e) => e.operations.map(ya), xa = async (e) => {
3443
3463
  let t = e.log ?? (() => {}), n = {
3444
3464
  branchId: e.branchId,
3445
3465
  mechanism: e.mechanism,
@@ -3458,10 +3478,10 @@ BEGIN
3458
3478
  applied: !1,
3459
3479
  converged: !1,
3460
3480
  residual: r,
3461
- infidelity: ya(o)
3481
+ infidelity: ba(o)
3462
3482
  };
3463
3483
  else {
3464
- let i = await e.plan(), o = ya(i), s = o.filter((e) => e.classification === "lossy"), c = Xi(i), l = c.operations.filter((e) => e.blocked !== void 0).map(va);
3484
+ let i = await e.plan(), o = ba(i), s = o.filter((e) => e.classification === "lossy"), c = Zi(i), l = c.operations.filter((e) => e.blocked !== void 0).map(ya);
3465
3485
  if (l.length > 0) a = {
3466
3486
  ...n,
3467
3487
  outcome: "blocked",
@@ -3486,7 +3506,7 @@ BEGIN
3486
3506
  };
3487
3507
  else {
3488
3508
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3489
- let i = ya(await e.replan());
3509
+ let i = ba(await e.replan());
3490
3510
  a = {
3491
3511
  ...n,
3492
3512
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3524,7 +3544,7 @@ BEGIN
3524
3544
  ...a,
3525
3545
  tornDown: o
3526
3546
  };
3527
- }, xa = (e) => {
3547
+ }, Sa = (e) => {
3528
3548
  switch (e.outcome) {
3529
3549
  case "clean": return 0;
3530
3550
  case "lossy": return 2;
@@ -3533,22 +3553,22 @@ BEGIN
3533
3553
  case "infidelity": return 1;
3534
3554
  case "failed": return 1;
3535
3555
  }
3536
- }, Sa = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Ca = (e) => {
3556
+ }, Ca = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, wa = (e) => {
3537
3557
  let t = [];
3538
3558
  if (t.push(`branch rehearsal · ${e.branchId} · mechanism ${e.mechanism}`), t.push(` branched ${e.branchedTables} table(s), replayed ${e.replayedForeignKeys} foreign key(s)`), e.outcome === "failed") t.push(` FAILED: ${e.error ?? "unknown error"}`);
3539
3559
  else if (e.outcome === "infidelity") {
3540
3560
  t.push(" BRANCH IS NOT A FAITHFUL COPY of the parent — the rehearsal proves nothing about your migration."), t.push(" The parent's own schema still differs from the branch by:");
3541
- for (let n of e.infidelity) t.push(Sa(n));
3561
+ for (let n of e.infidelity) t.push(Ca(n));
3542
3562
  } else {
3543
3563
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3544
- for (let n of e.operations) t.push(Sa(n));
3545
- if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(Sa(n));
3564
+ for (let n of e.operations) t.push(Ca(n));
3565
+ if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(Ca(n));
3546
3566
  }
3547
3567
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3548
- }, wa = (e, ...t) => ({
3568
+ }, Ta = (e, ...t) => ({
3549
3569
  _tag: "RawSqlFragment",
3550
3570
  strings: [...e],
3551
3571
  values: [...t]
3552
- }), Ta = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3572
+ }), Ea = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3553
3573
  //#endregion
3554
- export { A as DEFAULT_CDC_CHANNEL, m as FILE_MIGRATION_PATTERN, aa as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, pe as VOLTRO_MIGRATION_LOCK_KEY, D as acquireMigrationLock, W as appliedAtValue, It as applyNamespacedSchema, zi as applyPlan, Et as applySchema, ga as assessRollingDeployGate, xa as branchRehearsalExitCode, Vn as chunkTables, ma as classifyRollingDeploySafety, I as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, N as defaultJsonClause, ea as describeOutcome, Ji as destructiveScope, Xt as detectReactiveTriggerDrift, ni as emitAddIndexMysql, Lr as emitCreateTableMysql, _r as emitDropColumnDdl, vr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, er as engineFromVersion, Wt as fingerprintSchema, ye as fnv1a64, Ca as formatBranchRehearsal, Zt as formatReactiveTriggerDrift, qi as ignoreTablesFromEnv, $n as introspectSchema, ar as isAlreadySatisfied, g as isFileMigration, Ta as isRawSqlFragment, Ot as isReRunSafeDdl, Fn as mapPgType, o as migration, be as migrationLockKeyForSchema, E as migrationLockNameForSchema, Qr as mysqlIndexPrefixFor, Ye as notifyFunctionName, P as numericIdSql, Pn as parseEnumCheck, ca as pendingFileMigrationIds, Nn as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Hi as recordUpToDate, ba as rehearseMigrationOnBranch, va as rehearsedOperation, O as releaseMigrationLock, Fr as renderColumnMysql, Ar as renderColumnPg, he as resolveMigrationLockSchema, U as resolveMysqlEngine, da as rollbackFileBasedMigration, ha as rollingDeployUnsafeOps, la as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, $i as runPlannedMigrations, Gt as shortFingerprint, Kt as snapshotColumn, wa as sql, M as sqlType, fa as squashMigrationPlans, Xi as unblockLossy, Me as withMigrationLock };
3574
+ export { A as DEFAULT_CDC_CHANNEL, m as FILE_MIGRATION_PATTERN, oa as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, de as VOLTRO_MIGRATION_LOCK_KEY, je as acquireMigrationLock, W as appliedAtValue, It as applyNamespacedSchema, Bi as applyPlan, Et as applySchema, _a as assessRollingDeployGate, Sa as branchRehearsalExitCode, Vn as chunkTables, ha as classifyRollingDeploySafety, I as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, N as defaultJsonClause, ta as describeOutcome, Yi as destructiveScope, Xt as detectReactiveTriggerDrift, ni as emitAddIndexMysql, Lr as emitCreateTableMysql, _r as emitDropColumnDdl, vr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, er as engineFromVersion, Wt as fingerprintSchema, _e as fnv1a64, wa as formatBranchRehearsal, Zt as formatReactiveTriggerDrift, Ji as ignoreTablesFromEnv, $n as introspectSchema, ar as isAlreadySatisfied, g as isFileMigration, Ea as isRawSqlFragment, Ot as isReRunSafeDdl, Fn as mapPgType, o as migration, ve as migrationLockKeyForSchema, ye as migrationLockNameForSchema, Qr as mysqlIndexPrefixFor, Ye as notifyFunctionName, P as numericIdSql, Pn as parseEnumCheck, la as pendingFileMigrationIds, Nn as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Ui as recordUpToDate, xa as rehearseMigrationOnBranch, ya as rehearsedOperation, O as releaseMigrationLock, Fr as renderColumnMysql, Ar as renderColumnPg, pe as resolveMigrationLockSchema, U as resolveMysqlEngine, fa as rollbackFileBasedMigration, ga as rollingDeployUnsafeOps, ua as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, ea as runPlannedMigrations, Gt as shortFingerprint, Kt as snapshotColumn, Ta as sql, M as sqlType, pa as squashMigrationPlans, Zi as unblockLossy, Me as withMigrationLock };