@voltro/database 0.62.2 → 0.63.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 { $ as e, $t as t, Ht as n, Ut as r, a as i, at as a, c as o, d as s, en as c, et as l, g as u, h as d, i as f, it as p, o as m, r as h, s as g, tt as _, u as v, vt as y, wt as b, y as x } from "./frameworkLiveTables-CwDemhjW.js";
1
+ import { $ as e, $t as t, Ht as n, Ut as r, a as i, at as a, c as o, d as s, en as c, et as l, g as u, h as d, i as f, it as p, o as m, r as h, s as g, tt as _, u as v, vt as y, wt as b, y as x } from "./frameworkLiveTables-X6rOAleu.js";
2
2
  import { Effect as S, Schedule as C } from "effect";
3
- import { createHash as w } from "node:crypto";
4
- import { createLogger as T } from "@voltro/logger";
5
- import { SqlClient as E } from "@effect/sql";
6
- import { promises as ee } from "node:fs";
7
- import { join as te } from "node:path";
8
- import { pathToFileURL as ne } from "node:url";
3
+ import { createHash as ee } from "node:crypto";
4
+ import { createLogger as w } from "@voltro/logger";
5
+ import { SqlClient as T } from "@effect/sql";
6
+ import { promises as te } from "node:fs";
7
+ import { join as ne } from "node:path";
8
+ import { pathToFileURL as re } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var re = (e, t, n, r = 400) => {
10
+ var ie = (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 re = (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 = ie(o("code"));
41
+ let c = ae(o("code"));
42
42
  return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
- }, ie = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, ae = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, oe = (e) => e.replace(/"/g, "`"), se = (e) => typeof e == "string" ? e : e.name ?? String(e), ce = (e, t) => `_ua_${t}_${e}`.slice(0, 64), le = (e, t) => {
44
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(ae)) return e;
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;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!ae(t)) {
47
+ if (!oe(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = oe(t.where), o = [];
51
+ let a = se(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = se(r);
53
+ let i = ce(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 = ce(t.name, i);
55
+ let s = le(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,30 +75,30 @@ var re = (e, t, n, r = 400) => {
75
75
  appliedIndexes: r,
76
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
77
77
  };
78
- }, D = (e, t) => `${e}::${t}`, ue = (e, t) => {
78
+ }, E = (e, t) => `${e}::${t}`, de = (e, t) => {
79
79
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
80
80
  n.add(e);
81
81
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
82
- for (let t of o) n.has(t.target) ? i.add(D(e, t.column)) : r.has(t.target) || a(t.target);
82
+ for (let t of o) n.has(t.target) ? i.add(E(e, t.column)) : r.has(t.target) || a(t.target);
83
83
  n.delete(e), r.add(e);
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, de = 6322741009312437n, fe = (e) => {
87
+ }, fe = 6322741009312437n, pe = (e) => {
88
88
  let t = e?.trim();
89
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
90
- }, pe = (e) => e?.schema === void 0 ? fe(process.env.DB_SCHEMA) : fe(e.schema), me = 14695981039346656037n, he = 1099511628211n, ge = 18446744073709551615n, _e = (e) => {
91
- let t = me;
92
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * he & ge;
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;
93
93
  return t;
94
- }, ve = (e) => {
95
- let t = fe(e);
96
- return t === void 0 ? de : _e(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
94
  }, ye = (e) => {
98
- let t = `voltro_migration_${de.toString(36)}`, n = fe(e);
95
+ let t = pe(e);
96
+ return t === void 0 ? fe : ve(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
+ }, D = (e) => {
98
+ let t = `voltro_migration_${fe.toString(36)}`, n = pe(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${(_e(`voltro_migration_lock:${n}`) & ge).toString(16)}`;
101
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(ve(`voltro_migration_lock:${n}`) & _e).toString(16)}`;
102
102
  }, be = 250, xe = () => {
103
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
104
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
@@ -126,20 +126,20 @@ var re = (e, t, n, r = 400) => {
126
126
  }), ke = (e, t) => S.gen(function* () {
127
127
  yield* e`EXEC sp_releaseapplock @Resource = ${t}, @LockOwner = 'Session'`;
128
128
  }), Ae = S.void, je = (e, t) => {
129
- let n = pe(t);
129
+ let n = me(t);
130
130
  return e.onDialectOrElse({
131
- mysql: () => Te(e, ye(n)),
132
- mssql: () => Oe(e, ye(n)),
131
+ mysql: () => Te(e, D(n)),
132
+ mssql: () => Oe(e, D(n)),
133
133
  sqlite: () => Ae,
134
- orElse: () => Se(e, ve(n))
134
+ orElse: () => Se(e, ye(n))
135
135
  });
136
136
  }, O = (e, t) => {
137
- let n = pe(t);
137
+ let n = me(t);
138
138
  return e.onDialectOrElse({
139
- mysql: () => Ee(e, ye(n)),
140
- mssql: () => ke(e, ye(n)),
139
+ mysql: () => Ee(e, D(n)),
140
+ mssql: () => ke(e, D(n)),
141
141
  sqlite: () => Ae,
142
- orElse: () => Ce(e, ve(n))
142
+ orElse: () => Ce(e, ye(n))
143
143
  });
144
144
  }, Me = (e, t, n) => S.acquireUseRelease(je(e, n), () => t, () => O(e, n).pipe(S.orDie)), Ne = (e) => e.onDialectOrElse({
145
145
  pg: () => "postgres",
@@ -217,8 +217,13 @@ var re = (e, t, n, r = 400) => {
217
217
  Object.keys(Pe);
218
218
  //#endregion
219
219
  //#region src/migrations/reactiveTriggerName.ts
220
- var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "framework_changes" ? `${qe}${e}` : `${qe}${t}_${e}`, Ye = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Xe = "voltro:notify:v2", Ze = T({ scope: "voltro:migrate" }), j = (e) => {
221
- Ze.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
220
+ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "framework_changes" ? `${qe}${e}` : `${qe}${t}_${e}`, Ye = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Xe = "voltro:notify:v2", Ze = (e, t) => {
221
+ if (e.type === "text" && e.generatedAs === void 0) {
222
+ if (e.maxLength !== void 0) return e.maxLength;
223
+ if (t || e.hasDefault && e.defaultFactory === void 0 || e.oneOf !== void 0 && e.oneOf.length > 0) return 450;
224
+ }
225
+ }, Qe = w({ scope: "voltro:migrate" }), j = (e) => {
226
+ Qe.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
222
227
  }, M = (e, t) => {
223
228
  let n = e.type;
224
229
  if (e.spatial) {
@@ -300,7 +305,10 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
300
305
  }
301
306
  if (t === "mssql") switch (n) {
302
307
  case "id": return "NVARCHAR(64)";
303
- case "text": return e.hasDefault && e.defaultFactory === void 0 || e.oneOf && e.oneOf.length > 0 ? "NVARCHAR(450)" : "NVARCHAR(MAX)";
308
+ case "text": {
309
+ let t = Ze(e, !1);
310
+ return t === void 0 ? "NVARCHAR(MAX)" : `NVARCHAR(${t})`;
311
+ }
304
312
  case "integer": return "INT";
305
313
  case "real": return "FLOAT";
306
314
  case "boolean": return "BIT";
@@ -330,11 +338,11 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
330
338
  case "array": return "TEXT[]";
331
339
  case "interval": return "INTERVAL";
332
340
  }
333
- }, Qe = (e, t) => {
341
+ }, $e = (e, t) => {
334
342
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
335
343
  let n = e.defaultValue;
336
- return n === "now" ? l(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 ? N(n, t) : null;
337
- }, $e = (e, t, n) => {
344
+ return n === "now" ? l(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) ? et(n, e, t) : typeof n == "object" && n ? N(n, t) : null;
345
+ }, et = (e, t, n) => {
338
346
  if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return N(e, n);
339
347
  let r = M({
340
348
  ...t,
@@ -362,18 +370,18 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
362
370
  case "setNull": return "SET NULL";
363
371
  case "noAction": return "NO ACTION";
364
372
  }
365
- }, et = (e, t, n) => n === null ? _(e, t) : `${_(n, t)}.${_(e, t)}`, tt = 191, nt = (e, t) => {
373
+ }, tt = (e, t, n) => n === null ? _(e, t) : `${_(n, t)}.${_(e, t)}`, nt = 191, rt = (e, t) => {
366
374
  if (!e || t !== "mysql" && t !== "mariadb") return !1;
367
375
  let n = M(e, t).toUpperCase();
368
376
  return n.endsWith("TEXT") || n.endsWith("BLOB");
369
- }, rt = (e, t, n) => {
377
+ }, it = (e, t, n) => {
370
378
  let r = _(e, n);
371
379
  if (n !== "mysql" && n !== "mariadb") return r;
372
380
  let i = t[e];
373
381
  if (!i) return r;
374
382
  let a = M(i, n).toUpperCase();
375
- return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${tt})` : r;
376
- }, it = (e, t) => {
383
+ return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${nt})` : r;
384
+ }, at = (e, t) => {
377
385
  if (!e.generatedAs) return null;
378
386
  let { expr: n, stored: r } = e.generatedAs;
379
387
  if (t === "postgres") return r || j("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
@@ -381,56 +389,57 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
381
389
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
382
390
  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.");
383
391
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
384
- }, at = (t, n, r, i, a = !1, o = !1) => {
392
+ }, ot = (t, n, r, i, a = !1, o = !1) => {
385
393
  if (n.type === "id" && n.idScheme?.kind === "numeric") return P(t, r);
386
- let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : M(n, r), c = [_(t, r), s];
387
- n.type === "id" && !o && c.push("PRIMARY KEY");
388
- let u = it(n, r);
389
- if (u) c.push(u);
394
+ let s = r === "mssql" ? Ze(n, i?.has(t) ?? !1) : void 0, c = s === void 0 ? M(n, r) : `NVARCHAR(${s})`, u = [_(t, r), c];
395
+ n.type === "id" && !o && u.push("PRIMARY KEY");
396
+ let d = at(n, r);
397
+ if (d) u.push(d);
390
398
  else {
391
- n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && !nt(n, r) && c.push("UNIQUE");
392
- let e = Qe(n, r);
393
- e && c.push(e);
399
+ n.nullable || u.push("NOT NULL"), n.unique && n.type !== "id" && !rt(n, r) && u.push("UNIQUE");
400
+ let e = $e(n, r);
401
+ e && u.push(e);
394
402
  }
395
403
  if (n.type === "reference" && n.references && !a && !e(r)) {
396
404
  let e = n.references();
397
- c.push(`REFERENCES ${_(e.tableName, r)} (${_("id", r)})`);
405
+ u.push(`REFERENCES ${_(e.tableName, r)} (${_("id", r)})`);
398
406
  let t = F(n.onDelete ?? "restrict", r);
399
- c.push(`ON DELETE ${t}`);
407
+ u.push(`ON DELETE ${t}`);
400
408
  let i = F(n.refOnUpdate ?? "noAction", r);
401
- i !== "NO ACTION" && c.push(`ON UPDATE ${i}`);
409
+ i !== "NO ACTION" && u.push(`ON UPDATE ${i}`);
402
410
  }
403
411
  if (n.oneOf && n.oneOf.length > 0) {
404
412
  let e = n.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
405
- c.push(`CHECK (${_(t, r)} IN (${e}))`);
413
+ u.push(`CHECK (${_(t, r)} IN (${e}))`);
406
414
  }
407
- if (n.checks && n.checks.length > 0) for (let e of n.checks) c.push(`CHECK (${e})`);
415
+ if (n.checks && n.checks.length > 0) for (let e of n.checks) u.push(`CHECK (${e})`);
408
416
  if (n.type === "enum" && n.enumValues && n.enumValues.length > 0 && (r === "mssql" || l(r))) {
409
417
  let e = n.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
410
- c.push(`CHECK (${_(t, r)} IN (${e}))`);
418
+ u.push(`CHECK (${_(t, r)} IN (${e}))`);
411
419
  }
412
420
  if (n.type === "json" || n.type === "array") {
413
421
  let e = _(t, r);
414
- l(r) ? c.push(`CHECK (${e} IS NULL OR json_valid(${e}))`) : r === "mssql" && c.push(`CHECK (${e} IS NULL OR ISJSON(${e}) = 1)`);
422
+ l(r) ? u.push(`CHECK (${e} IS NULL OR json_valid(${e}))`) : r === "mssql" && u.push(`CHECK (${e} IS NULL OR ISJSON(${e}) = 1)`);
415
423
  }
416
- return c.join(" ");
417
- }, ot = (t, n, r = null, i) => {
424
+ return u.join(" ");
425
+ }, st = (t, n, r = null, i) => {
418
426
  let a = /* @__PURE__ */ new Set();
419
427
  for (let e of t.appliedIndexes ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
420
428
  for (let e of t.appliedUniques ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
421
- let o = t.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(t.fields).map(([e, t]) => ` ${at(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (t.appliedUniques ?? []).map((e) => {
422
- let r = e.fields.map((e) => rt(e, t.fields, n)).join(", ");
429
+ for (let [e, n] of Object.entries(t.fields)) n.unique && a.add(e);
430
+ let o = t.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(t.fields).map(([e, t]) => ` ${ot(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (t.appliedUniques ?? []).map((e) => {
431
+ let r = e.fields.map((e) => it(e, t.fields, n)).join(", ");
423
432
  return ` CONSTRAINT ${_(e.name, n)} UNIQUE (${r})`;
424
- }), u = (t.appliedChecks ?? []).map((e) => ` CONSTRAINT ${_(e.name, n)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${o.map((e) => rt(e, t.fields, n)).join(", ")})`] : [], f = e(n) ? Object.entries(t.fields).flatMap(([e, a]) => {
433
+ }), u = (t.appliedChecks ?? []).map((e) => ` CONSTRAINT ${_(e.name, n)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${o.map((e) => it(e, t.fields, n)).join(", ")})`] : [], f = e(n) ? Object.entries(t.fields).flatMap(([e, a]) => {
425
434
  if (a.type !== "reference" || !a.references || (i?.has(e) ?? !1)) return [];
426
435
  let o = a.references(), s = F(a.onDelete ?? "restrict", n), c = F(a.refOnUpdate ?? "noAction", n);
427
- return [` CONSTRAINT ${_(`${t.tableName}_${e}_fkey`, n)} FOREIGN KEY (${_(e, n)}) REFERENCES ${et(o.tableName, n, r)} (${_("id", n)}) ON DELETE ${s}${c === "NO ACTION" ? "" : ` ON UPDATE ${c}`}`];
436
+ return [` CONSTRAINT ${_(`${t.tableName}_${e}_fkey`, n)} FOREIGN KEY (${_(e, n)}) REFERENCES ${tt(o.tableName, n, r)} (${_("id", n)}) ON DELETE ${s}${c === "NO ACTION" ? "" : ` ON UPDATE ${c}`}`];
428
437
  }) : [], p = [
429
438
  ...d,
430
439
  ...l,
431
440
  ...u,
432
441
  ...f
433
- ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = et(t.tableName, n, r);
442
+ ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = tt(t.tableName, n, r);
434
443
  if (n === "mssql") {
435
444
  let e = r === null ? t.tableName : `${r}.${t.tableName}`, n = `CREATE TABLE ${h} (\n${m}\n)`;
436
445
  return `IF OBJECT_ID('${e.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
@@ -440,10 +449,10 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
440
449
  m,
441
450
  ");"
442
451
  ].join("\n");
443
- }, st = (e, t, n) => {
452
+ }, ct = (e, t, n) => {
444
453
  let r = `${e}_${t.name}_fts`, i = (e) => _(e, n), a = t.columns.map(i).join(", "), o = t.columns.map((e) => `new.${i(e)}`).join(", "), s = [];
445
454
  return s.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${i(r)} USING fts5(${a}, row_id UNINDEXED, tokenize='porter');`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ai`)} AFTER INSERT ON ${i(e)} BEGIN\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ad`)} AFTER DELETE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_au`)} AFTER UPDATE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s;
446
- }, ct = (e, t, n = null) => {
455
+ }, lt = (e, t, n = null) => {
447
456
  let r = [], i = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, n, r, i) => {
448
457
  let o = {
449
458
  using: "",
@@ -489,7 +498,7 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
489
498
  return o;
490
499
  }, c = (n, r) => {
491
500
  let i = n.map((n) => {
492
- if (typeof n == "string") return rt(n, e.fields, t);
501
+ if (typeof n == "string") return it(n, e.fields, t);
493
502
  if ("jsonPath" in n) {
494
503
  let { column: e, path: r, numeric: i } = n.jsonPath;
495
504
  return `(${d(e, r, t, { numeric: i })})`;
@@ -500,11 +509,11 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
500
509
  }, l = (e, r, i, a, o, l = "", u = !1) => {
501
510
  let d = s(e, r, a, o);
502
511
  if (d.skip) return "";
503
- let f = c(i, d.opclass), p = `${d.withSuffix}${l}`, m = et(r, t, n), h = u ? "UNIQUE " : "";
512
+ let f = c(i, d.opclass), p = `${d.withSuffix}${l}`, m = tt(r, t, n), h = u ? "UNIQUE " : "";
504
513
  return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${h}INDEX ${_(e, t)} ON ${m}${d.using} (${f})${p};` : t === "mysql" ? `CREATE ${h}INDEX ${_(e, t)} ON ${m}${d.using} (${f})${p};` : `CREATE ${h}INDEX IF NOT EXISTS ${_(e, t)} ON ${m}${d.using} (${f})${p};`;
505
514
  };
506
515
  if (t === "mysql" || t === "mariadb") for (let [n, i] of Object.entries(e.fields)) {
507
- if (!i.unique || i.type === "id" || !nt(i, t)) continue;
516
+ if (!i.unique || i.type === "id" || !rt(i, t)) continue;
508
517
  let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
509
518
  a && r.push(a);
510
519
  }
@@ -518,7 +527,7 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
518
527
  let i = n.columns.map((e) => _(e, t)).join(", ");
519
528
  r.push(`CREATE FULLTEXT INDEX ${_(n.name, t)} ON ${_(e.tableName, t)} (${i});`);
520
529
  } 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.`);
521
- else t === "sqlite" ? r.push(...st(e.tableName, n, t)) : j(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
530
+ else t === "sqlite" ? r.push(...ct(e.tableName, n, t)) : j(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
522
531
  for (let n of e.appliedIndexes) {
523
532
  if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
524
533
  j(`[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(...).`);
@@ -536,11 +545,11 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
536
545
  r.push(l(a, e.tableName, [t])), i.add(o([t]));
537
546
  }
538
547
  return r.join("\n");
539
- }, lt = (e, t, n = A) => {
548
+ }, ut = (e, t, n = A) => {
540
549
  if (t !== "postgres") return [];
541
550
  let r = e.filter((e) => e.isReactive !== !1);
542
- return r.length === 0 ? [] : [ut(n), ...r.map((e) => ft(e, n))];
543
- }, ut = (e) => `
551
+ return r.length === 0 ? [] : [dt(n), ...r.map((e) => pt(e, n))];
552
+ }, dt = (e) => `
544
553
  CREATE OR REPLACE FUNCTION ${Ye(e)}() RETURNS trigger AS $$
545
554
  DECLARE
546
555
  payload TEXT;
@@ -600,22 +609,22 @@ BEGIN
600
609
  RETURN COALESCE(NEW, OLD);
601
610
  END;
602
611
  $$ LANGUAGE plpgsql;
603
- `.trim(), dt = (e, t) => {
612
+ `.trim(), ft = (e, t) => {
604
613
  let n = Je(e.tableName, t);
605
614
  return [
606
615
  `ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL`,
607
616
  `DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}"`,
608
617
  `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${Ye(t)}()`
609
618
  ];
610
- }, ft = (e, t) => dt(e, t).map((e) => `${e};`).join("\n"), pt = (e) => {
619
+ }, pt = (e, t) => ft(e, t).map((e) => `${e};`).join("\n"), mt = (e) => {
611
620
  if (e.dialect !== "postgres") return [];
612
621
  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));
613
- (i.length > 0 || e.functionOutdated === !0) && r.push(ut(t));
614
- for (let e of i) r.push(...dt(n.get(e), t));
622
+ (i.length > 0 || e.functionOutdated === !0) && r.push(dt(t));
623
+ for (let e of i) r.push(...ft(n.get(e), t));
615
624
  for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Je(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
616
625
  return r;
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 = ue(e.map((e) => e.tableName), (e) => {
626
+ }, ht = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), gt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), _t = (e) => {
627
+ let t = new Map(e.map((e) => [e.tableName, e])), n = de(e.map((e) => e.tableName), (e) => {
619
628
  let n = t.get(e);
620
629
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
621
630
  if (n.type !== "reference" || !n.references) return [];
@@ -626,7 +635,7 @@ $$ LANGUAGE plpgsql;
626
635
  }] : [];
627
636
  }) : [];
628
637
  }), r = [];
629
- for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(D(t.tableName, e)) && r.push({
638
+ for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(E(t.tableName, e)) && r.push({
630
639
  table: t.tableName,
631
640
  column: e,
632
641
  targetTable: i.references().tableName,
@@ -637,7 +646,7 @@ $$ LANGUAGE plpgsql;
637
646
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
638
647
  a.add(e.tableName);
639
648
  for (let [r, i] of Object.entries(e.fields)) {
640
- if (i.type !== "reference" || !i.references || n.has(D(e.tableName, r))) continue;
649
+ if (i.type !== "reference" || !i.references || n.has(E(e.tableName, r))) continue;
641
650
  let a = i.references();
642
651
  if (a.tableName === e.tableName) continue;
643
652
  let o = t.get(a.tableName);
@@ -651,7 +660,7 @@ $$ LANGUAGE plpgsql;
651
660
  sorted: o,
652
661
  cyclic: r
653
662
  };
654
- }, _t = (e, t, n = null) => {
663
+ }, vt = (e, t, n = null) => {
655
664
  let r = (e) => n ? `${_(n, t)}.${_(e, t)}` : _(e, t), i = `${e.table}_${e.column}_fkey`, a = F(e.onDelete, t), o = F(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${_(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${_(e.column, t)}) REFERENCES ${r(e.targetTable)} (${_("id", t)})${s}`;
656
665
  switch (t) {
657
666
  case "postgres": return [
@@ -666,7 +675,7 @@ $$ LANGUAGE plpgsql;
666
675
  case "mariadb": return `ALTER TABLE ${r(e.table)} ${c(!0)};`;
667
676
  default: return `ALTER TABLE ${r(e.table)} ${c(!1)};`;
668
677
  }
669
- }, vt = (e, t) => {
678
+ }, yt = (e, t) => {
670
679
  let n = /* @__PURE__ */ new Map();
671
680
  if (l(t)) return n;
672
681
  for (let t of e) {
@@ -674,7 +683,7 @@ $$ LANGUAGE plpgsql;
674
683
  e.add(t.column), n.set(t.table, e);
675
684
  }
676
685
  return n;
677
- }, yt = (e, t) => {
686
+ }, bt = (e, t) => {
678
687
  if (t !== "postgres") return "";
679
688
  let n = /* @__PURE__ */ new Map();
680
689
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -690,7 +699,7 @@ $$ LANGUAGE plpgsql;
690
699
  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 $$;`);
691
700
  }
692
701
  return r.join("\n\n");
693
- }, bt = (e, t) => {
702
+ }, xt = (e, t) => {
694
703
  if (t !== "postgres") return "";
695
704
  let n = /* @__PURE__ */ new Set();
696
705
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
@@ -704,30 +713,30 @@ BEGIN
704
713
  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 $$;`);
705
714
  }
706
715
  return r.join("\n\n");
707
- }, xt = (e) => {
716
+ }, St = (e) => {
708
717
  let t = [], n = [];
709
718
  for (let r of e) u(r) ? n.push(r) : t.push(r);
710
719
  return {
711
720
  tables: t,
712
721
  views: n
713
722
  };
714
- }, St = (e, t, n = A) => {
715
- let { tables: r, views: i } = xt(e), { sorted: a, cyclic: o } = gt(r.map((e) => le(e, t))), s = vt(o, t), c = [];
716
- t === "postgres" && mt(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && ht(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
717
- let u = bt(a, t);
723
+ }, Ct = (e, t, n = A) => {
724
+ let { tables: r, views: i } = St(e), { sorted: a, cyclic: o } = _t(r.map((e) => ue(e, t))), s = yt(o, t), c = [];
725
+ t === "postgres" && ht(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && gt(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
726
+ let u = xt(a, t);
718
727
  u && c.push(u);
719
- let d = yt(a, t);
728
+ let d = bt(a, t);
720
729
  d && c.push(d);
721
- for (let e of a) c.push(ot(e, t, null, s.get(e.tableName)));
722
- if (!l(t)) for (let e of o) c.push(_t(e, t));
730
+ for (let e of a) c.push(st(e, t, null, s.get(e.tableName)));
731
+ if (!l(t)) for (let e of o) c.push(vt(e, t));
723
732
  for (let e of a) {
724
- let n = ct(e, t);
733
+ let n = lt(e, t);
725
734
  n && c.push(n);
726
735
  }
727
- c.push(...lt(a, t, n));
736
+ c.push(...ut(a, t, n));
728
737
  for (let e of i) c.push(x(e, t));
729
738
  return c.join("\n\n") + "\n";
730
- }, Ct = (e, t, n) => {
739
+ }, wt = (e, t, n) => {
731
740
  let r = _(e, t);
732
741
  switch (t) {
733
742
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
@@ -737,62 +746,62 @@ BEGIN
737
746
  case "turso":
738
747
  case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
739
748
  }
740
- }, wt = (e, t, n, r) => {
741
- let i = Ct(n, t, r), a = _(n, t);
742
- if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${St(e, t)}`;
743
- if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${St(e, t)}`;
744
- let { sorted: o, cyclic: s } = gt(e), c = vt(s, t), u = [i];
745
- for (let e of o) u.push(ot(e, t, n, c.get(e.tableName)));
746
- if (!l(t)) for (let e of s) u.push(_t(e, t, n));
749
+ }, Tt = (e, t, n, r) => {
750
+ let i = wt(n, t, r), a = _(n, t);
751
+ if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Ct(e, t)}`;
752
+ if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Ct(e, t)}`;
753
+ let { sorted: o, cyclic: s } = _t(e), c = yt(s, t), u = [i];
754
+ for (let e of o) u.push(st(e, t, n, c.get(e.tableName)));
755
+ if (!l(t)) for (let e of s) u.push(vt(e, t, n));
747
756
  for (let e of o) {
748
- let r = ct(e, t, n);
757
+ let r = lt(e, t, n);
749
758
  r && u.push(r);
750
759
  }
751
760
  return u.join("\n\n") + "\n";
752
- }, Tt = (e, t, n = A) => {
753
- let { sorted: r, cyclic: i } = gt(e), a = vt(i, t), o = [], s = bt(r, t);
761
+ }, Et = (e, t, n = A) => {
762
+ let { sorted: r, cyclic: i } = _t(e), a = yt(i, t), o = [], s = xt(r, t);
754
763
  s && o.push(s);
755
- let c = yt(r, t);
764
+ let c = bt(r, t);
756
765
  c && o.push(c);
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 = A, r = {}) => S.gen(function* () {
761
- let i = yield* E.SqlClient;
762
- yield* Me(i, Nt(i, St(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
763
- }), Dt = (e, t) => {
766
+ for (let e of r) o.push(st(e, t, null, a.get(e.tableName)));
767
+ for (let e of i) o.push(vt(e, t));
768
+ return o.push(...ut(r, t, n)), o.join("\n\n") + "\n";
769
+ }, Dt = (e, t = "postgres", n = A, r = {}) => S.gen(function* () {
770
+ let i = yield* T.SqlClient;
771
+ yield* Me(i, Pt(i, Ct(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
772
+ }), Ot = (e, t) => {
764
773
  let n = t.cause ?? {};
765
774
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
766
- }, Ot = (e, t) => {
775
+ }, kt = (e, t) => {
767
776
  let n = e.trimStart();
768
777
  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));
769
- }, kt = () => {
778
+ }, At = () => {
770
779
  let e = Number(process.env.VOLTRO_MIGRATION_DDL_RETRIES);
771
780
  return Number.isInteger(e) && e >= 0 ? e : 4;
772
- }, At = (e) => ({
781
+ }, jt = (e) => ({
773
782
  while: e,
774
- times: kt(),
783
+ times: At(),
775
784
  schedule: C.jittered(C.exponential("50 millis"))
776
- }), jt = class {
785
+ }), Mt = class {
777
786
  statement;
778
787
  error;
779
788
  _tag = "DdlStatementFailed";
780
789
  constructor(e, t) {
781
790
  this.statement = e, this.error = t;
782
791
  }
783
- }, Mt = (e, t, n) => S.gen(function* () {
784
- let r = yield* E.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(S.catchIf((e) => Dt(a, e), () => S.succeed([])), S.tapError((e) => S.sync(() => {
788
- Ze.error(re("migrate: statement failed", a, e, 200));
792
+ }, Nt = (e, t, n) => S.gen(function* () {
793
+ let r = yield* T.SqlClient, i = n !== void 0 && Fe(t) === "per-operation";
794
+ for (let a of Ft(e)) {
795
+ process.env.VOLTRO_MIGRATE_DEBUG === "1" && Qe.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
796
+ let e = r.unsafe(a).pipe(S.catchIf((e) => Ot(a, e), () => S.succeed([])), S.tapError((e) => S.sync(() => {
797
+ Qe.error(ie("migrate: statement failed", a, e, 200));
789
798
  })));
790
- yield* (i && n !== void 0 && Ot(a, t) ? e.pipe(S.retry(At((e) => n(e) === "retry"))) : e).pipe(S.mapError((e) => new jt(a, e)));
799
+ yield* (i && n !== void 0 && kt(a, t) ? e.pipe(S.retry(jt((e) => n(e) === "retry"))) : e).pipe(S.mapError((e) => new Mt(a, e)));
791
800
  }
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(S.retry(At((e) => r(a(e)) === "retry"))) : i).pipe(S.orDieWith((e) => e instanceof jt ? Error(re("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
795
- }, Pt = (e) => {
801
+ }), Pt = (e, t, n, r) => {
802
+ let i = n === "turso" ? Nt(t, n, r) : e.withTransaction(Nt(t, n, r)), a = (e) => e instanceof Mt ? e.error : e;
803
+ return (r !== void 0 && Fe(n) === "plan-transactional" ? i.pipe(S.retry(jt((e) => r(a(e)) === "retry"))) : i).pipe(S.orDieWith((e) => e instanceof Mt ? Error(ie("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
804
+ }, Ft = (e) => {
796
805
  let t = [], n = "", r = !1;
797
806
  for (let i = 0; i < e.length; i++) {
798
807
  if (e.slice(i, i + 2) === "$$") {
@@ -807,43 +816,43 @@ BEGIN
807
816
  }
808
817
  let i = n.trim();
809
818
  return i.length > 0 && t.push(i), t;
810
- }, Ft = async (e, t, n = "postgres", r = {}) => {
811
- await S.runPromise(Et(e, n, void 0, r).pipe(S.provide(t)));
812
- }, It = (e, t, n = "postgres", r = {}) => S.gen(function* () {
813
- let i = wt(e, n, t), a = yield* E.SqlClient;
814
- yield* Me(a, Nt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
815
- }), Lt = async (e, t, n, r = "postgres", i = {}) => {
816
- await S.runPromise(It(e, t, r, i).pipe(S.provide(n))), await s({
819
+ }, It = async (e, t, n = "postgres", r = {}) => {
820
+ await S.runPromise(Dt(e, n, void 0, r).pipe(S.provide(t)));
821
+ }, Lt = (e, t, n = "postgres", r = {}) => S.gen(function* () {
822
+ let i = Tt(e, n, t), a = yield* T.SqlClient;
823
+ yield* Me(a, Pt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
824
+ }), Rt = async (e, t, n, r = "postgres", i = {}) => {
825
+ await S.runPromise(Lt(e, t, r, i).pipe(S.provide(n))), await s({
817
826
  namespace: t,
818
827
  dialect: r
819
828
  });
820
- }, Rt = async (e, t, n = "postgres", r = {}) => {
829
+ }, zt = async (e, t, n = "postgres", r = {}) => {
821
830
  await S.runPromise(S.gen(function* () {
822
- let t = Tt(e, n), i = yield* E.SqlClient;
823
- yield* Me(i, Nt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
831
+ let t = Et(e, n), i = yield* T.SqlClient;
832
+ yield* Me(i, Pt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
824
833
  }).pipe(S.provide(t)));
825
- }, zt = (e) => {
834
+ }, Bt = (e) => {
826
835
  if (e == null) return e;
827
- if (Array.isArray(e)) return e.map(zt);
836
+ if (Array.isArray(e)) return e.map(Bt);
828
837
  if (typeof e != "object") return e;
829
838
  let t = {};
830
839
  for (let n of Object.keys(e).sort()) {
831
840
  let r = e[n];
832
- r !== void 0 && (t[n] = zt(r));
841
+ r !== void 0 && (t[n] = Bt(r));
833
842
  }
834
843
  return t;
835
- }, Bt = (e) => {
844
+ }, Vt = (e) => {
836
845
  if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs) return e;
837
846
  let { idScheme: t, sensitive: n, safe: r, generatedAs: i, ...a } = e;
838
847
  return a;
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) => ({
848
+ }, Ht = (e) => [...e].map(Vt).sort((e, t) => e.name.localeCompare(t.name)), Ut = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), Wt = (e) => [...e].map((e) => ({
840
849
  name: e.name,
841
- columns: Vt(e.columns),
842
- indexes: Ht(e.indexes)
843
- })).sort((e, t) => e.name.localeCompare(t.name)), Wt = (e) => {
844
- let t = { tables: Ut(e.tables) }, n = JSON.stringify(zt(t));
845
- return w("sha256").update(n).digest("hex");
846
- }, Gt = (e) => e.slice(0, 16), Kt = (e, t) => {
850
+ columns: Ht(e.columns),
851
+ indexes: Ut(e.indexes)
852
+ })).sort((e, t) => e.name.localeCompare(t.name)), Gt = (e) => {
853
+ let t = { tables: Wt(e.tables) }, n = JSON.stringify(Bt(t));
854
+ return ee("sha256").update(n).digest("hex");
855
+ }, Kt = (e) => e.slice(0, 16), qt = (e, t) => {
847
856
  let n = t.references ? {
848
857
  table: t.references().tableName,
849
858
  column: "id",
@@ -882,7 +891,7 @@ BEGIN
882
891
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
883
892
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
884
893
  };
885
- }, qt = (e) => {
894
+ }, Jt = (e) => {
886
895
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
887
896
  n.has(e.name) || (n.add(e.name), t.push(e));
888
897
  }, i = e.appliedPrimaryKey ?? [];
@@ -930,11 +939,11 @@ BEGIN
930
939
  });
931
940
  }
932
941
  return t;
933
- }, Jt = (e) => {
942
+ }, Yt = (e) => {
934
943
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
935
944
  for (let [r, i] of Object.entries(e.fields)) {
936
945
  if (i.dropped) continue;
937
- let e = Kt(r, i);
946
+ let e = qt(r, i);
938
947
  n.push(t.has(r) ? {
939
948
  ...e,
940
949
  unique: !0
@@ -944,11 +953,11 @@ BEGIN
944
953
  return {
945
954
  name: e.tableName,
946
955
  columns: n,
947
- indexes: qt(e),
956
+ indexes: Jt(e),
948
957
  ...r.length > 0 ? { primaryKey: [...r] } : {},
949
958
  ...i === void 0 ? {} : { renamedFrom: i }
950
959
  };
951
- }, Yt = (e) => {
960
+ }, Xt = (e) => {
952
961
  let t = /* @__PURE__ */ new Map();
953
962
  for (let n of e) for (let e of n.indexes) {
954
963
  let r = t.get(e.name);
@@ -956,9 +965,9 @@ BEGIN
956
965
  t.set(e.name, n.name);
957
966
  }
958
967
  }, I = (e, t) => {
959
- let n = e.filter((e) => !i(e.tableName)).map((e) => Jt(le(e, t)));
960
- return Yt(n), { tables: n };
961
- }, Xt = (e, t, n = A) => S.gen(function* () {
968
+ let n = e.filter((e) => !i(e.tableName)).map((e) => Yt(ue(e, t)));
969
+ return Xt(n), { tables: n };
970
+ }, Zt = (e, t, n = A) => S.gen(function* () {
962
971
  let r = (yield* e`
963
972
  SELECT p.prosrc
964
973
  FROM pg_proc p
@@ -989,7 +998,7 @@ BEGIN
989
998
  stale: l.sort(),
990
999
  functionOutdated: i
991
1000
  };
992
- }), Zt = (e) => {
1001
+ }), Qt = (e) => {
993
1002
  let t = [];
994
1003
  if (e.missing.length > 0) {
995
1004
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -1000,19 +1009,19 @@ BEGIN
1000
1009
  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.`);
1001
1010
  }
1002
1011
  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;
1003
- }, Qt = {
1012
+ }, $t = {
1004
1013
  postgres: !0,
1005
1014
  mysql: !0,
1006
1015
  mariadb: !0,
1007
1016
  mssql: !0,
1008
1017
  sqlite: !0
1009
- }, $t = {
1018
+ }, en = {
1010
1019
  postgres: !0,
1011
1020
  mysql: !1,
1012
1021
  mariadb: !1,
1013
1022
  mssql: !0,
1014
1023
  sqlite: !0
1015
- }, en = (e) => {
1024
+ }, tn = (e) => {
1016
1025
  switch (e) {
1017
1026
  case "add-column":
1018
1027
  case "drop-column":
@@ -1022,10 +1031,10 @@ BEGIN
1022
1031
  case "add-foreign-key":
1023
1032
  case "add-unique":
1024
1033
  case "add-unique-composite":
1025
- case "add-check": return $t;
1026
- default: return Qt;
1034
+ case "add-check": return en;
1035
+ default: return $t;
1027
1036
  }
1028
- }, tn = (e, t) => {
1037
+ }, nn = (e, t) => {
1029
1038
  let n = new Map(t.tables.map((e) => [e.name, e]));
1030
1039
  return new Map(e.map((e) => [e.tableName, {
1031
1040
  table: e,
@@ -1037,7 +1046,7 @@ BEGIN
1037
1046
  if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1038
1047
  let t = e;
1039
1048
  return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1040
- }, nn = (e) => {
1049
+ }, rn = (e) => {
1041
1050
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1042
1051
  let t = e.defaultValue;
1043
1052
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
@@ -1057,12 +1066,12 @@ BEGIN
1057
1066
  return L(JSON.parse(a));
1058
1067
  } catch {}
1059
1068
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1060
- }, rn = (e, t) => {
1061
- let n = nn(e), r = nn(t);
1069
+ }, an = (e, t) => {
1070
+ let n = rn(e), r = rn(t);
1062
1071
  if (n === r) return !0;
1063
1072
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1064
1073
  return i(n) === i(r);
1065
- }, an = (e) => {
1074
+ }, on = (e) => {
1066
1075
  if (!e) return null;
1067
1076
  let t = (e) => e === "restrict" ? "noAction" : e;
1068
1077
  return {
@@ -1071,33 +1080,37 @@ BEGIN
1071
1080
  onDelete: t(e.onDelete),
1072
1081
  onUpdate: t(e.onUpdate)
1073
1082
  };
1074
- }, on = (e, t) => {
1083
+ }, sn = (e, t) => {
1075
1084
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1076
1085
  if (!n && !r) return !0;
1077
1086
  if (!n || !r || n.length !== r.length) return !1;
1078
1087
  let i = [...n].sort(), a = [...r].sort();
1079
1088
  return i.every((e, t) => e === a[t]);
1080
- }, sn = (e, t) => {
1089
+ }, cn = (e, t, n) => {
1090
+ if (t === "mssql") {
1091
+ let t = Ze(e, n);
1092
+ if (t !== void 0) return t;
1093
+ }
1081
1094
  try {
1082
1095
  let n = /\((\d+)\)/.exec(M(e, t));
1083
1096
  return n ? Number(n[1]) : void 0;
1084
1097
  } catch {
1085
1098
  return;
1086
1099
  }
1087
- }, cn = (e, t, n) => n === void 0 || l(n) ? !0 : e.type !== "text" || t.type !== "text" || sn(e, n) === t.maxLength, ln = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && rn(e, t) && cn(e, t, n) && JSON.stringify(an(e.references)) === JSON.stringify(an(t.references)) && on(e.oneOf, t.oneOf), un = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1100
+ }, ln = (e, t, n, r) => n === void 0 || l(n) ? !0 : e.type !== "text" || t.type !== "text" || cn(e, n, r) === t.maxLength, un = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && an(e, t) && ln(e, t, n, r) && JSON.stringify(on(e.references)) === JSON.stringify(on(t.references)) && sn(e.oneOf, t.oneOf), dn = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1088
1101
  kind: "add-check",
1089
1102
  table: e,
1090
1103
  column: t.name,
1091
1104
  values: t.oneOf
1092
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, dn = (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])), fn = (e, t, n) => {
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 = [];
1105
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, fn = (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])), pn = (e, t, n) => {
1106
+ let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [], c = new Set(e.indexes.flatMap((e) => e.columns));
1094
1107
  for (let t of e.columns) {
1095
1108
  let e = r.get(t.name);
1096
1109
  if (!e) {
1097
1110
  a.push(t);
1098
1111
  continue;
1099
1112
  }
1100
- ln(t, e, n) || s.push({
1113
+ un(t, e, n, c.has(t.name) || t.unique) || s.push({
1101
1114
  declared: t,
1102
1115
  live: e
1103
1116
  });
@@ -1108,47 +1121,47 @@ BEGIN
1108
1121
  removed: o,
1109
1122
  changed: s
1110
1123
  };
1111
- }, pn = (e, t) => {
1112
- let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
1124
+ }, mn = (e, t, n) => {
1125
+ let r = (e) => n === "turso" || n === "sqlite" ? e.toLowerCase() : e, i = new Map(t.indexes.map((e) => [r(e.name), e])), a = new Map(e.indexes.map((e) => [r(e.name), e])), o = [], s = [];
1113
1126
  for (let t of e.indexes) {
1114
- let e = n.get(t.name);
1115
- (!e || !dn(t, e)) && i.push(t);
1127
+ let e = i.get(r(t.name));
1128
+ (!e || !fn(t, e)) && o.push(t);
1116
1129
  }
1117
- for (let e of t.indexes) r.has(e.name) || a.push(e);
1130
+ for (let e of t.indexes) a.has(r(e.name)) || s.push(e);
1118
1131
  return {
1119
- added: i,
1120
- removed: a
1132
+ added: o,
1133
+ removed: s
1121
1134
  };
1122
1135
  }, R = (e, t, n, r) => ({
1123
1136
  op: e,
1124
1137
  classification: t,
1125
- atomicByDialect: en(e.kind),
1138
+ atomicByDialect: tn(e.kind),
1126
1139
  ...n ? { reason: n } : {},
1127
1140
  ...r ? { blocked: r } : {}
1128
- }), mn = (e, t, n) => {
1141
+ }), hn = (e, t, n) => {
1129
1142
  let r = {
1130
1143
  kind: "add-column",
1131
1144
  table: e,
1132
1145
  column: t
1133
1146
  };
1134
1147
  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` });
1135
- }, hn = (e, t, n) => {
1148
+ }, gn = (e, t, n) => {
1136
1149
  let r = {
1137
1150
  kind: "drop-column",
1138
1151
  table: e,
1139
1152
  column: t.name
1140
1153
  };
1141
1154
  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` });
1142
- }, gn = (e, t, n, r, i) => R({
1155
+ }, _n = (e, t, n, r, i) => R({
1143
1156
  kind: "create-table",
1144
1157
  table: e,
1145
1158
  columns: t,
1146
1159
  indexes: n,
1147
1160
  ...r && r.length > 0 ? { primaryKey: r } : {}
1148
- }, "safe", i ?? "new table — no data to preserve"), _n = (e) => R({
1161
+ }, "safe", i ?? "new table — no data to preserve"), vn = (e) => R({
1149
1162
  kind: "drop-table",
1150
1163
  table: e
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" }), vn = 5e4, yn = (e, t, n, r) => {
1164
+ }, "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" }), yn = 5e4, bn = (e, t, n, r) => {
1152
1165
  let i = (n ?? 0) >= r, a;
1153
1166
  return a = t.unique ? t.columns.length === 1 ? {
1154
1167
  kind: "add-unique",
@@ -1164,7 +1177,7 @@ BEGIN
1164
1177
  table: e,
1165
1178
  index: t
1166
1179
  }, 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");
1167
- }, bn = (e, t) => t.unique && t.columns.length > 1 ? R({
1180
+ }, xn = (e, t) => t.unique && t.columns.length > 1 ? R({
1168
1181
  kind: "drop-unique-composite",
1169
1182
  table: e,
1170
1183
  name: t.name
@@ -1172,7 +1185,7 @@ BEGIN
1172
1185
  kind: "drop-index",
1173
1186
  table: e,
1174
1187
  index: t.name
1175
- }, "safe", "drop index (no data loss — index is derived data)"), xn = (e, t) => {
1188
+ }, "safe", "drop index (no data loss — index is derived data)"), Sn = (e, t) => {
1176
1189
  if (e === "reference") return "text";
1177
1190
  switch (t) {
1178
1191
  case "sqlite":
@@ -1180,10 +1193,10 @@ BEGIN
1180
1193
  case "mssql": return e === "json" ? "text" : e;
1181
1194
  default: return e;
1182
1195
  }
1183
- }, Sn = (e, t, n) => {
1196
+ }, Cn = (e, t, n) => {
1184
1197
  let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
1185
1198
  return n === "postgres" ? `${r} — add \`{ using: '${t.name}::${t.type}' }\` when the cast is not implicit, or use a file-based migration` : `${r} — ${n === void 0 ? "this dialect" : n} converts in place (\`using\` is postgres-only and is ignored here), so verify the conversion is value-preserving for your data, or use a file-based migration`;
1186
- }, Cn = (e, t, n, r, i, a) => {
1199
+ }, wn = (e, t, n, r, i, a) => {
1187
1200
  let o = [];
1188
1201
  if (t.nullable !== n.nullable) {
1189
1202
  let n = {
@@ -1208,7 +1221,7 @@ BEGIN
1208
1221
  column: t.name
1209
1222
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1210
1223
  }
1211
- if (xn(t.type, r) !== xn(n.type, r)) {
1224
+ if (Sn(t.type, r) !== Sn(n.type, r)) {
1212
1225
  let i = t.narrowedFrom;
1213
1226
  if (i && i.from === n.type) {
1214
1227
  let r = {
@@ -1228,7 +1241,7 @@ BEGIN
1228
1241
  from: n.type,
1229
1242
  to: t.type
1230
1243
  };
1231
- o.push(R(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: Sn(n.type, t, r) }));
1244
+ o.push(R(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: Cn(n.type, t, r) }));
1232
1245
  }
1233
1246
  }
1234
1247
  if (t.type === "text" && n.type === "text" && !l(r ?? "postgres") && t.maxLength !== n.maxLength) {
@@ -1241,7 +1254,7 @@ BEGIN
1241
1254
  to: "text"
1242
1255
  }, 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)}`));
1243
1256
  }
1244
- if (!rn(t, n)) {
1257
+ if (!an(t, n)) {
1245
1258
  let n = {
1246
1259
  kind: "alter-column-default",
1247
1260
  table: e,
@@ -1251,21 +1264,21 @@ BEGIN
1251
1264
  };
1252
1265
  o.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1253
1266
  }
1254
- if (!on(t.oneOf, n.oneOf)) {
1267
+ if (!sn(t.oneOf, n.oneOf)) {
1255
1268
  n.oneOf && n.oneOf.length > 0 && o.push(R({
1256
1269
  kind: "drop-check",
1257
1270
  table: e,
1258
1271
  column: t.name
1259
1272
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1260
- let r = un(e, t);
1273
+ let r = dn(e, t);
1261
1274
  r && o.push(r);
1262
1275
  }
1263
- return JSON.stringify(an(t.references)) !== JSON.stringify(an(n.references)) && (n.references && o.push(R({
1276
+ return JSON.stringify(on(t.references)) !== JSON.stringify(on(n.references)) && (n.references && o.push(R({
1264
1277
  kind: "drop-foreign-key",
1265
1278
  table: e,
1266
1279
  column: t.name
1267
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...wn(e, t))), o;
1268
- }, wn = (e, t) => {
1280
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Tn(e, t))), o;
1281
+ }, Tn = (e, t) => {
1269
1282
  let n = [];
1270
1283
  if (!t.references) return n;
1271
1284
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1281,7 +1294,7 @@ BEGIN
1281
1294
  ...a,
1282
1295
  orphanPolicy: i
1283
1296
  }, "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;
1284
- }, Tn = (e, t, n) => {
1297
+ }, En = (e, t, n) => {
1285
1298
  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));
1286
1299
  for (let [n, c] of Object.entries(t)) {
1287
1300
  let t = c.renamedFrom;
@@ -1297,22 +1310,22 @@ BEGIN
1297
1310
  consumedAddedNames: i,
1298
1311
  consumedRemovedNames: a
1299
1312
  };
1300
- }, En = /* @__PURE__ */ new Set([
1313
+ }, Dn = /* @__PURE__ */ new Set([
1301
1314
  "postgres",
1302
1315
  "mysql",
1303
1316
  "mariadb",
1304
1317
  "mssql"
1305
- ]), Dn = {
1318
+ ]), On = {
1306
1319
  ops: [],
1307
1320
  consumedAddedNames: /* @__PURE__ */ new Set(),
1308
1321
  consumedRemovedNames: /* @__PURE__ */ new Set()
1309
- }, On = (e) => !e.unique && !e.expression, kn = (e, t, n, r, i) => {
1310
- if (i === void 0 || !En.has(i)) return Dn;
1311
- let a = t.added.filter((e) => On(e) && !r.has(e.name));
1312
- if (a.length === 0) return Dn;
1322
+ }, kn = (e) => !e.unique && !e.expression, An = (e, t, n, r, i) => {
1323
+ if (i === void 0 || !Dn.has(i)) return On;
1324
+ let a = t.added.filter((e) => kn(e) && !r.has(e.name));
1325
+ if (a.length === 0) return On;
1313
1326
  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();
1314
1327
  for (let n of t.removed) {
1315
- if (!On(n)) continue;
1328
+ if (!kn(n)) continue;
1316
1329
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1317
1330
  if (r.length !== 1) continue;
1318
1331
  let i = r[0];
@@ -1328,7 +1341,7 @@ BEGIN
1328
1341
  consumedAddedNames: l,
1329
1342
  consumedRemovedNames: u
1330
1343
  };
1331
- }, An = (e, t, n) => {
1344
+ }, jn = (e, t, n) => {
1332
1345
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1333
1346
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1334
1347
  for (let c of e.tables) {
@@ -1368,12 +1381,12 @@ BEGIN
1368
1381
  claimedOldNames: c,
1369
1382
  refusals: o
1370
1383
  };
1371
- }, jn = (e, t, n, r) => {
1384
+ }, Mn = (e, t, n, r) => {
1372
1385
  if (t === void 0) return {
1373
1386
  live: e,
1374
1387
  ops: []
1375
1388
  };
1376
- let i = r !== void 0 && En.has(r), a = [], o = e.indexes.map((e) => {
1389
+ let i = r !== void 0 && Dn.has(r), a = [], o = e.indexes.map((e) => {
1377
1390
  if (!e.name.startsWith(t)) return e;
1378
1391
  let r = `${n}${e.name.slice(t.length)}`;
1379
1392
  return r === e.name ? e : e.name === `${t}_pkey` ? {
@@ -1399,7 +1412,7 @@ BEGIN
1399
1412
  },
1400
1413
  ops: a
1401
1414
  };
1402
- }, Mn = (e) => {
1415
+ }, Nn = (e) => {
1403
1416
  let t = {
1404
1417
  safe: 0,
1405
1418
  needsDefault: 0,
@@ -1432,42 +1445,42 @@ BEGIN
1432
1445
  case "multi-step": t.multiStep++;
1433
1446
  }
1434
1447
  return t;
1435
- }, Nn = (e) => {
1436
- let t = I(e.declared, e.dialect), n = tn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? vn, a = [], o = An(t, r, n);
1448
+ }, Pn = (e) => {
1449
+ let t = I(e.declared, e.dialect), n = nn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? yn, a = [], o = jn(t, r, n);
1437
1450
  a.push(...o.ops);
1438
1451
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1439
- a.push(gn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1452
+ a.push(_n(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1440
1453
  for (let t of e.columns) {
1441
- let n = un(e.name, t);
1454
+ let n = dn(e.name, t);
1442
1455
  n && a.push(n);
1443
1456
  }
1444
1457
  }
1445
1458
  let s = new Set(e.ignoreTables ?? []);
1446
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || h(t.name) || f(t.name) || s.has(t.name) || a.push(_n(t.name));
1459
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || h(t.name) || f(t.name) || s.has(t.name) || a.push(vn(t.name));
1447
1460
  for (let s of t.tables) {
1448
1461
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1449
1462
  if (!c) continue;
1450
- let l = jn(c, t, s.name, e.dialect);
1463
+ let l = Mn(c, t, s.name, e.dialect);
1451
1464
  a.push(...l.ops);
1452
- let u = l.live, d = n.get(s.name), p = fn(s, u, e.dialect), m = pn(s, u), h = Tn(d.table, d.columnDefs, p);
1465
+ let u = l.live, d = n.get(s.name), p = pn(s, u, e.dialect), m = mn(s, u, e.dialect), h = En(d.table, d.columnDefs, p);
1453
1466
  a.push(...h.ops);
1454
1467
  for (let e of p.removed) {
1455
1468
  if (h.consumedRemovedNames.has(e.name) || f(e.name)) continue;
1456
1469
  let t = d.columnDefs[e.name];
1457
- a.push(hn(s.name, e, t));
1470
+ a.push(gn(s.name, e, t));
1458
1471
  }
1459
1472
  for (let e of p.added) {
1460
1473
  if (h.consumedAddedNames.has(e.name)) continue;
1461
1474
  let t = d.columnDefs[e.name];
1462
- a.push(mn(s.name, e, t));
1463
- let n = un(s.name, e);
1464
- n && a.push(n), a.push(...wn(s.name, e));
1475
+ a.push(hn(s.name, e, t));
1476
+ let n = dn(s.name, e);
1477
+ n && a.push(n), a.push(...Tn(s.name, e));
1465
1478
  }
1466
- let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = kn(s.name, m, g, new Set(u.indexes.map((e) => e.name)), e.dialect);
1479
+ let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = An(s.name, m, g, new Set(u.indexes.map((e) => e.name)), e.dialect);
1467
1480
  a.push(..._.ops);
1468
- for (let e of m.added) _.consumedAddedNames.has(e.name) || a.push(yn(s.name, e, u.rowCount, i));
1469
- for (let e of m.removed) _.consumedRemovedNames.has(e.name) || a.push(bn(s.name, e));
1470
- for (let { declared: t, live: n } of p.changed) a.push(...Cn(s.name, t, n, e.dialect, u.rowCount, i));
1481
+ for (let e of m.added) _.consumedAddedNames.has(e.name) || a.push(bn(s.name, e, u.rowCount, i));
1482
+ for (let e of m.removed) _.consumedRemovedNames.has(e.name) || a.push(xn(s.name, e));
1483
+ for (let { declared: t, live: n } of p.changed) a.push(...wn(s.name, t, n, e.dialect, u.rowCount, i));
1471
1484
  }
1472
1485
  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) => {
1473
1486
  let t = l.get(e);
@@ -1475,8 +1488,8 @@ BEGIN
1475
1488
  column: e.name,
1476
1489
  target: e.references.table
1477
1490
  }] : []) : [];
1478
- }, d = ue([...c], u), p = [];
1479
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(D(e.name, t.name)) || p.push(R({
1491
+ }, d = de([...c], u), p = [];
1492
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(E(e.name, t.name)) || p.push(R({
1480
1493
  kind: "add-foreign-key",
1481
1494
  table: e.name,
1482
1495
  column: t.name,
@@ -1491,8 +1504,8 @@ BEGIN
1491
1504
  let n = a[t];
1492
1505
  if (n.op.kind !== "create-table") continue;
1493
1506
  let r = n.op;
1494
- if (!r.columns.some((e) => d.has(D(r.table, e.name)))) continue;
1495
- let i = r.columns.map((t) => d.has(D(r.table, t.name)) ? e(t) : t);
1507
+ if (!r.columns.some((e) => d.has(E(r.table, e.name)))) continue;
1508
+ let i = r.columns.map((t) => d.has(E(r.table, t.name)) ? e(t) : t);
1496
1509
  a[t] = {
1497
1510
  ...n,
1498
1511
  op: {
@@ -1512,7 +1525,7 @@ BEGIN
1512
1525
  let i = new Set(t).add(e), a = 0;
1513
1526
  for (let t of r.columns) {
1514
1527
  let n = t.references?.table;
1515
- n && n !== e && !d.has(D(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1528
+ n && n !== e && !d.has(E(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1516
1529
  }
1517
1530
  return g.set(e, a), a;
1518
1531
  }, v = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, y = (e) => {
@@ -1548,11 +1561,11 @@ BEGIN
1548
1561
  });
1549
1562
  return {
1550
1563
  operations: S,
1551
- fromFingerprint: Wt(e.live),
1552
- toFingerprint: Wt(t),
1553
- summary: Mn(S)
1564
+ fromFingerprint: Gt(e.live),
1565
+ toFingerprint: Gt(t),
1566
+ summary: Nn(S)
1554
1567
  };
1555
- }, Pn = (e) => {
1568
+ }, Fn = (e) => {
1556
1569
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1557
1570
  if (!t) return null;
1558
1571
  let n = [...e.replace(/\\'/g, "'").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
@@ -1560,7 +1573,7 @@ BEGIN
1560
1573
  column: t[1],
1561
1574
  values: n
1562
1575
  };
1563
- }, Fn = (e, t) => {
1576
+ }, In = (e, t) => {
1564
1577
  if (t === "vector") return "vector";
1565
1578
  switch (e) {
1566
1579
  case "text":
@@ -1587,7 +1600,7 @@ BEGIN
1587
1600
  case "USER-DEFINED": return "text";
1588
1601
  default: return "text";
1589
1602
  }
1590
- }, In = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1603
+ }, Ln = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1591
1604
  expr: e,
1592
1605
  stored: t
1593
1606
  } }, z = (e) => {
@@ -1598,25 +1611,25 @@ BEGIN
1598
1611
  case "SET DEFAULT": return "noAction";
1599
1612
  default: return "noAction";
1600
1613
  }
1601
- }, Ln = (e, t) => {
1614
+ }, Rn = (e, t) => {
1602
1615
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1603
1616
  return Number.isInteger(n) && n > 0 ? n : t;
1604
- }, Rn = () => Ln(process.env.VOLTRO_INTROSPECT_BATCH, 20), zn = 300, Bn = () => {
1617
+ }, zn = () => Rn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Bn = 300, Vn = () => {
1605
1618
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1606
- return e !== void 0 && e.trim() === "0" ? 0 : Ln(e, 3e4);
1607
- }, Vn = (e, t) => {
1619
+ return e !== void 0 && e.trim() === "0" ? 0 : Rn(e, 3e4);
1620
+ }, Hn = (e, t) => {
1608
1621
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1609
1622
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1610
1623
  return r;
1611
- }, Hn = (e) => {
1612
- let t = Bn(), n = S.gen(function* () {
1624
+ }, Un = (e) => {
1625
+ let t = Vn(), n = S.gen(function* () {
1613
1626
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1614
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Rn(), a = (e, t) => S.gen(function* () {
1627
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = zn(), a = (e, t) => S.gen(function* () {
1615
1628
  let r = [];
1616
- for (let a of Vn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1629
+ for (let a of Hn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1617
1630
  return r;
1618
1631
  }), o = [];
1619
- for (let t = 0;; t += zn) {
1632
+ for (let t = 0;; t += Bn) {
1620
1633
  let n = yield* e`
1621
1634
  SELECT c.relname AS table_name,
1622
1635
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1624,9 +1637,9 @@ BEGIN
1624
1637
  JOIN pg_namespace n ON n.oid = c.relnamespace
1625
1638
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1626
1639
  ORDER BY c.relname
1627
- LIMIT ${r(zn)} OFFSET ${r(t)}
1640
+ LIMIT ${r(Bn)} OFFSET ${r(t)}
1628
1641
  `;
1629
- if (o.push(...n), n.length < zn) break;
1642
+ if (o.push(...n), n.length < Bn) break;
1630
1643
  }
1631
1644
  let s = /* @__PURE__ */ new Set(), c = [];
1632
1645
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1721,18 +1734,18 @@ BEGIN
1721
1734
  let t = v.get(e.table_name);
1722
1735
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1723
1736
  }
1724
- let w = /* @__PURE__ */ new Map();
1737
+ let ee = /* @__PURE__ */ new Map();
1725
1738
  for (let e of f) {
1726
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = w.get(t);
1739
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = ee.get(t);
1727
1740
  n || (n = {
1728
1741
  table: e.table_name,
1729
1742
  columns: []
1730
- }, w.set(t, n)), n.columns.push({
1743
+ }, ee.set(t, n)), n.columns.push({
1731
1744
  name: e.column_name,
1732
1745
  position: e.position
1733
1746
  });
1734
1747
  }
1735
- for (let [e, t] of w) {
1748
+ for (let [e, t] of ee) {
1736
1749
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1737
1750
  if (n.length === 1) {
1738
1751
  let e = y.get(t.table);
@@ -1757,10 +1770,10 @@ BEGIN
1757
1770
  let n = t.get(e.index_name);
1758
1771
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1759
1772
  }
1760
- let T = [];
1773
+ let w = [];
1761
1774
  for (let e of c) {
1762
1775
  let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = x.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1763
- let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Fn(t.data_type, t.udt_name), c = a ? {
1776
+ 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" : In(t.data_type, t.udt_name), c = a ? {
1764
1777
  table: a.target_table,
1765
1778
  column: a.target_column,
1766
1779
  onDelete: z(a.delete_rule),
@@ -1776,7 +1789,7 @@ BEGIN
1776
1789
  ...t.column_default === null ? {} : { defaultValue: t.column_default },
1777
1790
  ...c ? { references: c } : {},
1778
1791
  ...l ? { oneOf: l } : {},
1779
- ...In(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1792
+ ...Ln(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1780
1793
  };
1781
1794
  }), l = [], u = C.get(e.table_name);
1782
1795
  if (u) for (let [t, n] of u) {
@@ -1802,20 +1815,20 @@ BEGIN
1802
1815
  unique: !0
1803
1816
  });
1804
1817
  let d = Number(e.row_count ?? 0);
1805
- T.push({
1818
+ w.push({
1806
1819
  name: e.table_name,
1807
1820
  columns: c,
1808
1821
  indexes: l,
1809
1822
  ...d > 0 ? { rowCount: d } : {}
1810
1823
  });
1811
1824
  }
1812
- return { tables: T };
1825
+ return { tables: w };
1813
1826
  });
1814
1827
  return (t > 0 ? e.withTransaction(n) : n).pipe(S.catchAll((e) => {
1815
1828
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1816
1829
  return n.includes("statement timeout") || n.includes("57014") ? S.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.`)) : S.fail(e);
1817
1830
  }));
1818
- }, Un = (e, t) => {
1831
+ }, Wn = (e, t) => {
1819
1832
  switch (e.toLowerCase()) {
1820
1833
  case "varchar":
1821
1834
  case "char":
@@ -1851,7 +1864,7 @@ BEGIN
1851
1864
  let t = e, n = {};
1852
1865
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1853
1866
  return n;
1854
- }), Wn = (e) => S.gen(function* () {
1867
+ }), Gn = (e) => S.gen(function* () {
1855
1868
  let t = B(yield* e`
1856
1869
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1857
1870
  FROM information_schema.tables
@@ -1891,7 +1904,7 @@ BEGIN
1891
1904
  c.add(`${e.table_name}.${t[1]}`);
1892
1905
  continue;
1893
1906
  }
1894
- let n = Pn(e.check_clause);
1907
+ let n = Fn(e.check_clause);
1895
1908
  n && l.set(`${e.table_name}.${n.column}`, n.values);
1896
1909
  }
1897
1910
  let u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
@@ -1914,7 +1927,7 @@ BEGIN
1914
1927
  let t = u.get(e.table_name) ?? [], n = d.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(), o = f.get(e.table_name);
1915
1928
  if (o) for (let e of o.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1916
1929
  let s = t.map((t) => {
1917
- let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = o ? "reference" : n && t.column_name === "id" ? "id" : c.has(`${e.table_name}.${t.column_name}`) ? "json" : Un(t.data_type, t.column_type), u = o ? {
1930
+ let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = o ? "reference" : n && t.column_name === "id" ? "id" : c.has(`${e.table_name}.${t.column_name}`) ? "json" : Wn(t.data_type, t.column_type), u = o ? {
1918
1931
  table: o.target_table,
1919
1932
  column: o.target_column,
1920
1933
  onDelete: z(o.delete_rule),
@@ -1930,7 +1943,7 @@ BEGIN
1930
1943
  ...f === null ? {} : { defaultValue: f },
1931
1944
  ...u ? { references: u } : {},
1932
1945
  ...p ? { oneOf: p } : {},
1933
- ...In(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
1946
+ ...Ln(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
1934
1947
  };
1935
1948
  }), m = new Set(n.map((e) => e.source_column)), h = [];
1936
1949
  if (o) for (let [t, n] of o) {
@@ -1957,10 +1970,10 @@ BEGIN
1957
1970
  });
1958
1971
  }
1959
1972
  return { tables: p };
1960
- }), Gn = (e) => {
1973
+ }), Kn = (e) => {
1961
1974
  let t = e.toUpperCase();
1962
1975
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1963
- }, Kn = (e) => S.gen(function* () {
1976
+ }, qn = (e) => e === 1 || e === !0, Jn = (e) => S.gen(function* () {
1964
1977
  let t = yield* e`
1965
1978
  SELECT name, sql FROM sqlite_master
1966
1979
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1971,13 +1984,13 @@ BEGIN
1971
1984
  let n = [...e[2].matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
1972
1985
  n.length > 0 && t.set(e[1], n);
1973
1986
  }
1974
- let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set();
1987
+ let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = new Map(o.map((e) => [e.name.toLowerCase(), e.name])), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set();
1975
1988
  for (let t of c) {
1976
- let r = (yield* e.unsafe(`PRAGMA index_info(${n(t.name)})`)).map((e) => e.name).filter((e) => e !== null);
1977
- d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1989
+ let r = (yield* e.unsafe(`PRAGMA index_info(${n(t.name)})`)).map((e) => e.name).filter((e) => e !== null).map((e) => d.get(e.toLowerCase()) ?? e);
1990
+ f.set(t.name, r), qn(t.unique) && r.length === 1 && p.add(r[0]);
1978
1991
  }
1979
- let p = o.map((e) => {
1980
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Gn(e.type), a = r ? {
1992
+ let m = o.map((e) => {
1993
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Kn(e.type), a = r ? {
1981
1994
  table: r.table,
1982
1995
  column: r.to,
1983
1996
  onDelete: z(r.on_delete),
@@ -1987,37 +2000,37 @@ BEGIN
1987
2000
  name: e.name,
1988
2001
  type: i,
1989
2002
  nullable: e.notnull === 0,
1990
- unique: f.has(e.name) || n && e.name === "id",
2003
+ unique: p.has(e.name) || n && e.name === "id",
1991
2004
  hasDefault: e.dflt_value !== null,
1992
2005
  ...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
1993
2006
  ...a ? { references: a } : {},
1994
2007
  ...o ? { oneOf: o } : {},
1995
- ...In(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2008
+ ...Ln(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
1996
2009
  };
1997
- }), m = new Set(s.map((e) => e.from)), h = [];
2010
+ }), h = new Set(s.map((e) => e.from)), g = [];
1998
2011
  for (let e of c) {
1999
2012
  if (e.origin === "pk") continue;
2000
- let t = d.get(e.name) ?? [];
2001
- (t.length !== 1 || e.unique !== 1) && (t.length === 1 && e.unique !== 1 && m.has(t[0]) && e.name !== `${i}_${t[0]}_idx` || h.push({
2013
+ let t = f.get(e.name) ?? [];
2014
+ t.length === 1 && qn(e.unique) || t.length === 1 && !qn(e.unique) && h.has(t[0]) && e.name !== `${i}_${t[0]}_idx` || g.push({
2002
2015
  name: e.name,
2003
2016
  table: i,
2004
2017
  columns: t,
2005
- unique: e.unique === 1
2006
- }));
2018
+ unique: qn(e.unique)
2019
+ });
2007
2020
  }
2008
- u.length > 0 && h.push({
2021
+ u.length > 0 && g.push({
2009
2022
  name: `${i}_pkey`,
2010
2023
  table: i,
2011
2024
  columns: u,
2012
2025
  unique: !0
2013
2026
  }), r.push({
2014
2027
  name: i,
2015
- columns: p,
2016
- indexes: h
2028
+ columns: m,
2029
+ indexes: g
2017
2030
  });
2018
2031
  }
2019
2032
  return { tables: r };
2020
- }), qn = (e) => {
2033
+ }), Yn = (e) => {
2021
2034
  switch (e.toLowerCase()) {
2022
2035
  case "int":
2023
2036
  case "smallint":
@@ -2039,7 +2052,7 @@ BEGIN
2039
2052
  case "image": return "bytes";
2040
2053
  default: return "text";
2041
2054
  }
2042
- }, V = (e) => e === !0 || e === 1, Jn = (e) => S.gen(function* () {
2055
+ }, V = (e) => e === !0 || e === 1, Xn = (e) => S.gen(function* () {
2043
2056
  let t = yield* e`
2044
2057
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2045
2058
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -2105,12 +2118,12 @@ BEGIN
2105
2118
  else V(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2106
2119
  }
2107
2120
  let m = t.map((t) => {
2108
- let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : qn(t.data_type), l = a ? {
2121
+ let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : Yn(t.data_type), l = a ? {
2109
2122
  table: a.target_table,
2110
2123
  column: a.target_column,
2111
- onDelete: Yn(a.delete_rule),
2112
- onUpdate: Yn(a.update_rule)
2113
- } : void 0, u = t.column_default === null ? null : Xn(t.column_default), d = c.get(`${e}.${t.column_name}`);
2124
+ onDelete: Zn(a.delete_rule),
2125
+ onUpdate: Zn(a.update_rule)
2126
+ } : void 0, u = t.column_default === null ? null : Qn(t.column_default), d = c.get(`${e}.${t.column_name}`);
2114
2127
  return {
2115
2128
  name: t.column_name,
2116
2129
  type: o,
@@ -2121,7 +2134,7 @@ BEGIN
2121
2134
  ...u === null ? {} : { defaultValue: u },
2122
2135
  ...l ? { references: l } : {},
2123
2136
  ...d ? { oneOf: d } : {},
2124
- ...In(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2137
+ ...Ln(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2125
2138
  };
2126
2139
  }), h = [];
2127
2140
  if (o) for (let [t, n] of o) {
@@ -2145,18 +2158,18 @@ BEGIN
2145
2158
  });
2146
2159
  }
2147
2160
  return { tables: f };
2148
- }), Yn = (e) => {
2161
+ }), Zn = (e) => {
2149
2162
  switch (e.toUpperCase().replace(/_/g, " ")) {
2150
2163
  case "CASCADE": return "cascade";
2151
2164
  case "SET NULL": return "setNull";
2152
2165
  case "SET DEFAULT": return "noAction";
2153
2166
  default: return "noAction";
2154
2167
  }
2155
- }, Xn = (e) => {
2168
+ }, Qn = (e) => {
2156
2169
  let t = e.trim();
2157
2170
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2158
2171
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2159
- }, Zn = /* @__PURE__ */ new Set([
2172
+ }, $n = /* @__PURE__ */ new Set([
2160
2173
  "character varying",
2161
2174
  "varchar",
2162
2175
  "nvarchar",
@@ -2164,71 +2177,71 @@ BEGIN
2164
2177
  "character",
2165
2178
  "nchar"
2166
2179
  ]), H = (e, t) => {
2167
- if (!Zn.has(e.toLowerCase())) return;
2180
+ if (!$n.has(e.toLowerCase())) return;
2168
2181
  let n = Number(t);
2169
2182
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2170
- }, Qn = /* @__PURE__ */ new Set([k]), $n = (e) => e.onDialectOrElse({
2171
- mysql: () => Wn(e),
2172
- mssql: () => Jn(e),
2173
- sqlite: () => Kn(e),
2174
- orElse: () => Hn(e)
2183
+ }, er = /* @__PURE__ */ new Set([k]), tr = (e) => e.onDialectOrElse({
2184
+ mysql: () => Gn(e),
2185
+ mssql: () => Xn(e),
2186
+ sqlite: () => Jn(e),
2187
+ orElse: () => Un(e)
2175
2188
  }).pipe(S.map((e) => ({
2176
2189
  ...e,
2177
- tables: e.tables.filter((e) => !Qn.has(e.name))
2178
- }))), er = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", tr = /* @__PURE__ */ new WeakMap(), U = (e) => S.suspend(() => {
2179
- let t = tr.get(e);
2180
- return t === void 0 ? nr(e).pipe(S.tap((t) => S.sync(() => tr.set(e, t)))) : S.succeed(t);
2181
- }), nr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(S.map((e) => {
2190
+ tables: e.tables.filter((e) => !er.has(e.name))
2191
+ }))), nr = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", rr = /* @__PURE__ */ new WeakMap(), ir = (e) => S.suspend(() => {
2192
+ let t = rr.get(e);
2193
+ return t === void 0 ? ar(e).pipe(S.tap((t) => S.sync(() => rr.set(e, t)))) : S.succeed(t);
2194
+ }), ar = (e) => e.unsafe("SELECT VERSION() AS v").pipe(S.map((e) => {
2182
2195
  let t = e[0]?.v;
2183
- return typeof t == "string" ? er(t) : "mysql";
2184
- }), S.catchAll(() => S.succeed("mysql"))), rr = (e) => {
2196
+ return typeof t == "string" ? nr(t) : "mysql";
2197
+ }), S.catchAll(() => S.succeed("mysql"))), or = (e) => {
2185
2198
  let t = e;
2186
2199
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2187
2200
  let e = t;
2188
2201
  if (typeof e.errno == "number") return e.errno;
2189
2202
  t = e.cause;
2190
2203
  }
2191
- }, ir = (e) => {
2204
+ }, sr = (e) => {
2192
2205
  let t = [], n = e;
2193
2206
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2194
2207
  let e = n;
2195
2208
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2196
2209
  }
2197
2210
  return t.join(" | ");
2198
- }, ar = (e, t) => {
2211
+ }, cr = (e, t) => {
2199
2212
  if (t.length === 0) return !1;
2200
- let n = rr(e), r = ir(e);
2213
+ let n = or(e), r = sr(e);
2201
2214
  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)));
2202
- }, or = {
2215
+ }, lr = {
2203
2216
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2204
2217
  errno: [1061]
2205
- }, sr = {
2218
+ }, ur = {
2206
2219
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2207
2220
  errno: [1091]
2208
- }, cr = {
2221
+ }, dr = {
2209
2222
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2210
2223
  messageIncludes: ["no such column"]
2211
- }, lr = {
2224
+ }, fr = {
2212
2225
  why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
2213
2226
  errno: [1091, 3940]
2214
- }, W = (e, t) => e.onDialectOrElse({
2227
+ }, U = (e, t) => e.onDialectOrElse({
2215
2228
  mysql: () => S.succeed(t.replace("T", " ").replace("Z", "")),
2216
2229
  orElse: () => S.succeed(t)
2217
- }), ur = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, dr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), fr = (e, t) => {
2218
- if ((e.type !== "text" || e.maxLength === void 0) && !dr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2230
+ }), pr = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, mr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), hr = (e, t) => {
2231
+ if ((e.type !== "text" || e.maxLength === void 0) && !mr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2219
2232
  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;
2220
2233
  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.`);
2221
2234
  return M(e, t);
2222
- }, pr = (e) => {
2223
- let t = fr(e, "postgres");
2224
- return t === void 0 ? mr(e) : t;
2225
- }, mr = (e) => {
2235
+ }, gr = (e) => {
2236
+ let t = hr(e, "postgres");
2237
+ return t === void 0 ? _r(e) : t;
2238
+ }, _r = (e) => {
2226
2239
  switch (e.type) {
2227
2240
  case "id": return "text";
2228
2241
  case "text": return "text";
2229
2242
  case "integer": return "integer";
2230
2243
  case "real": return "double precision";
2231
- case "decimal": return ur(e, "NUMERIC");
2244
+ case "decimal": return pr(e, "NUMERIC");
2232
2245
  case "bigint": return "bigint";
2233
2246
  case "boolean": return "boolean";
2234
2247
  case "timestamp": return "timestamptz";
@@ -2242,15 +2255,15 @@ BEGIN
2242
2255
  case "interval": return "interval";
2243
2256
  case "raw": return e.rawDdl ?? "text";
2244
2257
  }
2245
- }, hr = (e) => {
2246
- let t = fr(e, "mariadb");
2258
+ }, vr = (e) => {
2259
+ let t = hr(e, "mariadb");
2247
2260
  if (t !== void 0) return t;
2248
2261
  switch (e.type) {
2249
2262
  case "id": return "VARCHAR(64)";
2250
2263
  case "text": return "LONGTEXT";
2251
2264
  case "integer": return "INT";
2252
2265
  case "real": return "DOUBLE";
2253
- case "decimal": return ur(e, "DECIMAL");
2266
+ case "decimal": return pr(e, "DECIMAL");
2254
2267
  case "bigint": return "BIGINT";
2255
2268
  case "boolean": return "TINYINT(1)";
2256
2269
  case "timestamp": return "DATETIME(6)";
@@ -2264,64 +2277,64 @@ BEGIN
2264
2277
  case "interval": return "BIGINT";
2265
2278
  case "raw": return e.rawDdl ?? "LONGTEXT";
2266
2279
  }
2267
- }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, gr = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", _r = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, vr = (e, t = "mariadb") => `ALTER TABLE ${K(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${K(e.column)}, ALGORITHM=COPY;`, yr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, br = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Yr(t)}`)};`, xr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Cr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Sr = (e, t) => {
2280
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, yr = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", br = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, xr = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, Sr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Cr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Zr(t)}`)};`, wr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Er(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Tr = (e, t) => {
2268
2281
  let { defaultFactory: n, ...r } = e;
2269
2282
  return M(e, t) !== M({
2270
2283
  ...r,
2271
2284
  hasDefault: !1
2272
2285
  }, t);
2273
- }, Cr = (e, t) => {
2286
+ }, Er = (e, t) => {
2274
2287
  let n = t(e.defaultValue);
2275
2288
  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.`);
2276
2289
  return n;
2277
- }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], wr = (e, t, n) => {
2278
- let r = q(e, t, n);
2279
- return r ? Kt(n, r) : void 0;
2280
- }, Tr = (e, t, n) => {
2281
- let r = n ?? e.nullable, i = Qe(e, "mariadb");
2290
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Dr = (e, t, n) => {
2291
+ let r = K(e, t, n);
2292
+ return r ? qt(n, r) : void 0;
2293
+ }, Or = (e, t, n) => {
2294
+ let r = n ?? e.nullable, i = $e(e, "mariadb");
2282
2295
  return [
2283
- K(t),
2296
+ G(t),
2284
2297
  M(e, "mariadb"),
2285
2298
  r ? null : "NOT NULL",
2286
2299
  i
2287
2300
  ].filter(Boolean).join(" ");
2288
- }, Er = (e, t) => e == null ? null : Array.isArray(e) ? Dr(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" ? N(e, "mariadb") : null, Dr = (e, t, n) => $e(e, t ?? { type: "json" }, n), Or = (e, t) => e == null ? null : Array.isArray(e) ? Dr(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" ? N(e, "postgres") : null, kr = (e, t) => {
2301
+ }, kr = (e, t) => e == null ? null : Array.isArray(e) ? Ar(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" ? N(e, "mariadb") : null, Ar = (e, t, n) => et(e, t ?? { type: "json" }, n), jr = (e, t) => e == null ? null : Array.isArray(e) ? Ar(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" ? N(e, "postgres") : null, q = (e, t) => {
2289
2302
  if (!e.generatedAs) return null;
2290
2303
  let { expr: n, stored: r } = e.generatedAs;
2291
2304
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2292
- }, Ar = (e) => {
2305
+ }, Mr = (e) => {
2293
2306
  if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "postgres");
2294
- let t = kr(e, "postgres");
2295
- if (t) return `${G(e.name)} ${pr(e)} ${t}`;
2296
- let n = [G(e.name), pr(e)];
2307
+ let t = q(e, "postgres");
2308
+ if (t) return `${W(e.name)} ${gr(e)} ${t}`;
2309
+ let n = [W(e.name), gr(e)];
2297
2310
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2298
- let t = Or(e.defaultValue, e);
2311
+ let t = jr(e.defaultValue, e);
2299
2312
  t && n.push(t);
2300
2313
  }
2301
- return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2314
+ return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2302
2315
  cascade: "CASCADE",
2303
2316
  restrict: "RESTRICT",
2304
2317
  setNull: "SET NULL",
2305
2318
  noAction: "NO ACTION"
2306
2319
  }[e.references.onDelete]}`)), n.join(" ");
2307
- }, jr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Mr = (e) => {
2308
- let t = e.columns.map((e) => ` ${Ar(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${jr(e, G)}\n)`];
2309
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(ei).join(", ")})`);
2320
+ }, Nr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Pr = (e) => {
2321
+ let t = e.columns.map((e) => ` ${Mr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Nr(e, W)}\n)`];
2322
+ 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(ni).join(", ")})`);
2310
2323
  return n;
2311
- }, Nr = 191, Pr = (e) => {
2312
- let t = hr(e).toUpperCase();
2324
+ }, Fr = 191, Ir = (e) => {
2325
+ let t = vr(e).toUpperCase();
2313
2326
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2314
- }, Fr = (e) => {
2327
+ }, Lr = (e) => {
2315
2328
  if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mariadb");
2316
- let t = kr(e, "mariadb");
2317
- if (t) return `${K(e.name)} ${hr(e)} ${t}`;
2318
- let n = [K(e.name), hr(e)];
2319
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Pr(e) && n.push("UNIQUE"), e.hasDefault) {
2320
- let t = Er(e.defaultValue, e);
2329
+ let t = q(e, "mariadb");
2330
+ if (t) return `${G(e.name)} ${vr(e)} ${t}`;
2331
+ let n = [G(e.name), vr(e)];
2332
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Ir(e) && n.push("UNIQUE"), e.hasDefault) {
2333
+ let t = kr(e.defaultValue, e);
2321
2334
  t && n.push(t);
2322
2335
  }
2323
2336
  return n.join(" ");
2324
- }, Ir = (e) => e.columns.flatMap((t) => {
2337
+ }, Rr = (e) => e.columns.flatMap((t) => {
2325
2338
  if (!t.references) return [];
2326
2339
  let n = t.references.onDelete ? ` ON DELETE ${{
2327
2340
  cascade: "CASCADE",
@@ -2329,27 +2342,27 @@ BEGIN
2329
2342
  setNull: "SET NULL",
2330
2343
  noAction: "NO ACTION"
2331
2344
  }[t.references.onDelete]}` : "";
2332
- return [` CONSTRAINT ${K(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${K(t.name)}) REFERENCES ${K(t.references.table)} (${K(t.references.column)})${n}`];
2333
- }), Lr = (e, t = "mariadb") => {
2345
+ return [` CONSTRAINT ${G(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${G(t.name)}) REFERENCES ${G(t.references.table)} (${G(t.references.column)})${n}`];
2346
+ }), zr = (e, t = "mariadb") => {
2334
2347
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2335
- let t = Qr(n.get(e));
2336
- return t === void 0 ? K(e) : `${K(e)}(${t})`;
2337
- }, i = e.columns.map((e) => ` ${Fr(e)}`).join(",\n"), a = Ir(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${o}${jr(e, r)}\n)`];
2338
- for (let n of e.columns) n.unique && n.type !== "id" && Pr(n) && s.push(`CREATE UNIQUE INDEX ${gr(t)}${K(`${e.table}_${n.name}_key`)} ON ${K(e.table)} (${r(n.name)})`);
2339
- for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${gr(t)}${K(n.name)} ON ${K(e.table)} (${n.columns.map(r).join(", ")})`);
2348
+ let t = ei(n.get(e));
2349
+ return t === void 0 ? G(e) : `${G(e)}(${t})`;
2350
+ }, i = e.columns.map((e) => ` ${Lr(e)}`).join(",\n"), a = Rr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Nr(e, r)}\n)`];
2351
+ for (let n of e.columns) n.unique && n.type !== "id" && Ir(n) && s.push(`CREATE UNIQUE INDEX ${yr(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2352
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${yr(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2340
2353
  return s;
2341
- }, Rr = {
2354
+ }, Br = {
2342
2355
  cascade: "CASCADE",
2343
2356
  restrict: "RESTRICT",
2344
2357
  setNull: "SET NULL",
2345
2358
  noAction: "NO ACTION"
2346
- }, zr = {
2359
+ }, Vr = {
2347
2360
  cascade: "CASCADE",
2348
2361
  restrict: "NO ACTION",
2349
2362
  setNull: "SET NULL",
2350
2363
  noAction: "NO ACTION"
2351
- }, Br = (e) => {
2352
- let t = fr(e, "sqlite");
2364
+ }, Hr = (e) => {
2365
+ let t = hr(e, "sqlite");
2353
2366
  if (t !== void 0) return t;
2354
2367
  switch (e.type) {
2355
2368
  case "integer":
@@ -2360,60 +2373,60 @@ BEGIN
2360
2373
  case "bytes": return "BLOB";
2361
2374
  default: return "TEXT";
2362
2375
  }
2363
- }, Vr = (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" ? N(e, "sqlite") : null, Hr = (e) => {
2376
+ }, Ur = (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" ? N(e, "sqlite") : null, Wr = (e) => {
2364
2377
  if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "sqlite");
2365
- let t = kr(e, "sqlite");
2366
- if (t) return `${G(e.name)} ${Br(e)} ${t}`;
2367
- let n = [G(e.name), Br(e)];
2378
+ let t = q(e, "sqlite");
2379
+ if (t) return `${W(e.name)} ${Hr(e)} ${t}`;
2380
+ let n = [W(e.name), Hr(e)];
2368
2381
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2369
- let t = Vr(e.defaultValue, "CURRENT_TIMESTAMP");
2382
+ let t = Ur(e.defaultValue, "CURRENT_TIMESTAMP");
2370
2383
  t && n.push(t);
2371
2384
  }
2372
- if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Rr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2385
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Br[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2373
2386
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2374
- n.push(`CHECK (${G(e.name)} IN (${t}))`);
2387
+ n.push(`CHECK (${W(e.name)} IN (${t}))`);
2375
2388
  }
2376
2389
  return n.join(" ");
2377
- }, Ur = (e) => {
2378
- let t = e.columns.map((e) => ` ${Hr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${jr(e, G)}\n)`];
2379
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
2390
+ }, Gr = (e) => {
2391
+ let t = e.columns.map((e) => ` ${Wr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Nr(e, W)}\n)`];
2392
+ 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(", ")})`);
2380
2393
  return n;
2381
2394
  }, J = (e, t) => {
2382
2395
  let n = t.find((t) => t.tableName === e);
2383
2396
  if (!n) return [];
2384
- let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
2385
- ...Ur({
2397
+ let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2398
+ ...Gr({
2386
2399
  kind: "create-table",
2387
2400
  table: i,
2388
2401
  columns: r.columns,
2389
2402
  indexes: [],
2390
2403
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
2391
2404
  }),
2392
- `INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
2393
- `DROP TABLE ${G(e)}`,
2394
- `ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
2405
+ `INSERT INTO ${W(i)} (${a}) SELECT ${a} FROM ${W(e)}`,
2406
+ `DROP TABLE ${W(e)}`,
2407
+ `ALTER TABLE ${W(i)} RENAME TO ${W(e)}`
2395
2408
  ];
2396
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
2409
+ 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(", ")})`);
2397
2410
  return o;
2398
- }, Wr = (e, t, n, r) => {
2411
+ }, Kr = (e, t, n, r) => {
2399
2412
  let i = r ?? e.nullable;
2400
2413
  return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${M(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2401
- }, Gr = (e, t) => {
2414
+ }, qr = (e, t) => {
2402
2415
  let n = `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 + ']');` + (t ? ` ${t}` : "");
2403
2416
  if (!e.hasDefault) return n;
2404
- let r = Vr(e.defaultValue, "SYSUTCDATETIME()");
2417
+ let r = Ur(e.defaultValue, "SYSUTCDATETIME()");
2405
2418
  if (!r) return n;
2406
2419
  let i = r.replace(/^DEFAULT\s+/i, "");
2407
2420
  return `${n} ALTER TABLE ${Y(e.table)} ADD DEFAULT ${i} FOR ${Y(e.column)};`;
2408
- }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Kr = (e) => {
2409
- let t = fr(e, "mssql");
2421
+ }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Jr = (e) => {
2422
+ let t = hr(e, "mssql");
2410
2423
  if (t !== void 0) return t;
2411
2424
  switch (e.type) {
2412
2425
  case "id":
2413
2426
  case "reference": return "NVARCHAR(64)";
2414
2427
  case "integer": return "INT";
2415
2428
  case "real": return "FLOAT";
2416
- case "decimal": return ur(e, "DECIMAL");
2429
+ case "decimal": return pr(e, "DECIMAL");
2417
2430
  case "bigint": return "BIGINT";
2418
2431
  case "boolean": return "BIT";
2419
2432
  case "timestamp": return "DATETIME2(6)";
@@ -2421,44 +2434,44 @@ BEGIN
2421
2434
  case "bytes": return "VARBINARY(MAX)";
2422
2435
  default: return "NVARCHAR(MAX)";
2423
2436
  }
2424
- }, qr = (e, t) => {
2437
+ }, Yr = (e, t) => {
2425
2438
  if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mssql");
2426
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Kr(e), r = kr(e, "mssql");
2439
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Jr(e), r = q(e, "mssql");
2427
2440
  if (r) return `${Y(e.name)} ${r}`;
2428
2441
  let i = [Y(e.name), n];
2429
2442
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2430
- let t = Vr(e.defaultValue, "SYSUTCDATETIME()");
2443
+ let t = Ur(e.defaultValue, "SYSUTCDATETIME()");
2431
2444
  t && i.push(t);
2432
2445
  }
2433
- return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${zr[e.references.onDelete]}`)), i.join(" ");
2434
- }, Jr = (e) => {
2435
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${qr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${jr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2446
+ return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Vr[e.references.onDelete]}`)), i.join(" ");
2447
+ }, Xr = (e) => {
2448
+ let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((e) => ` ${Yr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Nr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2436
2449
  for (let n of e.indexes) {
2437
2450
  if (n.name === `${e.table}_pkey`) continue;
2438
2451
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Y(n.name)} ON ${Y(e.table)} (${n.columns.map(Y).join(", ")})`;
2439
2452
  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)}')`);
2440
2453
  }
2441
2454
  return a;
2442
- }, Yr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Xr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Zr = (e, t, n) => {
2443
- let r = `${e.table}${Yr(t)}`;
2455
+ }, Zr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Qr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, $r = (e, t, n) => {
2456
+ let r = `${e.table}${Zr(t)}`;
2444
2457
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2445
- }, Qr = (e) => {
2446
- if (e === void 0 || !Pr(e)) return;
2458
+ }, ei = (e) => {
2459
+ if (e === void 0 || !Ir(e)) return;
2447
2460
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2448
- return t === void 0 ? Nr : Math.min(Nr, t);
2449
- }, $r = (e, t, n) => {
2450
- let r = Qr(wr(e, t, n));
2451
- return r === void 0 ? K(n) : `${K(n)}(${r})`;
2452
- }, ei = (e) => e.startsWith("(") ? e : G(e), ti = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(ei).join(", ")});`, ni = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${gr(n)}${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => $r(t, e.table, n)).join(", ")});`, ri = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, ii = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, ai = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, oi = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, si = (e) => {
2461
+ return t === void 0 ? Fr : Math.min(Fr, t);
2462
+ }, ti = (e, t, n) => {
2463
+ let r = ei(Dr(e, t, n));
2464
+ return r === void 0 ? G(n) : `${G(n)}(${r})`;
2465
+ }, ni = (e) => e.startsWith("(") ? e : W(e), ri = (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(ni).join(", ")});`, ii = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${yr(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => ti(t, e.table, n)).join(", ")});`, ai = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, oi = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, si = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ci = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, li = (e) => {
2453
2466
  let t = (e) => e.replace(/'/g, "''");
2454
2467
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2455
- }, ci = (e) => `ALTER INDEX ${G(e.from)} RENAME TO ${G(e.to)};`, li = (e) => `ALTER TABLE ${K(e.table)} RENAME INDEX ${K(e.from)} TO ${K(e.to)};`, ui = (e) => {
2468
+ }, ui = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, di = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, fi = (e) => {
2456
2469
  let t = (e) => e.replace(/'/g, "''");
2457
2470
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2458
- }, di = (e) => {
2471
+ }, pi = (e) => {
2459
2472
  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(", ")})`;
2460
2473
  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)}');`;
2461
- }, fi = (e, t, n) => {
2474
+ }, mi = (e, t, n) => {
2462
2475
  let r = n.find((t) => t.tableName === e);
2463
2476
  if (!r) return [];
2464
2477
  let i = [];
@@ -2467,13 +2480,13 @@ BEGIN
2467
2480
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Y(e)} ALTER COLUMN ${Y(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2468
2481
  }
2469
2482
  return i;
2470
- }, pi = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, mi = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${$r(t, e.table, e.column)});`, hi = (e) => {
2471
- let t = e.fields.map((e) => G(e)).join(", ");
2472
- return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2473
- }, gi = (e, t) => {
2474
- let n = e.fields.map((n) => $r(t, e.table, n)).join(", ");
2475
- return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2476
- }, _i = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, vi = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, yi = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, bi = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, xi = (e, t) => {
2483
+ }, hi = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, gi = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${ti(t, e.table, e.column)});`, _i = (e) => {
2484
+ let t = e.fields.map((e) => W(e)).join(", ");
2485
+ return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2486
+ }, vi = (e, t) => {
2487
+ let n = e.fields.map((n) => ti(t, e.table, n)).join(", ");
2488
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2489
+ }, yi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, bi = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, xi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, Si = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Ci = (e, t) => {
2477
2490
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2478
2491
  if (e.orphanPolicy) {
2479
2492
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2491,10 +2504,10 @@ BEGIN
2491
2504
  setNull: "SET NULL",
2492
2505
  noAction: "NO ACTION"
2493
2506
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2494
- }, Si = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, Ci = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, wi = (e, t) => {
2507
+ }, wi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Ti = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, Ei = (e, t) => {
2495
2508
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2496
2509
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2497
- }, Ti = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, Ei = (e, t) => S.gen(function* () {
2510
+ }, Di = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Oi = (e, t) => S.gen(function* () {
2498
2511
  let n = yield* e`
2499
2512
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2500
2513
  FROM information_schema.check_constraints cc
@@ -2507,18 +2520,18 @@ BEGIN
2507
2520
  WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), S.orElseSucceed(() => []));
2508
2521
  for (let e of n) {
2509
2522
  let n = String(e.n ?? "");
2510
- if (n !== "" && Pn(String(e.c ?? ""))?.column === t.column) return n;
2523
+ if (n !== "" && Fn(String(e.c ?? ""))?.column === t.column) return n;
2511
2524
  }
2512
- }), Di = (e, t, n) => S.gen(function* () {
2513
- let r = yield* Ei(e, t);
2514
- r !== void 0 && (yield* X(e, `ALTER TABLE ${K(t.table)} DROP CONSTRAINT ${K(r)};`, t.kind, [lr]));
2515
- let i = yield* Ei(e, t);
2525
+ }), ki = (e, t, n) => S.gen(function* () {
2526
+ let r = yield* Oi(e, t);
2527
+ r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [fr]));
2528
+ let i = yield* Oi(e, t);
2516
2529
  if (i === void 0) return;
2517
- let a = q(n, t.table, t.column);
2530
+ let a = K(n, t.table, t.column);
2518
2531
  if (!a) return yield* S.die(/* @__PURE__ */ Error(`applier: cannot drop the CHECK on '${t.table}.${t.column}' — it is column-level (catalog name '${i}'), which this family removes only by redefining the column, and the declared column is not available to redefine it from.`));
2519
- yield* X(e, `ALTER TABLE ${K(t.table)} MODIFY COLUMN ${Tr(a, t.column)};`, t.kind);
2520
- }), Oi = (e, t, n, r) => {
2521
- let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Y : G, s = a ? hr(i) : r === "mssql" ? Kr(i) : r === "sqlite" ? Br(i) : pr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Er(e, i) : r === "mssql" ? Vr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Vr(e, "CURRENT_TIMESTAMP") : Or(e, i), u = kr(i, r);
2532
+ yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Or(a, t.column)};`, t.kind);
2533
+ }), Ai = (e, t, n, r) => {
2534
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Y : W, s = a ? vr(i) : r === "mssql" ? Jr(i) : r === "sqlite" ? Hr(i) : gr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? kr(e, i) : r === "mssql" ? Ur(e, "SYSUTCDATETIME()") : r === "sqlite" ? Ur(e, "CURRENT_TIMESTAMP") : jr(e, i), u = q(i, r);
2522
2535
  if (u) {
2523
2536
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2524
2537
  return {
@@ -2546,7 +2559,7 @@ BEGIN
2546
2559
  post: f ? [f] : []
2547
2560
  };
2548
2561
  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;
2549
- }, ki = (e) => {
2562
+ }, ji = (e) => {
2550
2563
  let t = new Map(e.map((e) => [e.tableName, e]));
2551
2564
  return (e, n) => {
2552
2565
  let r = t.get(e);
@@ -2566,12 +2579,12 @@ BEGIN
2566
2579
  ...o
2567
2580
  };
2568
2581
  };
2569
- }, X = (e, t, n, r = []) => e.unsafe(t).pipe(S.catchIf((e) => ar(e, r), () => S.void), S.tapError((e) => S.sync(() => {
2570
- process.stderr.write(re(`applier: statement failed (op=${n})`, t, e, 400));
2582
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(S.catchIf((e) => cr(e, r), () => S.void), S.tapError((e) => S.sync(() => {
2583
+ process.stderr.write(ie(`applier: statement failed (op=${n})`, t, e, 400));
2571
2584
  })), S.mapError((e) => {
2572
- let r = re(`applier: statement failed (op=${n})`, t, e, 400).trim();
2585
+ let r = ie(`applier: statement failed (op=${n})`, t, e, 400).trim();
2573
2586
  return Object.assign(e, { message: r });
2574
- }), S.map(() => void 0)), Z = (e, t, n) => S.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : _(r, t)} FROM ${_(n, t)} WHERE 1=0`).pipe(S.as(!0), S.catchAll(() => S.succeed(!1))), Ai = (e, t) => S.gen(function* () {
2587
+ }), S.map(() => void 0)), Z = (e, t, n) => S.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : _(r, t)} FROM ${_(n, t)} WHERE 1=0`).pipe(S.as(!0), S.catchAll(() => S.succeed(!1))), Mi = (e, t) => S.gen(function* () {
2575
2588
  let n = I([Ie], t).tables[0];
2576
2589
  if (!n) return yield* S.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2577
2590
  let r = {
@@ -2580,18 +2593,18 @@ BEGIN
2580
2593
  columns: n.columns,
2581
2594
  indexes: []
2582
2595
  }, i = yield* e.onDialectOrElse({
2583
- mysql: () => U(e).pipe(S.map((e) => Lr(r, e))),
2584
- mssql: () => S.succeed(Jr(r)),
2585
- sqlite: () => S.succeed(Ur(r)),
2586
- orElse: () => S.succeed(Mr(r))
2596
+ mysql: () => ir(e).pipe(S.map((e) => zr(r, e))),
2597
+ mssql: () => S.succeed(Xr(r)),
2598
+ sqlite: () => S.succeed(Gr(r)),
2599
+ orElse: () => S.succeed(Pr(r))
2587
2600
  });
2588
2601
  yield* S.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2589
- }), ji = (e) => e`
2602
+ }), Ni = (e) => e`
2590
2603
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2591
2604
  ${e("status")}, ${e("payload")}
2592
2605
  FROM ${e(k)}
2593
- `, Mi = (e, t, n, r) => S.gen(function* () {
2594
- let i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2606
+ `, Pi = (e, t, n, r) => S.gen(function* () {
2607
+ let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2595
2608
  yield* S.forEach(r, ({ index: r, planned: a }) => e`
2596
2609
  INSERT INTO ${e(k)}
2597
2610
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
@@ -2602,8 +2615,8 @@ BEGIN
2602
2615
  ${a.op.kind}, ${Re(a.op)}, ${"pending"},
2603
2616
  ${JSON.stringify(a)}, ${i})
2604
2617
  `, { discard: !0 });
2605
- }), Ni = (e, t, n, r, i) => S.gen(function* () {
2606
- let a = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2618
+ }), Fi = (e, t, n, r, i) => S.gen(function* () {
2619
+ let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2607
2620
  if (r === "applied") {
2608
2621
  yield* e`
2609
2622
  UPDATE ${e(k)}
@@ -2618,8 +2631,8 @@ BEGIN
2618
2631
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2619
2632
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2620
2633
  `;
2621
- }), Pi = (e, t, n, r) => S.gen(function* () {
2622
- let i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2634
+ }), Ii = (e, t, n, r) => S.gen(function* () {
2635
+ let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2623
2636
  r.length > 0 && (yield* e`
2624
2637
  UPDATE ${e(k)}
2625
2638
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
@@ -2629,7 +2642,7 @@ BEGIN
2629
2642
  SET ${e("status")} = ${"pending"}
2630
2643
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2631
2644
  `);
2632
- }), Fi = (e, t) => t === void 0 ? e`DELETE FROM ${e(k)}`.pipe(S.asVoid) : e`DELETE FROM ${e(k)} WHERE ${e("runId")} = ${t}`.pipe(S.asVoid), Ii = (e, t, n) => S.gen(function* () {
2645
+ }), Li = (e, t) => t === void 0 ? e`DELETE FROM ${e(k)}`.pipe(S.asVoid) : e`DELETE FROM ${e(k)} WHERE ${e("runId")} = ${t}`.pipe(S.asVoid), Ri = (e, t, n) => S.gen(function* () {
2633
2646
  if (Ke(n.op, n.classification, t) !== "artefact-repair") return "clean";
2634
2647
  let r = n.op, i = (e) => _(e, t);
2635
2648
  if (t === "sqlite" || t === "turso") {
@@ -2640,113 +2653,113 @@ BEGIN
2640
2653
  if (r.kind !== "alter-column-type") return "clean";
2641
2654
  let a = `${r.column}${He}`, o = `${r.column}${Ue}`, s = yield* $(e, t, r.table, r.column), c = yield* $(e, t, r.table, a), l = yield* $(e, t, r.table, o), u = (e) => S.logWarning(`migration resume: ${e}`).pipe(S.annotateLogs({ scope: "voltro:migrate" }));
2642
2655
  return !c && !l ? "clean" : s && c && !l ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(a)}`, "resume-repair"), yield* u(`dropped a half-populated shadow column '${r.table}.${a}' — replaying the type change`), "outstanding") : !s && c && l ? (yield* X(e, `ALTER TABLE ${i(r.table)} RENAME COLUMN ${i(a)} TO ${i(r.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(o)}`, "resume-repair"), yield* u(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : s && !c && l ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(o)}`, "resume-repair"), yield* u(`dropped the leftover pre-swap column '${r.table}.${o}'`), "applied") : yield* S.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${s}, ${a}=${c}, ${o}=${l}).\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.`));
2643
- }), Li = (e, t, n, r = "fresh") => S.gen(function* () {
2644
- let i = process.hrtime.bigint(), a = ki(n.declared), o = t.op;
2656
+ }), zi = (e, t, n, r = "fresh") => S.gen(function* () {
2657
+ let i = process.hrtime.bigint(), a = ji(n.declared), o = t.op;
2645
2658
  switch (o.kind) {
2646
2659
  case "create-table": {
2647
2660
  let t = yield* e.onDialectOrElse({
2648
- mysql: () => U(e).pipe(S.map((e) => Lr(o, e))),
2649
- mssql: () => S.succeed(Jr(o)),
2650
- sqlite: () => S.succeed(Ur(o)),
2651
- orElse: () => S.succeed(Mr(o))
2661
+ mysql: () => ir(e).pipe(S.map((e) => zr(o, e))),
2662
+ mssql: () => S.succeed(Xr(o)),
2663
+ sqlite: () => S.succeed(Gr(o)),
2664
+ orElse: () => S.succeed(Pr(o))
2652
2665
  }), n = yield* e.onDialectOrElse({
2653
- mysql: () => S.succeed([or]),
2666
+ mysql: () => S.succeed([lr]),
2654
2667
  orElse: () => S.succeed([])
2655
2668
  });
2656
2669
  for (let r of t) yield* X(e, r, o.kind, n);
2657
2670
  break;
2658
2671
  }
2659
2672
  case "drop-table": {
2660
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Zr(o, n, e) : Xr(o, e);
2673
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? $r(o, n, e) : Qr(o, e);
2661
2674
  yield* e.onDialectOrElse({
2662
- mysql: () => X(e, r(K), o.kind),
2663
- orElse: () => X(e, r(G), o.kind)
2675
+ mysql: () => X(e, r(G), o.kind),
2676
+ orElse: () => X(e, r(W), o.kind)
2664
2677
  });
2665
2678
  break;
2666
2679
  }
2667
2680
  case "drop-column": {
2668
2681
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2669
2682
  yield* e.onDialectOrElse({
2670
- mysql: () => U(e).pipe(S.flatMap((r) => X(e, t ? br(o, n, K) : vr(o, r), o.kind, t ? [] : [sr]))),
2671
- sqlite: () => X(e, t ? br(o, n, G) : _r(o, G, !1), o.kind, t ? [] : [cr]),
2672
- orElse: () => X(e, t ? br(o, n, G) : _r(o, G), o.kind)
2683
+ mysql: () => ir(e).pipe(S.flatMap((r) => X(e, t ? Cr(o, n, G) : xr(o, r), o.kind, t ? [] : [ur]))),
2684
+ sqlite: () => X(e, t ? Cr(o, n, W) : br(o, W, !1), o.kind, t ? [] : [dr]),
2685
+ orElse: () => X(e, t ? Cr(o, n, W) : br(o, W), o.kind)
2673
2686
  });
2674
2687
  break;
2675
2688
  }
2676
2689
  case "rename-column":
2677
2690
  yield* e.onDialectOrElse({
2678
- mysql: () => X(e, yr(o, K), o.kind),
2691
+ mysql: () => X(e, Sr(o, G), o.kind),
2679
2692
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2680
- orElse: () => X(e, yr(o, G), o.kind)
2693
+ orElse: () => X(e, Sr(o, W), o.kind)
2681
2694
  });
2682
2695
  break;
2683
2696
  case "add-index":
2684
2697
  yield* e.onDialectOrElse({
2685
- mysql: () => U(e).pipe(S.flatMap((t) => X(e, ni(o, n.declared, t), o.kind, [or]))),
2686
- mssql: () => Z(e, [...fi(o.table, o.index.columns, n.declared), di(o)], o.kind),
2687
- orElse: () => X(e, ti(o, t.classification === "online-required"), o.kind)
2698
+ mysql: () => ir(e).pipe(S.flatMap((t) => X(e, ii(o, n.declared, t), o.kind, [lr]))),
2699
+ mssql: () => Z(e, [...mi(o.table, o.index.columns, n.declared), pi(o)], o.kind),
2700
+ orElse: () => X(e, ri(o, t.classification === "online-required"), o.kind)
2688
2701
  });
2689
2702
  break;
2690
2703
  case "drop-index":
2691
2704
  yield* e.onDialectOrElse({
2692
- mysql: () => X(e, ii(o), o.kind),
2693
- mssql: () => X(e, ai(o), o.kind),
2694
- orElse: () => X(e, ri(o), o.kind)
2705
+ mysql: () => X(e, oi(o), o.kind),
2706
+ mssql: () => X(e, si(o), o.kind),
2707
+ orElse: () => X(e, ai(o), o.kind)
2695
2708
  });
2696
2709
  break;
2697
2710
  case "rename-table":
2698
2711
  yield* e.onDialectOrElse({
2699
- mysql: () => X(e, oi(o, K), o.kind),
2700
- mssql: () => X(e, si(o), o.kind),
2701
- orElse: () => X(e, oi(o, G), o.kind)
2712
+ mysql: () => X(e, ci(o, G), o.kind),
2713
+ mssql: () => X(e, li(o), o.kind),
2714
+ orElse: () => X(e, ci(o, W), o.kind)
2702
2715
  });
2703
2716
  break;
2704
2717
  case "rename-index":
2705
2718
  yield* e.onDialectOrElse({
2706
- mysql: () => X(e, li(o), o.kind),
2707
- mssql: () => X(e, ui(o), o.kind),
2708
- orElse: () => X(e, ci(o), o.kind)
2719
+ mysql: () => X(e, di(o), o.kind),
2720
+ mssql: () => X(e, fi(o), o.kind),
2721
+ orElse: () => X(e, ui(o), o.kind)
2709
2722
  });
2710
2723
  break;
2711
2724
  case "add-unique":
2712
2725
  yield* e.onDialectOrElse({
2713
- mysql: () => X(e, mi(o, n.declared), o.kind),
2726
+ mysql: () => X(e, gi(o, n.declared), o.kind),
2714
2727
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2715
- mssql: () => Z(e, [...fi(o.table, [o.column], n.declared), pi(o)], o.kind),
2716
- orElse: () => X(e, pi(o), o.kind)
2728
+ mssql: () => Z(e, [...mi(o.table, [o.column], n.declared), hi(o)], o.kind),
2729
+ orElse: () => X(e, hi(o), o.kind)
2717
2730
  });
2718
2731
  break;
2719
2732
  case "drop-unique":
2720
2733
  yield* e.onDialectOrElse({
2721
- mysql: () => X(e, bi(o), o.kind),
2734
+ mysql: () => X(e, Si(o), o.kind),
2722
2735
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2723
- orElse: () => X(e, yi(o), o.kind)
2736
+ orElse: () => X(e, xi(o), o.kind)
2724
2737
  });
2725
2738
  break;
2726
2739
  case "add-unique-composite":
2727
2740
  yield* e.onDialectOrElse({
2728
- mysql: () => X(e, gi(o, n.declared), o.kind),
2741
+ mysql: () => X(e, vi(o, n.declared), o.kind),
2729
2742
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2730
- mssql: () => Z(e, [...fi(o.table, o.fields, n.declared), hi(o)], o.kind),
2731
- orElse: () => X(e, hi(o), o.kind)
2743
+ mssql: () => Z(e, [...mi(o.table, o.fields, n.declared), _i(o)], o.kind),
2744
+ orElse: () => X(e, _i(o), o.kind)
2732
2745
  });
2733
2746
  break;
2734
2747
  case "drop-unique-composite":
2735
2748
  yield* e.onDialectOrElse({
2736
- mysql: () => X(e, vi(o), o.kind),
2749
+ mysql: () => X(e, bi(o), o.kind),
2737
2750
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2738
- orElse: () => X(e, _i(o), o.kind)
2751
+ orElse: () => X(e, yi(o), o.kind)
2739
2752
  });
2740
2753
  break;
2741
2754
  case "add-foreign-key":
2742
2755
  yield* e.onDialectOrElse({
2743
- mysql: () => Z(e, xi(o, K), o.kind),
2756
+ mysql: () => Z(e, Ci(o, G), o.kind),
2744
2757
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2745
- orElse: () => Z(e, xi(o, G), o.kind)
2758
+ orElse: () => Z(e, Ci(o, W), o.kind)
2746
2759
  });
2747
2760
  break;
2748
2761
  case "add-column": {
2749
- let n = Oi(o, t, a, yield* e.onDialectOrElse({
2762
+ let n = Ai(o, t, a, yield* e.onDialectOrElse({
2750
2763
  mysql: () => S.succeed("mariadb"),
2751
2764
  mssql: () => S.succeed("mssql"),
2752
2765
  sqlite: () => S.succeed("sqlite"),
@@ -2792,47 +2805,47 @@ BEGIN
2792
2805
  case "alter-column-nullability":
2793
2806
  yield* e.onDialectOrElse({
2794
2807
  mysql: () => {
2795
- let t = q(n.declared, o.table, o.column);
2796
- return t ? X(e, `ALTER TABLE ${K(o.table)} MODIFY COLUMN ${Tr(t, o.column, o.toNullable)};`, o.kind) : S.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.`));
2808
+ let t = K(n.declared, o.table, o.column);
2809
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(t, o.column, o.toNullable)};`, o.kind) : S.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.`));
2797
2810
  },
2798
2811
  mssql: () => {
2799
- let t = q(n.declared, o.table, o.column);
2800
- return t ? X(e, Wr(t, o.column, o.table, o.toNullable), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2812
+ let t = K(n.declared, o.table, o.column);
2813
+ return t ? X(e, Kr(t, o.column, o.table, o.toNullable), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2801
2814
  },
2802
2815
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2803
- orElse: () => X(e, `ALTER TABLE ${G(o.table)} ALTER COLUMN ${G(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2816
+ orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2804
2817
  });
2805
2818
  break;
2806
2819
  case "alter-column-default": {
2807
- let t = wr(n.declared, o.table, o.column), r = q(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Sr(r, e) ? r : void 0;
2820
+ let t = Dr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Tr(r, e) ? r : void 0;
2808
2821
  yield* e.onDialectOrElse({
2809
2822
  mysql: () => {
2810
2823
  let n = i("mariadb");
2811
- return X(e, n ? `ALTER TABLE ${K(o.table)} MODIFY COLUMN ${Tr(n, o.column)};` : xr(o, K, (e) => Er(e, t)), o.kind);
2824
+ return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(n, o.column)};` : wr(o, G, (e) => kr(e, t)), o.kind);
2812
2825
  },
2813
2826
  mssql: () => {
2814
2827
  let t = i("mssql");
2815
- return X(e, Gr(o, t ? Wr(t, o.column, o.table) : void 0), o.kind);
2828
+ return X(e, qr(o, t ? Kr(t, o.column, o.table) : void 0), o.kind);
2816
2829
  },
2817
2830
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2818
- orElse: () => X(e, xr(o, G, (e) => Or(e, t)), o.kind)
2831
+ orElse: () => X(e, wr(o, W, (e) => jr(e, t)), o.kind)
2819
2832
  });
2820
2833
  break;
2821
2834
  }
2822
2835
  case "alter-column-type": {
2823
- let r = pr(wr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2836
+ let r = gr(Dr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2824
2837
  if (t.classification !== "online-required") {
2825
2838
  yield* e.onDialectOrElse({
2826
2839
  mysql: () => {
2827
- let t = q(n.declared, o.table, o.column);
2828
- return t ? X(e, `ALTER TABLE ${K(o.table)} MODIFY COLUMN ${Tr(t, o.column)};`, o.kind) : S.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.`));
2840
+ let t = K(n.declared, o.table, o.column);
2841
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(t, o.column)};`, o.kind) : S.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.`));
2829
2842
  },
2830
2843
  mssql: () => {
2831
- let t = q(n.declared, o.table, o.column);
2832
- return t ? X(e, Wr(t, o.column, o.table), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2844
+ let t = K(n.declared, o.table, o.column);
2845
+ return t ? X(e, Kr(t, o.column, o.table), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2833
2846
  },
2834
2847
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2835
- orElse: () => X(e, `ALTER TABLE ${G(o.table)} ALTER COLUMN ${G(o.column)} TYPE ${r}${i};`, o.kind)
2848
+ orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
2836
2849
  });
2837
2850
  break;
2838
2851
  }
@@ -2841,34 +2854,34 @@ BEGIN
2841
2854
  orElse: () => S.void
2842
2855
  });
2843
2856
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2844
- yield* e.unsafe(`ALTER TABLE ${G(o.table)} ADD COLUMN ${G(a)} ${r}`);
2845
- let c = o.using ?? G(o.column), l;
2857
+ yield* e.unsafe(`ALTER TABLE ${W(o.table)} ADD COLUMN ${W(a)} ${r}`);
2858
+ let c = o.using ?? W(o.column), l;
2846
2859
  for (;;) {
2847
2860
  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)}`;
2848
2861
  if (t.length === 0) break;
2849
- yield* e.unsafe(`UPDATE ${G(o.table)} SET ${G(a)} = ${c} WHERE ${G(o.column)} IS NOT NULL AND ${G(a)} IS NULL AND ${G("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2862
+ 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;
2850
2863
  }
2851
- yield* S.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${G(o.table)} RENAME COLUMN ${G(o.column)} TO ${G(s)}`), yield* e.unsafe(`ALTER TABLE ${G(o.table)} RENAME COLUMN ${G(a)} TO ${G(o.column)}`), yield* e.unsafe(`ALTER TABLE ${G(o.table)} DROP COLUMN ${G(s)}`);
2864
+ yield* S.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(S.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)}`);
2852
2865
  break;
2853
2866
  }
2854
2867
  case "drop-foreign-key":
2855
2868
  yield* e.onDialectOrElse({
2856
- mysql: () => X(e, Ci(o), o.kind),
2869
+ mysql: () => X(e, Ti(o), o.kind),
2857
2870
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2858
- orElse: () => X(e, Si(o), o.kind)
2871
+ orElse: () => X(e, wi(o), o.kind)
2859
2872
  });
2860
2873
  break;
2861
2874
  case "add-check":
2862
2875
  yield* e.onDialectOrElse({
2863
- mysql: () => X(e, wi(o, K), o.kind),
2876
+ mysql: () => X(e, Ei(o, G), o.kind),
2864
2877
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2865
- orElse: () => X(e, wi(o, G), o.kind)
2878
+ orElse: () => X(e, Ei(o, W), o.kind)
2866
2879
  });
2867
2880
  break;
2868
2881
  case "drop-check": yield* e.onDialectOrElse({
2869
- mysql: () => Di(e, o, n.declared),
2882
+ mysql: () => ki(e, o, n.declared),
2870
2883
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2871
- orElse: () => X(e, Ti(o), o.kind)
2884
+ orElse: () => X(e, Di(o), o.kind)
2872
2885
  });
2873
2886
  }
2874
2887
  return {
@@ -2876,7 +2889,7 @@ BEGIN
2876
2889
  status: "applied",
2877
2890
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2878
2891
  };
2879
- }), Ri = (e, t, n, r) => S.gen(function* () {
2892
+ }), Bi = (e, t, n, r) => S.gen(function* () {
2880
2893
  let i = [...new Set(r.map((e) => e.runId))];
2881
2894
  if (i.length > 1) return yield* S.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 \`${k}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2882
2895
  let a = i[0], o = [...r].map((e) => ({
@@ -2890,7 +2903,7 @@ BEGIN
2890
2903
  runId: a,
2891
2904
  why: "no operation had started — no DDL ran"
2892
2905
  };
2893
- let l = s ? yield* Ii(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2906
+ let l = s ? yield* Ri(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2894
2907
  if (u !== n.toFingerprint) return {
2895
2908
  kind: "discard",
2896
2909
  runId: a,
@@ -2901,7 +2914,7 @@ BEGIN
2901
2914
  kind: "discard",
2902
2915
  runId: a,
2903
2916
  why: "every recorded operation had already taken effect"
2904
- } : (yield* Pi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* S.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), {
2917
+ } : (yield* Ii(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* S.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), {
2905
2918
  kind: "resume",
2906
2919
  runId: a,
2907
2920
  ops: f.map((e) => ({
@@ -2909,7 +2922,7 @@ BEGIN
2909
2922
  planned: e.planned
2910
2923
  }))
2911
2924
  });
2912
- }), zi = (e) => {
2925
+ }), Vi = (e) => {
2913
2926
  let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
2914
2927
  return [
2915
2928
  t.kind,
@@ -2918,14 +2931,14 @@ BEGIN
2918
2931
  n("name"),
2919
2932
  n("to")
2920
2933
  ].join("\0");
2921
- }, Bi = (e, t, n) => S.gen(function* () {
2934
+ }, Hi = (e, t, n) => S.gen(function* () {
2922
2935
  let r = t.operations.filter((e) => e.blocked);
2923
2936
  if (r.length > 0) return yield* S.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2924
2937
  yield* je(e, { schema: n.lockSchema });
2925
- let i = Date.now(), a = [], o = Ne(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => zi(e))), l = {
2938
+ let i = Date.now(), a = [], o = Ne(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => Vi(e))), l = {
2926
2939
  ...s,
2927
2940
  operations: s.operations.map((e) => {
2928
- if (!e.blocked || !c.has(zi(e))) return e;
2941
+ if (!e.blocked || !c.has(Vi(e))) return e;
2929
2942
  let { blocked: t, ...n } = e;
2930
2943
  return n;
2931
2944
  })
@@ -2938,20 +2951,20 @@ BEGIN
2938
2951
  planned: e
2939
2952
  })), g = "fresh";
2940
2953
  try {
2941
- yield* Ai(e, o);
2942
- let t = yield* ji(e);
2954
+ yield* Mi(e, o);
2955
+ let t = yield* Ni(e);
2943
2956
  if (t.length > 0) {
2944
- let n = yield* Ri(e, o, l, t);
2945
- n.kind === "resume" ? (m = n.runId, h = n.ops, g = "resume") : (yield* S.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* Fi(e, n.runId));
2957
+ let n = yield* Bi(e, o, l, t);
2958
+ n.kind === "resume" ? (m = n.runId, h = n.ops, g = "resume") : (yield* S.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* Li(e, n.runId));
2946
2959
  }
2947
- g === "fresh" && h.length > 0 && (yield* Mi(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(S.gen(function* () {
2948
- let e = yield* E.SqlClient;
2949
- for (let t of f) a.push(yield* Li(e, t, n));
2960
+ g === "fresh" && h.length > 0 && (yield* Pi(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(S.gen(function* () {
2961
+ let e = yield* T.SqlClient;
2962
+ for (let t of f) a.push(yield* zi(e, t, n));
2950
2963
  })));
2951
2964
  for (let { index: t, planned: r } of h) {
2952
- yield* Ni(e, m, t, "started");
2953
- let i = a.length, o = yield* Li(e, r, n, g).pipe(S.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${h.length + f.length} operation(s) applied before this one${f.length > 0 ? ` (${f.length} of them in a transaction)` : ""}.\n` + (d ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
2954
- a.push(o), yield* Ni(e, m, t, "applied", o.durationMs);
2965
+ yield* Fi(e, m, t, "started");
2966
+ let i = a.length, o = yield* zi(e, r, n, g).pipe(S.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${h.length + f.length} operation(s) applied before this one${f.length > 0 ? ` (${f.length} of them in a transaction)` : ""}.\n` + (d ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
2967
+ a.push(o), yield* Fi(e, m, t, "applied", o.durationMs);
2955
2968
  }
2956
2969
  } finally {
2957
2970
  yield* O(e, { schema: n.lockSchema }).pipe(S.orDie);
@@ -2961,23 +2974,23 @@ BEGIN
2961
2974
  let e = _.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2962
2975
  return yield* S.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${l.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${_.operations.length}:\n${e}${_.operations.length > 10 ? `\n … and ${_.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2963
2976
  }
2964
- let y = a.filter((e) => e.status === "applied").length, b = Date.now() - i, x = m, C = (/* @__PURE__ */ new Date()).toISOString(), w = yield* W(e, C), T = [...f, ...h.map((e) => e.planned)];
2977
+ let y = a.filter((e) => e.status === "applied").length, b = Date.now() - i, x = m, C = (/* @__PURE__ */ new Date()).toISOString(), ee = yield* U(e, C), w = [...f, ...h.map((e) => e.planned)];
2965
2978
  yield* e`
2966
2979
  INSERT INTO ${e("_voltro_migration_plans")}
2967
2980
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
2968
2981
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
2969
2982
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
2970
2983
  VALUES
2971
- (${x}, ${l.toFingerprint}, ${_.fromFingerprint}, ${JSON.stringify(T)},
2984
+ (${x}, ${l.toFingerprint}, ${_.fromFingerprint}, ${JSON.stringify(w)},
2972
2985
  ${n.appliedBy}, ${n.environment}, ${n.source},
2973
- ${b}, ${w}, ${n.notes ?? null})
2974
- `, yield* Fi(e, m);
2975
- let ee = [...new Set(T.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2976
- return yield* S.promise(() => v({ changedTables: ee }).catch(() => {})), {
2986
+ ${b}, ${ee}, ${n.notes ?? null})
2987
+ `, yield* Li(e, m);
2988
+ let te = [...new Set(w.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2989
+ return yield* S.promise(() => v({ changedTables: te }).catch(() => {})), {
2977
2990
  id: x,
2978
2991
  appliedAt: C,
2979
2992
  fingerprint: l.toFingerprint,
2980
- operations: T,
2993
+ operations: w,
2981
2994
  appliedBy: n.appliedBy,
2982
2995
  environment: n.environment,
2983
2996
  durationMs: b,
@@ -2985,14 +2998,14 @@ BEGIN
2985
2998
  source: n.source,
2986
2999
  ...n.notes ? { notes: n.notes } : {}
2987
3000
  };
2988
- }), Vi = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Hi = (e) => e`
3001
+ }), Ui = (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"), Wi = (e) => e`
2989
3002
  SELECT fingerprint
2990
3003
  FROM _voltro_migration_plans
2991
3004
  ORDER BY ${e("appliedAt")} DESC
2992
3005
  LIMIT 1
2993
- `.pipe(S.map((e) => e.length > 0 ? e[0].fingerprint : void 0), S.catchAll(() => S.succeed(void 0))), Ui = (e, t, n) => S.gen(function* () {
2994
- if ((yield* Hi(e)) === t.toFingerprint) return "already-current";
2995
- let r = `plan_${Date.now().toString(36)}`, i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
3006
+ `.pipe(S.map((e) => e.length > 0 ? e[0].fingerprint : void 0), S.catchAll(() => S.succeed(void 0))), Gi = (e, t, n) => S.gen(function* () {
3007
+ if ((yield* Wi(e)) === t.toFingerprint) return "already-current";
3008
+ let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2996
3009
  return yield* e`
2997
3010
  INSERT INTO ${e("_voltro_migration_plans")}
2998
3011
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -3003,8 +3016,8 @@ BEGIN
3003
3016
  ${n.appliedBy}, ${n.environment}, ${n.source},
3004
3017
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
3005
3018
  `, "recorded";
3006
- }).pipe(S.catchAll(() => S.succeed("already-current"))), Wi = (e, t) => S.gen(function* () {
3007
- let n = Wt(I(t, Ne(e))), r = yield* Hi(e);
3019
+ }).pipe(S.catchAll(() => S.succeed("already-current"))), Ki = (e, t) => S.gen(function* () {
3020
+ let n = Gt(I(t, Ne(e))), r = yield* Wi(e);
3008
3021
  return r === n ? {
3009
3022
  kind: "up-to-date",
3010
3023
  fingerprint: n
@@ -3013,23 +3026,23 @@ BEGIN
3013
3026
  expected: n,
3014
3027
  ...r === void 0 ? {} : { actual: r }
3015
3028
  };
3016
- }), Gi = [
3029
+ }), qi = [
3017
3030
  "pgeagertest_",
3018
3031
  "mig_e2e_",
3019
3032
  "mig_test_",
3020
3033
  "mysqleagertest_",
3021
3034
  "mssqleagertest_",
3022
3035
  "sqliteeagertest_"
3023
- ], Ki = (e) => Gi.some((t) => e.startsWith(t)), qi = (e, t) => S.gen(function* () {
3036
+ ], Ji = (e) => qi.some((t) => e.startsWith(t)), Yi = (e, t) => S.gen(function* () {
3024
3037
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
3025
- let n = t.filter((e) => Ki(e.name)).map((e) => e.name);
3038
+ let n = t.filter((e) => Ji(e.name)).map((e) => e.name);
3026
3039
  if (n.length === 0) return [];
3027
3040
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(S.catchAll(() => S.void));
3028
3041
  return n;
3029
- }), Ji = () => {
3042
+ }), Xi = () => {
3030
3043
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
3031
3044
  return e.length > 0 ? { ignoreTables: e } : {};
3032
- }, Yi = (e) => {
3045
+ }, Zi = (e) => {
3033
3046
  if (e === void 0) return;
3034
3047
  let t = e.trim();
3035
3048
  if (t === "") return;
@@ -3039,48 +3052,48 @@ BEGIN
3039
3052
  kind: "tables",
3040
3053
  tables: new Set(n)
3041
3054
  } : void 0;
3042
- }, Xi = (e) => typeof e.table == "string" ? e.table : void 0, Zi = (e, t = { kind: "all" }) => ({
3055
+ }, Qi = (e) => typeof e.table == "string" ? e.table : void 0, $i = (e, t = { kind: "all" }) => ({
3043
3056
  ...e,
3044
3057
  operations: e.operations.map((e) => {
3045
3058
  if (!e.blocked || e.classification !== "lossy") return e;
3046
3059
  if (t?.kind === "tables") {
3047
- let n = Xi(e.op);
3060
+ let n = Qi(e.op);
3048
3061
  if (n === void 0 || !t.tables.has(n)) return e;
3049
3062
  }
3050
3063
  let { blocked: n, ...r } = e;
3051
3064
  return r;
3052
3065
  })
3053
- }), Qi = (e, t, n) => t === "postgres" ? Xt(e, n).pipe(S.flatMap((e) => {
3054
- let t = Zt(e);
3066
+ }), ea = (e, t, n) => t === "postgres" ? Zt(e, n).pipe(S.flatMap((e) => {
3067
+ let t = Qt(e);
3055
3068
  return t === void 0 ? S.void : S.logWarning(`auto-migrate: ${t}`).pipe(S.annotateLogs({ scope: "voltro:migrate" }));
3056
- }), S.catchAll(() => S.void)) : S.void, $i = (e, t, n) => S.gen(function* () {
3069
+ }), S.catchAll(() => S.void)) : S.void, ta = (e, t, n) => S.gen(function* () {
3057
3070
  let r = Ne(e), i = t;
3058
3071
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
3059
- let t = Wt(I(i, r));
3060
- if ((yield* Hi(e)) === t) return yield* Qi(e, r, i), {
3072
+ let t = Gt(I(i, r));
3073
+ if ((yield* Wi(e)) === t) return yield* ea(e, r, i), {
3061
3074
  kind: "up-to-date",
3062
3075
  fingerprint: t
3063
3076
  };
3064
3077
  }
3065
- let a = yield* $n(e), o = yield* qi(e, a.tables);
3078
+ let a = yield* tr(e), o = yield* Yi(e, a.tables);
3066
3079
  o.length > 0 && (yield* S.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(S.annotateLogs({
3067
3080
  scope: "voltro:migrate",
3068
3081
  count: o.length
3069
- })), a = yield* $n(e));
3070
- let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !h(e.name) || s.has(e.name)), l = Nn({
3082
+ })), a = yield* tr(e));
3083
+ let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !h(e.name) || s.has(e.name)), l = Pn({
3071
3084
  declared: i,
3072
3085
  live: { tables: c(a.tables) },
3073
3086
  dialect: r,
3074
- ...Ji()
3087
+ ...Xi()
3075
3088
  });
3076
3089
  if (l.summary.blocked > 0) {
3077
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Yi(process.env.VOLTRO_DESTRUCTIVE_OK);
3078
- if (t === void 0 || !e || (l = Zi(l, t), l.operations.some((e) => e.blocked))) return {
3090
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Zi(process.env.VOLTRO_DESTRUCTIVE_OK);
3091
+ if (t === void 0 || !e || (l = $i(l, t), l.operations.some((e) => e.blocked))) return {
3079
3092
  kind: "refused-blocked",
3080
3093
  plan: l
3081
3094
  };
3082
3095
  }
3083
- return l.operations.length === 0 ? (yield* Ui(e, l, {
3096
+ return l.operations.length === 0 ? (yield* Gi(e, l, {
3084
3097
  appliedBy: n.appliedBy,
3085
3098
  environment: n.environment === "prod" ? "dev" : n.environment,
3086
3099
  source: "auto-diff"
@@ -3089,37 +3102,37 @@ BEGIN
3089
3102
  fingerprint: l.toFingerprint
3090
3103
  }) : {
3091
3104
  kind: "applied",
3092
- applied: yield* Bi(e, l, {
3105
+ applied: yield* Hi(e, l, {
3093
3106
  declared: t,
3094
3107
  appliedBy: n.appliedBy,
3095
3108
  environment: n.environment === "prod" ? "dev" : n.environment,
3096
3109
  source: "auto-diff",
3097
3110
  replan: (e) => S.gen(function* () {
3098
- let t = yield* $n(e);
3099
- return Nn({
3111
+ let t = yield* tr(e);
3112
+ return Pn({
3100
3113
  declared: i,
3101
3114
  live: { tables: c(t.tables) },
3102
3115
  dialect: r,
3103
- ...Ji()
3116
+ ...Xi()
3104
3117
  });
3105
3118
  })
3106
3119
  }),
3107
3120
  plan: l
3108
3121
  };
3109
- }), ea = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? S.succeed({
3122
+ }), na = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? S.succeed({
3110
3123
  kind: "skipped",
3111
3124
  reason: "VOLTRO_AUTO_MIGRATE=0"
3112
- }) : n.environment === "prod" ? Wi(e, t) : $i(e, t, n), ta = (e, t) => {
3125
+ }) : n.environment === "prod" ? Ki(e, t) : ta(e, t, n), ra = (e, t) => {
3113
3126
  switch (e.kind) {
3114
3127
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
3115
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${Gt(e.fingerprint)})`;
3128
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${Kt(e.fingerprint)})`;
3116
3129
  case "applied": {
3117
3130
  let t = e.plan.summary;
3118
- 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=${Gt(e.applied.fingerprint)}`;
3131
+ 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=${Kt(e.applied.fingerprint)}`;
3119
3132
  }
3120
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${Gt(e.expected)}` + (e.actual ? ` live=${Gt(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3133
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${Kt(e.expected)}` + (e.actual ? ` live=${Kt(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3121
3134
  case "refused-blocked": {
3122
- let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + Vi(e.plan), c = [""];
3135
+ 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` + Ui(e.plan), c = [""];
3123
3136
  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) {
3124
3137
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3125
3138
  for (let r of e.plan.operations) {
@@ -3136,7 +3149,7 @@ BEGIN
3136
3149
  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");
3137
3150
  }
3138
3151
  }
3139
- }, na = T({ scope: "voltro:migrate" }), ra = /* @__PURE__ */ new Set([
3152
+ }, ia = w({ scope: "voltro:migrate" }), aa = /* @__PURE__ */ new Set([
3140
3153
  "node_modules",
3141
3154
  "dist",
3142
3155
  "build",
@@ -3145,12 +3158,12 @@ BEGIN
3145
3158
  ".next",
3146
3159
  ".git",
3147
3160
  ".framework"
3148
- ]), ia = async (e) => {
3161
+ ]), oa = async (e) => {
3149
3162
  let t = [], n = async (e) => {
3150
- let r = await ee.readdir(e, { withFileTypes: !0 }).catch(() => []);
3163
+ let r = await te.readdir(e, { withFileTypes: !0 }).catch(() => []);
3151
3164
  for (let i of r) {
3152
- if (ra.has(i.name)) continue;
3153
- let r = te(e, i.name);
3165
+ if (aa.has(i.name)) continue;
3166
+ let r = ne(e, i.name);
3154
3167
  i.isDirectory() ? await n(r) : i.isFile() && m.test(i.name) && t.push(r);
3155
3168
  }
3156
3169
  };
@@ -3158,12 +3171,12 @@ BEGIN
3158
3171
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3159
3172
  return n.localeCompare(r);
3160
3173
  });
3161
- }, aa = async (e) => {
3174
+ }, sa = async (e) => {
3162
3175
  let t = [];
3163
3176
  for (let n of e) {
3164
- let e = (await import(ne(n).href)).default;
3177
+ let e = (await import(re(n).href)).default;
3165
3178
  if (!g(e)) {
3166
- na.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3179
+ ia.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3167
3180
  continue;
3168
3181
  }
3169
3182
  t.push({
@@ -3172,11 +3185,11 @@ BEGIN
3172
3185
  });
3173
3186
  }
3174
3187
  return t;
3175
- }, oa = (e) => e`
3188
+ }, ca = (e) => e`
3176
3189
  SELECT ${e("id")}
3177
3190
  FROM ${e("_voltro_migration_plans")}
3178
3191
  WHERE ${e("source")} = 'file'
3179
- `.pipe(S.map((e) => e.map((e) => e.id)), S.catchAll(() => S.succeed([]))), sa = class extends Error {
3192
+ `.pipe(S.map((e) => e.map((e) => e.id)), S.catchAll(() => S.succeed([]))), la = class extends Error {
3180
3193
  migrationId;
3181
3194
  file;
3182
3195
  cause;
@@ -3184,7 +3197,7 @@ BEGIN
3184
3197
  constructor(e, t, n) {
3185
3198
  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";
3186
3199
  }
3187
- }, ca = (e, t, n, r) => S.gen(function* () {
3200
+ }, ua = (e, t, n, r) => S.gen(function* () {
3188
3201
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3189
3202
  sql: e,
3190
3203
  log: {
@@ -3205,7 +3218,7 @@ BEGIN
3205
3218
  });
3206
3219
  let c = Date.now() - i;
3207
3220
  !S.isEffect(s) && c < 2 && (yield* S.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(S.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3208
- let l = yield* W(e, a);
3221
+ let l = yield* U(e, a);
3209
3222
  return yield* e`
3210
3223
  INSERT INTO ${e("_voltro_migration_plans")}
3211
3224
  (${e("id")}, ${e("fingerprint")}, ${e("operations")},
@@ -3218,10 +3231,10 @@ BEGIN
3218
3231
  }])},
3219
3232
  ${r}, ${n}, ${"file"},
3220
3233
  ${c}, ${l}, ${t.migration.description})
3221
- `.pipe(S.mapError((e) => new sa(t.migration.id, t.file, e))), { durationMs: c };
3222
- }), la = (e, t) => S.gen(function* () {
3234
+ `.pipe(S.mapError((e) => new la(t.migration.id, t.file, e))), { durationMs: c };
3235
+ }), da = (e, t) => S.gen(function* () {
3223
3236
  let n = yield* S.tryPromise({
3224
- try: () => ia(te(t, "migrations")),
3237
+ try: () => oa(ne(t, "migrations")),
3225
3238
  catch: (e) => e
3226
3239
  });
3227
3240
  if (n.length === 0) return {
@@ -3229,20 +3242,20 @@ BEGIN
3229
3242
  skipped: []
3230
3243
  };
3231
3244
  let r = yield* S.tryPromise({
3232
- try: () => aa(n),
3245
+ try: () => sa(n),
3233
3246
  catch: (e) => e
3234
3247
  });
3235
3248
  if (r.length === 0) return {
3236
3249
  pending: [],
3237
3250
  skipped: []
3238
3251
  };
3239
- let i = new Set(yield* oa(e));
3252
+ let i = new Set(yield* ca(e));
3240
3253
  return {
3241
3254
  pending: r.filter((e) => !i.has(e.migration.id)),
3242
3255
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3243
3256
  };
3244
- }), ua = (e, t) => la(e, t).pipe(S.map((e) => e.pending.map((e) => e.migration.id))), da = (e, t) => S.gen(function* () {
3245
- let { pending: n, skipped: r } = yield* la(e, t.projectRoot);
3257
+ }), fa = (e, t) => da(e, t).pipe(S.map((e) => e.pending.map((e) => e.migration.id))), pa = (e, t) => S.gen(function* () {
3258
+ let { pending: n, skipped: r } = yield* da(e, t.projectRoot);
3246
3259
  if (n.length === 0) return {
3247
3260
  applied: [],
3248
3261
  skipped: r
@@ -3256,7 +3269,7 @@ BEGIN
3256
3269
  id: r.migration.id,
3257
3270
  file: r.file
3258
3271
  }));
3259
- let { durationMs: n } = yield* ca(e, r, t.env, t.appliedBy);
3272
+ let { durationMs: n } = yield* ua(e, r, t.env, t.appliedBy);
3260
3273
  i.push({
3261
3274
  id: r.migration.id,
3262
3275
  durationMs: n
@@ -3273,18 +3286,18 @@ BEGIN
3273
3286
  applied: i,
3274
3287
  skipped: r
3275
3288
  };
3276
- }), fa = (e, t) => e`
3289
+ }), ma = (e, t) => e`
3277
3290
  SELECT ${e("id")}
3278
3291
  FROM ${e("_voltro_migration_plans")}
3279
3292
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3280
3293
  LIMIT 1
3281
- `, pa = (e, t) => S.gen(function* () {
3282
- if (!(yield* fa(e, t.id))[0]) return yield* S.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3294
+ `, ha = (e, t) => S.gen(function* () {
3295
+ if (!(yield* ma(e, t.id))[0]) return yield* S.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3283
3296
  let n = yield* S.tryPromise({
3284
- try: () => ia(te(t.projectRoot, "migrations")),
3297
+ try: () => oa(ne(t.projectRoot, "migrations")),
3285
3298
  catch: (e) => e
3286
3299
  }), r = (yield* S.tryPromise({
3287
- try: () => aa(n),
3300
+ try: () => sa(n),
3288
3301
  catch: (e) => e
3289
3302
  })).find((e) => e.migration.id === t.id);
3290
3303
  if (!r) return yield* S.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
@@ -3317,8 +3330,8 @@ BEGIN
3317
3330
  } finally {
3318
3331
  yield* O(e, { schema: t.lockSchema }).pipe(S.orDie);
3319
3332
  }
3320
- }), ma = (e) => S.gen(function* () {
3321
- let t = yield* E.SqlClient, n = yield* t`
3333
+ }), ga = (e) => S.gen(function* () {
3334
+ let t = yield* T.SqlClient, n = yield* t`
3322
3335
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3323
3336
  WHERE source = 'auto-diff'
3324
3337
  AND squashedAt IS NULL
@@ -3362,7 +3375,7 @@ BEGIN
3362
3375
  snapshotFingerprint: e.fingerprint,
3363
3376
  snapshotId: i
3364
3377
  };
3365
- }), ha = { safe: !0 }, ga = (e) => {
3378
+ }), _a = { safe: !0 }, va = (e) => {
3366
3379
  switch (e.kind) {
3367
3380
  case "drop-column": return {
3368
3381
  safe: !1,
@@ -3389,7 +3402,7 @@ BEGIN
3389
3402
  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`,
3390
3403
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3391
3404
  };
3392
- case "alter-column-nullability": return e.toNullable ? ha : {
3405
+ case "alter-column-nullability": return e.toNullable ? _a : {
3393
3406
  safe: !1,
3394
3407
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3395
3408
  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)`
@@ -3419,12 +3432,12 @@ BEGIN
3419
3432
  case "drop-unique":
3420
3433
  case "drop-unique-composite":
3421
3434
  case "drop-foreign-key":
3422
- case "drop-check": return ha;
3435
+ case "drop-check": return _a;
3423
3436
  }
3424
- }, _a = (e) => {
3437
+ }, ya = (e) => {
3425
3438
  let t = [];
3426
3439
  for (let n of e) {
3427
- let e = ga(n.op);
3440
+ let e = va(n.op);
3428
3441
  e.safe || t.push({
3429
3442
  op: n,
3430
3443
  reason: e.reason,
@@ -3432,7 +3445,7 @@ BEGIN
3432
3445
  });
3433
3446
  }
3434
3447
  return t;
3435
- }, va = (e) => {
3448
+ }, ba = (e) => {
3436
3449
  if (!e.enabled || e.unsafeCount === 0) return {
3437
3450
  refuse: !1,
3438
3451
  warnForced: !1,
@@ -3448,18 +3461,18 @@ BEGIN
3448
3461
  warnForced: !1,
3449
3462
  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.`
3450
3463
  };
3451
- }, ya = (e) => {
3464
+ }, xa = (e) => {
3452
3465
  let t = e.table;
3453
3466
  if (typeof t == "string") return t;
3454
3467
  let n = e.from;
3455
3468
  return typeof n == "string" ? n : void 0;
3456
- }, ba = (e) => ({
3469
+ }, Sa = (e) => ({
3457
3470
  kind: e.op.kind,
3458
- table: ya(e.op),
3471
+ table: xa(e.op),
3459
3472
  classification: e.classification,
3460
3473
  reason: e.reason,
3461
3474
  blockedFix: e.blocked?.fix
3462
- }), xa = (e) => e.operations.map(ba), Sa = async (e) => {
3475
+ }), Ca = (e) => e.operations.map(Sa), wa = async (e) => {
3463
3476
  let t = e.log ?? (() => {}), n = {
3464
3477
  branchId: e.branchId,
3465
3478
  mechanism: e.mechanism,
@@ -3478,10 +3491,10 @@ BEGIN
3478
3491
  applied: !1,
3479
3492
  converged: !1,
3480
3493
  residual: r,
3481
- infidelity: xa(o)
3494
+ infidelity: Ca(o)
3482
3495
  };
3483
3496
  else {
3484
- let i = await e.plan(), o = xa(i), s = o.filter((e) => e.classification === "lossy"), c = Zi(i), l = c.operations.filter((e) => e.blocked !== void 0).map(ba);
3497
+ let i = await e.plan(), o = Ca(i), s = o.filter((e) => e.classification === "lossy"), c = $i(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Sa);
3485
3498
  if (l.length > 0) a = {
3486
3499
  ...n,
3487
3500
  outcome: "blocked",
@@ -3506,7 +3519,7 @@ BEGIN
3506
3519
  };
3507
3520
  else {
3508
3521
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3509
- let i = xa(await e.replan());
3522
+ let i = Ca(await e.replan());
3510
3523
  a = {
3511
3524
  ...n,
3512
3525
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3544,7 +3557,7 @@ BEGIN
3544
3557
  ...a,
3545
3558
  tornDown: o
3546
3559
  };
3547
- }, Ca = (e) => {
3560
+ }, Ta = (e) => {
3548
3561
  switch (e.outcome) {
3549
3562
  case "clean": return 0;
3550
3563
  case "lossy": return 2;
@@ -3553,22 +3566,22 @@ BEGIN
3553
3566
  case "infidelity": return 1;
3554
3567
  case "failed": return 1;
3555
3568
  }
3556
- }, wa = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Ta = (e) => {
3569
+ }, Ea = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Da = (e) => {
3557
3570
  let t = [];
3558
3571
  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"}`);
3559
3572
  else if (e.outcome === "infidelity") {
3560
3573
  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:");
3561
- for (let n of e.infidelity) t.push(wa(n));
3574
+ for (let n of e.infidelity) t.push(Ea(n));
3562
3575
  } else {
3563
3576
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3564
- for (let n of e.operations) t.push(wa(n));
3565
- if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(wa(n));
3577
+ for (let n of e.operations) t.push(Ea(n));
3578
+ 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(Ea(n));
3566
3579
  }
3567
3580
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3568
- }, Ea = (e, ...t) => ({
3581
+ }, Oa = (e, ...t) => ({
3569
3582
  _tag: "RawSqlFragment",
3570
3583
  strings: [...e],
3571
3584
  values: [...t]
3572
- }), Da = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3585
+ }), ka = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3573
3586
  //#endregion
3574
- export { A as DEFAULT_CDC_CHANNEL, m as FILE_MIGRATION_PATTERN, sa as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, de as VOLTRO_MIGRATION_LOCK_KEY, je as acquireMigrationLock, W as appliedAtValue, It as applyNamespacedSchema, Bi as applyPlan, Et as applySchema, va as assessRollingDeployGate, Ca as branchRehearsalExitCode, Vn as chunkTables, ga as classifyRollingDeploySafety, I as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, N as defaultJsonClause, ta as describeOutcome, Yi as destructiveScope, Xt as detectReactiveTriggerDrift, ni as emitAddIndexMysql, Lr as emitCreateTableMysql, _r as emitDropColumnDdl, vr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, er as engineFromVersion, Wt as fingerprintSchema, _e as fnv1a64, Ta as formatBranchRehearsal, Zt as formatReactiveTriggerDrift, Ji as ignoreTablesFromEnv, $n as introspectSchema, ar as isAlreadySatisfied, g as isFileMigration, Da as isRawSqlFragment, Ot as isReRunSafeDdl, Fn as mapPgType, o as migration, ve as migrationLockKeyForSchema, ye as migrationLockNameForSchema, Qr as mysqlIndexPrefixFor, Ye as notifyFunctionName, P as numericIdSql, Pn as parseEnumCheck, ua as pendingFileMigrationIds, Nn as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Ui as recordUpToDate, Sa as rehearseMigrationOnBranch, ba as rehearsedOperation, O as releaseMigrationLock, Fr as renderColumnMysql, Ar as renderColumnPg, pe as resolveMigrationLockSchema, U as resolveMysqlEngine, pa as rollbackFileBasedMigration, _a as rollingDeployUnsafeOps, da as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, ea as runPlannedMigrations, Gt as shortFingerprint, Kt as snapshotColumn, Ea as sql, M as sqlType, ma as squashMigrationPlans, Zi as unblockLossy, Me as withMigrationLock };
3587
+ export { A as DEFAULT_CDC_CHANNEL, m as FILE_MIGRATION_PATTERN, la as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, fe as VOLTRO_MIGRATION_LOCK_KEY, je as acquireMigrationLock, U as appliedAtValue, Lt as applyNamespacedSchema, Hi as applyPlan, Dt as applySchema, ba as assessRollingDeployGate, Ta as branchRehearsalExitCode, Hn as chunkTables, va as classifyRollingDeploySafety, I as declaredSnapshot, et as defaultArrayClause, $e as defaultClause, N as defaultJsonClause, ra as describeOutcome, Zi as destructiveScope, Zt as detectReactiveTriggerDrift, ii as emitAddIndexMysql, zr as emitCreateTableMysql, br as emitDropColumnDdl, xr as emitDropColumnDdlMysql, Et as emitFrameworkBootstrapSql, wt as emitNamespaceProvisionDdl, Tt as emitNamespacedSchemaSql, Ct as emitSchemaSql, nr as engineFromVersion, Gt as fingerprintSchema, ve as fnv1a64, Da as formatBranchRehearsal, Qt as formatReactiveTriggerDrift, Xi as ignoreTablesFromEnv, tr as introspectSchema, cr as isAlreadySatisfied, g as isFileMigration, ka as isRawSqlFragment, kt as isReRunSafeDdl, In as mapPgType, o as migration, ye as migrationLockKeyForSchema, D as migrationLockNameForSchema, ei as mysqlIndexPrefixFor, Ye as notifyFunctionName, P as numericIdSql, Fn as parseEnumCheck, fa as pendingFileMigrationIds, Pn as planMigrations, Rt as provisionTenantNamespace, Je as reactiveTriggerName, mt as reactiveTriggerRepairSql, Gi as recordUpToDate, wa as rehearseMigrationOnBranch, Sa as rehearsedOperation, O as releaseMigrationLock, Lr as renderColumnMysql, Mr as renderColumnPg, me as resolveMigrationLockSchema, ir as resolveMysqlEngine, ha as rollbackFileBasedMigration, ya as rollingDeployUnsafeOps, pa as runFileBasedMigrations, zt as runFrameworkBootstrap, It as runMigrate, na as runPlannedMigrations, Kt as shortFingerprint, qt as snapshotColumn, Oa as sql, M as sqlType, ga as squashMigrationPlans, $i as unblockLossy, Me as withMigrationLock };