@voltro/database 0.41.0 → 0.42.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
- import { It as e, Jt as t, Lt as n, X as r, Z as i, _ as a, a as o, bt as s, c, et as l, i as u, l as d, m as f, mt as p, n as m, o as h, p as g, qt as _, r as v, tt as y } from "./frameworkLiveTables-BS6FuivX.js";
2
- import { Effect as b, Schedule as x } from "effect";
3
- import { createLogger as S } from "@voltro/logger";
1
+ import { Jt as e, Lt as t, Q as n, Rt as r, X as i, Yt as a, Z as o, _ as s, a as c, c as l, ht as u, i as d, l as f, m as p, n as m, nt as h, o as g, p as _, r as v, tt as y, xt as b } from "./frameworkLiveTables-XPFqj8n3.js";
2
+ import { Effect as x, Schedule as S } from "effect";
3
+ import { createLogger as ee } from "@voltro/logger";
4
4
  import { SqlClient as C } from "@effect/sql";
5
- import { createHash as ee } from "node:crypto";
6
- import { promises as te } from "node:fs";
7
- import { join as ne } from "node:path";
8
- import { pathToFileURL as re } from "node:url";
5
+ import { createHash as te } from "node:crypto";
6
+ import { promises as ne } from "node:fs";
7
+ import { join as re } from "node:path";
8
+ import { pathToFileURL as ie } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var ie = (e, t, n, r = 400) => {
10
+ var ae = (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 ie = (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 = ae(o("code"));
41
+ let c = oe(o("code"));
42
42
  return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
- }, ae = (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, oe = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, se = (e) => e.replace(/"/g, "`"), ce = (e) => typeof e == "string" ? e : e.name ?? String(e), le = (e, t) => `_ua_${t}_${e}`.slice(0, 64), ue = (e, t) => {
44
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(oe)) return e;
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;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!oe(t)) {
47
+ if (!se(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = se(t.where), o = [];
51
+ let a = ce(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = ce(r);
53
+ let i = le(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 = le(t.name, i);
55
+ let s = ue(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,7 +75,7 @@ var ie = (e, t, n, r = 400) => {
75
75
  appliedIndexes: r,
76
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
77
77
  };
78
- }, w = (e, t) => `${e}::${t}`, de = (e, t) => {
78
+ }, w = (e, t) => `${e}::${t}`, fe = (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));
@@ -84,90 +84,90 @@ var ie = (e, t, n, r = 400) => {
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, fe = 6322741009312437n, pe = (e) => {
87
+ }, pe = 6322741009312437n, me = (e) => {
88
88
  let t = e?.trim();
89
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
90
- }, me = (e) => e?.schema === void 0 ? pe(process.env.DB_SCHEMA) : pe(e.schema), he = 14695981039346656037n, ge = 1099511628211n, _e = 18446744073709551615n, ve = (e) => {
91
- let t = he;
92
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * ge & _e;
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;
93
93
  return t;
94
- }, ye = (e) => {
95
- let t = pe(e);
96
- return t === void 0 ? fe : ve(`voltro_migration_lock:${t}`) & 9223372036854775807n;
94
+ }, be = (e) => {
95
+ let t = me(e);
96
+ return t === void 0 ? pe : ye(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
97
  }, T = (e) => {
98
- let t = `voltro_migration_${fe.toString(36)}`, n = pe(e);
98
+ let t = `voltro_migration_${pe.toString(36)}`, n = me(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${(ve(`voltro_migration_lock:${n}`) & _e).toString(16)}`;
102
- }, be = 250, xe = () => {
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 = () => {
103
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
104
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
105
- }, Se = (e, t) => b.gen(function* () {
106
- let n = xe(), r = Date.now();
105
+ }, Ce = (e, t) => x.gen(function* () {
106
+ let n = Se(), 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* b.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* b.sleep(`${be} millis`);
110
+ Date.now() - r >= n && (yield* x.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* x.sleep(`${xe} millis`);
111
111
  }
112
- }), Ce = (e, t) => b.gen(function* () {
112
+ }), we = (e, t) => x.gen(function* () {
113
113
  yield* e`SELECT pg_advisory_unlock(${t.toString()}::bigint)`;
114
- }), we = 30, Te = (e, t) => b.gen(function* () {
114
+ }), Te = 30, Ee = (e, t) => x.gen(function* () {
115
115
  (yield* e`
116
- SELECT GET_LOCK(${t}, ${we}) AS got`)[0]?.got !== 1 && (yield* b.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) => b.gen(function* () {
116
+ SELECT GET_LOCK(${t}, ${Te}) AS got`)[0]?.got !== 1 && (yield* x.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) => x.gen(function* () {
118
118
  yield* e`SELECT RELEASE_LOCK(${t})`;
119
- }), De = 3e4, Oe = (e, t) => b.gen(function* () {
119
+ }), Oe = 3e4, ke = (e, t) => x.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 = ${De};
123
+ @LockOwner = 'Session', @LockTimeout = ${Oe};
124
124
  SELECT @res AS res`;
125
- (n[0]?.res ?? -999) < 0 && (yield* b.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' (sp_getapplock returned ${n[0]?.res ?? "no row"}; another migration is in progress).`)));
126
- }), ke = (e, t) => b.gen(function* () {
125
+ (n[0]?.res ?? -999) < 0 && (yield* x.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) => x.gen(function* () {
127
127
  yield* e`EXEC sp_releaseapplock @Resource = ${t}, @LockOwner = 'Session'`;
128
- }), Ae = b.void, E = (e, t) => {
129
- let n = me(t);
128
+ }), je = x.void, E = (e, t) => {
129
+ let n = he(t);
130
130
  return e.onDialectOrElse({
131
- mysql: () => Te(e, T(n)),
132
- mssql: () => Oe(e, T(n)),
133
- sqlite: () => Ae,
134
- orElse: () => Se(e, ye(n))
131
+ mysql: () => Ee(e, T(n)),
132
+ mssql: () => ke(e, T(n)),
133
+ sqlite: () => je,
134
+ orElse: () => Ce(e, be(n))
135
135
  });
136
136
  }, D = (e, t) => {
137
- let n = me(t);
137
+ let n = he(t);
138
138
  return e.onDialectOrElse({
139
- mysql: () => Ee(e, T(n)),
140
- mssql: () => ke(e, T(n)),
141
- sqlite: () => Ae,
142
- orElse: () => Ce(e, ye(n))
139
+ mysql: () => De(e, T(n)),
140
+ mssql: () => Ae(e, T(n)),
141
+ sqlite: () => je,
142
+ orElse: () => we(e, be(n))
143
143
  });
144
- }, je = (e, t, n) => b.acquireUseRelease(E(e, n), () => t, () => D(e, n).pipe(b.orDie)), Me = (e) => e.onDialectOrElse({
144
+ }, Me = (e, t, n) => x.acquireUseRelease(E(e, n), () => t, () => D(e, n).pipe(x.orDie)), Ne = (e) => e.onDialectOrElse({
145
145
  pg: () => "postgres",
146
146
  mysql: () => "mysql",
147
147
  mssql: () => "mssql",
148
148
  sqlite: () => "sqlite",
149
149
  orElse: () => "sqlite"
150
- }), Ne = {
150
+ }), Pe = {
151
151
  postgres: "plan-transactional",
152
152
  mssql: "plan-transactional",
153
153
  mysql: "per-operation",
154
154
  mariadb: "per-operation",
155
155
  sqlite: "per-operation",
156
156
  turso: "per-operation"
157
- }, Pe = (e) => Ne[e], O = "_voltro_migration_ops", Fe = l(O, {
158
- id: e({ prefix: "mop" }),
159
- runId: _(),
160
- planFingerprint: _(),
161
- opIndex: n(),
162
- opKind: _(),
163
- opTarget: _(),
164
- status: _(),
165
- payload: _(),
166
- startedAt: t().nullable(),
167
- appliedAt: t().nullable(),
168
- durationMs: n().nullable(),
169
- createdAt: t().default("now")
170
- }), Ie = (e) => {
157
+ }, Fe = (e) => Pe[e], O = "_voltro_migration_ops", Ie = y(O, {
158
+ id: t({ prefix: "mop" }),
159
+ runId: e(),
160
+ planFingerprint: e(),
161
+ opIndex: r(),
162
+ opKind: e(),
163
+ opTarget: e(),
164
+ status: e(),
165
+ payload: e(),
166
+ startedAt: a().nullable(),
167
+ appliedAt: a().nullable(),
168
+ durationMs: r().nullable(),
169
+ createdAt: a().default("now")
170
+ }), Le = (e) => {
171
171
  switch (e.kind) {
172
172
  case "create-table": return /* @__PURE__ */ new Set([
173
173
  `table:${e.table}`,
@@ -194,11 +194,11 @@ var ie = (e, t, n, r = 400) => {
194
194
  case "add-unique-composite":
195
195
  case "drop-unique-composite": return /* @__PURE__ */ new Set([`unique:${e.table}.${e.name}`]);
196
196
  }
197
- }, Le = (e) => [...Ie(e)].join(" "), Re = (e, t) => {
198
- let n = Ie(t);
199
- for (let t of Ie(e)) if (n.has(t)) return !0;
197
+ }, Re = (e) => [...Le(e)].join(" "), ze = (e, t) => {
198
+ let n = Le(t);
199
+ for (let t of Le(e)) if (n.has(t)) return !0;
200
200
  return !1;
201
- }, ze = (e, t) => e.operations.some((e) => Re(e.op, t)), Be = "__voltro_rebuild", Ve = "__shadow", He = "__old", Ue = /* @__PURE__ */ new Set([
201
+ }, Be = (e, t) => e.operations.some((e) => ze(e.op, t)), Ve = "__voltro_rebuild", He = "__shadow", Ue = "__old", We = /* @__PURE__ */ new Set([
202
202
  "add-unique",
203
203
  "drop-unique",
204
204
  "add-unique-composite",
@@ -210,15 +210,15 @@ var ie = (e, t, n, r = 400) => {
210
210
  "alter-column-nullability",
211
211
  "alter-column-type",
212
212
  "alter-column-default"
213
- ]), We = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ge = (e, t, n) => {
213
+ ]), Ge = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ke = (e, t, n) => {
214
214
  let r = n === "sqlite" || n === "turso";
215
- return e.kind === "alter-column-type" && t === "online-required" || r && Ue.has(e.kind) ? "artefact-repair" : We.has(e.kind) ? "idempotent" : "probe-then-replay";
215
+ return e.kind === "alter-column-type" && t === "online-required" || r && We.has(e.kind) ? "artefact-repair" : Ge.has(e.kind) ? "idempotent" : "probe-then-replay";
216
216
  };
217
- Object.keys(Ne);
217
+ Object.keys(Pe);
218
218
  //#endregion
219
219
  //#region src/migrations/reactiveTriggerName.ts
220
- var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "framework_changes" ? `${Ke}${e}` : `${Ke}${t}_${e}`, Je = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Ye = "voltro:notify:v2", Xe = S({ scope: "voltro:migrate" }), A = (e) => {
221
- Xe.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
220
+ var k = "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 = ee({ scope: "voltro:migrate" }), A = (e) => {
221
+ Ze.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
222
222
  }, j = (e, t) => {
223
223
  let n = e.type;
224
224
  if (e.spatial) {
@@ -237,36 +237,36 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
237
237
  }, t)}[]`;
238
238
  if (t === "mysql" || t === "mariadb") return "JSON";
239
239
  if (t === "mssql") return "NVARCHAR(MAX)";
240
- if (r(t)) return "TEXT";
240
+ if (o(t)) return "TEXT";
241
241
  }
242
242
  if (n === "vector") {
243
243
  let n = e.vectorDim;
244
244
  if (n === void 0) throw Error("vector column is missing its dimension — this is a framework bug.");
245
- let i = e.vectorPrecision === "half";
246
- if (t === "postgres") return i ? `HALFVEC(${n})` : `VECTOR(${n})`;
245
+ let r = e.vectorPrecision === "half";
246
+ if (t === "postgres") return r ? `HALFVEC(${n})` : `VECTOR(${n})`;
247
247
  if (t === "mysql" || t === "mariadb") return `VECTOR(${n})`;
248
248
  if (t === "mssql") return "VARBINARY(MAX)";
249
- if (r(t)) return "BLOB";
249
+ if (o(t)) return "BLOB";
250
250
  }
251
251
  if (n === "interval") {
252
252
  if (t === "postgres") return "INTERVAL";
253
253
  if (t === "mysql" || t === "mariadb" || t === "mssql") return "BIGINT";
254
- if (r(t)) return "INTEGER";
254
+ if (o(t)) return "INTEGER";
255
255
  }
256
256
  if (n === "decimal") {
257
- let n = e.precision, i = e.scale ?? 0;
257
+ let n = e.precision, r = e.scale ?? 0;
258
258
  if (n === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
259
- return r(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${i})` : `DECIMAL(${n}, ${i})`;
259
+ return o(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
260
260
  }
261
- if (n === "bigint") return r(t) ? "INTEGER" : "BIGINT";
261
+ if (n === "bigint") return o(t) ? "INTEGER" : "BIGINT";
262
262
  if (n === "enum") {
263
263
  if (t === "postgres") return e.enumName ?? "TEXT";
264
264
  if (t === "mysql" || t === "mariadb") return `ENUM(${(e.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
265
265
  if (t === "mssql") return "NVARCHAR(255)";
266
- if (r(t)) return "TEXT";
266
+ if (o(t)) return "TEXT";
267
267
  }
268
- if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : r(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
269
- if (r(t)) switch (n) {
268
+ if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : o(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
269
+ if (o(t)) switch (n) {
270
270
  case "id": return "TEXT";
271
271
  case "text": return "TEXT";
272
272
  case "integer": return "INTEGER";
@@ -330,11 +330,11 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
330
330
  case "array": return "TEXT[]";
331
331
  case "interval": return "INTERVAL";
332
332
  }
333
- }, Ze = (e, t) => {
333
+ }, Qe = (e, t) => {
334
334
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
335
335
  let n = e.defaultValue;
336
- return n === "now" ? r(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? Qe(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
337
- }, Qe = (e, t, n) => {
336
+ return n === "now" ? o(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? $e(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
337
+ }, $e = (e, t, n) => {
338
338
  if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return M(e, n);
339
339
  let r = j({
340
340
  ...t,
@@ -354,7 +354,7 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
354
354
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
355
355
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
356
356
  }
357
- }, $e = (e, t) => {
357
+ }, P = (e, t) => {
358
358
  if (e === "restrict" && t === "mssql") return "NO ACTION";
359
359
  switch (e) {
360
360
  case "cascade": return "CASCADE";
@@ -362,14 +362,18 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
362
362
  case "setNull": return "SET NULL";
363
363
  case "noAction": return "NO ACTION";
364
364
  }
365
- }, et = (e, t, n) => n === null ? i(e, t) : `${i(n, t)}.${i(e, t)}`, tt = 191, nt = (e, t, n) => {
366
- let r = i(e, n);
367
- if (n !== "mysql" && n !== "mariadb") return r;
365
+ }, et = (e, t, r) => r === null ? n(e, t) : `${n(r, t)}.${n(e, t)}`, tt = 191, nt = (e, t) => {
366
+ if (!e || t !== "mysql" && t !== "mariadb") return !1;
367
+ let n = j(e, t).toUpperCase();
368
+ return n.endsWith("TEXT") || n.endsWith("BLOB");
369
+ }, rt = (e, t, r) => {
370
+ let i = n(e, r);
371
+ if (r !== "mysql" && r !== "mariadb") return i;
368
372
  let a = t[e];
369
- if (!a) return r;
370
- let o = j(a, n).toUpperCase();
371
- return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${r}(${tt})` : r;
372
- }, rt = (e, t) => {
373
+ if (!a) return i;
374
+ let o = j(a, r).toUpperCase();
375
+ return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${tt})` : i;
376
+ }, it = (e, t) => {
373
377
  if (!e.generatedAs) return null;
374
378
  let { expr: n, stored: r } = e.generatedAs;
375
379
  if (t === "postgres") return r || A("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
@@ -377,65 +381,70 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
377
381
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
378
382
  if (t === "turso") throw Error("@voltro/sql-turso: generated columns (.generatedAs(...)) are not supported — Turso's MVCC mode (journal_mode=experimental_mvcc) rejects them. Drop the generated column, or use the 'sqlite' / 'postgres' dialect for this table.");
379
383
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
380
- }, it = (e, t, n, a, o = !1, s = !1) => {
381
- if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, n);
382
- let c = n === "mssql" && t.type === "text" && !t.generatedAs && t.maxLength === void 0 && a?.has(e) ? "NVARCHAR(450)" : j(t, n), l = [i(e, n), c];
383
- t.type === "id" && !s && l.push("PRIMARY KEY");
384
- let u = rt(t, n);
385
- if (u) l.push(u);
384
+ }, at = (e, t, r, a, s = !1, c = !1) => {
385
+ if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, r);
386
+ let l = r === "mssql" && t.type === "text" && !t.generatedAs && t.maxLength === void 0 && a?.has(e) ? "NVARCHAR(450)" : j(t, r), u = [n(e, r), l];
387
+ t.type === "id" && !c && u.push("PRIMARY KEY");
388
+ let d = it(t, r);
389
+ if (d) u.push(d);
386
390
  else {
387
- t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && l.push("UNIQUE");
388
- let e = Ze(t, n);
389
- e && l.push(e);
391
+ t.nullable || u.push("NOT NULL"), t.unique && t.type !== "id" && !nt(t, r) && u.push("UNIQUE");
392
+ let e = Qe(t, r);
393
+ e && u.push(e);
390
394
  }
391
- if (t.type === "reference" && t.references && !o) {
395
+ if (t.type === "reference" && t.references && !s && !i(r)) {
392
396
  let e = t.references();
393
- l.push(`REFERENCES ${i(e.tableName, n)} (${i("id", n)})`);
394
- let r = $e(t.onDelete ?? "restrict", n);
395
- l.push(`ON DELETE ${r}`);
396
- let a = $e(t.refOnUpdate ?? "noAction", n);
397
- a !== "NO ACTION" && l.push(`ON UPDATE ${a}`);
397
+ u.push(`REFERENCES ${n(e.tableName, r)} (${n("id", r)})`);
398
+ let i = P(t.onDelete ?? "restrict", r);
399
+ u.push(`ON DELETE ${i}`);
400
+ let a = P(t.refOnUpdate ?? "noAction", r);
401
+ a !== "NO ACTION" && u.push(`ON UPDATE ${a}`);
398
402
  }
399
403
  if (t.oneOf && t.oneOf.length > 0) {
400
- let r = t.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
401
- l.push(`CHECK (${i(e, n)} IN (${r}))`);
404
+ let i = t.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
405
+ u.push(`CHECK (${n(e, r)} IN (${i}))`);
402
406
  }
403
- if (t.checks && t.checks.length > 0) for (let e of t.checks) l.push(`CHECK (${e})`);
404
- if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" || r(n))) {
405
- let r = t.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
406
- l.push(`CHECK (${i(e, n)} IN (${r}))`);
407
+ if (t.checks && t.checks.length > 0) for (let e of t.checks) u.push(`CHECK (${e})`);
408
+ if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (r === "mssql" || o(r))) {
409
+ let i = t.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
410
+ u.push(`CHECK (${n(e, r)} IN (${i}))`);
407
411
  }
408
412
  if (t.type === "json" || t.type === "array") {
409
- let t = i(e, n);
410
- r(n) ? l.push(`CHECK (${t} IS NULL OR json_valid(${t}))`) : n === "mssql" && l.push(`CHECK (${t} IS NULL OR ISJSON(${t}) = 1)`);
411
- }
412
- return l.join(" ");
413
- }, at = (e, t, n = null, r) => {
414
- let a = /* @__PURE__ */ new Set();
415
- for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
416
- for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
417
- let o = e.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(e.fields).map(([e, n]) => ` ${it(e, n, t, a, r?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((n) => {
418
- let r = n.fields.map((n) => nt(n, e.fields, t)).join(", ");
419
- return ` CONSTRAINT ${i(n.name, t)} UNIQUE (${r})`;
420
- }), u = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${i(e.name, t)} CHECK (${e.expr})`), d = [
421
- ...s ? [` PRIMARY KEY (${o.map((n) => nt(n, e.fields, t)).join(", ")})`] : [],
422
- ...l,
423
- ...u
424
- ], f = d.length > 0 ? `${c},\n${d.join(",\n")}` : c, p = et(e.tableName, t, n);
413
+ let t = n(e, r);
414
+ o(r) ? u.push(`CHECK (${t} IS NULL OR json_valid(${t}))`) : r === "mssql" && u.push(`CHECK (${t} IS NULL OR ISJSON(${t}) = 1)`);
415
+ }
416
+ return u.join(" ");
417
+ }, ot = (e, t, r = null, a) => {
418
+ let o = /* @__PURE__ */ new Set();
419
+ for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
420
+ for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
421
+ let s = e.appliedPrimaryKey ?? [], c = s.length > 0, l = Object.entries(e.fields).map(([e, n]) => ` ${at(e, n, t, o, a?.has(e) ?? !1, c)}`).join(",\n"), u = (e.appliedUniques ?? []).map((r) => {
422
+ let i = r.fields.map((n) => rt(n, e.fields, t)).join(", ");
423
+ return ` CONSTRAINT ${n(r.name, t)} UNIQUE (${i})`;
424
+ }), d = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${n(e.name, t)} CHECK (${e.expr})`), f = c ? [` PRIMARY KEY (${s.map((n) => rt(n, e.fields, t)).join(", ")})`] : [], p = i(t) ? Object.entries(e.fields).flatMap(([i, o]) => {
425
+ if (o.type !== "reference" || !o.references || (a?.has(i) ?? !1)) return [];
426
+ let s = o.references(), c = P(o.onDelete ?? "restrict", t), l = P(o.refOnUpdate ?? "noAction", t);
427
+ return [` CONSTRAINT ${n(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${n(i, t)}) REFERENCES ${et(s.tableName, t, r)} (${n("id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
428
+ }) : [], m = [
429
+ ...f,
430
+ ...u,
431
+ ...d,
432
+ ...p
433
+ ], h = m.length > 0 ? `${l},\n${m.join(",\n")}` : l, g = et(e.tableName, t, r);
425
434
  if (t === "mssql") {
426
- let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${p} (\n${f}\n)`;
427
- return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
435
+ let t = r === null ? e.tableName : `${r}.${e.tableName}`, n = `CREATE TABLE ${g} (\n${h}\n)`;
436
+ return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
428
437
  }
429
438
  return [
430
- `CREATE TABLE IF NOT EXISTS ${p} (`,
431
- f,
439
+ `CREATE TABLE IF NOT EXISTS ${g} (`,
440
+ h,
432
441
  ");"
433
442
  ].join("\n");
434
- }, ot = (e, t, n) => {
435
- let r = `${e}_${t.name}_fts`, a = (e) => i(e, n), o = t.columns.map(a).join(", "), s = t.columns.map((e) => `new.${a(e)}`).join(", "), c = [];
436
- return c.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${a(r)} USING fts5(${o}, row_id UNINDEXED, tokenize='porter');`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_ai`)} AFTER INSERT ON ${a(e)} BEGIN\n INSERT INTO ${a(r)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_ad`)} AFTER DELETE ON ${a(e)} BEGIN\n DELETE FROM ${a(r)} WHERE row_id = old.${a("id")};\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_au`)} AFTER UPDATE ON ${a(e)} BEGIN\n DELETE FROM ${a(r)} WHERE row_id = old.${a("id")};\n INSERT INTO ${a(r)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c;
437
- }, st = (e, t, n = null) => {
438
- let r = [], a = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, n, r, i) => {
443
+ }, st = (e, t, r) => {
444
+ let i = `${e}_${t.name}_fts`, a = (e) => n(e, r), o = t.columns.map(a).join(", "), s = t.columns.map((e) => `new.${a(e)}`).join(", "), c = [];
445
+ return c.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${a(i)} USING fts5(${o}, row_id UNINDEXED, tokenize='porter');`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_ai`)} AFTER INSERT ON ${a(e)} BEGIN\n INSERT INTO ${a(i)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_ad`)} AFTER DELETE ON ${a(e)} BEGIN\n DELETE FROM ${a(i)} WHERE row_id = old.${a("id")};\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_au`)} AFTER UPDATE ON ${a(e)} BEGIN\n DELETE FROM ${a(i)} WHERE row_id = old.${a("id")};\n INSERT INTO ${a(i)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c;
446
+ }, ct = (e, t, r = null) => {
447
+ let i = [], a = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, n, r, i) => {
439
448
  let a = {
440
449
  using: "",
441
450
  withSuffix: "",
@@ -463,7 +472,7 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
463
472
  } : (A(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
464
473
  if (r === "hnsw") {
465
474
  if (t === "postgres") {
466
- let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? y(i?.hnsw?.distance);
475
+ let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? h(i?.hnsw?.distance);
467
476
  return {
468
477
  using: " USING hnsw",
469
478
  withSuffix: ` WITH (m = ${e}, ef_construction = ${t})`,
@@ -480,59 +489,64 @@ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
480
489
  return a;
481
490
  }, c = (n, r) => {
482
491
  let i = n.map((n) => {
483
- if (typeof n == "string") return nt(n, e.fields, t);
492
+ if (typeof n == "string") return rt(n, e.fields, t);
484
493
  if ("jsonPath" in n) {
485
494
  let { column: e, path: r, numeric: i } = n.jsonPath;
486
- return `(${g(e, r, t, { numeric: i })})`;
495
+ return `(${_(e, r, t, { numeric: i })})`;
487
496
  }
488
497
  return `(${n.expr})`;
489
498
  });
490
499
  return r !== void 0 && i.length === 1 ? `${i[0]} ${r}` : i.join(", ");
491
- }, l = (e, r, a, o, l, u = "", d = !1) => {
492
- let f = s(e, r, o, l);
500
+ }, l = (e, i, a, o, l, u = "", d = !1) => {
501
+ let f = s(e, i, o, l);
493
502
  if (f.skip) return "";
494
- let p = c(a, f.opclass), m = `${f.withSuffix}${u}`, h = et(r, t, n), g = d ? "UNIQUE " : "";
495
- return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${i(e, t)} ON ${h}${f.using} (${p})${m};` : t === "mysql" ? `CREATE ${g}INDEX ${i(e, t)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${i(e, t)} ON ${h}${f.using} (${p})${m};`;
503
+ let p = c(a, f.opclass), m = `${f.withSuffix}${u}`, h = et(i, t, r), g = d ? "UNIQUE " : "";
504
+ return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${n(e, t)} ON ${h}${f.using} (${p})${m};` : t === "mysql" ? `CREATE ${g}INDEX ${n(e, t)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${n(e, t)} ON ${h}${f.using} (${p})${m};`;
496
505
  };
497
- for (let n of e.appliedFullText ?? []) if (t === "postgres") {
498
- let a = n.config ?? "english", o = `${n.name}_tsv`, s = n.columns.map((e) => {
499
- let r = n.weights?.[e] ?? "A";
500
- return `setweight(to_tsvector('${a}', coalesce(${i(e, t)}, '')), '${r}')`;
506
+ if (t === "mysql" || t === "mariadb") for (let [n, r] of Object.entries(e.fields)) {
507
+ if (!r.unique || r.type === "id" || !nt(r, t)) continue;
508
+ let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
509
+ a && i.push(a);
510
+ }
511
+ for (let r of e.appliedFullText ?? []) if (t === "postgres") {
512
+ let a = r.config ?? "english", o = `${r.name}_tsv`, s = r.columns.map((e) => {
513
+ let i = r.weights?.[e] ?? "A";
514
+ return `setweight(to_tsvector('${a}', coalesce(${n(e, t)}, '')), '${i}')`;
501
515
  }).join(" || ");
502
- r.push(`ALTER TABLE ${i(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${i(o, t)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), r.push(`CREATE INDEX IF NOT EXISTS ${i(n.name, t)} ON ${i(e.tableName, t)} USING GIN (${i(o, t)});`);
516
+ i.push(`ALTER TABLE ${n(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${n(o, t)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), i.push(`CREATE INDEX IF NOT EXISTS ${n(r.name, t)} ON ${n(e.tableName, t)} USING GIN (${n(o, t)});`);
503
517
  } else if (t === "mysql" || t === "mariadb") {
504
- let a = n.columns.map((e) => i(e, t)).join(", ");
505
- r.push(`CREATE FULLTEXT INDEX ${i(n.name, t)} ON ${i(e.tableName, t)} (${a});`);
506
- } else if (t === "turso") throw Error(`@voltro/sql-turso: full-text index '${n.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
507
- else t === "sqlite" ? r.push(...ot(e.tableName, n, t)) : A(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
518
+ let a = r.columns.map((e) => n(e, t)).join(", ");
519
+ i.push(`CREATE FULLTEXT INDEX ${n(r.name, t)} ON ${n(e.tableName, t)} (${a});`);
520
+ } else if (t === "turso") throw Error(`@voltro/sql-turso: full-text index '${r.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
521
+ else t === "sqlite" ? i.push(...st(e.tableName, r, t)) : A(`[voltro:migrate] full-text index '${r.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
508
522
  for (let n of e.appliedIndexes) {
509
523
  if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
510
524
  A(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
511
525
  continue;
512
526
  }
513
527
  if (n.unique && n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${n.name}' on '${e.tableName}' cannot be expressed on ${t} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${t}, or move this table to postgres/sqlite/mssql.`);
514
- let i = "";
515
- n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? A(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : i = ` WHERE ${n.where}`);
516
- let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, i, n.unique === !0);
517
- s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && a.add(o(n.fields));
528
+ let r = "";
529
+ n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? A(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : r = ` WHERE ${n.where}`);
530
+ let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, r, n.unique === !0);
531
+ s !== "" && i.push(s), n.fields.every((e) => typeof e == "string") && a.add(o(n.fields));
518
532
  }
519
533
  for (let [t, n] of Object.entries(e.fields)) {
520
534
  if (n.type !== "reference" || n.fkAutoIndex === !1 || a.has(o([t]))) continue;
521
- let i = `${e.tableName}_${t}_idx`;
522
- r.push(l(i, e.tableName, [t])), a.add(o([t]));
535
+ let r = `${e.tableName}_${t}_idx`;
536
+ i.push(l(r, e.tableName, [t])), a.add(o([t]));
523
537
  }
524
- return r.join("\n");
525
- }, ct = (e, t, n = k) => {
538
+ return i.join("\n");
539
+ }, lt = (e, t, n = k) => {
526
540
  if (t !== "postgres") return [];
527
541
  let r = e.filter((e) => e.isReactive !== !1);
528
- return r.length === 0 ? [] : [lt(n), ...r.map((e) => dt(e, n))];
529
- }, lt = (e) => `
530
- CREATE OR REPLACE FUNCTION ${Je(e)}() RETURNS trigger AS $$
542
+ return r.length === 0 ? [] : [ut(n), ...r.map((e) => ft(e, n))];
543
+ }, ut = (e) => `
544
+ CREATE OR REPLACE FUNCTION ${Ye(e)}() RETURNS trigger AS $$
531
545
  DECLARE
532
546
  payload TEXT;
533
547
  pk JSONB;
534
548
  BEGIN
535
- -- ${Ye}
549
+ -- ${Xe}
536
550
  payload := json_build_object(
537
551
  'table', TG_TABLE_NAME,
538
552
  -- The schema the write landed in. Under namespace isolation this is
@@ -586,22 +600,22 @@ BEGIN
586
600
  RETURN COALESCE(NEW, OLD);
587
601
  END;
588
602
  $$ LANGUAGE plpgsql;
589
- `.trim(), ut = (e, t) => {
590
- let n = qe(e.tableName, t);
603
+ `.trim(), dt = (e, t) => {
604
+ let n = Je(e.tableName, t);
591
605
  return [
592
606
  `ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL`,
593
607
  `DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}"`,
594
- `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${Je(t)}()`
608
+ `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${Ye(t)}()`
595
609
  ];
596
- }, dt = (e, t) => ut(e, t).map((e) => `${e};`).join("\n"), ft = (e) => {
610
+ }, ft = (e, t) => dt(e, t).map((e) => `${e};`).join("\n"), pt = (e) => {
597
611
  if (e.dialect !== "postgres") return [];
598
612
  let t = e.channel ?? "framework_changes", n = new Map(e.tables.map((e) => [e.tableName, e])), r = [], i = e.missing.filter((e) => n.has(e));
599
- (i.length > 0 || e.functionOutdated === !0) && r.push(lt(t));
600
- for (let e of i) r.push(...ut(n.get(e), t));
601
- for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${qe(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
613
+ (i.length > 0 || e.functionOutdated === !0) && r.push(ut(t));
614
+ for (let e of i) r.push(...dt(n.get(e), t));
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`);
602
616
  return r;
603
- }, pt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), mt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), ht = (e) => {
604
- let t = new Map(e.map((e) => [e.tableName, e])), n = de(e.map((e) => e.tableName), (e) => {
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) => {
605
619
  let n = t.get(e);
606
620
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
607
621
  if (n.type !== "reference" || !n.references) return [];
@@ -637,30 +651,30 @@ $$ LANGUAGE plpgsql;
637
651
  sorted: o,
638
652
  cyclic: r
639
653
  };
640
- }, gt = (e, t, n = null) => {
641
- let r = (e) => n ? `${i(n, t)}.${i(e, t)}` : i(e, t), a = `${e.table}_${e.column}_fkey`, o = $e(e.onDelete, t), s = $e(e.onUpdate, t), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${i(a, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${i(e.column, t)}) REFERENCES ${r(e.targetTable)} (${i("id", t)})${c}`;
654
+ }, _t = (e, t, r = null) => {
655
+ let i = (e) => r ? `${n(r, t)}.${n(e, t)}` : n(e, t), a = `${e.table}_${e.column}_fkey`, o = P(e.onDelete, t), s = P(e.onUpdate, t), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${n(a, t)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${n(e.column, t)}) REFERENCES ${i(e.targetTable)} (${n("id", t)})${c}`;
642
656
  switch (t) {
643
657
  case "postgres": return [
644
658
  "DO $$ BEGIN",
645
659
  " IF NOT EXISTS (SELECT 1 FROM pg_constraint",
646
- ` WHERE conname = '${a}' AND conrelid = '${n ? `${n}.` : ""}${e.table}'::regclass) THEN`,
647
- ` ALTER TABLE ${r(e.table)} ${l(!1)};`,
660
+ ` WHERE conname = '${a}' AND conrelid = '${r ? `${r}.` : ""}${e.table}'::regclass) THEN`,
661
+ ` ALTER TABLE ${i(e.table)} ${l(!1)};`,
648
662
  " END IF;",
649
663
  "END $$;"
650
664
  ].join("\n");
651
- case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${a}') ALTER TABLE ${r(e.table)} ${l(!1)};`;
652
- case "mariadb": return `ALTER TABLE ${r(e.table)} ${l(!0)};`;
653
- default: return `ALTER TABLE ${r(e.table)} ${l(!1)};`;
665
+ case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${a}') ALTER TABLE ${i(e.table)} ${l(!1)};`;
666
+ case "mariadb": return `ALTER TABLE ${i(e.table)} ${l(!0)};`;
667
+ default: return `ALTER TABLE ${i(e.table)} ${l(!1)};`;
654
668
  }
655
- }, _t = (e, t) => {
669
+ }, vt = (e, t) => {
656
670
  let n = /* @__PURE__ */ new Map();
657
- if (r(t)) return n;
671
+ if (o(t)) return n;
658
672
  for (let t of e) {
659
673
  let e = n.get(t.table) ?? /* @__PURE__ */ new Set();
660
674
  e.add(t.column), n.set(t.table, e);
661
675
  }
662
676
  return n;
663
- }, vt = (e, t) => {
677
+ }, yt = (e, t) => {
664
678
  if (t !== "postgres") return "";
665
679
  let n = /* @__PURE__ */ new Map();
666
680
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -676,12 +690,12 @@ $$ LANGUAGE plpgsql;
676
690
  r.push(`DO $$ BEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${e.replace(/'/g, "''")}') THEN\n CREATE TYPE "${e}" AS ENUM (${n});\n END IF;\nEND $$;`);
677
691
  }
678
692
  return r.join("\n\n");
679
- }, yt = (e, t) => {
693
+ }, bt = (e, t) => {
680
694
  if (t !== "postgres") return "";
681
695
  let n = /* @__PURE__ */ new Set();
682
696
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
683
697
  let r = [];
684
- for (let e of n) for (let { from: t, to: n } of s(e)) {
698
+ for (let e of n) for (let { from: t, to: n } of b(e)) {
685
699
  let i = e.replace(/'/g, "''"), a = t.replace(/'/g, "''"), o = n.replace(/'/g, "''");
686
700
  r.push(`DO \$\$
687
701
  DECLARE
@@ -690,95 +704,95 @@ BEGIN
690
704
  SELECT oid INTO type_oid FROM pg_type WHERE typname = '${i}';\n IF type_oid IS NOT NULL\n AND EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${a}')\n AND NOT EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${o}') THEN\n IF current_setting('server_version_num')::int >= 140000 THEN\n EXECUTE format('ALTER TYPE %I RENAME VALUE %L TO %L', '${i}', '${a}', '${o}');\n ELSE\n UPDATE pg_enum SET enumlabel = '${o}' WHERE enumtypid = type_oid AND enumlabel = '${a}';\n END IF;\n END IF;\nEND $$;`);
691
705
  }
692
706
  return r.join("\n\n");
693
- }, bt = (e) => {
707
+ }, xt = (e) => {
694
708
  let t = [], n = [];
695
- for (let r of e) f(r) ? n.push(r) : t.push(r);
709
+ for (let r of e) p(r) ? n.push(r) : t.push(r);
696
710
  return {
697
711
  tables: t,
698
712
  views: n
699
713
  };
700
- }, xt = (e, t, n = k) => {
701
- let { tables: i, views: o } = bt(e), { sorted: s, cyclic: c } = ht(i.map((e) => ue(e, t))), l = _t(c, t), u = [];
702
- t === "postgres" && pt(s) && u.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && mt(s) && u.push("CREATE EXTENSION IF NOT EXISTS postgis;");
703
- let d = yt(s, t);
714
+ }, St = (e, t, n = k) => {
715
+ let { tables: r, views: i } = xt(e), { sorted: a, cyclic: c } = gt(r.map((e) => de(e, t))), l = vt(c, t), u = [];
716
+ t === "postgres" && mt(a) && u.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && ht(a) && u.push("CREATE EXTENSION IF NOT EXISTS postgis;");
717
+ let d = bt(a, t);
704
718
  d && u.push(d);
705
- let f = vt(s, t);
719
+ let f = yt(a, t);
706
720
  f && u.push(f);
707
- for (let e of s) u.push(at(e, t, null, l.get(e.tableName)));
708
- if (!r(t)) for (let e of c) u.push(gt(e, t));
709
- for (let e of s) {
710
- let n = st(e, t);
721
+ for (let e of a) u.push(ot(e, t, null, l.get(e.tableName)));
722
+ if (!o(t)) for (let e of c) u.push(_t(e, t));
723
+ for (let e of a) {
724
+ let n = ct(e, t);
711
725
  n && u.push(n);
712
726
  }
713
- u.push(...ct(s, t, n));
714
- for (let e of o) u.push(a(e, t));
727
+ u.push(...lt(a, t, n));
728
+ for (let e of i) u.push(s(e, t));
715
729
  return u.join("\n\n") + "\n";
716
- }, St = (e, t, n) => {
717
- let r = i(e, t);
730
+ }, Ct = (e, t, r) => {
731
+ let i = n(e, t);
718
732
  switch (t) {
719
- case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
733
+ case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${i};`;
720
734
  case "mysql":
721
- case "mariadb": return `CREATE DATABASE IF NOT EXISTS ${r};`;
722
- case "mssql": return `IF SCHEMA_ID('${e.replace(/'/g, "''")}') IS NULL EXEC(N'CREATE SCHEMA ${r.replace(/'/g, "''")}');`;
735
+ case "mariadb": return `CREATE DATABASE IF NOT EXISTS ${i};`;
736
+ case "mssql": return `IF SCHEMA_ID('${e.replace(/'/g, "''")}') IS NULL EXEC(N'CREATE SCHEMA ${i.replace(/'/g, "''")}');`;
723
737
  case "turso":
724
- case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
725
- }
726
- }, Ct = (e, t, n, a) => {
727
- let o = St(n, t, a), s = i(n, t);
728
- if (t === "postgres") return `${o}\n\nSET search_path TO ${s};\n\n${xt(e, t)}`;
729
- if (t === "mysql" || t === "mariadb") return `${o}\n\nUSE ${s};\n\n${xt(e, t)}`;
730
- let { sorted: c, cyclic: l } = ht(e), u = _t(l, t), d = [o];
731
- for (let e of c) d.push(at(e, t, n, u.get(e.tableName)));
732
- if (!r(t)) for (let e of l) d.push(gt(e, t, n));
738
+ case "sqlite": return `ATTACH DATABASE '${(r ?? `${e}.db`).replace(/'/g, "''")}' AS ${i};`;
739
+ }
740
+ }, wt = (e, t, r, i) => {
741
+ let a = Ct(r, t, i), s = n(r, t);
742
+ if (t === "postgres") return `${a}\n\nSET search_path TO ${s};\n\n${St(e, t)}`;
743
+ if (t === "mysql" || t === "mariadb") return `${a}\n\nUSE ${s};\n\n${St(e, t)}`;
744
+ let { sorted: c, cyclic: l } = gt(e), u = vt(l, t), d = [a];
745
+ for (let e of c) d.push(ot(e, t, r, u.get(e.tableName)));
746
+ if (!o(t)) for (let e of l) d.push(_t(e, t, r));
733
747
  for (let e of c) {
734
- let r = st(e, t, n);
735
- r && d.push(r);
748
+ let n = ct(e, t, r);
749
+ n && d.push(n);
736
750
  }
737
751
  return d.join("\n\n") + "\n";
738
- }, wt = (e, t, n = k) => {
739
- let { sorted: r, cyclic: i } = ht(e), a = _t(i, t), o = [], s = yt(r, t);
752
+ }, Tt = (e, t, n = k) => {
753
+ let { sorted: r, cyclic: i } = gt(e), a = vt(i, t), o = [], s = bt(r, t);
740
754
  s && o.push(s);
741
- let c = vt(r, t);
755
+ let c = yt(r, t);
742
756
  c && o.push(c);
743
- for (let e of r) o.push(at(e, t, null, a.get(e.tableName)));
744
- for (let e of i) o.push(gt(e, t));
745
- return o.push(...ct(r, t, n)), o.join("\n\n") + "\n";
746
- }, Tt = (e, t = "postgres", n = k, r = {}) => b.gen(function* () {
757
+ for (let e of r) o.push(ot(e, t, null, a.get(e.tableName)));
758
+ for (let e of i) o.push(_t(e, t));
759
+ return o.push(...lt(r, t, n)), o.join("\n\n") + "\n";
760
+ }, Et = (e, t = "postgres", n = k, r = {}) => x.gen(function* () {
747
761
  let i = yield* C.SqlClient;
748
- yield* je(i, Mt(i, xt(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(b.orDie);
749
- }), Et = (e, t) => {
762
+ yield* Me(i, Nt(i, St(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(x.orDie);
763
+ }), Dt = (e, t) => {
750
764
  let n = t.cause ?? {};
751
765
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
752
- }, Dt = (e, t) => {
766
+ }, Ot = (e, t) => {
753
767
  let n = e.trimStart();
754
768
  return !!(/\bIF NOT EXISTS\b/i.test(n) || /^CREATE OR REPLACE\b/i.test(n) || /^DROP\s[\s\S]*?\bIF EXISTS\b/i.test(n) || /^SET search_path\b/i.test(n) || /^USE[\s`"[]/i.test(n) || /^IF\s/i.test(n) || (t === "mysql" || t === "mariadb") && /^CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(n));
755
- }, Ot = () => {
769
+ }, kt = () => {
756
770
  let e = Number(process.env.VOLTRO_MIGRATION_DDL_RETRIES);
757
771
  return Number.isInteger(e) && e >= 0 ? e : 4;
758
- }, kt = (e) => ({
772
+ }, At = (e) => ({
759
773
  while: e,
760
- times: Ot(),
761
- schedule: x.jittered(x.exponential("50 millis"))
762
- }), At = class {
774
+ times: kt(),
775
+ schedule: S.jittered(S.exponential("50 millis"))
776
+ }), jt = class {
763
777
  statement;
764
778
  error;
765
779
  _tag = "DdlStatementFailed";
766
780
  constructor(e, t) {
767
781
  this.statement = e, this.error = t;
768
782
  }
769
- }, jt = (e, t, n) => b.gen(function* () {
770
- let r = yield* C.SqlClient, i = n !== void 0 && Pe(t) === "per-operation";
771
- for (let a of Nt(e)) {
772
- process.env.VOLTRO_MIGRATE_DEBUG === "1" && Xe.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
773
- let e = r.unsafe(a).pipe(b.catchIf((e) => Et(a, e), () => b.succeed([])), b.tapError((e) => b.sync(() => {
774
- Xe.error(ie("migrate: statement failed", a, e, 200));
783
+ }, Mt = (e, t, n) => x.gen(function* () {
784
+ let r = yield* C.SqlClient, i = n !== void 0 && Fe(t) === "per-operation";
785
+ for (let a of Pt(e)) {
786
+ process.env.VOLTRO_MIGRATE_DEBUG === "1" && Ze.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
787
+ let e = r.unsafe(a).pipe(x.catchIf((e) => Dt(a, e), () => x.succeed([])), x.tapError((e) => x.sync(() => {
788
+ Ze.error(ae("migrate: statement failed", a, e, 200));
775
789
  })));
776
- yield* (i && n !== void 0 && Dt(a, t) ? e.pipe(b.retry(kt((e) => n(e) === "retry"))) : e).pipe(b.mapError((e) => new At(a, e)));
790
+ yield* (i && n !== void 0 && Ot(a, t) ? e.pipe(x.retry(At((e) => n(e) === "retry"))) : e).pipe(x.mapError((e) => new jt(a, e)));
777
791
  }
778
- }), Mt = (e, t, n, r) => {
779
- let i = n === "turso" ? jt(t, n, r) : e.withTransaction(jt(t, n, r)), a = (e) => e instanceof At ? e.error : e;
780
- return (r !== void 0 && Pe(n) === "plan-transactional" ? i.pipe(b.retry(kt((e) => r(a(e)) === "retry"))) : i).pipe(b.orDieWith((e) => e instanceof At ? Error(ie("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
781
- }, Nt = (e) => {
792
+ }), Nt = (e, t, n, r) => {
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(x.retry(At((e) => r(a(e)) === "retry"))) : i).pipe(x.orDieWith((e) => e instanceof jt ? Error(ae("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
795
+ }, Pt = (e) => {
782
796
  let t = [], n = "", r = !1;
783
797
  for (let i = 0; i < e.length; i++) {
784
798
  if (e.slice(i, i + 2) === "$$") {
@@ -793,43 +807,43 @@ BEGIN
793
807
  }
794
808
  let i = n.trim();
795
809
  return i.length > 0 && t.push(i), t;
796
- }, Pt = async (e, t, n = "postgres", r = {}) => {
797
- await b.runPromise(Tt(e, n, void 0, r).pipe(b.provide(t)));
798
- }, Ft = (e, t, n = "postgres", r = {}) => b.gen(function* () {
799
- let i = Ct(e, n, t), a = yield* C.SqlClient;
800
- yield* je(a, Mt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(b.orDie);
801
- }), It = async (e, t, n, r = "postgres", i = {}) => {
802
- await b.runPromise(Ft(e, t, r, i).pipe(b.provide(n))), await d({
810
+ }, Ft = async (e, t, n = "postgres", r = {}) => {
811
+ await x.runPromise(Et(e, n, void 0, r).pipe(x.provide(t)));
812
+ }, It = (e, t, n = "postgres", r = {}) => x.gen(function* () {
813
+ let i = wt(e, n, t), a = yield* C.SqlClient;
814
+ yield* Me(a, Nt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(x.orDie);
815
+ }), Lt = async (e, t, n, r = "postgres", i = {}) => {
816
+ await x.runPromise(It(e, t, r, i).pipe(x.provide(n))), await f({
803
817
  namespace: t,
804
818
  dialect: r
805
819
  });
806
- }, Lt = async (e, t, n = "postgres", r = {}) => {
807
- await b.runPromise(b.gen(function* () {
808
- let t = wt(e, n), i = yield* C.SqlClient;
809
- yield* je(i, Mt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(b.orDie);
810
- }).pipe(b.provide(t)));
811
- }, Rt = (e) => {
820
+ }, Rt = async (e, t, n = "postgres", r = {}) => {
821
+ await x.runPromise(x.gen(function* () {
822
+ let t = Tt(e, n), i = yield* C.SqlClient;
823
+ yield* Me(i, Nt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(x.orDie);
824
+ }).pipe(x.provide(t)));
825
+ }, zt = (e) => {
812
826
  if (e == null) return e;
813
- if (Array.isArray(e)) return e.map(Rt);
827
+ if (Array.isArray(e)) return e.map(zt);
814
828
  if (typeof e != "object") return e;
815
829
  let t = {};
816
830
  for (let n of Object.keys(e).sort()) {
817
831
  let r = e[n];
818
- r !== void 0 && (t[n] = Rt(r));
832
+ r !== void 0 && (t[n] = zt(r));
819
833
  }
820
834
  return t;
821
- }, zt = (e) => {
835
+ }, Bt = (e) => {
822
836
  if (!e.idScheme && !e.sensitive && !e.safe) return e;
823
837
  let { idScheme: t, sensitive: n, safe: r, ...i } = e;
824
838
  return i;
825
- }, Bt = (e) => [...e].map(zt).sort((e, t) => e.name.localeCompare(t.name)), Vt = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), Ht = (e) => [...e].map((e) => ({
839
+ }, Vt = (e) => [...e].map(Bt).sort((e, t) => e.name.localeCompare(t.name)), Ht = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), Ut = (e) => [...e].map((e) => ({
826
840
  name: e.name,
827
- columns: Bt(e.columns),
828
- indexes: Vt(e.indexes)
829
- })).sort((e, t) => e.name.localeCompare(t.name)), P = (e) => {
830
- let t = { tables: Ht(e.tables) }, n = JSON.stringify(Rt(t));
831
- return ee("sha256").update(n).digest("hex");
832
- }, F = (e) => e.slice(0, 16), Ut = (e, t) => {
841
+ columns: Vt(e.columns),
842
+ indexes: Ht(e.indexes)
843
+ })).sort((e, t) => e.name.localeCompare(t.name)), F = (e) => {
844
+ let t = { tables: Ut(e.tables) }, n = JSON.stringify(zt(t));
845
+ return te("sha256").update(n).digest("hex");
846
+ }, I = (e) => e.slice(0, 16), Wt = (e, t) => {
833
847
  let n = t.references ? {
834
848
  table: t.references().tableName,
835
849
  column: "id",
@@ -868,7 +882,7 @@ BEGIN
868
882
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
869
883
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
870
884
  };
871
- }, Wt = (e) => {
885
+ }, Gt = (e) => {
872
886
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
873
887
  n.has(e.name) || (n.add(e.name), t.push(e));
874
888
  }, i = e.appliedPrimaryKey ?? [];
@@ -908,7 +922,7 @@ BEGIN
908
922
  let i = n;
909
923
  if (i.dropped || !i.references || i.fkAutoIndex === !1 || s.has(t)) continue;
910
924
  let a = `${e.tableName}_${t}_idx`;
911
- p(e.tableName, a, !0, [t]), r({
925
+ u(e.tableName, a, !0, [t]), r({
912
926
  name: a,
913
927
  table: e.tableName,
914
928
  columns: [t],
@@ -916,11 +930,11 @@ BEGIN
916
930
  });
917
931
  }
918
932
  return t;
919
- }, Gt = (e) => {
933
+ }, Kt = (e) => {
920
934
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
921
935
  for (let [r, i] of Object.entries(e.fields)) {
922
936
  if (i.dropped) continue;
923
- let e = Ut(r, i);
937
+ let e = Wt(r, i);
924
938
  n.push(t.has(r) ? {
925
939
  ...e,
926
940
  unique: !0
@@ -930,27 +944,27 @@ BEGIN
930
944
  return {
931
945
  name: e.tableName,
932
946
  columns: n,
933
- indexes: Wt(e),
947
+ indexes: Gt(e),
934
948
  ...r.length > 0 ? { primaryKey: [...r] } : {},
935
949
  ...i === void 0 ? {} : { renamedFrom: i }
936
950
  };
937
- }, Kt = (e) => {
951
+ }, qt = (e) => {
938
952
  let t = /* @__PURE__ */ new Map();
939
953
  for (let n of e) for (let e of n.indexes) {
940
954
  let r = t.get(e.name);
941
955
  if (r !== void 0 && r !== n.name) throw Error(`duplicate index name '${e.name}' across tables '${r}' and '${n.name}'. Index names must be unique per SCHEMA, not just per table — the DB creates only one, so the other never applies and 'db plan' re-emits it forever. Give each an explicit, table-prefixed name (e.g. '${n.name}_${e.name}').`);
942
956
  t.set(e.name, n.name);
943
957
  }
944
- }, I = (e, t) => {
945
- let n = e.map((e) => Gt(ue(e, t)));
946
- return Kt(n), { tables: n };
947
- }, qt = (e, t, n = k) => b.gen(function* () {
958
+ }, L = (e, t) => {
959
+ let n = e.map((e) => Kt(de(e, t)));
960
+ return qt(n), { tables: n };
961
+ }, Jt = (e, t, n = k) => x.gen(function* () {
948
962
  let r = (yield* e`
949
963
  SELECT p.prosrc
950
964
  FROM pg_proc p
951
965
  JOIN pg_namespace n ON n.oid = p.pronamespace
952
966
  WHERE n.nspname = current_schema()
953
- AND p.proname = ${Je(n)}
967
+ AND p.proname = ${Ye(n)}
954
968
  `)[0]?.prosrc, i = r !== void 0 && !r.includes("voltro:notify:v2"), a = t.filter((e) => !e.tableName.startsWith("_voltro_"));
955
969
  if (a.length === 0) return {
956
970
  missing: [],
@@ -964,10 +978,10 @@ BEGIN
964
978
  JOIN pg_namespace n ON n.oid = c.relnamespace
965
979
  WHERE NOT t.tgisinternal
966
980
  AND n.nspname = current_schema()
967
- AND t.tgname LIKE ${`${Ke}%`}
981
+ AND t.tgname LIKE ${`${qe}%`}
968
982
  `, s = new Set(o.map((e) => e.tgname)), c = [], l = [];
969
983
  for (let e of a) {
970
- let t = s.has(qe(e.tableName, n)), r = e.isReactive !== !1;
984
+ let t = s.has(Je(e.tableName, n)), r = e.isReactive !== !1;
971
985
  r && !t && c.push(e.tableName), !r && t && l.push(e.tableName);
972
986
  }
973
987
  return {
@@ -975,7 +989,7 @@ BEGIN
975
989
  stale: l.sort(),
976
990
  functionOutdated: i
977
991
  };
978
- }), Jt = (e) => {
992
+ }), Yt = (e) => {
979
993
  let t = [];
980
994
  if (e.missing.length > 0) {
981
995
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -986,19 +1000,19 @@ BEGIN
986
1000
  t.push(`${e.stale.length} .nonReactive() table(s) still carry a change trigger — ${n}. They keep paying REPLICA IDENTITY FULL and a NOTIFY on every write for a subscription nobody receives. \`voltro db apply\` removes them.`);
987
1001
  }
988
1002
  return e.functionOutdated && t.push("The change-notify function in this database is OLDER than the framework installed here. Its triggers fire, so nothing looks wrong — but a row too large for a NOTIFY payload (postgres caps it at 8000 bytes) is emitted without its primary key, and a change that carries no key cannot be re-read: it reaches subscriptions as a re-query and reaches every TAP — search index, analytics mirror, cdc-out, row history — as nothing at all. Run `voltro db apply` to replace it."), t.length > 0 ? t.join("\n") : void 0;
989
- }, Yt = {
1003
+ }, Xt = {
990
1004
  postgres: !0,
991
1005
  mysql: !0,
992
1006
  mariadb: !0,
993
1007
  mssql: !0,
994
1008
  sqlite: !0
995
- }, Xt = {
1009
+ }, Zt = {
996
1010
  postgres: !0,
997
1011
  mysql: !1,
998
1012
  mariadb: !1,
999
1013
  mssql: !0,
1000
1014
  sqlite: !0
1001
- }, Zt = (e) => {
1015
+ }, Qt = (e) => {
1002
1016
  switch (e) {
1003
1017
  case "add-column":
1004
1018
  case "drop-column":
@@ -1008,47 +1022,47 @@ BEGIN
1008
1022
  case "add-foreign-key":
1009
1023
  case "add-unique":
1010
1024
  case "add-unique-composite":
1011
- case "add-check": return Xt;
1012
- default: return Yt;
1025
+ case "add-check": return Zt;
1026
+ default: return Xt;
1013
1027
  }
1014
- }, Qt = (e, t) => {
1028
+ }, $t = (e, t) => {
1015
1029
  let n = new Map(t.tables.map((e) => [e.name, e]));
1016
1030
  return new Map(e.map((e) => [e.tableName, {
1017
1031
  table: e,
1018
1032
  snapshot: n.get(e.tableName),
1019
1033
  columnDefs: e.fields
1020
1034
  }]));
1021
- }, L = (e) => {
1035
+ }, R = (e) => {
1022
1036
  if (typeof e != "object" || !e) return JSON.stringify(e);
1023
- if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1037
+ if (Array.isArray(e)) return `[${e.map(R).join(",")}]`;
1024
1038
  let t = e;
1025
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1026
- }, $t = (e) => {
1039
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${R(t[e])}`).join(",")}}`;
1040
+ }, en = (e) => {
1027
1041
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1028
1042
  let t = e.defaultValue;
1029
1043
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1030
1044
  if (typeof t == "number") return String(t);
1031
- if (typeof t != "string") return L(t);
1045
+ if (typeof t != "string") return R(t);
1032
1046
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1033
1047
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1034
1048
  let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
1035
1049
  if (o) try {
1036
- return L(JSON.parse(o[1]));
1050
+ return R(JSON.parse(o[1]));
1037
1051
  } catch {}
1038
1052
  let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1039
1053
  if (s) try {
1040
- return L(JSON.parse(s[1]));
1054
+ return R(JSON.parse(s[1]));
1041
1055
  } catch {}
1042
1056
  if (a.startsWith("{") || a.startsWith("[")) try {
1043
- return L(JSON.parse(a));
1057
+ return R(JSON.parse(a));
1044
1058
  } catch {}
1045
1059
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1046
- }, en = (e, t) => {
1047
- let n = $t(e), r = $t(t);
1060
+ }, tn = (e, t) => {
1061
+ let n = en(e), r = en(t);
1048
1062
  if (n === r) return !0;
1049
1063
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1050
1064
  return i(n) === i(r);
1051
- }, tn = (e) => {
1065
+ }, nn = (e) => {
1052
1066
  if (!e) return null;
1053
1067
  let t = (e) => e === "restrict" ? "noAction" : e;
1054
1068
  return {
@@ -1057,25 +1071,25 @@ BEGIN
1057
1071
  onDelete: t(e.onDelete),
1058
1072
  onUpdate: t(e.onUpdate)
1059
1073
  };
1060
- }, nn = (e, t) => {
1074
+ }, rn = (e, t) => {
1061
1075
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1062
1076
  if (!n && !r) return !0;
1063
1077
  if (!n || !r || n.length !== r.length) return !1;
1064
1078
  let i = [...n].sort(), a = [...r].sort();
1065
1079
  return i.every((e, t) => e === a[t]);
1066
- }, rn = (e, t) => {
1080
+ }, an = (e, t) => {
1067
1081
  try {
1068
1082
  let n = /\((\d+)\)/.exec(j(e, t));
1069
1083
  return n ? Number(n[1]) : void 0;
1070
1084
  } catch {
1071
1085
  return;
1072
1086
  }
1073
- }, an = (e, t, n) => n === void 0 || r(n) ? !0 : e.type !== "text" || t.type !== "text" || rn(e, n) === t.maxLength, on = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && en(e, t) && an(e, t, n) && JSON.stringify(tn(e.references)) === JSON.stringify(tn(t.references)) && nn(e.oneOf, t.oneOf), sn = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1087
+ }, on = (e, t, n) => n === void 0 || o(n) ? !0 : e.type !== "text" || t.type !== "text" || an(e, n) === t.maxLength, sn = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && tn(e, t) && on(e, t, n) && JSON.stringify(nn(e.references)) === JSON.stringify(nn(t.references)) && rn(e.oneOf, t.oneOf), cn = (e, t) => t.oneOf && t.oneOf.length > 0 ? z({
1074
1088
  kind: "add-check",
1075
1089
  table: e,
1076
1090
  column: t.name,
1077
1091
  values: t.oneOf
1078
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, cn = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), ln = (e, t, n) => {
1092
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, ln = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), un = (e, t, n) => {
1079
1093
  let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [];
1080
1094
  for (let t of e.columns) {
1081
1095
  let e = r.get(t.name);
@@ -1083,7 +1097,7 @@ BEGIN
1083
1097
  a.push(t);
1084
1098
  continue;
1085
1099
  }
1086
- on(t, e, n) || s.push({
1100
+ sn(t, e, n) || s.push({
1087
1101
  declared: t,
1088
1102
  live: e
1089
1103
  });
@@ -1094,47 +1108,47 @@ BEGIN
1094
1108
  removed: o,
1095
1109
  changed: s
1096
1110
  };
1097
- }, un = (e, t) => {
1111
+ }, dn = (e, t) => {
1098
1112
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
1099
1113
  for (let t of e.indexes) {
1100
1114
  let e = n.get(t.name);
1101
- (!e || !cn(t, e)) && i.push(t);
1115
+ (!e || !ln(t, e)) && i.push(t);
1102
1116
  }
1103
1117
  for (let e of t.indexes) r.has(e.name) || a.push(e);
1104
1118
  return {
1105
1119
  added: i,
1106
1120
  removed: a
1107
1121
  };
1108
- }, R = (e, t, n, r) => ({
1122
+ }, z = (e, t, n, r) => ({
1109
1123
  op: e,
1110
1124
  classification: t,
1111
- atomicByDialect: Zt(e.kind),
1125
+ atomicByDialect: Qt(e.kind),
1112
1126
  ...n ? { reason: n } : {},
1113
1127
  ...r ? { blocked: r } : {}
1114
- }), dn = (e, t, n) => {
1128
+ }), fn = (e, t, n) => {
1115
1129
  let r = {
1116
1130
  kind: "add-column",
1117
1131
  table: e,
1118
1132
  column: t
1119
1133
  };
1120
- return t.nullable ? R(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? R(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? R(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : R(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1121
- }, fn = (e, t, n) => {
1134
+ return t.nullable ? z(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? z(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? z(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : z(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1135
+ }, pn = (e, t, n) => {
1122
1136
  let r = {
1123
1137
  kind: "drop-column",
1124
1138
  table: e,
1125
1139
  column: t.name
1126
1140
  };
1127
- return n?.dropped ? R(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : R(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1128
- }, pn = (e, t, n, r, i) => R({
1141
+ return n?.dropped ? z(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : z(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1142
+ }, mn = (e, t, n, r, i) => z({
1129
1143
  kind: "create-table",
1130
1144
  table: e,
1131
1145
  columns: t,
1132
1146
  indexes: n,
1133
1147
  ...r && r.length > 0 ? { primaryKey: r } : {}
1134
- }, "safe", i ?? "new table — no data to preserve"), mn = (e) => R({
1148
+ }, "safe", i ?? "new table — no data to preserve"), hn = (e) => z({
1135
1149
  kind: "drop-table",
1136
1150
  table: e
1137
- }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), hn = 5e4, gn = (e, t, n, r) => {
1151
+ }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), gn = 5e4, _n = (e, t, n, r) => {
1138
1152
  let i = (n ?? 0) >= r, a;
1139
1153
  return a = t.unique ? t.columns.length === 1 ? {
1140
1154
  kind: "add-unique",
@@ -1149,16 +1163,16 @@ BEGIN
1149
1163
  kind: "add-index",
1150
1164
  table: e,
1151
1165
  index: t
1152
- }, i ? R(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1153
- }, _n = (e, t) => t.unique && t.columns.length > 1 ? R({
1166
+ }, i ? z(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1167
+ }, vn = (e, t) => t.unique && t.columns.length > 1 ? z({
1154
1168
  kind: "drop-unique-composite",
1155
1169
  table: e,
1156
1170
  name: t.name
1157
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
1171
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : z({
1158
1172
  kind: "drop-index",
1159
1173
  table: e,
1160
1174
  index: t.name
1161
- }, "safe", "drop index (no data loss — index is derived data)"), vn = (e, t) => {
1175
+ }, "safe", "drop index (no data loss — index is derived data)"), yn = (e, t) => {
1162
1176
  if (e === "reference") return "text";
1163
1177
  switch (t) {
1164
1178
  case "sqlite":
@@ -1166,7 +1180,7 @@ BEGIN
1166
1180
  case "mssql": return e === "json" ? "text" : e;
1167
1181
  default: return e;
1168
1182
  }
1169
- }, yn = (e, t, n, i, a, o) => {
1183
+ }, bn = (e, t, n, r, i, a) => {
1170
1184
  let s = [];
1171
1185
  if (t.nullable !== n.nullable) {
1172
1186
  let n = {
@@ -1175,7 +1189,7 @@ BEGIN
1175
1189
  column: t.name,
1176
1190
  toNullable: t.nullable
1177
1191
  };
1178
- s.push(t.nullable ? R(n, "safe", `loosen ${e}.${t.name} to nullable`) : R(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1192
+ s.push(t.nullable ? z(n, "safe", `loosen ${e}.${t.name} to nullable`) : z(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1179
1193
  }
1180
1194
  if (t.unique !== n.unique) {
1181
1195
  if (t.unique) {
@@ -1183,15 +1197,15 @@ BEGIN
1183
1197
  kind: "add-unique",
1184
1198
  table: e,
1185
1199
  column: t.name
1186
- }, r = (a ?? 0) >= o;
1187
- s.push(r ? R(n, "online-required", `online unique build on ${a} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1188
- } else s.push(R({
1200
+ }, r = (i ?? 0) >= a;
1201
+ s.push(r ? z(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1202
+ } else s.push(z({
1189
1203
  kind: "drop-unique",
1190
1204
  table: e,
1191
1205
  column: t.name
1192
1206
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1193
1207
  }
1194
- if (vn(t.type, i) !== vn(n.type, i)) {
1208
+ if (yn(t.type, r) !== yn(n.type, r)) {
1195
1209
  let r = t.narrowedFrom;
1196
1210
  if (r && r.from === n.type) {
1197
1211
  let i = {
@@ -1202,7 +1216,7 @@ BEGIN
1202
1216
  to: t.type,
1203
1217
  ...r.using === void 0 ? {} : { using: r.using }
1204
1218
  };
1205
- s.push(R(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1219
+ s.push(z(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1206
1220
  } else {
1207
1221
  let r = {
1208
1222
  kind: "alter-column-type",
@@ -1211,12 +1225,12 @@ BEGIN
1211
1225
  from: n.type,
1212
1226
  to: t.type
1213
1227
  };
1214
- s.push(R(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1228
+ s.push(z(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1215
1229
  }
1216
1230
  }
1217
- if (t.type === "text" && n.type === "text" && !r(i ?? "postgres") && t.maxLength !== n.maxLength) {
1231
+ if (t.type === "text" && n.type === "text" && !o(r ?? "postgres") && t.maxLength !== n.maxLength) {
1218
1232
  let r = t.maxLength === void 0 || n.maxLength !== void 0 && t.maxLength > n.maxLength, i = n.maxLength === void 0 ? "unbounded" : `varchar(${n.maxLength})`, a = t.maxLength === void 0 ? "unbounded" : `varchar(${t.maxLength})`;
1219
- s.push(R({
1233
+ s.push(z({
1220
1234
  kind: "alter-column-type",
1221
1235
  table: e,
1222
1236
  column: t.name,
@@ -1224,7 +1238,7 @@ BEGIN
1224
1238
  to: "text"
1225
1239
  }, r ? "safe" : "needs-backfill", r ? `text length ${i} → ${a} on ${e}.${t.name} — widening, no data can be lost` : `text length ${i} → ${a} on ${e}.${t.name} — NARROWING; the ALTER fails if any existing value is longer than ${String(t.maxLength)}. Check first: SELECT COUNT(*) FROM ${e} WHERE LENGTH(${t.name}) > ${String(t.maxLength)}`));
1226
1240
  }
1227
- if (!en(t, n)) {
1241
+ if (!tn(t, n)) {
1228
1242
  let n = {
1229
1243
  kind: "alter-column-default",
1230
1244
  table: e,
@@ -1232,23 +1246,23 @@ BEGIN
1232
1246
  hasDefault: t.hasDefault,
1233
1247
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1234
1248
  };
1235
- s.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1249
+ s.push(z(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1236
1250
  }
1237
- if (!nn(t.oneOf, n.oneOf)) {
1238
- n.oneOf && n.oneOf.length > 0 && s.push(R({
1251
+ if (!rn(t.oneOf, n.oneOf)) {
1252
+ n.oneOf && n.oneOf.length > 0 && s.push(z({
1239
1253
  kind: "drop-check",
1240
1254
  table: e,
1241
1255
  column: t.name
1242
1256
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1243
- let r = sn(e, t);
1257
+ let r = cn(e, t);
1244
1258
  r && s.push(r);
1245
1259
  }
1246
- return JSON.stringify(tn(t.references)) !== JSON.stringify(tn(n.references)) && (n.references && s.push(R({
1260
+ return JSON.stringify(nn(t.references)) !== JSON.stringify(nn(n.references)) && (n.references && s.push(z({
1247
1261
  kind: "drop-foreign-key",
1248
1262
  table: e,
1249
1263
  column: t.name
1250
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), s.push(...bn(e, t))), s;
1251
- }, bn = (e, t) => {
1264
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), s.push(...xn(e, t))), s;
1265
+ }, xn = (e, t) => {
1252
1266
  let n = [];
1253
1267
  if (!t.references) return n;
1254
1268
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1260,15 +1274,15 @@ BEGIN
1260
1274
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1261
1275
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1262
1276
  };
1263
- return i === "null" && !t.nullable ? n.push(R(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(R({
1277
+ return i === "null" && !t.nullable ? n.push(z(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(z({
1264
1278
  ...a,
1265
1279
  orphanPolicy: i
1266
- }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(R(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1267
- }, xn = (e, t, n) => {
1280
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(z(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1281
+ }, Sn = (e, t, n) => {
1268
1282
  let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = new Set(n.removed.map((e) => e.name)), s = new Set(n.added.map((e) => e.name));
1269
1283
  for (let [n, c] of Object.entries(t)) {
1270
1284
  let t = c.renamedFrom;
1271
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1285
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(z({
1272
1286
  kind: "rename-column",
1273
1287
  table: e.tableName,
1274
1288
  from: t,
@@ -1280,26 +1294,26 @@ BEGIN
1280
1294
  consumedAddedNames: i,
1281
1295
  consumedRemovedNames: a
1282
1296
  };
1283
- }, Sn = /* @__PURE__ */ new Set([
1297
+ }, Cn = /* @__PURE__ */ new Set([
1284
1298
  "postgres",
1285
1299
  "mysql",
1286
1300
  "mariadb",
1287
1301
  "mssql"
1288
- ]), Cn = {
1302
+ ]), wn = {
1289
1303
  ops: [],
1290
1304
  consumedAddedNames: /* @__PURE__ */ new Set(),
1291
1305
  consumedRemovedNames: /* @__PURE__ */ new Set()
1292
- }, wn = (e) => !e.unique && !e.expression, Tn = (e, t, n, r, i) => {
1293
- if (i === void 0 || !Sn.has(i)) return Cn;
1294
- let a = t.added.filter((e) => wn(e) && !r.has(e.name));
1295
- if (a.length === 0) return Cn;
1306
+ }, Tn = (e) => !e.unique && !e.expression, En = (e, t, n, r, i) => {
1307
+ if (i === void 0 || !Cn.has(i)) return wn;
1308
+ let a = t.added.filter((e) => Tn(e) && !r.has(e.name));
1309
+ if (a.length === 0) return wn;
1296
1310
  let o = (e) => e.columns.map((e) => n.get(e) ?? e).join("\0"), s = (e) => e.columns.join("\0"), c = [], l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Set();
1297
1311
  for (let n of t.removed) {
1298
- if (!wn(n)) continue;
1312
+ if (!Tn(n)) continue;
1299
1313
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1300
1314
  if (r.length !== 1) continue;
1301
1315
  let i = r[0];
1302
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1316
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(z({
1303
1317
  kind: "rename-index",
1304
1318
  table: e,
1305
1319
  from: n.name,
@@ -1311,7 +1325,7 @@ BEGIN
1311
1325
  consumedAddedNames: l,
1312
1326
  consumedRemovedNames: u
1313
1327
  };
1314
- }, En = (e, t, n) => {
1328
+ }, Dn = (e, t, n) => {
1315
1329
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1316
1330
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1317
1331
  for (let c of e.tables) {
@@ -1322,7 +1336,7 @@ BEGIN
1322
1336
  continue;
1323
1337
  }
1324
1338
  if (t.has(c.name)) {
1325
- r.push(R({
1339
+ r.push(z({
1326
1340
  kind: "rename-table",
1327
1341
  from: e,
1328
1342
  to: c.name
@@ -1330,14 +1344,14 @@ BEGIN
1330
1344
  continue;
1331
1345
  }
1332
1346
  if ((s.get(e) ?? 0) !== 1) {
1333
- r.push(R({
1347
+ r.push(z({
1334
1348
  kind: "rename-table",
1335
1349
  from: e,
1336
1350
  to: c.name
1337
1351
  }, "needs-rename-annotation", `.renamedFrom('${e}') is claimed by ${s.get(e)} tables — nothing says which receives its rows`, { fix: `remove the \`.renamedFrom('${e}')\` marker from all but one of them.` }));
1338
1352
  continue;
1339
1353
  }
1340
- i.set(c.name, e), a.add(e), r.push(R({
1354
+ i.set(c.name, e), a.add(e), r.push(z({
1341
1355
  kind: "rename-table",
1342
1356
  from: e,
1343
1357
  to: c.name
@@ -1351,19 +1365,19 @@ BEGIN
1351
1365
  claimedOldNames: c,
1352
1366
  refusals: o
1353
1367
  };
1354
- }, Dn = (e, t, n, r) => {
1368
+ }, On = (e, t, n, r) => {
1355
1369
  if (t === void 0) return {
1356
1370
  live: e,
1357
1371
  ops: []
1358
1372
  };
1359
- let i = r !== void 0 && Sn.has(r), a = [], o = e.indexes.map((e) => {
1373
+ let i = r !== void 0 && Cn.has(r), a = [], o = e.indexes.map((e) => {
1360
1374
  if (!e.name.startsWith(t)) return e;
1361
1375
  let r = `${n}${e.name.slice(t.length)}`;
1362
1376
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1363
1377
  ...e,
1364
1378
  name: r,
1365
1379
  table: n
1366
- } : i ? (a.push(R({
1380
+ } : i ? (a.push(z({
1367
1381
  kind: "rename-index",
1368
1382
  table: n,
1369
1383
  from: e.name,
@@ -1382,7 +1396,7 @@ BEGIN
1382
1396
  },
1383
1397
  ops: a
1384
1398
  };
1385
- }, On = (e) => {
1399
+ }, kn = (e) => {
1386
1400
  let t = {
1387
1401
  safe: 0,
1388
1402
  needsDefault: 0,
@@ -1415,42 +1429,42 @@ BEGIN
1415
1429
  case "multi-step": t.multiStep++;
1416
1430
  }
1417
1431
  return t;
1418
- }, kn = (e) => {
1419
- let t = I(e.declared, e.dialect), n = Qt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? hn, a = [], o = En(t, r, n);
1432
+ }, An = (e) => {
1433
+ let t = L(e.declared, e.dialect), n = $t(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? gn, a = [], o = Dn(t, r, n);
1420
1434
  a.push(...o.ops);
1421
1435
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1422
- a.push(pn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1436
+ a.push(mn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1423
1437
  for (let t of e.columns) {
1424
- let n = sn(e.name, t);
1438
+ let n = cn(e.name, t);
1425
1439
  n && a.push(n);
1426
1440
  }
1427
1441
  }
1428
1442
  let s = new Set(e.ignoreTables ?? []);
1429
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || m(t.name) || v(t.name) || s.has(t.name) || a.push(mn(t.name));
1443
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || m(t.name) || v(t.name) || s.has(t.name) || a.push(hn(t.name));
1430
1444
  for (let s of t.tables) {
1431
1445
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1432
1446
  if (!c) continue;
1433
- let l = Dn(c, t, s.name, e.dialect);
1447
+ let l = On(c, t, s.name, e.dialect);
1434
1448
  a.push(...l.ops);
1435
- let u = l.live, d = n.get(s.name), f = ln(s, u, e.dialect), p = un(s, u), m = xn(d.table, d.columnDefs, f);
1449
+ let u = l.live, d = n.get(s.name), f = un(s, u, e.dialect), p = dn(s, u), m = Sn(d.table, d.columnDefs, f);
1436
1450
  a.push(...m.ops);
1437
1451
  for (let e of f.removed) {
1438
1452
  if (m.consumedRemovedNames.has(e.name) || v(e.name)) continue;
1439
1453
  let t = d.columnDefs[e.name];
1440
- a.push(fn(s.name, e, t));
1454
+ a.push(pn(s.name, e, t));
1441
1455
  }
1442
1456
  for (let e of f.added) {
1443
1457
  if (m.consumedAddedNames.has(e.name)) continue;
1444
1458
  let t = d.columnDefs[e.name];
1445
- a.push(dn(s.name, e, t));
1446
- let n = sn(s.name, e);
1447
- n && a.push(n), a.push(...bn(s.name, e));
1459
+ a.push(fn(s.name, e, t));
1460
+ let n = cn(s.name, e);
1461
+ n && a.push(n), a.push(...xn(s.name, e));
1448
1462
  }
1449
- let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Tn(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1463
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = En(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1450
1464
  a.push(...g.ops);
1451
- for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(gn(s.name, e, u.rowCount, i));
1452
- for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(_n(s.name, e));
1453
- for (let { declared: t, live: n } of f.changed) a.push(...yn(s.name, t, n, e.dialect, u.rowCount, i));
1465
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(_n(s.name, e, u.rowCount, i));
1466
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(vn(s.name, e));
1467
+ for (let { declared: t, live: n } of f.changed) a.push(...bn(s.name, t, n, e.dialect, u.rowCount, i));
1454
1468
  }
1455
1469
  let c = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), l = new Map(t.tables.map((e) => [e.name, e])), u = (e) => {
1456
1470
  let t = l.get(e);
@@ -1458,8 +1472,8 @@ BEGIN
1458
1472
  column: e.name,
1459
1473
  target: e.references.table
1460
1474
  }] : []) : [];
1461
- }, d = de([...c], u), f = [];
1462
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(R({
1475
+ }, d = fe([...c], u), f = [];
1476
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(z({
1463
1477
  kind: "add-foreign-key",
1464
1478
  table: e.name,
1465
1479
  column: t.name,
@@ -1531,19 +1545,19 @@ BEGIN
1531
1545
  });
1532
1546
  return {
1533
1547
  operations: S,
1534
- fromFingerprint: P(e.live),
1535
- toFingerprint: P(t),
1536
- summary: On(S)
1548
+ fromFingerprint: F(e.live),
1549
+ toFingerprint: F(t),
1550
+ summary: kn(S)
1537
1551
  };
1538
- }, An = (e) => {
1552
+ }, jn = (e) => {
1539
1553
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1540
1554
  if (!t) return null;
1541
- let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
1555
+ let n = [...e.replace(/\\'/g, "''").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
1542
1556
  return n.length === 0 ? null : {
1543
1557
  column: t[1],
1544
1558
  values: n
1545
1559
  };
1546
- }, jn = (e, t) => {
1560
+ }, Mn = (e, t) => {
1547
1561
  if (t === "vector") return "vector";
1548
1562
  switch (e) {
1549
1563
  case "text":
@@ -1570,7 +1584,7 @@ BEGIN
1570
1584
  case "USER-DEFINED": return "text";
1571
1585
  default: return "text";
1572
1586
  }
1573
- }, z = (e) => {
1587
+ }, B = (e) => {
1574
1588
  switch (e.toUpperCase()) {
1575
1589
  case "CASCADE": return "cascade";
1576
1590
  case "RESTRICT": return "restrict";
@@ -1578,25 +1592,25 @@ BEGIN
1578
1592
  case "SET DEFAULT": return "noAction";
1579
1593
  default: return "noAction";
1580
1594
  }
1581
- }, Mn = (e, t) => {
1595
+ }, Nn = (e, t) => {
1582
1596
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1583
1597
  return Number.isInteger(n) && n > 0 ? n : t;
1584
- }, Nn = () => Mn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Pn = 300, Fn = () => {
1598
+ }, Pn = () => Nn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Fn = 300, In = () => {
1585
1599
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1586
- return e !== void 0 && e.trim() === "0" ? 0 : Mn(e, 3e4);
1587
- }, In = (e, t) => {
1600
+ return e !== void 0 && e.trim() === "0" ? 0 : Nn(e, 3e4);
1601
+ }, Ln = (e, t) => {
1588
1602
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1589
1603
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1590
1604
  return r;
1591
- }, Ln = (e) => {
1592
- let t = Fn(), n = b.gen(function* () {
1605
+ }, Rn = (e) => {
1606
+ let t = In(), n = x.gen(function* () {
1593
1607
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1594
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Nn(), a = (e, t) => b.gen(function* () {
1608
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Pn(), a = (e, t) => x.gen(function* () {
1595
1609
  let r = [];
1596
- for (let a of In(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1610
+ for (let a of Ln(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1597
1611
  return r;
1598
1612
  }), o = [];
1599
- for (let t = 0;; t += Pn) {
1613
+ for (let t = 0;; t += Fn) {
1600
1614
  let n = yield* e`
1601
1615
  SELECT c.relname AS table_name,
1602
1616
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1604,9 +1618,9 @@ BEGIN
1604
1618
  JOIN pg_namespace n ON n.oid = c.relnamespace
1605
1619
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1606
1620
  ORDER BY c.relname
1607
- LIMIT ${r(Pn)} OFFSET ${r(t)}
1621
+ LIMIT ${r(Fn)} OFFSET ${r(t)}
1608
1622
  `;
1609
- if (o.push(...n), n.length < Pn) break;
1623
+ if (o.push(...n), n.length < Fn) break;
1610
1624
  }
1611
1625
  let s = /* @__PURE__ */ new Set(), c = [];
1612
1626
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1692,7 +1706,7 @@ BEGIN
1692
1706
  AND c.relname IN ${t}
1693
1707
  )
1694
1708
  SELECT * FROM ix ORDER BY table_name, index_name, position
1695
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map();
1709
+ `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), ee = /* @__PURE__ */ new Map();
1696
1710
  for (let e of u) {
1697
1711
  let t = _.get(e.table_name);
1698
1712
  t || (t = [], _.set(e.table_name, t)), t.push(e);
@@ -1701,25 +1715,25 @@ BEGIN
1701
1715
  let t = v.get(e.table_name);
1702
1716
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1703
1717
  }
1704
- let ee = /* @__PURE__ */ new Map();
1718
+ let C = /* @__PURE__ */ new Map();
1705
1719
  for (let e of f) {
1706
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = ee.get(t);
1720
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = C.get(t);
1707
1721
  n || (n = {
1708
1722
  table: e.table_name,
1709
1723
  columns: []
1710
- }, ee.set(t, n)), n.columns.push({
1724
+ }, C.set(t, n)), n.columns.push({
1711
1725
  name: e.column_name,
1712
1726
  position: e.position
1713
1727
  });
1714
1728
  }
1715
- for (let [e, t] of ee) {
1729
+ for (let [e, t] of C) {
1716
1730
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1717
1731
  if (n.length === 1) {
1718
1732
  let e = y.get(t.table);
1719
1733
  e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
1720
1734
  } else {
1721
- let r = x.get(t.table);
1722
- r || (r = [], x.set(t.table, r)), r.push({
1735
+ let r = b.get(t.table);
1736
+ r || (r = [], b.set(t.table, r)), r.push({
1723
1737
  name: e.slice(e.indexOf("\0") + 1),
1724
1738
  table: t.table,
1725
1739
  columns: n,
@@ -1732,24 +1746,24 @@ BEGIN
1732
1746
  t || (t = [], S.set(e.source_table, t)), t.push(e);
1733
1747
  }
1734
1748
  for (let e of g) {
1735
- let t = C.get(e.table_name);
1736
- t || (t = /* @__PURE__ */ new Map(), C.set(e.table_name, t));
1749
+ let t = ee.get(e.table_name);
1750
+ t || (t = /* @__PURE__ */ new Map(), ee.set(e.table_name, t));
1737
1751
  let n = t.get(e.index_name);
1738
1752
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1739
1753
  }
1740
1754
  let te = [];
1741
1755
  for (let e of c) {
1742
1756
  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 = S.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) => {
1743
- 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" : jn(t.data_type, t.udt_name), c = a ? {
1757
+ 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" : Mn(t.data_type, t.udt_name), c = a ? {
1744
1758
  table: a.target_table,
1745
1759
  column: a.target_column,
1746
- onDelete: z(a.delete_rule),
1747
- onUpdate: z(a.update_rule)
1760
+ onDelete: B(a.delete_rule),
1761
+ onUpdate: B(a.update_rule)
1748
1762
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1749
1763
  return {
1750
1764
  name: t.column_name,
1751
1765
  type: s,
1752
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1766
+ ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
1753
1767
  nullable: t.is_nullable === "YES",
1754
1768
  unique: i.has(t.column_name) || n && t.column_name === "id",
1755
1769
  hasDefault: t.column_default !== null,
@@ -1757,7 +1771,7 @@ BEGIN
1757
1771
  ...c ? { references: c } : {},
1758
1772
  ...l ? { oneOf: l } : {}
1759
1773
  };
1760
- }), l = [], u = C.get(e.table_name);
1774
+ }), l = [], u = ee.get(e.table_name);
1761
1775
  if (u) for (let [t, n] of u) {
1762
1776
  let r = /* @__PURE__ */ new Set(), i = [...n].filter((e) => e.column_name !== null && e.position !== null).sort((e, t) => (e.position ?? 0) - (t.position ?? 0)).filter((e) => {
1763
1777
  let t = e.position;
@@ -1773,7 +1787,7 @@ BEGIN
1773
1787
  ...a ? { expression: !0 } : {}
1774
1788
  });
1775
1789
  }
1776
- for (let t of x.get(e.table_name) ?? []) l.push(t);
1790
+ for (let t of b.get(e.table_name) ?? []) l.push(t);
1777
1791
  r.size > 0 && l.push({
1778
1792
  name: `${e.table_name}_pkey`,
1779
1793
  table: e.table_name,
@@ -1790,11 +1804,11 @@ BEGIN
1790
1804
  }
1791
1805
  return { tables: te };
1792
1806
  });
1793
- return (t > 0 ? e.withTransaction(n) : n).pipe(b.catchAll((e) => {
1807
+ return (t > 0 ? e.withTransaction(n) : n).pipe(x.catchAll((e) => {
1794
1808
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1795
- return n.includes("statement timeout") || n.includes("57014") ? b.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : b.fail(e);
1809
+ return n.includes("statement timeout") || n.includes("57014") ? x.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : x.fail(e);
1796
1810
  }));
1797
- }, Rn = (e, t) => {
1811
+ }, zn = (e, t) => {
1798
1812
  switch (e.toLowerCase()) {
1799
1813
  case "varchar":
1800
1814
  case "char":
@@ -1826,21 +1840,21 @@ BEGIN
1826
1840
  case "json": return "json";
1827
1841
  default: return "text";
1828
1842
  }
1829
- }, B = (e) => e.map((e) => {
1843
+ }, V = (e) => e.map((e) => {
1830
1844
  let t = e, n = {};
1831
1845
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1832
1846
  return n;
1833
- }), zn = (e) => b.gen(function* () {
1834
- let t = B(yield* e`
1847
+ }), Bn = (e) => x.gen(function* () {
1848
+ let t = V(yield* e`
1835
1849
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1836
1850
  FROM information_schema.tables
1837
1851
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1838
- ORDER BY table_name`), n = B(yield* e`
1852
+ ORDER BY table_name`), n = V(yield* e`
1839
1853
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1840
1854
  character_maximum_length
1841
1855
  FROM information_schema.columns
1842
1856
  WHERE table_schema = DATABASE()
1843
- ORDER BY table_name, ordinal_position`), r = B(yield* e`
1857
+ ORDER BY table_name, ordinal_position`), r = V(yield* e`
1844
1858
  SELECT k.table_name AS source_table,
1845
1859
  k.column_name AS source_column,
1846
1860
  k.referenced_table_name AS target_table,
@@ -1850,21 +1864,24 @@ BEGIN
1850
1864
  JOIN information_schema.referential_constraints r
1851
1865
  ON k.constraint_name = r.constraint_name
1852
1866
  AND k.table_schema = r.constraint_schema
1853
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = B(yield* e`
1867
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = V(yield* e`
1854
1868
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1855
1869
  FROM information_schema.statistics
1856
1870
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1857
- ORDER BY table_name, index_name, seq_in_index`), a = B(yield* e`
1858
- SELECT table_name, check_clause
1859
- FROM information_schema.check_constraints
1860
- WHERE constraint_schema = DATABASE()`.unprepared.pipe(b.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
1871
+ ORDER BY table_name, index_name, seq_in_index`), a = V(yield* e`
1872
+ SELECT tc.table_name AS table_name, cc.check_clause AS check_clause
1873
+ FROM information_schema.check_constraints cc
1874
+ JOIN information_schema.table_constraints tc
1875
+ ON tc.constraint_schema = cc.constraint_schema
1876
+ AND tc.constraint_name = cc.constraint_name
1877
+ WHERE cc.constraint_schema = DATABASE()`.unprepared.pipe(x.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
1861
1878
  for (let e of a) {
1862
1879
  let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
1863
1880
  if (t) {
1864
1881
  o.add(`${e.table_name}.${t[1]}`);
1865
1882
  continue;
1866
1883
  }
1867
- let n = An(e.check_clause);
1884
+ let n = jn(e.check_clause);
1868
1885
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1869
1886
  }
1870
1887
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1887,17 +1904,17 @@ BEGIN
1887
1904
  let t = c.get(e.table_name) ?? [], n = l.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), f = u.get(e.table_name);
1888
1905
  if (f) for (let e of f.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1889
1906
  let p = t.map((t) => {
1890
- let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Rn(t.data_type, t.column_type), u = c ? {
1907
+ let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : zn(t.data_type, t.column_type), u = c ? {
1891
1908
  table: c.target_table,
1892
1909
  column: c.target_column,
1893
- onDelete: z(c.delete_rule),
1894
- onUpdate: z(c.update_rule)
1910
+ onDelete: B(c.delete_rule),
1911
+ onUpdate: B(c.update_rule)
1895
1912
  } : void 0, d = a.has(t.column_name) || n && t.column_name === "id", f = t.column_default === "NULL" ? null : t.column_default, p = s.get(`${e.table_name}.${t.column_name}`);
1896
1913
  return {
1897
1914
  name: t.column_name,
1898
1915
  type: l,
1899
1916
  nullable: t.is_nullable === "YES",
1900
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1917
+ ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
1901
1918
  unique: d,
1902
1919
  hasDefault: f !== null,
1903
1920
  ...f === null ? {} : { defaultValue: f },
@@ -1929,10 +1946,10 @@ BEGIN
1929
1946
  });
1930
1947
  }
1931
1948
  return { tables: d };
1932
- }), Bn = (e) => {
1949
+ }), Vn = (e) => {
1933
1950
  let t = e.toUpperCase();
1934
1951
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1935
- }, Vn = (e) => b.gen(function* () {
1952
+ }, Hn = (e) => x.gen(function* () {
1936
1953
  let t = yield* e`
1937
1954
  SELECT name, sql FROM sqlite_master
1938
1955
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1949,11 +1966,11 @@ BEGIN
1949
1966
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1950
1967
  }
1951
1968
  let p = o.map((e) => {
1952
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Bn(e.type), a = r ? {
1969
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Vn(e.type), a = r ? {
1953
1970
  table: r.table,
1954
1971
  column: r.to,
1955
- onDelete: z(r.on_delete),
1956
- onUpdate: z(r.on_update)
1972
+ onDelete: B(r.on_delete),
1973
+ onUpdate: B(r.on_update)
1957
1974
  } : void 0, o = t.get(e.name);
1958
1975
  return {
1959
1976
  name: e.name,
@@ -1988,7 +2005,7 @@ BEGIN
1988
2005
  });
1989
2006
  }
1990
2007
  return { tables: r };
1991
- }), Hn = (e) => {
2008
+ }), Un = (e) => {
1992
2009
  switch (e.toLowerCase()) {
1993
2010
  case "int":
1994
2011
  case "smallint":
@@ -2010,7 +2027,7 @@ BEGIN
2010
2027
  case "image": return "bytes";
2011
2028
  default: return "text";
2012
2029
  }
2013
- }, V = (e) => e === !0 || e === 1, Un = (e) => b.gen(function* () {
2030
+ }, H = (e) => e === !0 || e === 1, Wn = (e) => x.gen(function* () {
2014
2031
  let t = yield* e`
2015
2032
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2016
2033
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -2067,21 +2084,21 @@ BEGIN
2067
2084
  let t = s.get(e) ?? [], n = c.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = new Set(n.map((e) => e.source_column)), a = l.get(e), d = [], f = /* @__PURE__ */ new Set();
2068
2085
  if (a) for (let [, e] of a) {
2069
2086
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2070
- if (V(t[0].is_primary)) for (let e of t) d.push(e.column_name);
2071
- else V(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
2087
+ if (H(t[0].is_primary)) for (let e of t) d.push(e.column_name);
2088
+ else H(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
2072
2089
  }
2073
2090
  let p = t.map((t) => {
2074
- let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Hn(t.data_type), s = i ? {
2091
+ let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Un(t.data_type), s = i ? {
2075
2092
  table: i.target_table,
2076
2093
  column: i.target_column,
2077
- onDelete: Wn(i.delete_rule),
2078
- onUpdate: Wn(i.update_rule)
2079
- } : void 0, c = t.column_default === null ? null : Gn(t.column_default), l = o.get(`${e}.${t.column_name}`);
2094
+ onDelete: Gn(i.delete_rule),
2095
+ onUpdate: Gn(i.update_rule)
2096
+ } : void 0, c = t.column_default === null ? null : Kn(t.column_default), l = o.get(`${e}.${t.column_name}`);
2080
2097
  return {
2081
2098
  name: t.column_name,
2082
2099
  type: a,
2083
2100
  nullable: t.is_nullable === "YES",
2084
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2101
+ ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
2085
2102
  unique: f.has(t.column_name) || n && t.column_name === "id",
2086
2103
  hasDefault: c !== null,
2087
2104
  ...c === null ? {} : { defaultValue: c },
@@ -2091,11 +2108,11 @@ BEGIN
2091
2108
  }), m = [];
2092
2109
  if (a) for (let [t, n] of a) {
2093
2110
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2094
- V(r[0].is_primary) || r.length === 1 && V(r[0].is_unique) || r.length === 1 && !V(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
2111
+ H(r[0].is_primary) || r.length === 1 && H(r[0].is_unique) || r.length === 1 && !H(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
2095
2112
  name: t,
2096
2113
  table: e,
2097
2114
  columns: r.map((e) => e.column_name),
2098
- unique: V(r[0].is_unique)
2115
+ unique: H(r[0].is_unique)
2099
2116
  });
2100
2117
  }
2101
2118
  d.length > 0 && m.push({
@@ -2110,54 +2127,87 @@ BEGIN
2110
2127
  });
2111
2128
  }
2112
2129
  return { tables: u };
2113
- }), Wn = (e) => {
2130
+ }), Gn = (e) => {
2114
2131
  switch (e.toUpperCase().replace(/_/g, " ")) {
2115
2132
  case "CASCADE": return "cascade";
2116
2133
  case "SET NULL": return "setNull";
2117
2134
  case "SET DEFAULT": return "noAction";
2118
2135
  default: return "noAction";
2119
2136
  }
2120
- }, Gn = (e) => {
2137
+ }, Kn = (e) => {
2121
2138
  let t = e.trim();
2122
2139
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2123
2140
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2124
- }, Kn = /* @__PURE__ */ new Set([
2141
+ }, qn = /* @__PURE__ */ new Set([
2125
2142
  "character varying",
2126
2143
  "varchar",
2127
2144
  "nvarchar",
2128
2145
  "char",
2129
2146
  "character",
2130
2147
  "nchar"
2131
- ]), H = (e, t) => {
2132
- if (!Kn.has(e.toLowerCase())) return;
2148
+ ]), U = (e, t) => {
2149
+ if (!qn.has(e.toLowerCase())) return;
2133
2150
  let n = Number(t);
2134
2151
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2135
- }, qn = /* @__PURE__ */ new Set([O]), Jn = (e) => e.onDialectOrElse({
2136
- mysql: () => zn(e),
2137
- mssql: () => Un(e),
2138
- sqlite: () => Vn(e),
2139
- orElse: () => Ln(e)
2140
- }).pipe(b.map((e) => ({
2152
+ }, Jn = /* @__PURE__ */ new Set([O]), Yn = (e) => e.onDialectOrElse({
2153
+ mysql: () => Bn(e),
2154
+ mssql: () => Wn(e),
2155
+ sqlite: () => Hn(e),
2156
+ orElse: () => Rn(e)
2157
+ }).pipe(x.map((e) => ({
2141
2158
  ...e,
2142
- tables: e.tables.filter((e) => !qn.has(e.name))
2143
- }))), U = (e, t) => e.onDialectOrElse({
2144
- mysql: () => b.succeed(t.replace("T", " ").replace("Z", "")),
2145
- orElse: () => b.succeed(t)
2146
- }), Yn = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, Xn = (e, t) => {
2159
+ tables: e.tables.filter((e) => !Jn.has(e.name))
2160
+ }))), Xn = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", Zn = /* @__PURE__ */ new WeakMap(), W = (e) => x.suspend(() => {
2161
+ let t = Zn.get(e);
2162
+ return t === void 0 ? Qn(e).pipe(x.tap((t) => x.sync(() => Zn.set(e, t)))) : x.succeed(t);
2163
+ }), Qn = (e) => e.unsafe("SELECT VERSION() AS v").pipe(x.map((e) => {
2164
+ let t = e[0]?.v;
2165
+ return typeof t == "string" ? Xn(t) : "mysql";
2166
+ }), x.catchAll(() => x.succeed("mysql"))), $n = (e) => {
2167
+ let t = e;
2168
+ for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2169
+ let e = t;
2170
+ if (typeof e.errno == "number") return e.errno;
2171
+ t = e.cause;
2172
+ }
2173
+ }, er = (e) => {
2174
+ let t = [], n = e;
2175
+ for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2176
+ let e = n;
2177
+ typeof e.message == "string" && t.push(e.message), n = e.cause;
2178
+ }
2179
+ return t.join(" | ");
2180
+ }, tr = (e, t) => {
2181
+ if (t.length === 0) return !1;
2182
+ let n = $n(e), r = er(e);
2183
+ return t.some((e) => e.errno !== void 0 && n !== void 0 && e.errno.includes(n) || e.messageIncludes !== void 0 && e.messageIncludes.some((e) => r.includes(e)));
2184
+ }, nr = {
2185
+ why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2186
+ errno: [1061]
2187
+ }, rr = {
2188
+ why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2189
+ errno: [1091]
2190
+ }, ir = {
2191
+ why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2192
+ messageIncludes: ["no such column"]
2193
+ }, G = (e, t) => e.onDialectOrElse({
2194
+ mysql: () => x.succeed(t.replace("T", " ").replace("Z", "")),
2195
+ orElse: () => x.succeed(t)
2196
+ }), ar = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, or = (e, t) => {
2147
2197
  if ((e.type !== "text" || e.maxLength === void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2148
2198
  let n = e.type === "vector" && e.vectorDim === void 0 ? "vector dimension" : e.type === "array" && e.arrayElement === void 0 ? "array element type" : e.type === "enum" && e.enumName === void 0 && e.enumValues === void 0 ? "enum name/values" : void 0;
2149
2199
  if (n !== void 0) throw Error(`migration applier: cannot render '${e.name}' (${e.type}) — the schema snapshot carries no ${n}. Rendering it as 'text' would emit DDL that applies successfully and changes nothing, so this fails instead. This is a framework bug: declaredSchema.ts must carry the parameter into the ColumnSnapshot.`);
2150
2200
  return j(e, t);
2151
- }, Zn = (e) => {
2152
- let t = Xn(e, "postgres");
2153
- return t === void 0 ? Qn(e) : t;
2154
- }, Qn = (e) => {
2201
+ }, sr = (e) => {
2202
+ let t = or(e, "postgres");
2203
+ return t === void 0 ? cr(e) : t;
2204
+ }, cr = (e) => {
2155
2205
  switch (e.type) {
2156
2206
  case "id": return "text";
2157
2207
  case "text": return "text";
2158
2208
  case "integer": return "integer";
2159
2209
  case "real": return "double precision";
2160
- case "decimal": return Yn(e, "NUMERIC");
2210
+ case "decimal": return ar(e, "NUMERIC");
2161
2211
  case "bigint": return "bigint";
2162
2212
  case "boolean": return "boolean";
2163
2213
  case "timestamp": return "timestamptz";
@@ -2171,15 +2221,15 @@ BEGIN
2171
2221
  case "interval": return "interval";
2172
2222
  case "raw": return e.rawDdl ?? "text";
2173
2223
  }
2174
- }, $n = (e) => {
2175
- let t = Xn(e, "mariadb");
2224
+ }, lr = (e) => {
2225
+ let t = or(e, "mariadb");
2176
2226
  if (t !== void 0) return t;
2177
2227
  switch (e.type) {
2178
2228
  case "id": return "VARCHAR(64)";
2179
2229
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
2180
2230
  case "integer": return "INT";
2181
2231
  case "real": return "DOUBLE";
2182
- case "decimal": return Yn(e, "DECIMAL");
2232
+ case "decimal": return ar(e, "DECIMAL");
2183
2233
  case "bigint": return "BIGINT";
2184
2234
  case "boolean": return "TINYINT(1)";
2185
2235
  case "timestamp": return "DATETIME(6)";
@@ -2193,82 +2243,86 @@ BEGIN
2193
2243
  case "interval": return "BIGINT";
2194
2244
  case "raw": return e.rawDdl ?? "LONGTEXT";
2195
2245
  }
2196
- }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, er = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, tr = (e) => `ALTER TABLE ${G(e.table)} DROP COLUMN IF EXISTS ${G(e.column)}, ALGORITHM=COPY;`, nr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, rr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${kr(t)}`)};`, ir = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${ar(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, ar = (e, t) => {
2246
+ }, K = (e) => `"${e}"`, q = (e) => `\`${e.replace(/`/g, "``")}\``, ur = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", dr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, fr = (e, t = "mariadb") => `ALTER TABLE ${q(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${q(e.column)}, ALGORITHM=COPY;`, pr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, mr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Ur(t)}`)};`, hr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${gr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, gr = (e, t) => {
2197
2247
  let n = t(e.defaultValue);
2198
2248
  if (n === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${e.column}' (${JSON.stringify(e.defaultValue)}). Emitting 'DEFAULT NULL' would apply cleanly and drop the default silently, so this fails instead. This is a framework bug — report the column type + default.`);
2199
2249
  return n;
2200
- }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], or = (e, t, n) => {
2201
- let r = K(e, t, n);
2202
- return r ? Ut(n, r) : void 0;
2203
- }, sr = (e, t, n) => {
2204
- let r = n ?? e.nullable, i = Ze(e, "mariadb");
2250
+ }, _r = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], vr = (e, t, n) => {
2251
+ let r = _r(e, t, n);
2252
+ return r ? Wt(n, r) : void 0;
2253
+ }, yr = (e, t, n) => {
2254
+ let r = n ?? e.nullable, i = Qe(e, "mariadb");
2205
2255
  return [
2206
- G(t),
2256
+ q(t),
2207
2257
  j(e, "mariadb"),
2208
2258
  r ? null : "NOT NULL",
2209
2259
  i
2210
2260
  ].filter(Boolean).join(" ");
2211
- }, cr = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, lr = (e, t, n) => Qe(e, t ?? { type: "json" }, n), ur = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, q = (e, t) => {
2261
+ }, br = (e, t) => e == null ? null : Array.isArray(e) ? xr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, xr = (e, t, n) => $e(e, t ?? { type: "json" }, n), Sr = (e, t) => e == null ? null : Array.isArray(e) ? xr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, Cr = (e, t) => {
2212
2262
  if (!e.generatedAs) return null;
2213
2263
  let { expr: n, stored: r } = e.generatedAs;
2214
2264
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2215
- }, dr = (e) => {
2265
+ }, wr = (e) => {
2216
2266
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2217
- let t = q(e, "postgres");
2218
- if (t) return `${W(e.name)} ${Zn(e)} ${t}`;
2219
- let n = [W(e.name), Zn(e)];
2267
+ let t = Cr(e, "postgres");
2268
+ if (t) return `${K(e.name)} ${sr(e)} ${t}`;
2269
+ let n = [K(e.name), sr(e)];
2220
2270
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2221
- let t = ur(e.defaultValue, e);
2271
+ let t = Sr(e.defaultValue, e);
2222
2272
  t && n.push(t);
2223
2273
  }
2224
- return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2274
+ return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2225
2275
  cascade: "CASCADE",
2226
2276
  restrict: "RESTRICT",
2227
2277
  setNull: "SET NULL",
2228
2278
  noAction: "NO ACTION"
2229
2279
  }[e.references.onDelete]}`)), n.join(" ");
2230
- }, fr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", pr = (e) => {
2231
- let t = e.columns.map((e) => ` ${dr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${fr(e, W)}\n)`];
2232
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(Pr).join(", ")})`);
2280
+ }, Tr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Er = (e) => {
2281
+ let t = e.columns.map((e) => ` ${wr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${t}${Tr(e, K)}\n)`];
2282
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(Jr).join(", ")})`);
2233
2283
  return n;
2234
- }, mr = 191, hr = (e) => {
2235
- let t = $n(e).toUpperCase();
2284
+ }, Dr = 191, Or = (e) => {
2285
+ let t = lr(e).toUpperCase();
2236
2286
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2237
- }, gr = (e) => {
2287
+ }, kr = (e) => {
2238
2288
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2239
- let t = q(e, "mariadb");
2240
- if (t) return `${G(e.name)} ${$n(e)} ${t}`;
2241
- let n = [G(e.name), $n(e)];
2242
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !hr(e) && n.push("UNIQUE"), e.hasDefault) {
2243
- let t = cr(e.defaultValue, e);
2289
+ let t = Cr(e, "mariadb");
2290
+ if (t) return `${q(e.name)} ${lr(e)} ${t}`;
2291
+ let n = [q(e.name), lr(e)];
2292
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Or(e) && n.push("UNIQUE"), e.hasDefault) {
2293
+ let t = br(e.defaultValue, e);
2244
2294
  t && n.push(t);
2245
2295
  }
2246
- return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2296
+ return n.join(" ");
2297
+ }, Ar = (e) => e.columns.flatMap((t) => {
2298
+ if (!t.references) return [];
2299
+ let n = t.references.onDelete ? ` ON DELETE ${{
2247
2300
  cascade: "CASCADE",
2248
2301
  restrict: "RESTRICT",
2249
2302
  setNull: "SET NULL",
2250
2303
  noAction: "NO ACTION"
2251
- }[e.references.onDelete]}`)), n.join(" ");
2252
- }, _r = (e) => {
2253
- let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
2254
- let n = Mr(t.get(e));
2255
- return n === void 0 ? G(e) : `${G(e)}(${n})`;
2256
- }, r = e.columns.map((e) => ` ${gr(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${r}${fr(e, n)}\n)`];
2257
- for (let t of e.columns) t.unique && t.type !== "id" && hr(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${G(`${e.table}_${t.name}_key`)} ON ${G(e.table)} (${n(t.name)})`);
2258
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(n).join(", ")})`);
2259
- return i;
2260
- }, vr = {
2304
+ }[t.references.onDelete]}` : "";
2305
+ return [` CONSTRAINT ${q(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${q(t.name)}) REFERENCES ${q(t.references.table)} (${q(t.references.column)})${n}`];
2306
+ }), jr = (e, t = "mariadb") => {
2307
+ let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2308
+ let t = Kr(n.get(e));
2309
+ return t === void 0 ? q(e) : `${q(e)}(${t})`;
2310
+ }, i = e.columns.map((e) => ` ${kr(e)}`).join(",\n"), a = Ar(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${q(e.table)} (\n${o}${Tr(e, r)}\n)`];
2311
+ for (let n of e.columns) n.unique && n.type !== "id" && Or(n) && s.push(`CREATE UNIQUE INDEX ${ur(t)}${q(`${e.table}_${n.name}_key`)} ON ${q(e.table)} (${r(n.name)})`);
2312
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${ur(t)}${q(n.name)} ON ${q(e.table)} (${n.columns.map(r).join(", ")})`);
2313
+ return s;
2314
+ }, Mr = {
2261
2315
  cascade: "CASCADE",
2262
2316
  restrict: "RESTRICT",
2263
2317
  setNull: "SET NULL",
2264
2318
  noAction: "NO ACTION"
2265
- }, yr = {
2319
+ }, Nr = {
2266
2320
  cascade: "CASCADE",
2267
2321
  restrict: "NO ACTION",
2268
2322
  setNull: "SET NULL",
2269
2323
  noAction: "NO ACTION"
2270
- }, br = (e) => {
2271
- let t = Xn(e, "sqlite");
2324
+ }, Pr = (e) => {
2325
+ let t = or(e, "sqlite");
2272
2326
  if (t !== void 0) return t;
2273
2327
  switch (e.type) {
2274
2328
  case "integer":
@@ -2279,60 +2333,60 @@ BEGIN
2279
2333
  case "bytes": return "BLOB";
2280
2334
  default: return "TEXT";
2281
2335
  }
2282
- }, xr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Sr = (e) => {
2336
+ }, Fr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Ir = (e) => {
2283
2337
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2284
- let t = q(e, "sqlite");
2285
- if (t) return `${W(e.name)} ${br(e)} ${t}`;
2286
- let n = [W(e.name), br(e)];
2338
+ let t = Cr(e, "sqlite");
2339
+ if (t) return `${K(e.name)} ${Pr(e)} ${t}`;
2340
+ let n = [K(e.name), Pr(e)];
2287
2341
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2288
- let t = xr(e.defaultValue, "CURRENT_TIMESTAMP");
2342
+ let t = Fr(e.defaultValue, "CURRENT_TIMESTAMP");
2289
2343
  t && n.push(t);
2290
2344
  }
2291
- if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${vr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2345
+ if (e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Mr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2292
2346
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2293
- n.push(`CHECK (${W(e.name)} IN (${t}))`);
2347
+ n.push(`CHECK (${K(e.name)} IN (${t}))`);
2294
2348
  }
2295
2349
  return n.join(" ");
2296
- }, Cr = (e) => {
2297
- let t = e.columns.map((e) => ` ${Sr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${fr(e, W)}\n)`];
2298
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(W).join(", ")})`);
2350
+ }, Lr = (e) => {
2351
+ let t = e.columns.map((e) => ` ${Ir(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${t}${Tr(e, K)}\n)`];
2352
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(K).join(", ")})`);
2299
2353
  return n;
2300
2354
  }, J = (e, t) => {
2301
2355
  let n = t.find((t) => t.tableName === e);
2302
2356
  if (!n) return [];
2303
- let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2304
- ...Cr({
2357
+ let r = L([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => K(e.name)).join(", "), o = [
2358
+ ...Lr({
2305
2359
  kind: "create-table",
2306
2360
  table: i,
2307
2361
  columns: r.columns,
2308
2362
  indexes: [],
2309
2363
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
2310
2364
  }),
2311
- `INSERT INTO ${W(i)} (${a}) SELECT ${a} FROM ${W(e)}`,
2312
- `DROP TABLE ${W(e)}`,
2313
- `ALTER TABLE ${W(i)} RENAME TO ${W(e)}`
2365
+ `INSERT INTO ${K(i)} (${a}) SELECT ${a} FROM ${K(e)}`,
2366
+ `DROP TABLE ${K(e)}`,
2367
+ `ALTER TABLE ${K(i)} RENAME TO ${K(e)}`
2314
2368
  ];
2315
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e)} (${t.columns.map(W).join(", ")})`);
2369
+ for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e)} (${t.columns.map(K).join(", ")})`);
2316
2370
  return o;
2317
- }, wr = (e, t, n, r) => {
2371
+ }, Rr = (e, t, n, r) => {
2318
2372
  let i = r ?? e.nullable;
2319
2373
  return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2320
- }, Tr = (e) => {
2374
+ }, zr = (e) => {
2321
2375
  let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Y(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
2322
2376
  if (!e.hasDefault) return t;
2323
- let n = xr(e.defaultValue, "SYSUTCDATETIME()");
2377
+ let n = Fr(e.defaultValue, "SYSUTCDATETIME()");
2324
2378
  if (!n) return t;
2325
2379
  let r = n.replace(/^DEFAULT\s+/i, "");
2326
2380
  return `${t} ALTER TABLE ${Y(e.table)} ADD DEFAULT ${r} FOR ${Y(e.column)};`;
2327
- }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Er = (e) => {
2328
- let t = Xn(e, "mssql");
2381
+ }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Br = (e) => {
2382
+ let t = or(e, "mssql");
2329
2383
  if (t !== void 0) return t;
2330
2384
  switch (e.type) {
2331
2385
  case "id":
2332
2386
  case "reference": return "NVARCHAR(64)";
2333
2387
  case "integer": return "INT";
2334
2388
  case "real": return "FLOAT";
2335
- case "decimal": return Yn(e, "DECIMAL");
2389
+ case "decimal": return ar(e, "DECIMAL");
2336
2390
  case "bigint": return "BIGINT";
2337
2391
  case "boolean": return "BIT";
2338
2392
  case "timestamp": return "DATETIME2(6)";
@@ -2340,44 +2394,44 @@ BEGIN
2340
2394
  case "bytes": return "VARBINARY(MAX)";
2341
2395
  default: return "NVARCHAR(MAX)";
2342
2396
  }
2343
- }, Dr = (e, t) => {
2397
+ }, Vr = (e, t) => {
2344
2398
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2345
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Er(e), r = q(e, "mssql");
2399
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Br(e), r = Cr(e, "mssql");
2346
2400
  if (r) return `${Y(e.name)} ${r}`;
2347
2401
  let i = [Y(e.name), n];
2348
2402
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2349
- let t = xr(e.defaultValue, "SYSUTCDATETIME()");
2403
+ let t = Fr(e.defaultValue, "SYSUTCDATETIME()");
2350
2404
  t && i.push(t);
2351
2405
  }
2352
- return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${yr[e.references.onDelete]}`)), i.join(" ");
2353
- }, Or = (e) => {
2354
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Dr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${fr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2406
+ return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Nr[e.references.onDelete]}`)), i.join(" ");
2407
+ }, Hr = (e) => {
2408
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Vr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Tr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2355
2409
  for (let n of e.indexes) {
2356
2410
  if (n.name === `${e.table}_pkey`) continue;
2357
2411
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Y(n.name)} ON ${Y(e.table)} (${n.columns.map(Y).join(", ")})`;
2358
2412
  a.push(`IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(n.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(r)}')`);
2359
2413
  }
2360
2414
  return a;
2361
- }, kr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Ar = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, jr = (e, t, n) => {
2362
- let r = `${e.table}${kr(t)}`;
2415
+ }, Ur = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Wr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Gr = (e, t, n) => {
2416
+ let r = `${e.table}${Ur(t)}`;
2363
2417
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2364
- }, Mr = (e) => {
2365
- if (e === void 0 || !hr(e)) return;
2418
+ }, Kr = (e) => {
2419
+ if (e === void 0 || !Or(e)) return;
2366
2420
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2367
- return t === void 0 ? mr : Math.min(mr, t);
2368
- }, Nr = (e, t, n) => {
2369
- let r = Mr(or(e, t, n));
2370
- return r === void 0 ? G(n) : `${G(n)}(${r})`;
2371
- }, Pr = (e) => e.startsWith("(") ? e : W(e), Fr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map(Pr).join(", ")});`, Ir = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => Nr(t, e.table, n)).join(", ")});`, Lr = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, Rr = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, zr = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, Br = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Vr = (e) => {
2421
+ return t === void 0 ? Dr : Math.min(Dr, t);
2422
+ }, qr = (e, t, n) => {
2423
+ let r = Kr(vr(e, t, n));
2424
+ return r === void 0 ? q(n) : `${q(n)}(${r})`;
2425
+ }, Jr = (e) => e.startsWith("(") ? e : K(e), Yr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map(Jr).join(", ")});`, Xr = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${ur(n)}${q(e.index.name)} ON ${q(e.table)} (${e.index.columns.map((n) => qr(t, e.table, n)).join(", ")});`, Zr = (e) => `DROP INDEX IF EXISTS ${K(e.index)};`, Qr = (e) => `DROP INDEX ${q(e.index)} ON ${q(e.table)};`, $r = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ei = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, ti = (e) => {
2372
2426
  let t = (e) => e.replace(/'/g, "''");
2373
2427
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2374
- }, Hr = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, Ur = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, Wr = (e) => {
2428
+ }, ni = (e) => `ALTER INDEX ${K(e.from)} RENAME TO ${K(e.to)};`, ri = (e) => `ALTER TABLE ${q(e.table)} RENAME INDEX ${q(e.from)} TO ${q(e.to)};`, ii = (e) => {
2375
2429
  let t = (e) => e.replace(/'/g, "''");
2376
2430
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2377
- }, Gr = (e) => {
2431
+ }, ai = (e) => {
2378
2432
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Y(e.index.name)} ON ${Y(e.table)} (${e.index.columns.map(Y).join(", ")})`;
2379
2433
  return `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(e.index.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(n)}');`;
2380
- }, Kr = (e, t, n) => {
2434
+ }, oi = (e, t, n) => {
2381
2435
  let r = n.find((t) => t.tableName === e);
2382
2436
  if (!r) return [];
2383
2437
  let i = [];
@@ -2386,13 +2440,13 @@ BEGIN
2386
2440
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Y(e)} ALTER COLUMN ${Y(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2387
2441
  }
2388
2442
  return i;
2389
- }, qr = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, Jr = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${Nr(t, e.table, e.column)});`, Yr = (e) => {
2390
- let t = e.fields.map((e) => W(e)).join(", ");
2391
- return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2392
- }, Xr = (e, t) => {
2393
- let n = e.fields.map((n) => Nr(t, e.table, n)).join(", ");
2394
- return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2395
- }, Zr = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, Qr = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, $r = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, ei = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, ti = (e, t) => {
2443
+ }, si = (e) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${K(e.column)});`, ci = (e, t) => `ALTER TABLE ${q(e.table)} ADD CONSTRAINT ${q(`${e.table}_${e.column}_key`)} UNIQUE (${qr(t, e.table, e.column)});`, li = (e) => {
2444
+ let t = e.fields.map((e) => K(e)).join(", ");
2445
+ return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${t});`;
2446
+ }, ui = (e, t) => {
2447
+ let n = e.fields.map((n) => qr(t, e.table, n)).join(", ");
2448
+ return `ALTER TABLE ${q(e.table)} ADD CONSTRAINT ${q(e.name)} UNIQUE (${n});`;
2449
+ }, di = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(e.name)};`, fi = (e) => `ALTER TABLE ${q(e.table)} DROP INDEX ${q(e.name)};`, pi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_key`)};`, mi = (e) => `ALTER TABLE ${q(e.table)} DROP INDEX ${q(`${e.table}_${e.column}_key`)};`, hi = (e, t) => {
2396
2450
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2397
2451
  if (e.orphanPolicy) {
2398
2452
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2410,11 +2464,11 @@ BEGIN
2410
2464
  setNull: "SET NULL",
2411
2465
  noAction: "NO ACTION"
2412
2466
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2413
- }, ni = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, ri = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, ii = (e, t) => {
2467
+ }, gi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_fkey`)};`, _i = (e) => `ALTER TABLE ${q(e.table)} DROP FOREIGN KEY ${q(`${e.table}_${e.column}_fkey`)};`, vi = (e, t) => {
2414
2468
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2415
2469
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2416
- }, ai = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, oi = (e) => `ALTER TABLE ${G(e.table)} DROP CHECK ${G(`${e.table}_${e.column}_check`)};`, si = (e, t, n, r) => {
2417
- let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Y : W, s = a ? $n(i) : r === "mssql" ? Er(i) : r === "sqlite" ? br(i) : Zn(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? cr(e, i) : r === "mssql" ? xr(e, "SYSUTCDATETIME()") : r === "sqlite" ? xr(e, "CURRENT_TIMESTAMP") : ur(e, i), u = q(i, r);
2470
+ }, yi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_check`)};`, bi = (e) => `ALTER TABLE ${q(e.table)} DROP CHECK ${q(`${e.table}_${e.column}_check`)};`, xi = (e, t, n, r) => {
2471
+ let i = e.column, a = r === "mariadb", o = a ? q : r === "mssql" ? Y : K, s = a ? lr(i) : r === "mssql" ? Br(i) : r === "sqlite" ? Pr(i) : sr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? br(e, i) : r === "mssql" ? Fr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Fr(e, "CURRENT_TIMESTAMP") : Sr(e, i), u = Cr(i, r);
2418
2472
  if (u) {
2419
2473
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2420
2474
  return {
@@ -2442,7 +2496,7 @@ BEGIN
2442
2496
  post: f ? [f] : []
2443
2497
  };
2444
2498
  return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
2445
- }, ci = (e) => {
2499
+ }, Si = (e) => {
2446
2500
  let t = new Map(e.map((e) => [e.tableName, e]));
2447
2501
  return (e, n) => {
2448
2502
  let r = t.get(e);
@@ -2462,44 +2516,44 @@ BEGIN
2462
2516
  ...o
2463
2517
  };
2464
2518
  };
2465
- }, X = (e, t, n) => e.unsafe(t).pipe(b.tapError((e) => b.sync(() => {
2466
- process.stderr.write(ie(`applier: statement failed (op=${n})`, t, e, 400));
2467
- })), b.mapError((e) => {
2468
- let r = ie(`applier: statement failed (op=${n})`, t, e, 400).trim();
2519
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(x.catchIf((e) => tr(e, r), () => x.void), x.tapError((e) => x.sync(() => {
2520
+ process.stderr.write(ae(`applier: statement failed (op=${n})`, t, e, 400));
2521
+ })), x.mapError((e) => {
2522
+ let r = ae(`applier: statement failed (op=${n})`, t, e, 400).trim();
2469
2523
  return Object.assign(e, { message: r });
2470
- }), b.map(() => void 0)), Z = (e, t, n) => b.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 ? "*" : i(r, t)} FROM ${i(n, t)} WHERE 1=0`).pipe(b.as(!0), b.catchAll(() => b.succeed(!1))), li = (e, t) => b.gen(function* () {
2471
- let n = I([Fe], t).tables[0];
2472
- if (!n) return yield* b.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2524
+ }), x.map(() => void 0)), Z = (e, t, n) => x.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, r, i) => e.unsafe(`SELECT ${i === void 0 ? "*" : n(i, t)} FROM ${n(r, t)} WHERE 1=0`).pipe(x.as(!0), x.catchAll(() => x.succeed(!1))), Ci = (e, t) => x.gen(function* () {
2525
+ let n = L([Ie], t).tables[0];
2526
+ if (!n) return yield* x.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2473
2527
  let r = {
2474
2528
  kind: "create-table",
2475
2529
  table: O,
2476
2530
  columns: n.columns,
2477
2531
  indexes: []
2478
2532
  }, i = yield* e.onDialectOrElse({
2479
- mysql: () => b.succeed(_r(r)),
2480
- mssql: () => b.succeed(Or(r)),
2481
- sqlite: () => b.succeed(Cr(r)),
2482
- orElse: () => b.succeed(pr(r))
2533
+ mysql: () => W(e).pipe(x.map((e) => jr(r, e))),
2534
+ mssql: () => x.succeed(Hr(r)),
2535
+ sqlite: () => x.succeed(Lr(r)),
2536
+ orElse: () => x.succeed(Er(r))
2483
2537
  });
2484
- yield* b.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2485
- }), ui = (e) => e`
2538
+ yield* x.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2539
+ }), wi = (e) => e`
2486
2540
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2487
2541
  ${e("status")}, ${e("payload")}
2488
2542
  FROM ${e(O)}
2489
- `, di = (e, t, n, r) => b.gen(function* () {
2490
- let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2491
- yield* b.forEach(r, ({ index: r, planned: a }) => e`
2543
+ `, Ti = (e, t, n, r) => x.gen(function* () {
2544
+ let i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2545
+ yield* x.forEach(r, ({ index: r, planned: a }) => e`
2492
2546
  INSERT INTO ${e(O)}
2493
2547
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2494
2548
  ${e("opKind")}, ${e("opTarget")}, ${e("status")}, ${e("payload")},
2495
2549
  ${e("createdAt")})
2496
2550
  VALUES
2497
2551
  (${`mop_${t}_${r}`}, ${t}, ${n}, ${r},
2498
- ${a.op.kind}, ${Le(a.op)}, ${"pending"},
2552
+ ${a.op.kind}, ${Re(a.op)}, ${"pending"},
2499
2553
  ${JSON.stringify(a)}, ${i})
2500
2554
  `, { discard: !0 });
2501
- }), fi = (e, t, n, r, i) => b.gen(function* () {
2502
- let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2555
+ }), Ei = (e, t, n, r, i) => x.gen(function* () {
2556
+ let a = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2503
2557
  if (r === "applied") {
2504
2558
  yield* e`
2505
2559
  UPDATE ${e(O)}
@@ -2514,8 +2568,8 @@ BEGIN
2514
2568
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2515
2569
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2516
2570
  `;
2517
- }), pi = (e, t, n, r) => b.gen(function* () {
2518
- let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2571
+ }), Di = (e, t, n, r) => x.gen(function* () {
2572
+ let i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2519
2573
  r.length > 0 && (yield* e`
2520
2574
  UPDATE ${e(O)}
2521
2575
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
@@ -2525,126 +2579,130 @@ BEGIN
2525
2579
  SET ${e("status")} = ${"pending"}
2526
2580
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2527
2581
  `);
2528
- }), mi = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(b.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(b.asVoid), hi = (e, t, n) => b.gen(function* () {
2529
- if (Ge(n.op, n.classification, t) !== "artefact-repair") return "clean";
2530
- let r = n.op, a = (e) => i(e, t);
2582
+ }), Oi = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(x.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(x.asVoid), ki = (e, t, r) => x.gen(function* () {
2583
+ if (Ke(r.op, r.classification, t) !== "artefact-repair") return "clean";
2584
+ let i = r.op, a = (e) => n(e, t);
2531
2585
  if (t === "sqlite" || t === "turso") {
2532
- if (!("table" in r)) return "clean";
2533
- let n = `${r.table}${Be}`;
2534
- return (yield* $(e, t, n)) ? ((yield* $(e, t, r.table)) ? yield* X(e, `DROP TABLE ${a(n)}`, "resume-repair") : yield* X(e, `ALTER TABLE ${a(n)} RENAME TO ${a(r.table)}`, "resume-repair"), yield* b.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
2535
- }
2536
- if (r.kind !== "alter-column-type") return "clean";
2537
- let o = `${r.column}${Ve}`, s = `${r.column}${He}`, c = yield* $(e, t, r.table, r.column), l = yield* $(e, t, r.table, o), u = yield* $(e, t, r.table, s), d = (e) => b.logWarning(`migration resume: ${e}`).pipe(b.annotateLogs({ scope: "voltro:migrate" }));
2538
- return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(o)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${r.table}.${o}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* X(e, `ALTER TABLE ${a(r.table)} RENAME COLUMN ${a(o)} TO ${a(r.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${r.table}.${s}'`), "applied") : yield* b.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${o}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2539
- }), gi = (e, t, n, r = "fresh") => b.gen(function* () {
2540
- let i = process.hrtime.bigint(), a = ci(n.declared), o = t.op;
2586
+ if (!("table" in i)) return "clean";
2587
+ let n = `${i.table}${Ve}`;
2588
+ return (yield* $(e, t, n)) ? ((yield* $(e, t, i.table)) ? yield* X(e, `DROP TABLE ${a(n)}`, "resume-repair") : yield* X(e, `ALTER TABLE ${a(n)} RENAME TO ${a(i.table)}`, "resume-repair"), yield* x.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${i.table}' — replaying the operation`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
2589
+ }
2590
+ if (i.kind !== "alter-column-type") return "clean";
2591
+ let o = `${i.column}${He}`, s = `${i.column}${Ue}`, c = yield* $(e, t, i.table, i.column), l = yield* $(e, t, i.table, o), u = yield* $(e, t, i.table, s), d = (e) => x.logWarning(`migration resume: ${e}`).pipe(x.annotateLogs({ scope: "voltro:migrate" }));
2592
+ return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(o)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${i.table}.${o}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* X(e, `ALTER TABLE ${a(i.table)} RENAME COLUMN ${a(o)} TO ${a(i.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${i.table}.${i.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${i.table}.${s}'`), "applied") : yield* x.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${i.table}.${i.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${o}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2593
+ }), Ai = (e, t, n, r = "fresh") => x.gen(function* () {
2594
+ let i = process.hrtime.bigint(), a = Si(n.declared), o = t.op;
2541
2595
  switch (o.kind) {
2542
2596
  case "create-table": {
2543
2597
  let t = yield* e.onDialectOrElse({
2544
- mysql: () => b.succeed(_r(o)),
2545
- mssql: () => b.succeed(Or(o)),
2546
- sqlite: () => b.succeed(Cr(o)),
2547
- orElse: () => b.succeed(pr(o))
2598
+ mysql: () => W(e).pipe(x.map((e) => jr(o, e))),
2599
+ mssql: () => x.succeed(Hr(o)),
2600
+ sqlite: () => x.succeed(Lr(o)),
2601
+ orElse: () => x.succeed(Er(o))
2602
+ }), n = yield* e.onDialectOrElse({
2603
+ mysql: () => x.succeed([nr]),
2604
+ orElse: () => x.succeed([])
2548
2605
  });
2549
- for (let n of t) yield* X(e, n, o.kind);
2606
+ for (let r of t) yield* X(e, r, o.kind, n);
2550
2607
  break;
2551
2608
  }
2552
2609
  case "drop-table": {
2553
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? jr(o, n, e) : Ar(o, e);
2610
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Gr(o, n, e) : Wr(o, e);
2554
2611
  yield* e.onDialectOrElse({
2555
- mysql: () => X(e, r(G), o.kind),
2556
- orElse: () => X(e, r(W), o.kind)
2612
+ mysql: () => X(e, r(q), o.kind),
2613
+ orElse: () => X(e, r(K), o.kind)
2557
2614
  });
2558
2615
  break;
2559
2616
  }
2560
2617
  case "drop-column": {
2561
2618
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2562
2619
  yield* e.onDialectOrElse({
2563
- mysql: () => X(e, t ? rr(o, n, G) : tr(o), o.kind),
2564
- orElse: () => X(e, t ? rr(o, n, W) : er(o, W), o.kind)
2620
+ mysql: () => W(e).pipe(x.flatMap((r) => X(e, t ? mr(o, n, q) : fr(o, r), o.kind, t ? [] : [rr]))),
2621
+ sqlite: () => X(e, t ? mr(o, n, K) : dr(o, K, !1), o.kind, t ? [] : [ir]),
2622
+ orElse: () => X(e, t ? mr(o, n, K) : dr(o, K), o.kind)
2565
2623
  });
2566
2624
  break;
2567
2625
  }
2568
2626
  case "rename-column":
2569
2627
  yield* e.onDialectOrElse({
2570
- mysql: () => X(e, nr(o, G), o.kind),
2628
+ mysql: () => X(e, pr(o, q), o.kind),
2571
2629
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2572
- orElse: () => X(e, nr(o, W), o.kind)
2630
+ orElse: () => X(e, pr(o, K), o.kind)
2573
2631
  });
2574
2632
  break;
2575
2633
  case "add-index":
2576
2634
  yield* e.onDialectOrElse({
2577
- mysql: () => X(e, Ir(o, n.declared), o.kind),
2578
- mssql: () => Z(e, [...Kr(o.table, o.index.columns, n.declared), Gr(o)], o.kind),
2579
- orElse: () => X(e, Fr(o, t.classification === "online-required"), o.kind)
2635
+ mysql: () => W(e).pipe(x.flatMap((t) => X(e, Xr(o, n.declared, t), o.kind, [nr]))),
2636
+ mssql: () => Z(e, [...oi(o.table, o.index.columns, n.declared), ai(o)], o.kind),
2637
+ orElse: () => X(e, Yr(o, t.classification === "online-required"), o.kind)
2580
2638
  });
2581
2639
  break;
2582
2640
  case "drop-index":
2583
2641
  yield* e.onDialectOrElse({
2584
- mysql: () => X(e, Rr(o), o.kind),
2585
- mssql: () => X(e, zr(o), o.kind),
2586
- orElse: () => X(e, Lr(o), o.kind)
2642
+ mysql: () => X(e, Qr(o), o.kind),
2643
+ mssql: () => X(e, $r(o), o.kind),
2644
+ orElse: () => X(e, Zr(o), o.kind)
2587
2645
  });
2588
2646
  break;
2589
2647
  case "rename-table":
2590
2648
  yield* e.onDialectOrElse({
2591
- mysql: () => X(e, Br(o, G), o.kind),
2592
- mssql: () => X(e, Vr(o), o.kind),
2593
- orElse: () => X(e, Br(o, W), o.kind)
2649
+ mysql: () => X(e, ei(o, q), o.kind),
2650
+ mssql: () => X(e, ti(o), o.kind),
2651
+ orElse: () => X(e, ei(o, K), o.kind)
2594
2652
  });
2595
2653
  break;
2596
2654
  case "rename-index":
2597
2655
  yield* e.onDialectOrElse({
2598
- mysql: () => X(e, Ur(o), o.kind),
2599
- mssql: () => X(e, Wr(o), o.kind),
2600
- orElse: () => X(e, Hr(o), o.kind)
2656
+ mysql: () => X(e, ri(o), o.kind),
2657
+ mssql: () => X(e, ii(o), o.kind),
2658
+ orElse: () => X(e, ni(o), o.kind)
2601
2659
  });
2602
2660
  break;
2603
2661
  case "add-unique":
2604
2662
  yield* e.onDialectOrElse({
2605
- mysql: () => X(e, Jr(o, n.declared), o.kind),
2663
+ mysql: () => X(e, ci(o, n.declared), o.kind),
2606
2664
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2607
- mssql: () => Z(e, [...Kr(o.table, [o.column], n.declared), qr(o)], o.kind),
2608
- orElse: () => X(e, qr(o), o.kind)
2665
+ mssql: () => Z(e, [...oi(o.table, [o.column], n.declared), si(o)], o.kind),
2666
+ orElse: () => X(e, si(o), o.kind)
2609
2667
  });
2610
2668
  break;
2611
2669
  case "drop-unique":
2612
2670
  yield* e.onDialectOrElse({
2613
- mysql: () => X(e, ei(o), o.kind),
2671
+ mysql: () => X(e, mi(o), o.kind),
2614
2672
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2615
- orElse: () => X(e, $r(o), o.kind)
2673
+ orElse: () => X(e, pi(o), o.kind)
2616
2674
  });
2617
2675
  break;
2618
2676
  case "add-unique-composite":
2619
2677
  yield* e.onDialectOrElse({
2620
- mysql: () => X(e, Xr(o, n.declared), o.kind),
2678
+ mysql: () => X(e, ui(o, n.declared), o.kind),
2621
2679
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2622
- mssql: () => Z(e, [...Kr(o.table, o.fields, n.declared), Yr(o)], o.kind),
2623
- orElse: () => X(e, Yr(o), o.kind)
2680
+ mssql: () => Z(e, [...oi(o.table, o.fields, n.declared), li(o)], o.kind),
2681
+ orElse: () => X(e, li(o), o.kind)
2624
2682
  });
2625
2683
  break;
2626
2684
  case "drop-unique-composite":
2627
2685
  yield* e.onDialectOrElse({
2628
- mysql: () => X(e, Qr(o), o.kind),
2686
+ mysql: () => X(e, fi(o), o.kind),
2629
2687
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2630
- orElse: () => X(e, Zr(o), o.kind)
2688
+ orElse: () => X(e, di(o), o.kind)
2631
2689
  });
2632
2690
  break;
2633
2691
  case "add-foreign-key":
2634
2692
  yield* e.onDialectOrElse({
2635
- mysql: () => Z(e, ti(o, G), o.kind),
2693
+ mysql: () => Z(e, hi(o, q), o.kind),
2636
2694
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2637
- orElse: () => Z(e, ti(o, W), o.kind)
2695
+ orElse: () => Z(e, hi(o, K), o.kind)
2638
2696
  });
2639
2697
  break;
2640
2698
  case "add-column": {
2641
- let n = si(o, t, a, yield* e.onDialectOrElse({
2642
- mysql: () => b.succeed("mariadb"),
2643
- mssql: () => b.succeed("mssql"),
2644
- sqlite: () => b.succeed("sqlite"),
2645
- orElse: () => b.succeed("postgres")
2699
+ let n = xi(o, t, a, yield* e.onDialectOrElse({
2700
+ mysql: () => x.succeed("mariadb"),
2701
+ mssql: () => x.succeed("mssql"),
2702
+ sqlite: () => x.succeed("sqlite"),
2703
+ orElse: () => x.succeed("postgres")
2646
2704
  }));
2647
- if (!(r === "resume" && (yield* $(e, Me(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2705
+ if (!(r === "resume" && (yield* $(e, Ne(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2648
2706
  if (n.backfillKind === "sql" && n.backfillSql) {
2649
2707
  if (t.classification !== "online-required" && n.batchSize === void 0) yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql}`;
2650
2708
  else {
@@ -2653,10 +2711,10 @@ BEGIN
2653
2711
  let s = i === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(o.column.name)} IS NULL ORDER BY ${e("id")} ${Q(e, t)}` : yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(o.column.name)} IS NULL AND ${e("id")} > ${i} ORDER BY ${e("id")} ${Q(e, t)}`;
2654
2712
  if (s.length === 0) break;
2655
2713
  let c = s.map((e) => e.id);
2656
- yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql} WHERE ${e("id")} IN ${e.in(c)}`, a += s.length, yield* b.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows`).pipe(b.annotateLogs({
2714
+ yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql} WHERE ${e("id")} IN ${e.in(c)}`, a += s.length, yield* x.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows`).pipe(x.annotateLogs({
2657
2715
  scope: "voltro:migrate",
2658
2716
  mode: "sql-batched"
2659
- })), i = s[s.length - 1].id, r > 0 && (yield* b.sleep(`${r} millis`));
2717
+ })), i = s[s.length - 1].id, r > 0 && (yield* x.sleep(`${r} millis`));
2660
2718
  }
2661
2719
  }
2662
2720
  } else if (n.backfillKind === "js" && n.backfillJs) {
@@ -2665,17 +2723,17 @@ BEGIN
2665
2723
  let s = i === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(o.column.name)} IS NULL ORDER BY ${e("id")} ${Q(e, t)}` : yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(o.column.name)} IS NULL AND ${e("id")} > ${i} ORDER BY ${e("id")} ${Q(e, t)}`;
2666
2724
  if (s.length === 0) break;
2667
2725
  for (let t of s) {
2668
- let r = yield* b.tryPromise({
2726
+ let r = yield* x.tryPromise({
2669
2727
  try: () => Promise.resolve(n.backfillJs({ id: t.id })),
2670
2728
  catch: (e) => e
2671
- }).pipe(b.orDie);
2729
+ }).pipe(x.orDie);
2672
2730
  yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${r} WHERE ${e("id")} = ${t.id}`;
2673
2731
  }
2674
- a += s.length, yield* b.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(b.annotateLogs({
2732
+ a += s.length, yield* x.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(x.annotateLogs({
2675
2733
  scope: "voltro:migrate",
2676
2734
  table: o.table,
2677
2735
  column: o.column.name
2678
- })), i = s[s.length - 1].id, r > 0 && (yield* b.sleep(`${r} millis`));
2736
+ })), i = s[s.length - 1].id, r > 0 && (yield* x.sleep(`${r} millis`));
2679
2737
  }
2680
2738
  }
2681
2739
  for (let t of n.post) yield* X(e, t, o.kind);
@@ -2684,77 +2742,77 @@ BEGIN
2684
2742
  case "alter-column-nullability":
2685
2743
  yield* e.onDialectOrElse({
2686
2744
  mysql: () => {
2687
- let t = K(n.declared, o.table, o.column);
2688
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${sr(t, o.column, o.toNullable)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2745
+ let t = _r(n.declared, o.table, o.column);
2746
+ return t ? X(e, `ALTER TABLE ${q(o.table)} MODIFY COLUMN ${yr(t, o.column, o.toNullable)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2689
2747
  },
2690
2748
  mssql: () => {
2691
- let t = K(n.declared, o.table, o.column);
2692
- return t ? X(e, wr(t, o.column, o.table, o.toNullable), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2749
+ let t = _r(n.declared, o.table, o.column);
2750
+ return t ? X(e, Rr(t, o.column, o.table, o.toNullable), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2693
2751
  },
2694
2752
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2695
- orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2753
+ orElse: () => X(e, `ALTER TABLE ${K(o.table)} ALTER COLUMN ${K(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2696
2754
  });
2697
2755
  break;
2698
2756
  case "alter-column-default": {
2699
- let t = or(n.declared, o.table, o.column);
2757
+ let t = vr(n.declared, o.table, o.column);
2700
2758
  yield* e.onDialectOrElse({
2701
- mysql: () => X(e, ir(o, G, (e) => cr(e, t)), o.kind),
2702
- mssql: () => X(e, Tr(o), o.kind),
2759
+ mysql: () => X(e, hr(o, q, (e) => br(e, t)), o.kind),
2760
+ mssql: () => X(e, zr(o), o.kind),
2703
2761
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2704
- orElse: () => X(e, ir(o, W, (e) => ur(e, t)), o.kind)
2762
+ orElse: () => X(e, hr(o, K, (e) => Sr(e, t)), o.kind)
2705
2763
  });
2706
2764
  break;
2707
2765
  }
2708
2766
  case "alter-column-type": {
2709
- let r = Zn(or(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2767
+ let r = sr(vr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2710
2768
  if (t.classification !== "online-required") {
2711
2769
  yield* e.onDialectOrElse({
2712
2770
  mysql: () => {
2713
- let t = K(n.declared, o.table, o.column);
2714
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${sr(t, o.column)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2771
+ let t = _r(n.declared, o.table, o.column);
2772
+ return t ? X(e, `ALTER TABLE ${q(o.table)} MODIFY COLUMN ${yr(t, o.column)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2715
2773
  },
2716
2774
  mssql: () => {
2717
- let t = K(n.declared, o.table, o.column);
2718
- return t ? X(e, wr(t, o.column, o.table), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2775
+ let t = _r(n.declared, o.table, o.column);
2776
+ return t ? X(e, Rr(t, o.column, o.table), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2719
2777
  },
2720
2778
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2721
- orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
2779
+ orElse: () => X(e, `ALTER TABLE ${K(o.table)} ALTER COLUMN ${K(o.column)} TYPE ${r}${i};`, o.kind)
2722
2780
  });
2723
2781
  break;
2724
2782
  }
2725
2783
  yield* e.onDialectOrElse({
2726
- mysql: () => b.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${o.table}.${o.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
2727
- orElse: () => b.void
2784
+ mysql: () => x.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${o.table}.${o.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
2785
+ orElse: () => x.void
2728
2786
  });
2729
2787
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2730
- yield* e.unsafe(`ALTER TABLE ${W(o.table)} ADD COLUMN ${W(a)} ${r}`);
2731
- let c = o.using ?? W(o.column), l;
2788
+ yield* e.unsafe(`ALTER TABLE ${K(o.table)} ADD COLUMN ${K(a)} ${r}`);
2789
+ let c = o.using ?? K(o.column), l;
2732
2790
  for (;;) {
2733
2791
  let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${Q(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${Q(e, 5e3)}`;
2734
2792
  if (t.length === 0) break;
2735
- yield* e.unsafe(`UPDATE ${W(o.table)} SET ${W(a)} = ${c} WHERE ${W(o.column)} IS NOT NULL AND ${W(a)} IS NULL AND ${W("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2793
+ yield* e.unsafe(`UPDATE ${K(o.table)} SET ${K(a)} = ${c} WHERE ${K(o.column)} IS NOT NULL AND ${K(a)} IS NULL AND ${K("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2736
2794
  }
2737
- yield* b.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(o.column)} TO ${W(s)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(a)} TO ${W(o.column)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} DROP COLUMN ${W(s)}`);
2795
+ yield* x.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${K(o.table)} RENAME COLUMN ${K(o.column)} TO ${K(s)}`), yield* e.unsafe(`ALTER TABLE ${K(o.table)} RENAME COLUMN ${K(a)} TO ${K(o.column)}`), yield* e.unsafe(`ALTER TABLE ${K(o.table)} DROP COLUMN ${K(s)}`);
2738
2796
  break;
2739
2797
  }
2740
2798
  case "drop-foreign-key":
2741
2799
  yield* e.onDialectOrElse({
2742
- mysql: () => X(e, ri(o), o.kind),
2800
+ mysql: () => X(e, _i(o), o.kind),
2743
2801
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2744
- orElse: () => X(e, ni(o), o.kind)
2802
+ orElse: () => X(e, gi(o), o.kind)
2745
2803
  });
2746
2804
  break;
2747
2805
  case "add-check":
2748
2806
  yield* e.onDialectOrElse({
2749
- mysql: () => X(e, ii(o, G), o.kind),
2807
+ mysql: () => X(e, vi(o, q), o.kind),
2750
2808
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2751
- orElse: () => X(e, ii(o, W), o.kind)
2809
+ orElse: () => X(e, vi(o, K), o.kind)
2752
2810
  });
2753
2811
  break;
2754
2812
  case "drop-check": yield* e.onDialectOrElse({
2755
- mysql: () => X(e, oi(o), o.kind),
2813
+ mysql: () => X(e, bi(o), o.kind),
2756
2814
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2757
- orElse: () => X(e, ai(o), o.kind)
2815
+ orElse: () => X(e, yi(o), o.kind)
2758
2816
  });
2759
2817
  }
2760
2818
  return {
@@ -2762,32 +2820,32 @@ BEGIN
2762
2820
  status: "applied",
2763
2821
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2764
2822
  };
2765
- }), _i = (e, t, n, r) => b.gen(function* () {
2823
+ }), ji = (e, t, n, r) => x.gen(function* () {
2766
2824
  let i = [...new Set(r.map((e) => e.runId))];
2767
- if (i.length > 1) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2825
+ if (i.length > 1) return yield* x.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2768
2826
  let a = i[0], o = [...r].map((e) => ({
2769
2827
  index: Number(e.opIndex),
2770
2828
  status: e.status,
2771
2829
  planned: JSON.parse(e.payload)
2772
2830
  })).sort((e, t) => e.index - t.index), s = o.find((e) => e.status === "started"), c = o.filter((e) => e.status === "started").length;
2773
- if (c > 1) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${O}\` by hand before re-running.`));
2774
- if (yield* b.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${Le(s.planned.op)}` : ""}`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2831
+ if (c > 1) return yield* x.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${O}\` by hand before re-running.`));
2832
+ if (yield* x.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${Re(s.planned.op)}` : ""}`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2775
2833
  kind: "discard",
2776
2834
  runId: a,
2777
2835
  why: "no operation had started — no DDL ran"
2778
2836
  };
2779
- let l = s ? yield* hi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2837
+ let l = s ? yield* ki(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2780
2838
  if (u !== n.toFingerprint) return {
2781
2839
  kind: "discard",
2782
2840
  runId: a,
2783
2841
  why: `the declared schema changed since the interruption (recorded target ${u.slice(0, 12)}…, current ${n.toFingerprint.slice(0, 12)}…) — applying the freshly-diffed plan instead`
2784
2842
  };
2785
- let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : ze(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2843
+ let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : Be(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2786
2844
  return f.length === 0 ? {
2787
2845
  kind: "discard",
2788
2846
  runId: a,
2789
2847
  why: "every recorded operation had already taken effect"
2790
- } : (yield* pi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* b.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), {
2848
+ } : (yield* Di(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* x.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), {
2791
2849
  kind: "resume",
2792
2850
  runId: a,
2793
2851
  ops: f.map((e) => ({
@@ -2795,55 +2853,55 @@ BEGIN
2795
2853
  planned: e.planned
2796
2854
  }))
2797
2855
  });
2798
- }), vi = (e, t, n) => b.gen(function* () {
2856
+ }), Mi = (e, t, n) => x.gen(function* () {
2799
2857
  let r = t.operations.filter((e) => e.blocked);
2800
- if (r.length > 0) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2858
+ if (r.length > 0) return yield* x.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2801
2859
  yield* E(e, { schema: n.lockSchema });
2802
- let i = Date.now(), a = [], o = Me(e), s = Pe(o) === "plan-transactional", l = s ? t.operations.filter((e) => e.classification !== "online-required") : [], u = s ? t.operations.filter((e) => e.classification === "online-required") : t.operations, d = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, f = u.map((e, t) => ({
2860
+ let i = Date.now(), a = [], o = Ne(e), s = Fe(o) === "plan-transactional", c = s ? t.operations.filter((e) => e.classification !== "online-required") : [], u = s ? t.operations.filter((e) => e.classification === "online-required") : t.operations, d = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, f = u.map((e, t) => ({
2803
2861
  index: t,
2804
2862
  planned: e
2805
2863
  })), p = "fresh";
2806
2864
  try {
2807
- yield* li(e, o);
2808
- let r = yield* ui(e);
2865
+ yield* Ci(e, o);
2866
+ let r = yield* wi(e);
2809
2867
  if (r.length > 0) {
2810
- let n = yield* _i(e, o, t, r);
2811
- n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* b.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* mi(e, n.runId));
2868
+ let n = yield* ji(e, o, t, r);
2869
+ n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* x.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* Oi(e, n.runId));
2812
2870
  }
2813
- p === "fresh" && f.length > 0 && (yield* di(e, d, t.toFingerprint, f)), l.length > 0 && (yield* e.withTransaction(b.gen(function* () {
2871
+ p === "fresh" && f.length > 0 && (yield* Ti(e, d, t.toFingerprint, f)), c.length > 0 && (yield* e.withTransaction(x.gen(function* () {
2814
2872
  let e = yield* C.SqlClient;
2815
- for (let t of l) a.push(yield* gi(e, t, n));
2873
+ for (let t of c) a.push(yield* Ai(e, t, n));
2816
2874
  })));
2817
2875
  for (let { index: t, planned: r } of f) {
2818
- yield* fi(e, d, t, "started");
2819
- let i = yield* gi(e, r, n, p);
2820
- a.push(i), yield* fi(e, d, t, "applied", i.durationMs);
2876
+ yield* Ei(e, d, t, "started");
2877
+ let i = yield* Ai(e, r, n, p);
2878
+ a.push(i), yield* Ei(e, d, t, "applied", i.durationMs);
2821
2879
  }
2822
2880
  } finally {
2823
- yield* D(e, { schema: n.lockSchema }).pipe(b.orDie);
2881
+ yield* D(e, { schema: n.lockSchema }).pipe(x.orDie);
2824
2882
  }
2825
2883
  let m = yield* n.replan(e);
2826
2884
  if (m.operations.length > 0) {
2827
2885
  let e = m.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");
2828
- return yield* b.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 ${m.operations.length}:\n${e}${m.operations.length > 10 ? `\n … and ${m.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.`));
2886
+ return yield* x.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 ${m.operations.length}:\n${e}${m.operations.length > 10 ? `\n … and ${m.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.`));
2829
2887
  }
2830
- let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* U(e, v), x = [...l, ...f.map((e) => e.planned)];
2888
+ let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* G(e, v), b = [...c, ...f.map((e) => e.planned)];
2831
2889
  yield* e`
2832
2890
  INSERT INTO ${e("_voltro_migration_plans")}
2833
2891
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
2834
2892
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
2835
2893
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
2836
2894
  VALUES
2837
- (${_}, ${t.toFingerprint}, ${m.fromFingerprint}, ${JSON.stringify(x)},
2895
+ (${_}, ${t.toFingerprint}, ${m.fromFingerprint}, ${JSON.stringify(b)},
2838
2896
  ${n.appliedBy}, ${n.environment}, ${n.source},
2839
2897
  ${g}, ${y}, ${n.notes ?? null})
2840
- `, yield* mi(e, d);
2841
- let S = [...new Set(x.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2842
- return yield* b.promise(() => c({ changedTables: S }).catch(() => {})), {
2898
+ `, yield* Oi(e, d);
2899
+ let S = [...new Set(b.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2900
+ return yield* x.promise(() => l({ changedTables: S }).catch(() => {})), {
2843
2901
  id: _,
2844
2902
  appliedAt: v,
2845
2903
  fingerprint: t.toFingerprint,
2846
- operations: x,
2904
+ operations: b,
2847
2905
  appliedBy: n.appliedBy,
2848
2906
  environment: n.environment,
2849
2907
  durationMs: g,
@@ -2851,14 +2909,14 @@ BEGIN
2851
2909
  source: n.source,
2852
2910
  ...n.notes ? { notes: n.notes } : {}
2853
2911
  };
2854
- }), yi = (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"), bi = (e) => e`
2912
+ }), Ni = (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"), Pi = (e) => e`
2855
2913
  SELECT fingerprint
2856
2914
  FROM _voltro_migration_plans
2857
2915
  ORDER BY ${e("appliedAt")} DESC
2858
2916
  LIMIT 1
2859
- `.pipe(b.map((e) => e.length > 0 ? e[0].fingerprint : void 0), b.catchAll(() => b.succeed(void 0))), xi = (e, t, n) => b.gen(function* () {
2860
- if ((yield* bi(e)) === t.toFingerprint) return "already-current";
2861
- let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2917
+ `.pipe(x.map((e) => e.length > 0 ? e[0].fingerprint : void 0), x.catchAll(() => x.succeed(void 0))), Fi = (e, t, n) => x.gen(function* () {
2918
+ if ((yield* Pi(e)) === t.toFingerprint) return "already-current";
2919
+ let r = `plan_${Date.now().toString(36)}`, i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2862
2920
  return yield* e`
2863
2921
  INSERT INTO ${e("_voltro_migration_plans")}
2864
2922
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -2869,8 +2927,8 @@ BEGIN
2869
2927
  ${n.appliedBy}, ${n.environment}, ${n.source},
2870
2928
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
2871
2929
  `, "recorded";
2872
- }).pipe(b.catchAll(() => b.succeed("already-current"))), Si = (e, t) => b.gen(function* () {
2873
- let n = P(I(t, Me(e))), r = yield* bi(e);
2930
+ }).pipe(x.catchAll(() => x.succeed("already-current"))), Ii = (e, t) => x.gen(function* () {
2931
+ let n = F(L(t, Ne(e))), r = yield* Pi(e);
2874
2932
  return r === n ? {
2875
2933
  kind: "up-to-date",
2876
2934
  fingerprint: n
@@ -2879,23 +2937,23 @@ BEGIN
2879
2937
  expected: n,
2880
2938
  ...r === void 0 ? {} : { actual: r }
2881
2939
  };
2882
- }), Ci = [
2940
+ }), Li = [
2883
2941
  "pgeagertest_",
2884
2942
  "mig_e2e_",
2885
2943
  "mig_test_",
2886
2944
  "mysqleagertest_",
2887
2945
  "mssqleagertest_",
2888
2946
  "sqliteeagertest_"
2889
- ], wi = (e) => Ci.some((t) => e.startsWith(t)), Ti = (e, t) => b.gen(function* () {
2947
+ ], Ri = (e) => Li.some((t) => e.startsWith(t)), zi = (e, t) => x.gen(function* () {
2890
2948
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2891
- let n = t.filter((e) => wi(e.name)).map((e) => e.name);
2949
+ let n = t.filter((e) => Ri(e.name)).map((e) => e.name);
2892
2950
  if (n.length === 0) return [];
2893
- for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(b.catchAll(() => b.void));
2951
+ for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(x.catchAll(() => x.void));
2894
2952
  return n;
2895
- }), Ei = () => {
2953
+ }), Bi = () => {
2896
2954
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2897
2955
  return e.length > 0 ? { ignoreTables: e } : {};
2898
- }, Di = (e) => {
2956
+ }, Vi = (e) => {
2899
2957
  if (e === void 0) return;
2900
2958
  let t = e.trim();
2901
2959
  if (t === "") return;
@@ -2905,48 +2963,48 @@ BEGIN
2905
2963
  kind: "tables",
2906
2964
  tables: new Set(n)
2907
2965
  } : void 0;
2908
- }, Oi = (e) => typeof e.table == "string" ? e.table : void 0, ki = (e, t = { kind: "all" }) => ({
2966
+ }, Hi = (e) => typeof e.table == "string" ? e.table : void 0, Ui = (e, t = { kind: "all" }) => ({
2909
2967
  ...e,
2910
2968
  operations: e.operations.map((e) => {
2911
2969
  if (!e.blocked || e.classification !== "lossy") return e;
2912
2970
  if (t?.kind === "tables") {
2913
- let n = Oi(e.op);
2971
+ let n = Hi(e.op);
2914
2972
  if (n === void 0 || !t.tables.has(n)) return e;
2915
2973
  }
2916
2974
  let { blocked: n, ...r } = e;
2917
2975
  return r;
2918
2976
  })
2919
- }), Ai = (e, t, n) => t === "postgres" ? qt(e, n).pipe(b.flatMap((e) => {
2920
- let t = Jt(e);
2921
- return t === void 0 ? b.void : b.logWarning(`auto-migrate: ${t}`).pipe(b.annotateLogs({ scope: "voltro:migrate" }));
2922
- }), b.catchAll(() => b.void)) : b.void, ji = (e, t, n) => b.gen(function* () {
2923
- let r = Me(e), i = t;
2977
+ }), Wi = (e, t, n) => t === "postgres" ? Jt(e, n).pipe(x.flatMap((e) => {
2978
+ let t = Yt(e);
2979
+ return t === void 0 ? x.void : x.logWarning(`auto-migrate: ${t}`).pipe(x.annotateLogs({ scope: "voltro:migrate" }));
2980
+ }), x.catchAll(() => x.void)) : x.void, Gi = (e, t, n) => x.gen(function* () {
2981
+ let r = Ne(e), i = t;
2924
2982
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2925
- let t = P(I(i, r));
2926
- if ((yield* bi(e)) === t) return yield* Ai(e, r, i), {
2983
+ let t = F(L(i, r));
2984
+ if ((yield* Pi(e)) === t) return yield* Wi(e, r, i), {
2927
2985
  kind: "up-to-date",
2928
2986
  fingerprint: t
2929
2987
  };
2930
2988
  }
2931
- let a = yield* Jn(e), o = yield* Ti(e, a.tables);
2932
- o.length > 0 && (yield* b.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(b.annotateLogs({
2989
+ let a = yield* Yn(e), o = yield* zi(e, a.tables);
2990
+ o.length > 0 && (yield* x.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(x.annotateLogs({
2933
2991
  scope: "voltro:migrate",
2934
2992
  count: o.length
2935
- })), a = yield* Jn(e));
2936
- let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !m(e.name) || s.has(e.name)), l = kn({
2993
+ })), a = yield* Yn(e));
2994
+ let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !m(e.name) || s.has(e.name)), l = An({
2937
2995
  declared: i,
2938
2996
  live: { tables: c(a.tables) },
2939
2997
  dialect: r,
2940
- ...Ei()
2998
+ ...Bi()
2941
2999
  });
2942
3000
  if (l.summary.blocked > 0) {
2943
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Di(process.env.VOLTRO_DESTRUCTIVE_OK);
2944
- if (t === void 0 || !e || (l = ki(l, t), l.operations.some((e) => e.blocked))) return {
3001
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Vi(process.env.VOLTRO_DESTRUCTIVE_OK);
3002
+ if (t === void 0 || !e || (l = Ui(l, t), l.operations.some((e) => e.blocked))) return {
2945
3003
  kind: "refused-blocked",
2946
3004
  plan: l
2947
3005
  };
2948
3006
  }
2949
- return l.operations.length === 0 ? (yield* xi(e, l, {
3007
+ return l.operations.length === 0 ? (yield* Fi(e, l, {
2950
3008
  appliedBy: n.appliedBy,
2951
3009
  environment: n.environment === "prod" ? "dev" : n.environment,
2952
3010
  source: "auto-diff"
@@ -2955,37 +3013,37 @@ BEGIN
2955
3013
  fingerprint: l.toFingerprint
2956
3014
  }) : {
2957
3015
  kind: "applied",
2958
- applied: yield* vi(e, l, {
3016
+ applied: yield* Mi(e, l, {
2959
3017
  declared: t,
2960
3018
  appliedBy: n.appliedBy,
2961
3019
  environment: n.environment === "prod" ? "dev" : n.environment,
2962
3020
  source: "auto-diff",
2963
- replan: (e) => b.gen(function* () {
2964
- let t = yield* Jn(e);
2965
- return kn({
3021
+ replan: (e) => x.gen(function* () {
3022
+ let t = yield* Yn(e);
3023
+ return An({
2966
3024
  declared: i,
2967
3025
  live: { tables: c(t.tables) },
2968
3026
  dialect: r,
2969
- ...Ei()
3027
+ ...Bi()
2970
3028
  });
2971
3029
  })
2972
3030
  }),
2973
3031
  plan: l
2974
3032
  };
2975
- }), Mi = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? b.succeed({
3033
+ }), Ki = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? x.succeed({
2976
3034
  kind: "skipped",
2977
3035
  reason: "VOLTRO_AUTO_MIGRATE=0"
2978
- }) : n.environment === "prod" ? Si(e, t) : ji(e, t, n), Ni = (e, t) => {
3036
+ }) : n.environment === "prod" ? Ii(e, t) : Gi(e, t, n), qi = (e, t) => {
2979
3037
  switch (e.kind) {
2980
3038
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2981
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${F(e.fingerprint)})`;
3039
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${I(e.fingerprint)})`;
2982
3040
  case "applied": {
2983
3041
  let t = e.plan.summary;
2984
- return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${F(e.applied.fingerprint)}`;
3042
+ return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${I(e.applied.fingerprint)}`;
2985
3043
  }
2986
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${F(e.expected)}` + (e.actual ? ` live=${F(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3044
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${I(e.expected)}` + (e.actual ? ` live=${I(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2987
3045
  case "refused-blocked": {
2988
- 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` + yi(e.plan), c = [""];
3046
+ 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` + Ni(e.plan), c = [""];
2989
3047
  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) {
2990
3048
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2991
3049
  for (let r of e.plan.operations) {
@@ -3002,7 +3060,7 @@ BEGIN
3002
3060
  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");
3003
3061
  }
3004
3062
  }
3005
- }, Pi = /* @__PURE__ */ new Set([
3063
+ }, Ji = /* @__PURE__ */ new Set([
3006
3064
  "node_modules",
3007
3065
  "dist",
3008
3066
  "build",
@@ -3011,24 +3069,24 @@ BEGIN
3011
3069
  ".next",
3012
3070
  ".git",
3013
3071
  ".framework"
3014
- ]), Fi = async (e) => {
3072
+ ]), Yi = async (e) => {
3015
3073
  let t = [], n = async (e) => {
3016
- let r = await te.readdir(e, { withFileTypes: !0 }).catch(() => []);
3074
+ let r = await ne.readdir(e, { withFileTypes: !0 }).catch(() => []);
3017
3075
  for (let i of r) {
3018
- if (Pi.has(i.name)) continue;
3019
- let r = ne(e, i.name);
3020
- i.isDirectory() ? await n(r) : i.isFile() && u.test(i.name) && t.push(r);
3076
+ if (Ji.has(i.name)) continue;
3077
+ let r = re(e, i.name);
3078
+ i.isDirectory() ? await n(r) : i.isFile() && d.test(i.name) && t.push(r);
3021
3079
  }
3022
3080
  };
3023
3081
  return await n(e), t.sort((e, t) => {
3024
3082
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3025
3083
  return n.localeCompare(r);
3026
3084
  });
3027
- }, Ii = async (e) => {
3085
+ }, Xi = async (e) => {
3028
3086
  let t = [];
3029
3087
  for (let n of e) {
3030
- let e = (await import(re(n).href)).default;
3031
- if (!o(e)) {
3088
+ let e = (await import(ie(n).href)).default;
3089
+ if (!c(e)) {
3032
3090
  process.stderr.write(`[voltro:migrate] ${n} has no default-exported \`migration(...)\` — skipped\n`);
3033
3091
  continue;
3034
3092
  }
@@ -3038,11 +3096,11 @@ BEGIN
3038
3096
  });
3039
3097
  }
3040
3098
  return t;
3041
- }, Li = (e) => e`
3099
+ }, Zi = (e) => e`
3042
3100
  SELECT ${e("id")}
3043
3101
  FROM ${e("_voltro_migration_plans")}
3044
3102
  WHERE ${e("source")} = 'file'
3045
- `.pipe(b.map((e) => e.map((e) => e.id)), b.catchAll(() => b.succeed([]))), Ri = class extends Error {
3103
+ `.pipe(x.map((e) => e.map((e) => e.id)), x.catchAll(() => x.succeed([]))), Qi = class extends Error {
3046
3104
  migrationId;
3047
3105
  file;
3048
3106
  cause;
@@ -3050,28 +3108,28 @@ BEGIN
3050
3108
  constructor(e, t, n) {
3051
3109
  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";
3052
3110
  }
3053
- }, zi = (e, t, n, r) => b.gen(function* () {
3111
+ }, $i = (e, t, n, r) => x.gen(function* () {
3054
3112
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3055
3113
  sql: e,
3056
3114
  log: {
3057
- info: (e, n) => b.logInfo(e).pipe(b.annotateLogs({
3115
+ info: (e, n) => x.logInfo(e).pipe(x.annotateLogs({
3058
3116
  scope: `migrations:file:${t.migration.id}`,
3059
3117
  ...n ?? {}
3060
3118
  })),
3061
- warn: (e, n) => b.logWarning(e).pipe(b.annotateLogs({
3119
+ warn: (e, n) => x.logWarning(e).pipe(x.annotateLogs({
3062
3120
  scope: `migrations:file:${t.migration.id}`,
3063
3121
  ...n ?? {}
3064
3122
  }))
3065
3123
  },
3066
3124
  appliedAt: a
3067
3125
  }, s = t.migration.up(o);
3068
- b.isEffect(s) ? yield* s : yield* b.tryPromise({
3126
+ x.isEffect(s) ? yield* s : yield* x.tryPromise({
3069
3127
  try: () => s,
3070
3128
  catch: (e) => e
3071
3129
  });
3072
3130
  let c = Date.now() - i;
3073
- !b.isEffect(s) && c < 2 && (yield* b.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(b.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3074
- let l = yield* U(e, a);
3131
+ !x.isEffect(s) && c < 2 && (yield* x.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(x.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3132
+ let l = yield* G(e, a);
3075
3133
  return yield* e`
3076
3134
  INSERT INTO ${e("_voltro_migration_plans")}
3077
3135
  (${e("id")}, ${e("fingerprint")}, ${e("operations")},
@@ -3084,31 +3142,31 @@ BEGIN
3084
3142
  }])},
3085
3143
  ${r}, ${n}, ${"file"},
3086
3144
  ${c}, ${l}, ${t.migration.description})
3087
- `.pipe(b.mapError((e) => new Ri(t.migration.id, t.file, e))), { durationMs: c };
3088
- }), Bi = (e, t) => b.gen(function* () {
3089
- let n = yield* b.tryPromise({
3090
- try: () => Fi(ne(t, "migrations")),
3145
+ `.pipe(x.mapError((e) => new Qi(t.migration.id, t.file, e))), { durationMs: c };
3146
+ }), ea = (e, t) => x.gen(function* () {
3147
+ let n = yield* x.tryPromise({
3148
+ try: () => Yi(re(t, "migrations")),
3091
3149
  catch: (e) => e
3092
3150
  });
3093
3151
  if (n.length === 0) return {
3094
3152
  pending: [],
3095
3153
  skipped: []
3096
3154
  };
3097
- let r = yield* b.tryPromise({
3098
- try: () => Ii(n),
3155
+ let r = yield* x.tryPromise({
3156
+ try: () => Xi(n),
3099
3157
  catch: (e) => e
3100
3158
  });
3101
3159
  if (r.length === 0) return {
3102
3160
  pending: [],
3103
3161
  skipped: []
3104
3162
  };
3105
- let i = new Set(yield* Li(e));
3163
+ let i = new Set(yield* Zi(e));
3106
3164
  return {
3107
3165
  pending: r.filter((e) => !i.has(e.migration.id)),
3108
3166
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3109
3167
  };
3110
- }), Vi = (e, t) => Bi(e, t).pipe(b.map((e) => e.pending.map((e) => e.migration.id))), Hi = (e, t) => b.gen(function* () {
3111
- let { pending: n, skipped: r } = yield* Bi(e, t.projectRoot);
3168
+ }), ta = (e, t) => ea(e, t).pipe(x.map((e) => e.pending.map((e) => e.migration.id))), na = (e, t) => x.gen(function* () {
3169
+ let { pending: n, skipped: r } = yield* ea(e, t.projectRoot);
3112
3170
  if (n.length === 0) return {
3113
3171
  applied: [],
3114
3172
  skipped: r
@@ -3117,61 +3175,61 @@ BEGIN
3117
3175
  let i = [];
3118
3176
  try {
3119
3177
  for (let r of n) {
3120
- yield* b.logInfo("file-based migration applying").pipe(b.annotateLogs({
3178
+ yield* x.logInfo("file-based migration applying").pipe(x.annotateLogs({
3121
3179
  scope: "voltro:migrate",
3122
3180
  id: r.migration.id,
3123
3181
  file: r.file
3124
3182
  }));
3125
- let { durationMs: n } = yield* zi(e, r, t.env, t.appliedBy);
3183
+ let { durationMs: n } = yield* $i(e, r, t.env, t.appliedBy);
3126
3184
  i.push({
3127
3185
  id: r.migration.id,
3128
3186
  durationMs: n
3129
- }), yield* b.logInfo("file-based migration applied").pipe(b.annotateLogs({
3187
+ }), yield* x.logInfo("file-based migration applied").pipe(x.annotateLogs({
3130
3188
  scope: "voltro:migrate",
3131
3189
  id: r.migration.id,
3132
3190
  durationMs: n
3133
3191
  }));
3134
3192
  }
3135
3193
  } finally {
3136
- yield* D(e, { schema: t.lockSchema }).pipe(b.orDie);
3194
+ yield* D(e, { schema: t.lockSchema }).pipe(x.orDie);
3137
3195
  }
3138
3196
  return {
3139
3197
  applied: i,
3140
3198
  skipped: r
3141
3199
  };
3142
- }), Ui = (e, t) => e`
3200
+ }), ra = (e, t) => e`
3143
3201
  SELECT ${e("id")}
3144
3202
  FROM ${e("_voltro_migration_plans")}
3145
3203
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3146
3204
  LIMIT 1
3147
- `, Wi = (e, t) => b.gen(function* () {
3148
- if (!(yield* Ui(e, t.id))[0]) return yield* b.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3149
- let n = yield* b.tryPromise({
3150
- try: () => Fi(ne(t.projectRoot, "migrations")),
3205
+ `, ia = (e, t) => x.gen(function* () {
3206
+ if (!(yield* ra(e, t.id))[0]) return yield* x.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3207
+ let n = yield* x.tryPromise({
3208
+ try: () => Yi(re(t.projectRoot, "migrations")),
3151
3209
  catch: (e) => e
3152
- }), r = (yield* b.tryPromise({
3153
- try: () => Ii(n),
3210
+ }), r = (yield* x.tryPromise({
3211
+ try: () => Xi(n),
3154
3212
  catch: (e) => e
3155
3213
  })).find((e) => e.migration.id === t.id);
3156
- if (!r) return yield* b.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3214
+ if (!r) return yield* x.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3157
3215
  yield* E(e, { schema: t.lockSchema });
3158
3216
  let i = Date.now();
3159
3217
  try {
3160
3218
  let n = {
3161
3219
  sql: e,
3162
3220
  log: {
3163
- info: (e, n) => b.logInfo(e).pipe(b.annotateLogs({
3221
+ info: (e, n) => x.logInfo(e).pipe(x.annotateLogs({
3164
3222
  scope: `migrations:file:${t.id}`,
3165
3223
  ...n ?? {}
3166
3224
  })),
3167
- warn: (e, n) => b.logWarning(e).pipe(b.annotateLogs({
3225
+ warn: (e, n) => x.logWarning(e).pipe(x.annotateLogs({
3168
3226
  scope: `migrations:file:${t.id}`,
3169
3227
  ...n ?? {}
3170
3228
  }))
3171
3229
  },
3172
3230
  appliedAt: (/* @__PURE__ */ new Date()).toISOString()
3173
3231
  }, a = r.migration.down(n);
3174
- b.isEffect(a) ? yield* a : yield* b.tryPromise({
3232
+ x.isEffect(a) ? yield* a : yield* x.tryPromise({
3175
3233
  try: () => a,
3176
3234
  catch: (e) => e
3177
3235
  });
@@ -3181,9 +3239,9 @@ BEGIN
3181
3239
  durationMs: o
3182
3240
  };
3183
3241
  } finally {
3184
- yield* D(e, { schema: t.lockSchema }).pipe(b.orDie);
3242
+ yield* D(e, { schema: t.lockSchema }).pipe(x.orDie);
3185
3243
  }
3186
- }), Gi = (e) => b.gen(function* () {
3244
+ }), aa = (e) => x.gen(function* () {
3187
3245
  let t = yield* C.SqlClient, n = yield* t`
3188
3246
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3189
3247
  WHERE source = 'auto-diff'
@@ -3191,9 +3249,9 @@ BEGIN
3191
3249
  AND appliedAt < ${e.before}
3192
3250
  ORDER BY appliedAt DESC
3193
3251
  `;
3194
- if (n.length === 0) return yield* b.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3252
+ if (n.length === 0) return yield* x.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3195
3253
  let r = n[0];
3196
- if (r.fingerprint !== e.fingerprint) return yield* b.fail(/* @__PURE__ */ Error(`squash: latest pre-squash fingerprint (${r.fingerprint.slice(0, 12)}…) differs from current declared-schema fingerprint (${e.fingerprint.slice(0, 12)}…). This means the working tree carries un-applied changes — squashing now would lock the drift in.\n\nFix: run \`voltro db apply\` first to align the live schema with the working tree, then re-squash.`));
3254
+ if (r.fingerprint !== e.fingerprint) return yield* x.fail(/* @__PURE__ */ Error(`squash: latest pre-squash fingerprint (${r.fingerprint.slice(0, 12)}…) differs from current declared-schema fingerprint (${e.fingerprint.slice(0, 12)}…). This means the working tree carries un-applied changes — squashing now would lock the drift in.\n\nFix: run \`voltro db apply\` first to align the live schema with the working tree, then re-squash.`));
3197
3255
  yield* t`
3198
3256
  UPDATE _voltro_migration_plans
3199
3257
  SET squashedAt = CURRENT_TIMESTAMP
@@ -3228,7 +3286,7 @@ BEGIN
3228
3286
  snapshotFingerprint: e.fingerprint,
3229
3287
  snapshotId: i
3230
3288
  };
3231
- }), Ki = { safe: !0 }, qi = (e) => {
3289
+ }), oa = { safe: !0 }, sa = (e) => {
3232
3290
  switch (e.kind) {
3233
3291
  case "drop-column": return {
3234
3292
  safe: !1,
@@ -3255,7 +3313,7 @@ BEGIN
3255
3313
  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`,
3256
3314
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3257
3315
  };
3258
- case "alter-column-nullability": return e.toNullable ? Ki : {
3316
+ case "alter-column-nullability": return e.toNullable ? oa : {
3259
3317
  safe: !1,
3260
3318
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3261
3319
  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)`
@@ -3285,12 +3343,12 @@ BEGIN
3285
3343
  case "drop-unique":
3286
3344
  case "drop-unique-composite":
3287
3345
  case "drop-foreign-key":
3288
- case "drop-check": return Ki;
3346
+ case "drop-check": return oa;
3289
3347
  }
3290
- }, Ji = (e) => {
3348
+ }, ca = (e) => {
3291
3349
  let t = [];
3292
3350
  for (let n of e) {
3293
- let e = qi(n.op);
3351
+ let e = sa(n.op);
3294
3352
  e.safe || t.push({
3295
3353
  op: n,
3296
3354
  reason: e.reason,
@@ -3298,7 +3356,7 @@ BEGIN
3298
3356
  });
3299
3357
  }
3300
3358
  return t;
3301
- }, Yi = (e) => {
3359
+ }, la = (e) => {
3302
3360
  if (!e.enabled || e.unsafeCount === 0) return {
3303
3361
  refuse: !1,
3304
3362
  warnForced: !1,
@@ -3314,18 +3372,18 @@ BEGIN
3314
3372
  warnForced: !1,
3315
3373
  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.`
3316
3374
  };
3317
- }, Xi = (e) => {
3375
+ }, ua = (e) => {
3318
3376
  let t = e.table;
3319
3377
  if (typeof t == "string") return t;
3320
3378
  let n = e.from;
3321
3379
  return typeof n == "string" ? n : void 0;
3322
- }, Zi = (e) => ({
3380
+ }, da = (e) => ({
3323
3381
  kind: e.op.kind,
3324
- table: Xi(e.op),
3382
+ table: ua(e.op),
3325
3383
  classification: e.classification,
3326
3384
  reason: e.reason,
3327
3385
  blockedFix: e.blocked?.fix
3328
- }), Qi = (e) => e.operations.map(Zi), $i = async (e) => {
3386
+ }), fa = (e) => e.operations.map(da), pa = async (e) => {
3329
3387
  let t = e.log ?? (() => {}), n = {
3330
3388
  branchId: e.branchId,
3331
3389
  mechanism: e.mechanism,
@@ -3344,10 +3402,10 @@ BEGIN
3344
3402
  applied: !1,
3345
3403
  converged: !1,
3346
3404
  residual: r,
3347
- infidelity: Qi(o)
3405
+ infidelity: fa(o)
3348
3406
  };
3349
3407
  else {
3350
- let i = await e.plan(), o = Qi(i), s = o.filter((e) => e.classification === "lossy"), c = ki(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Zi);
3408
+ let i = await e.plan(), o = fa(i), s = o.filter((e) => e.classification === "lossy"), c = Ui(i), l = c.operations.filter((e) => e.blocked !== void 0).map(da);
3351
3409
  if (l.length > 0) a = {
3352
3410
  ...n,
3353
3411
  outcome: "blocked",
@@ -3372,7 +3430,7 @@ BEGIN
3372
3430
  };
3373
3431
  else {
3374
3432
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3375
- let i = Qi(await e.replan());
3433
+ let i = fa(await e.replan());
3376
3434
  a = {
3377
3435
  ...n,
3378
3436
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3410,7 +3468,7 @@ BEGIN
3410
3468
  ...a,
3411
3469
  tornDown: o
3412
3470
  };
3413
- }, ea = (e) => {
3471
+ }, ma = (e) => {
3414
3472
  switch (e.outcome) {
3415
3473
  case "clean": return 0;
3416
3474
  case "lossy": return 2;
@@ -3419,22 +3477,22 @@ BEGIN
3419
3477
  case "infidelity": return 1;
3420
3478
  case "failed": return 1;
3421
3479
  }
3422
- }, ta = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, na = (e) => {
3480
+ }, ha = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, ga = (e) => {
3423
3481
  let t = [];
3424
3482
  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"}`);
3425
3483
  else if (e.outcome === "infidelity") {
3426
3484
  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:");
3427
- for (let n of e.infidelity) t.push(ta(n));
3485
+ for (let n of e.infidelity) t.push(ha(n));
3428
3486
  } else {
3429
3487
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3430
- for (let n of e.operations) t.push(ta(n));
3431
- 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(ta(n));
3488
+ for (let n of e.operations) t.push(ha(n));
3489
+ 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(ha(n));
3432
3490
  }
3433
3491
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3434
- }, ra = (e, ...t) => ({
3492
+ }, _a = (e, ...t) => ({
3435
3493
  _tag: "RawSqlFragment",
3436
3494
  strings: [...e],
3437
3495
  values: [...t]
3438
- }), ia = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3496
+ }), va = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3439
3497
  //#endregion
3440
- export { k as DEFAULT_CDC_CHANNEL, u as FILE_MIGRATION_PATTERN, Ri as FileMigrationLedgerError, Ke as REACTIVE_TRIGGER_PREFIX, fe as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, U as appliedAtValue, Ft as applyNamespacedSchema, vi as applyPlan, Tt as applySchema, Yi as assessRollingDeployGate, ea as branchRehearsalExitCode, In as chunkTables, qi as classifyRollingDeploySafety, I as declaredSnapshot, Qe as defaultArrayClause, Ze as defaultClause, M as defaultJsonClause, Ni as describeOutcome, Di as destructiveScope, qt as detectReactiveTriggerDrift, Ir as emitAddIndexMysql, _r as emitCreateTableMysql, er as emitDropColumnDdl, tr as emitDropColumnDdlMysql, wt as emitFrameworkBootstrapSql, St as emitNamespaceProvisionDdl, Ct as emitNamespacedSchemaSql, xt as emitSchemaSql, P as fingerprintSchema, ve as fnv1a64, na as formatBranchRehearsal, Jt as formatReactiveTriggerDrift, Ei as ignoreTablesFromEnv, Jn as introspectSchema, o as isFileMigration, ia as isRawSqlFragment, Dt as isReRunSafeDdl, jn as mapPgType, h as migration, ye as migrationLockKeyForSchema, T as migrationLockNameForSchema, Mr as mysqlIndexPrefixFor, Je as notifyFunctionName, N as numericIdSql, An as parseEnumCheck, Vi as pendingFileMigrationIds, kn as planMigrations, It as provisionTenantNamespace, qe as reactiveTriggerName, ft as reactiveTriggerRepairSql, xi as recordUpToDate, $i as rehearseMigrationOnBranch, Zi as rehearsedOperation, D as releaseMigrationLock, gr as renderColumnMysql, dr as renderColumnPg, me as resolveMigrationLockSchema, Wi as rollbackFileBasedMigration, Ji as rollingDeployUnsafeOps, Hi as runFileBasedMigrations, Lt as runFrameworkBootstrap, Pt as runMigrate, Mi as runPlannedMigrations, F as shortFingerprint, Ut as snapshotColumn, ra as sql, j as sqlType, Gi as squashMigrationPlans, ki as unblockLossy, je as withMigrationLock };
3498
+ export { k as DEFAULT_CDC_CHANNEL, d as FILE_MIGRATION_PATTERN, Qi as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, pe as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, G as appliedAtValue, It as applyNamespacedSchema, Mi as applyPlan, Et as applySchema, la as assessRollingDeployGate, ma as branchRehearsalExitCode, Ln as chunkTables, sa as classifyRollingDeploySafety, L as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, M as defaultJsonClause, qi as describeOutcome, Vi as destructiveScope, Jt as detectReactiveTriggerDrift, Xr as emitAddIndexMysql, jr as emitCreateTableMysql, dr as emitDropColumnDdl, fr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, Xn as engineFromVersion, F as fingerprintSchema, ye as fnv1a64, ga as formatBranchRehearsal, Yt as formatReactiveTriggerDrift, Bi as ignoreTablesFromEnv, Yn as introspectSchema, tr as isAlreadySatisfied, c as isFileMigration, va as isRawSqlFragment, Ot as isReRunSafeDdl, Mn as mapPgType, g as migration, be as migrationLockKeyForSchema, T as migrationLockNameForSchema, Kr as mysqlIndexPrefixFor, Ye as notifyFunctionName, N as numericIdSql, jn as parseEnumCheck, ta as pendingFileMigrationIds, An as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Fi as recordUpToDate, pa as rehearseMigrationOnBranch, da as rehearsedOperation, D as releaseMigrationLock, kr as renderColumnMysql, wr as renderColumnPg, he as resolveMigrationLockSchema, W as resolveMysqlEngine, ia as rollbackFileBasedMigration, ca as rollingDeployUnsafeOps, na as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, Ki as runPlannedMigrations, I as shortFingerprint, Wt as snapshotColumn, _a as sql, j as sqlType, aa as squashMigrationPlans, Ui as unblockLossy, Me as withMigrationLock };