@voltro/database 0.69.0 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sql.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { C as e, Jt as t, Ot as n, St as r, a as i, an as a, at as o, b as s, c, ct as l, d as u, f as d, h as f, i as p, it as m, lt as h, m as g, o as _, on as v, qt as y, rt as b, s as x, u as S, y as C } from "./frameworkLiveTables-CWbTSnjk.js";
2
- import { Effect as w, Exit as ee, Schedule as te, Scope as ne } from "effect";
3
- import { createHash as re } from "node:crypto";
4
- import { createLogger as ie } from "@voltro/logger";
5
- import { SqlClient as T } from "@effect/sql";
6
- import { promises as ae } from "node:fs";
7
- import { join as oe } from "node:path";
8
- import { pathToFileURL as se } from "node:url";
2
+ import { Effect as w, Exit as T, Schedule as ee, Scope as te } from "effect";
3
+ import { createHash as ne } from "node:crypto";
4
+ import { createLogger as re } from "@voltro/logger";
5
+ import { SqlClient as E } from "@effect/sql";
6
+ import { promises as ie } from "node:fs";
7
+ import { join as ae } from "node:path";
8
+ import { pathToFileURL as oe } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var ce = (e, t, n, r = 400) => {
10
+ var se = (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 ce = (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 = le(o("code"));
41
+ let c = ce(o("code"));
42
42
  return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
- }, le = (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, ue = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, de = (e) => e.replace(/"/g, "`"), fe = (e) => typeof e == "string" ? e : e.name ?? String(e), pe = (e, t) => `_ua_${t}_${e}`.slice(0, 64), me = (e, t) => {
44
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(ue)) return e;
43
+ }, ce = (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, le = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, ue = (e) => e.replace(/"/g, "`"), de = (e) => typeof e == "string" ? e : e.name ?? String(e), fe = (e, t) => `_ua_${t}_${e}`.slice(0, 64), pe = (e, t) => {
44
+ if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(le)) return e;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!ue(t)) {
47
+ if (!le(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = de(t.where), o = [];
51
+ let a = ue(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = fe(r);
53
+ let i = de(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 = pe(t.name, i);
55
+ let s = fe(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,82 +75,82 @@ var ce = (e, t, n, r = 400) => {
75
75
  appliedIndexes: r,
76
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
77
77
  };
78
- }, E = (e, t) => `${e}::${t}`, he = (e, t) => {
78
+ }, D = (e, t) => `${e}::${t}`, me = (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(E(e, t.column)) : r.has(t.target) || a(t.target);
82
+ for (let t of o) n.has(t.target) ? i.add(D(e, t.column)) : r.has(t.target) || a(t.target);
83
83
  n.delete(e), r.add(e);
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, D = (e, t) => e.executeUnprepared(t, [], void 0), ge = 6322741009312437n, _e = (e) => {
87
+ }, O = (e, t) => e.executeUnprepared(t, [], void 0), he = 6322741009312437n, ge = (e) => {
88
88
  let t = e?.trim();
89
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
90
- }, ve = (e) => e?.schema === void 0 ? _e(process.env.DB_SCHEMA) : _e(e.schema), ye = 14695981039346656037n, be = 1099511628211n, xe = 18446744073709551615n, Se = (e) => {
91
- let t = ye;
92
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * be & xe;
90
+ }, _e = (e) => e?.schema === void 0 ? ge(process.env.DB_SCHEMA) : ge(e.schema), ve = 14695981039346656037n, ye = 1099511628211n, be = 18446744073709551615n, xe = (e) => {
91
+ let t = ve;
92
+ for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * ye & be;
93
93
  return t;
94
+ }, Se = (e) => {
95
+ let t = ge(e);
96
+ return t === void 0 ? he : xe(`voltro_migration_lock:${t}`) & 9223372036854775807n;
94
97
  }, Ce = (e) => {
95
- let t = _e(e);
96
- return t === void 0 ? ge : Se(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
- }, we = (e) => {
98
- let t = `voltro_migration_${ge.toString(36)}`, n = _e(e);
98
+ let t = `voltro_migration_${he.toString(36)}`, n = ge(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${(Se(`voltro_migration_lock:${n}`) & xe).toString(16)}`;
102
- }, Te = 250, Ee = () => {
101
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(xe(`voltro_migration_lock:${n}`) & be).toString(16)}`;
102
+ }, we = 250, Te = () => {
103
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
104
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
105
- }, De = (e, t) => w.gen(function* () {
106
- let n = Ee(), r = Date.now();
105
+ }, Ee = (e, t) => w.gen(function* () {
106
+ let n = Te(), r = Date.now();
107
107
  for (;;) {
108
- if ((yield* D(e, `SELECT pg_try_advisory_lock(${t.toString()}::bigint) AS got`))[0]?.got) return;
109
- Date.now() - r >= n && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(n / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* w.sleep(`${Te} millis`);
108
+ if ((yield* O(e, `SELECT pg_try_advisory_lock(${t.toString()}::bigint) AS got`))[0]?.got) return;
109
+ Date.now() - r >= n && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(n / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* w.sleep(`${we} millis`);
110
110
  }
111
- }), Oe = (e, t) => w.asVoid(D(e, `SELECT pg_advisory_unlock(${t.toString()}::bigint)`)), ke = 30, Ae = (e, t) => w.gen(function* () {
112
- (yield* D(e, `SELECT GET_LOCK('${t}', ${String(ke)}) AS got`))[0]?.got !== 1 && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${ke}s (another migration is in progress, or a prior one left it held).`)));
113
- }), je = (e, t) => w.asVoid(D(e, `SELECT RELEASE_LOCK('${t}')`)), Me = 3e4, Ne = (e, t) => w.gen(function* () {
114
- let n = yield* D(e, `
111
+ }), De = (e, t) => w.asVoid(O(e, `SELECT pg_advisory_unlock(${t.toString()}::bigint)`)), Oe = 30, ke = (e, t) => w.gen(function* () {
112
+ (yield* O(e, `SELECT GET_LOCK('${t}', ${String(Oe)}) AS got`))[0]?.got !== 1 && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${Oe}s (another migration is in progress, or a prior one left it held).`)));
113
+ }), Ae = (e, t) => w.asVoid(O(e, `SELECT RELEASE_LOCK('${t}')`)), je = 3e4, Me = (e, t) => w.gen(function* () {
114
+ let n = yield* O(e, `
115
115
  DECLARE @res int;
116
116
  EXEC @res = sp_getapplock @Resource = '${t}', @LockMode = 'Exclusive',
117
- @LockOwner = 'Session', @LockTimeout = ${String(Me)};
117
+ @LockOwner = 'Session', @LockTimeout = ${String(je)};
118
118
  SELECT @res AS res`);
119
119
  (n[0]?.res ?? -999) < 0 && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' (sp_getapplock returned ${n[0]?.res ?? "no row"}; another migration is in progress).`)));
120
- }), Pe = (e, t) => w.asVoid(D(e, `EXEC sp_releaseapplock @Resource = '${t}', @LockOwner = 'Session'`)), Fe = w.void, Ie = (e, t) => w.gen(function* () {
121
- let n = ve(t), r = we(n), i = Ce(n);
120
+ }), Ne = (e, t) => w.asVoid(O(e, `EXEC sp_releaseapplock @Resource = '${t}', @LockOwner = 'Session'`)), Pe = w.void, Fe = (e, t) => w.gen(function* () {
121
+ let n = _e(t), r = Ce(n), i = Se(n);
122
122
  if (!e.onDialectOrElse({
123
123
  mysql: () => !0,
124
124
  mssql: () => !0,
125
125
  sqlite: () => !1,
126
126
  orElse: () => !0
127
- })) return { release: Fe };
128
- let a = yield* ne.make(), o = yield* w.provideService(e.reserve, ne.Scope, a), s = ne.close(a, ee.void);
127
+ })) return { release: Pe };
128
+ let a = yield* te.make(), o = yield* w.provideService(e.reserve, te.Scope, a), s = te.close(a, T.void);
129
129
  return yield* e.onDialectOrElse({
130
+ mysql: () => ke(o, r),
131
+ mssql: () => Me(o, r),
132
+ sqlite: () => Pe,
133
+ orElse: () => Ee(o, i)
134
+ }).pipe(w.onExit((e) => T.isSuccess(e) ? w.void : s)), { release: e.onDialectOrElse({
130
135
  mysql: () => Ae(o, r),
131
136
  mssql: () => Ne(o, r),
132
- sqlite: () => Fe,
137
+ sqlite: () => Pe,
133
138
  orElse: () => De(o, i)
134
- }).pipe(w.onExit((e) => ee.isSuccess(e) ? w.void : s)), { release: e.onDialectOrElse({
135
- mysql: () => je(o, r),
136
- mssql: () => Pe(o, r),
137
- sqlite: () => Fe,
138
- orElse: () => Oe(o, i)
139
139
  }).pipe(w.ensuring(s)) };
140
- }), Le = (e, t, n) => w.acquireUseRelease(Ie(e, n), () => t, (e) => e.release.pipe(w.orDie)), Re = (e) => e.onDialectOrElse({
140
+ }), Ie = (e, t, n) => w.acquireUseRelease(Fe(e, n), () => t, (e) => e.release.pipe(w.orDie)), Le = (e) => e.onDialectOrElse({
141
141
  pg: () => "postgres",
142
142
  mysql: () => "mysql",
143
143
  mssql: () => "mssql",
144
144
  sqlite: () => "sqlite",
145
145
  orElse: () => "sqlite"
146
- }), ze = {
146
+ }), Re = {
147
147
  postgres: "plan-transactional",
148
148
  mssql: "plan-transactional",
149
149
  mysql: "per-operation",
150
150
  mariadb: "per-operation",
151
151
  sqlite: "per-operation",
152
152
  turso: "per-operation"
153
- }, Be = (e) => ze[e], O = "_voltro_migration_ops", Ve = l(O, {
153
+ }, ze = (e) => Re[e], k = "_voltro_migration_ops", Be = l(k, {
154
154
  id: y({ prefix: "mop" }),
155
155
  runId: a(),
156
156
  planFingerprint: a(),
@@ -163,7 +163,7 @@ var ce = (e, t, n, r = 400) => {
163
163
  appliedAt: v().nullable(),
164
164
  durationMs: t().nullable(),
165
165
  createdAt: v().default("now")
166
- }), He = (e) => {
166
+ }), Ve = (e) => {
167
167
  switch (e.kind) {
168
168
  case "create-table": return /* @__PURE__ */ new Set([
169
169
  `table:${e.table}`,
@@ -190,11 +190,11 @@ var ce = (e, t, n, r = 400) => {
190
190
  case "add-unique-composite":
191
191
  case "drop-unique-composite": return /* @__PURE__ */ new Set([`unique:${e.table}.${e.name}`]);
192
192
  }
193
- }, Ue = (e) => [...He(e)].join(" "), We = (e, t) => {
194
- let n = He(t);
195
- for (let t of He(e)) if (n.has(t)) return !0;
193
+ }, He = (e) => [...Ve(e)].join(" "), Ue = (e, t) => {
194
+ let n = Ve(t);
195
+ for (let t of Ve(e)) if (n.has(t)) return !0;
196
196
  return !1;
197
- }, Ge = (e, t) => e.operations.some((e) => We(e.op, t)), Ke = "__voltro_rebuild", qe = "__shadow", Je = "__old", Ye = /* @__PURE__ */ new Set([
197
+ }, We = (e, t) => e.operations.some((e) => Ue(e.op, t)), Ge = "__voltro_rebuild", Ke = "__shadow", qe = "__old", Je = /* @__PURE__ */ new Set([
198
198
  "add-unique",
199
199
  "drop-unique",
200
200
  "add-unique-composite",
@@ -206,21 +206,21 @@ var ce = (e, t, n, r = 400) => {
206
206
  "alter-column-nullability",
207
207
  "alter-column-type",
208
208
  "alter-column-default"
209
- ]), Xe = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ze = (e, t, n) => {
209
+ ]), Ye = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Xe = (e, t, n) => {
210
210
  let r = n === "sqlite" || n === "turso";
211
- return e.kind === "alter-column-type" && t === "online-required" || r && Ye.has(e.kind) ? "artefact-repair" : Xe.has(e.kind) ? "idempotent" : "probe-then-replay";
211
+ return e.kind === "alter-column-type" && t === "online-required" || r && Je.has(e.kind) ? "artefact-repair" : Ye.has(e.kind) ? "idempotent" : "probe-then-replay";
212
212
  };
213
- Object.keys(ze);
213
+ Object.keys(Re);
214
214
  //#endregion
215
215
  //#region src/migrations/reactiveTriggerName.ts
216
- var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "framework_changes" ? `${Qe}${e}` : `${Qe}${t}_${e}`, et = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, tt = "voltro:notify:v2", nt = (e, t) => {
216
+ var A = "framework_changes", Ze = "framework_changes_", Qe = (e, t) => t === "framework_changes" ? `${Ze}${e}` : `${Ze}${t}_${e}`, $e = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, et = "voltro:notify:v2", tt = (e, t) => {
217
217
  if (e.type === "text" && e.generatedAs === void 0) {
218
218
  if (e.maxLength !== void 0) return e.maxLength;
219
219
  if (t || e.hasDefault && e.defaultFactory === void 0 || e.oneOf !== void 0 && e.oneOf.length > 0) return 450;
220
220
  }
221
- }, rt = ie({ scope: "voltro:migrate" }), A = (e) => {
222
- rt.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
223
- }, j = (e, t) => {
221
+ }, nt = re({ scope: "voltro:migrate" }), j = (e) => {
222
+ nt.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
223
+ }, M = (e, t) => {
224
224
  let n = e.type;
225
225
  if (e.spatial) {
226
226
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -231,7 +231,7 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
231
231
  return e.rawDdl;
232
232
  }
233
233
  if (n === "array" && e.arrayElement) {
234
- if (t === "postgres") return `${j({
234
+ if (t === "postgres") return `${M({
235
235
  ...e,
236
236
  type: e.arrayElement,
237
237
  arrayElement: void 0
@@ -302,7 +302,7 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
302
302
  if (t === "mssql") switch (n) {
303
303
  case "id": return "NVARCHAR(64)";
304
304
  case "text": {
305
- let t = nt(e, !1);
305
+ let t = tt(e, !1);
306
306
  return t === void 0 ? "NVARCHAR(MAX)" : `NVARCHAR(${t})`;
307
307
  }
308
308
  case "integer": return "INT";
@@ -334,22 +334,22 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
334
334
  case "array": return "TEXT[]";
335
335
  case "interval": return "INTERVAL";
336
336
  }
337
- }, it = (e, t) => {
337
+ }, rt = (e, t) => {
338
338
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
339
339
  let n = e.defaultValue;
340
- return n === "now" ? m(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) ? at(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
341
- }, at = (e, t, n) => {
342
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return M(e, n);
343
- let r = j({
340
+ return n === "now" ? m(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) ? it(n, e, t) : typeof n == "object" && n ? N(n, t) : null;
341
+ }, it = (e, t, n) => {
342
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return N(e, n);
343
+ let r = M({
344
344
  ...t,
345
345
  type: t.arrayElement,
346
346
  arrayElement: void 0
347
347
  }, n);
348
348
  return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
349
- }, M = (e, t) => {
349
+ }, N = (e, t) => {
350
350
  let n = JSON.stringify(e).replace(/'/g, "''");
351
351
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CONVERT('${n}' USING utf8mb4))` : `DEFAULT '${n}'`;
352
- }, N = (e, t) => {
352
+ }, P = (e, t) => {
353
353
  switch (t) {
354
354
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
355
355
  case "mysql":
@@ -358,7 +358,7 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
358
358
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
359
359
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
360
360
  }
361
- }, P = (e, t) => {
361
+ }, F = (e, t) => {
362
362
  if (e === "restrict" && t === "mssql") return "NO ACTION";
363
363
  switch (e) {
364
364
  case "cascade": return "CASCADE";
@@ -366,42 +366,42 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
366
366
  case "setNull": return "SET NULL";
367
367
  case "noAction": return "NO ACTION";
368
368
  }
369
- }, ot = (e, t, n) => n === null ? o(e, t) : `${o(n, t)}.${o(e, t)}`, st = 191, ct = (e, t) => {
369
+ }, at = (e, t, n) => n === null ? o(e, t) : `${o(n, t)}.${o(e, t)}`, ot = 191, st = (e, t) => {
370
370
  if (!e || t !== "mysql" && t !== "mariadb") return !1;
371
- let n = j(e, t).toUpperCase();
371
+ let n = M(e, t).toUpperCase();
372
372
  return n.endsWith("TEXT") || n.endsWith("BLOB");
373
- }, lt = (e, t, n) => {
373
+ }, ct = (e, t, n) => {
374
374
  let r = o(e, n);
375
375
  if (n !== "mysql" && n !== "mariadb") return r;
376
376
  let i = t[e];
377
377
  if (!i) return r;
378
- let a = j(i, n).toUpperCase();
379
- return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${st})` : r;
380
- }, ut = (e, t) => {
378
+ let a = M(i, n).toUpperCase();
379
+ return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${ot})` : r;
380
+ }, lt = (e, t) => {
381
381
  if (!e.generatedAs) return null;
382
382
  let { expr: n, stored: r } = e.generatedAs;
383
- if (t === "postgres") return r || A("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
383
+ if (t === "postgres") return r || j("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
384
384
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
385
385
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
386
386
  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.");
387
387
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
388
- }, dt = (e, t, n, r, i = !1, a = !1) => {
389
- if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, n);
390
- let s = n === "mssql" ? nt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? j(t, n) : `NVARCHAR(${s})`, l = [o(e, n), c];
388
+ }, ut = (e, t, n, r, i = !1, a = !1) => {
389
+ if (t.type === "id" && t.idScheme?.kind === "numeric") return P(e, n);
390
+ let s = n === "mssql" ? tt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? M(t, n) : `NVARCHAR(${s})`, l = [o(e, n), c];
391
391
  t.type === "id" && !a && l.push("PRIMARY KEY");
392
- let u = ut(t, n);
392
+ let u = lt(t, n);
393
393
  if (u) l.push(u);
394
394
  else {
395
- t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !ct(t, n) && l.push("UNIQUE");
396
- let e = it(t, n);
395
+ t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !st(t, n) && l.push("UNIQUE");
396
+ let e = rt(t, n);
397
397
  e && l.push(e);
398
398
  }
399
399
  if (t.type === "reference" && t.references && !i && !b(n)) {
400
400
  let e = t.references();
401
401
  l.push(`REFERENCES ${o(e.tableName, n)} (${o(t.referenceColumn ?? "id", n)})`);
402
- let r = P(t.onDelete ?? "restrict", n);
402
+ let r = F(t.onDelete ?? "restrict", n);
403
403
  l.push(`ON DELETE ${r}`);
404
- let i = P(t.refOnUpdate ?? "noAction", n);
404
+ let i = F(t.refOnUpdate ?? "noAction", n);
405
405
  i !== "NO ACTION" && l.push(`ON UPDATE ${i}`);
406
406
  }
407
407
  if (t.oneOf && t.oneOf.length > 0) {
@@ -418,26 +418,26 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
418
418
  m(n) ? l.push(`CHECK (${t} IS NULL OR json_valid(${t}))`) : n === "mssql" && l.push(`CHECK (${t} IS NULL OR ISJSON(${t}) = 1)`);
419
419
  }
420
420
  return l.join(" ");
421
- }, ft = (e, t, n = null, r) => {
421
+ }, dt = (e, t, n = null, r) => {
422
422
  let i = /* @__PURE__ */ new Set();
423
423
  for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
424
424
  for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
425
425
  for (let [t, n] of Object.entries(e.fields)) n.unique && i.add(t);
426
426
  let a = e.appliedPrimaryKey ?? [];
427
427
  for (let e of a) i.add(e);
428
- let s = a.length > 0, c = Object.entries(e.fields).map(([e, n]) => ` ${dt(e, n, t, i, r?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((n) => {
429
- let r = n.fields.map((n) => lt(n, e.fields, t)).join(", ");
428
+ let s = a.length > 0, c = Object.entries(e.fields).map(([e, n]) => ` ${ut(e, n, t, i, r?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((n) => {
429
+ let r = n.fields.map((n) => ct(n, e.fields, t)).join(", ");
430
430
  return ` CONSTRAINT ${o(n.name, t)} UNIQUE (${r})`;
431
- }), u = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${o(e.name, t)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${a.map((n) => lt(n, e.fields, t)).join(", ")})`] : [], f = b(t) ? Object.entries(e.fields).flatMap(([i, a]) => {
431
+ }), u = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${o(e.name, t)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${a.map((n) => ct(n, e.fields, t)).join(", ")})`] : [], f = b(t) ? Object.entries(e.fields).flatMap(([i, a]) => {
432
432
  if (a.type !== "reference" || !a.references || (r?.has(i) ?? !1)) return [];
433
- let s = a.references(), c = P(a.onDelete ?? "restrict", t), l = P(a.refOnUpdate ?? "noAction", t);
434
- return [` CONSTRAINT ${o(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${o(i, t)}) REFERENCES ${ot(s.tableName, t, n)} (${o(a.referenceColumn ?? "id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
433
+ let s = a.references(), c = F(a.onDelete ?? "restrict", t), l = F(a.refOnUpdate ?? "noAction", t);
434
+ return [` CONSTRAINT ${o(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${o(i, t)}) REFERENCES ${at(s.tableName, t, n)} (${o(a.referenceColumn ?? "id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
435
435
  }) : [], p = [
436
436
  ...d,
437
437
  ...l,
438
438
  ...u,
439
439
  ...f
440
- ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = ot(e.tableName, t, n);
440
+ ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = at(e.tableName, t, n);
441
441
  if (t === "mssql") {
442
442
  let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${h} (\n${m}\n)`;
443
443
  return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
@@ -447,10 +447,10 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
447
447
  m,
448
448
  ");"
449
449
  ].join("\n");
450
- }, pt = (e, t, n) => {
450
+ }, ft = (e, t, n) => {
451
451
  let r = `${e}_${t.name}_fts`, i = (e) => o(e, n), a = t.columns.map(i).join(", "), s = t.columns.map((e) => `new.${i(e)}`).join(", "), c = [];
452
452
  return c.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${i(r)} USING fts5(${a}, row_id UNINDEXED, tokenize='porter');`), c.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ai`)} AFTER INSERT ON ${i(e)} BEGIN\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${s}, new.${i("id")});\nEND;`), c.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;`), c.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 (${s}, new.${i("id")});\nEND;`), c;
453
- }, mt = (e, t, n = null) => {
453
+ }, pt = (e, t, n = null) => {
454
454
  let r = [], i = /* @__PURE__ */ new Set(), a = (e) => e.join("\0"), s = (e, n, r, i) => {
455
455
  let a = {
456
456
  using: "",
@@ -462,21 +462,21 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
462
462
  using: " USING GIST",
463
463
  withSuffix: "",
464
464
  skip: !1
465
- } : (A(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
465
+ } : (j(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
466
466
  if (r === "gin") return t === "postgres" ? {
467
467
  using: " USING GIN",
468
468
  withSuffix: "",
469
469
  skip: !1
470
- } : t === "mysql" || t === "mariadb" ? (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
470
+ } : t === "mysql" || t === "mariadb" ? (j(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
471
471
  using: "",
472
472
  withSuffix: "",
473
473
  skip: !0
474
- }) : (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
474
+ }) : (j(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
475
475
  if (r === "brin") return t === "postgres" ? {
476
476
  using: " USING BRIN",
477
477
  withSuffix: "",
478
478
  skip: !1
479
- } : (A(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
479
+ } : (j(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
480
480
  if (r === "hnsw") {
481
481
  if (t === "postgres") {
482
482
  let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? h(i?.hnsw?.distance);
@@ -487,7 +487,7 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
487
487
  skip: !1
488
488
  };
489
489
  }
490
- return A(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
490
+ return j(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
491
491
  using: "",
492
492
  withSuffix: "",
493
493
  skip: !0
@@ -496,7 +496,7 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
496
496
  return a;
497
497
  }, c = (n, r) => {
498
498
  let i = n.map((n) => {
499
- if (typeof n == "string") return lt(n, e.fields, t);
499
+ if (typeof n == "string") return ct(n, e.fields, t);
500
500
  if ("jsonPath" in n) {
501
501
  let { column: e, path: r, numeric: i } = n.jsonPath;
502
502
  return `(${C(e, r, t, { numeric: i })})`;
@@ -507,11 +507,11 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
507
507
  }, l = (e, r, i, a, l, u = "", d = !1) => {
508
508
  let f = s(e, r, a, l);
509
509
  if (f.skip) return "";
510
- let p = c(i, f.opclass), m = `${f.withSuffix}${u}`, h = ot(r, t, n), g = d ? "UNIQUE " : "";
510
+ let p = c(i, f.opclass), m = `${f.withSuffix}${u}`, h = at(r, t, n), g = d ? "UNIQUE " : "";
511
511
  return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${o(e, t)} ON ${h}${f.using} (${p})${m};` : t === "mysql" ? `CREATE ${g}INDEX ${o(e, t)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${o(e, t)} ON ${h}${f.using} (${p})${m};`;
512
512
  };
513
513
  if (t === "mysql" || t === "mariadb") for (let [n, i] of Object.entries(e.fields)) {
514
- if (!i.unique || i.type === "id" || !ct(i, t)) continue;
514
+ if (!i.unique || i.type === "id" || !st(i, t)) continue;
515
515
  let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
516
516
  a && r.push(a);
517
517
  }
@@ -525,15 +525,15 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
525
525
  let i = n.columns.map((e) => o(e, t)).join(", ");
526
526
  r.push(`CREATE FULLTEXT INDEX ${o(n.name, t)} ON ${o(e.tableName, t)} (${i});`);
527
527
  } 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.`);
528
- else t === "sqlite" ? r.push(...pt(e.tableName, n, t)) : A(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
528
+ else t === "sqlite" ? r.push(...ft(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).`);
529
529
  for (let n of e.appliedIndexes) {
530
530
  if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
531
- A(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
531
+ 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(...).`);
532
532
  continue;
533
533
  }
534
534
  if (n.unique && n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${n.name}' on '${e.tableName}' cannot be expressed on ${t} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${t}, or move this table to postgres/sqlite/mssql.`);
535
535
  let o = "";
536
- n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? A(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : o = ` WHERE ${n.where}`);
536
+ n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? j(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : o = ` WHERE ${n.where}`);
537
537
  let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, o, n.unique === !0);
538
538
  s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && i.add(a(n.fields));
539
539
  }
@@ -543,17 +543,17 @@ var k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "fr
543
543
  r.push(l(o, e.tableName, [t])), i.add(a([t]));
544
544
  }
545
545
  return r.join("\n");
546
- }, ht = (e, t, n = k) => {
546
+ }, mt = (e, t, n = A) => {
547
547
  if (t !== "postgres") return [];
548
548
  let r = e.filter((e) => e.isReactive !== !1);
549
- return r.length === 0 ? [] : [gt(n), ...r.map((e) => vt(e, n))];
550
- }, gt = (e) => `
551
- CREATE OR REPLACE FUNCTION ${et(e)}() RETURNS trigger AS $$
549
+ return r.length === 0 ? [] : [ht(n), ...r.map((e) => _t(e, n))];
550
+ }, ht = (e) => `
551
+ CREATE OR REPLACE FUNCTION ${$e(e)}() RETURNS trigger AS $$
552
552
  DECLARE
553
553
  payload TEXT;
554
554
  pk JSONB;
555
555
  BEGIN
556
- -- ${tt}
556
+ -- ${et}
557
557
  payload := json_build_object(
558
558
  'table', TG_TABLE_NAME,
559
559
  -- The schema the write landed in. Under namespace isolation this is
@@ -607,22 +607,22 @@ BEGIN
607
607
  RETURN COALESCE(NEW, OLD);
608
608
  END;
609
609
  $$ LANGUAGE plpgsql;
610
- `.trim(), _t = (e, t) => {
611
- let n = $e(e.tableName, t);
610
+ `.trim(), gt = (e, t) => {
611
+ let n = Qe(e.tableName, t);
612
612
  return [
613
613
  `ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL`,
614
614
  `DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}"`,
615
- `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${et(t)}()`
615
+ `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${$e(t)}()`
616
616
  ];
617
- }, vt = (e, t) => _t(e, t).map((e) => `${e};`).join("\n"), yt = (e) => {
617
+ }, _t = (e, t) => gt(e, t).map((e) => `${e};`).join("\n"), vt = (e) => {
618
618
  if (e.dialect !== "postgres") return [];
619
619
  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));
620
- (i.length > 0 || e.functionOutdated === !0) && r.push(gt(t));
621
- for (let e of i) r.push(..._t(n.get(e), t));
622
- for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${$e(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
620
+ (i.length > 0 || e.functionOutdated === !0) && r.push(ht(t));
621
+ for (let e of i) r.push(...gt(n.get(e), t));
622
+ for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Qe(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
623
623
  return r;
624
- }, bt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), xt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), St = (e) => {
625
- let t = new Map(e.map((e) => [e.tableName, e])), n = he(e.map((e) => e.tableName), (e) => {
624
+ }, yt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), bt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), xt = (e) => {
625
+ let t = new Map(e.map((e) => [e.tableName, e])), n = me(e.map((e) => e.tableName), (e) => {
626
626
  let n = t.get(e);
627
627
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
628
628
  if (n.type !== "reference" || !n.references) return [];
@@ -633,7 +633,7 @@ $$ LANGUAGE plpgsql;
633
633
  }] : [];
634
634
  }) : [];
635
635
  }), r = [];
636
- 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({
636
+ 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({
637
637
  table: t.tableName,
638
638
  column: e,
639
639
  targetTable: i.references().tableName,
@@ -645,7 +645,7 @@ $$ LANGUAGE plpgsql;
645
645
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
646
646
  a.add(e.tableName);
647
647
  for (let [r, i] of Object.entries(e.fields)) {
648
- if (i.type !== "reference" || !i.references || n.has(E(e.tableName, r))) continue;
648
+ if (i.type !== "reference" || !i.references || n.has(D(e.tableName, r))) continue;
649
649
  let a = i.references();
650
650
  if (a.tableName === e.tableName) continue;
651
651
  let o = t.get(a.tableName);
@@ -659,8 +659,8 @@ $$ LANGUAGE plpgsql;
659
659
  sorted: o,
660
660
  cyclic: r
661
661
  };
662
- }, Ct = (e, t, n = null) => {
663
- let r = (e) => n ? `${o(n, t)}.${o(e, t)}` : o(e, t), i = `${e.table}_${e.column}_fkey`, a = P(e.onDelete, t), s = P(e.onUpdate, t), c = ` ON DELETE ${a}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${o(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${o(e.column, t)}) REFERENCES ${r(e.targetTable)} (${o(e.targetColumn, t)})${c}`;
662
+ }, St = (e, t, n = null) => {
663
+ let r = (e) => n ? `${o(n, t)}.${o(e, t)}` : o(e, t), i = `${e.table}_${e.column}_fkey`, a = F(e.onDelete, t), s = F(e.onUpdate, t), c = ` ON DELETE ${a}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${o(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${o(e.column, t)}) REFERENCES ${r(e.targetTable)} (${o(e.targetColumn, t)})${c}`;
664
664
  switch (t) {
665
665
  case "postgres": return [
666
666
  "DO $$ BEGIN",
@@ -674,7 +674,7 @@ $$ LANGUAGE plpgsql;
674
674
  case "mariadb": return `ALTER TABLE ${r(e.table)} ${l(!0)};`;
675
675
  default: return `ALTER TABLE ${r(e.table)} ${l(!1)};`;
676
676
  }
677
- }, wt = (e, t) => {
677
+ }, Ct = (e, t) => {
678
678
  let n = /* @__PURE__ */ new Map();
679
679
  if (m(t)) return n;
680
680
  for (let t of e) {
@@ -682,7 +682,7 @@ $$ LANGUAGE plpgsql;
682
682
  e.add(t.column), n.set(t.table, e);
683
683
  }
684
684
  return n;
685
- }, Tt = (e, t) => {
685
+ }, wt = (e, t) => {
686
686
  if (t !== "postgres") return "";
687
687
  let n = /* @__PURE__ */ new Map();
688
688
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -698,7 +698,7 @@ $$ LANGUAGE plpgsql;
698
698
  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 $$;`);
699
699
  }
700
700
  return r.join("\n\n");
701
- }, Et = (e, t) => {
701
+ }, Tt = (e, t) => {
702
702
  if (t !== "postgres") return "";
703
703
  let r = /* @__PURE__ */ new Set();
704
704
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && r.add(e.enumName);
@@ -712,30 +712,30 @@ BEGIN
712
712
  SELECT oid INTO type_oid FROM pg_type WHERE typname = '${n}';\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', '${n}', '${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 $$;`);
713
713
  }
714
714
  return i.join("\n\n");
715
- }, Dt = (e) => {
715
+ }, Et = (e) => {
716
716
  let t = [], n = [];
717
717
  for (let r of e) s(r) ? n.push(r) : t.push(r);
718
718
  return {
719
719
  tables: t,
720
720
  views: n
721
721
  };
722
- }, Ot = (t, n, r = k) => {
723
- let { tables: i, views: a } = Dt(t), { sorted: o, cyclic: s } = St(i.map((e) => me(e, n))), c = wt(s, n), l = [];
724
- n === "postgres" && bt(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && xt(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
725
- let u = Et(o, n);
722
+ }, Dt = (t, n, r = A) => {
723
+ let { tables: i, views: a } = Et(t), { sorted: o, cyclic: s } = xt(i.map((e) => pe(e, n))), c = Ct(s, n), l = [];
724
+ n === "postgres" && yt(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && bt(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
725
+ let u = Tt(o, n);
726
726
  u && l.push(u);
727
- let d = Tt(o, n);
727
+ let d = wt(o, n);
728
728
  d && l.push(d);
729
- for (let e of o) l.push(ft(e, n, null, c.get(e.tableName)));
730
- if (!m(n)) for (let e of s) l.push(Ct(e, n));
729
+ for (let e of o) l.push(dt(e, n, null, c.get(e.tableName)));
730
+ if (!m(n)) for (let e of s) l.push(St(e, n));
731
731
  for (let e of o) {
732
- let t = mt(e, n);
732
+ let t = pt(e, n);
733
733
  t && l.push(t);
734
734
  }
735
- l.push(...ht(o, n, r));
735
+ l.push(...mt(o, n, r));
736
736
  for (let t of a) l.push(e(t, n));
737
737
  return l.join("\n\n") + "\n";
738
- }, kt = (e, t, n) => {
738
+ }, Ot = (e, t, n) => {
739
739
  let r = o(e, t);
740
740
  switch (t) {
741
741
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
@@ -745,62 +745,62 @@ BEGIN
745
745
  case "turso":
746
746
  case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
747
747
  }
748
- }, At = (e, t, n, r) => {
749
- let i = kt(n, t, r), a = o(n, t);
750
- if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Ot(e, t)}`;
751
- if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Ot(e, t)}`;
752
- let { sorted: s, cyclic: c } = St(e), l = wt(c, t), u = [i];
753
- for (let e of s) u.push(ft(e, t, n, l.get(e.tableName)));
754
- if (!m(t)) for (let e of c) u.push(Ct(e, t, n));
748
+ }, kt = (e, t, n, r) => {
749
+ let i = Ot(n, t, r), a = o(n, t);
750
+ if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Dt(e, t)}`;
751
+ if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Dt(e, t)}`;
752
+ let { sorted: s, cyclic: c } = xt(e), l = Ct(c, t), u = [i];
753
+ for (let e of s) u.push(dt(e, t, n, l.get(e.tableName)));
754
+ if (!m(t)) for (let e of c) u.push(St(e, t, n));
755
755
  for (let e of s) {
756
- let r = mt(e, t, n);
756
+ let r = pt(e, t, n);
757
757
  r && u.push(r);
758
758
  }
759
759
  return u.join("\n\n") + "\n";
760
- }, jt = (e, t, n = k) => {
761
- let { sorted: r, cyclic: i } = St(e), a = wt(i, t), o = [], s = Et(r, t);
760
+ }, At = (e, t, n = A) => {
761
+ let { sorted: r, cyclic: i } = xt(e), a = Ct(i, t), o = [], s = Tt(r, t);
762
762
  s && o.push(s);
763
- let c = Tt(r, t);
763
+ let c = wt(r, t);
764
764
  c && o.push(c);
765
- for (let e of r) o.push(ft(e, t, null, a.get(e.tableName)));
766
- for (let e of i) o.push(Ct(e, t));
767
- return o.push(...ht(r, t, n)), o.join("\n\n") + "\n";
768
- }, Mt = (e, t = "postgres", n = k, r = {}) => w.gen(function* () {
769
- let i = yield* T.SqlClient;
770
- yield* Le(i, zt(i, Ot(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
771
- }), Nt = (e, t) => {
765
+ for (let e of r) o.push(dt(e, t, null, a.get(e.tableName)));
766
+ for (let e of i) o.push(St(e, t));
767
+ return o.push(...mt(r, t, n)), o.join("\n\n") + "\n";
768
+ }, jt = (e, t = "postgres", n = A, r = {}) => w.gen(function* () {
769
+ let i = yield* E.SqlClient;
770
+ yield* Ie(i, Rt(i, Dt(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
771
+ }), Mt = (e, t) => {
772
772
  let n = t.cause ?? {};
773
773
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
774
- }, Pt = (e, t) => {
774
+ }, Nt = (e, t) => {
775
775
  let n = e.trimStart();
776
776
  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));
777
- }, Ft = () => {
777
+ }, Pt = () => {
778
778
  let e = Number(process.env.VOLTRO_MIGRATION_DDL_RETRIES);
779
779
  return Number.isInteger(e) && e >= 0 ? e : 4;
780
- }, It = (e) => ({
780
+ }, Ft = (e) => ({
781
781
  while: e,
782
- times: Ft(),
783
- schedule: te.jittered(te.exponential("50 millis"))
784
- }), Lt = class {
782
+ times: Pt(),
783
+ schedule: ee.jittered(ee.exponential("50 millis"))
784
+ }), It = class {
785
785
  statement;
786
786
  error;
787
787
  _tag = "DdlStatementFailed";
788
788
  constructor(e, t) {
789
789
  this.statement = e, this.error = t;
790
790
  }
791
- }, Rt = (e, t, n) => w.gen(function* () {
792
- let r = yield* T.SqlClient, i = n !== void 0 && Be(t) === "per-operation";
793
- for (let a of Bt(e)) {
794
- process.env.VOLTRO_MIGRATE_DEBUG === "1" && rt.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
795
- let e = r.unsafe(a).pipe(w.catchIf((e) => Nt(a, e), () => w.succeed([])), w.tapError((e) => w.sync(() => {
796
- rt.error(ce("migrate: statement failed", a, e, 200));
791
+ }, Lt = (e, t, n) => w.gen(function* () {
792
+ let r = yield* E.SqlClient, i = n !== void 0 && ze(t) === "per-operation";
793
+ for (let a of zt(e)) {
794
+ process.env.VOLTRO_MIGRATE_DEBUG === "1" && nt.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
795
+ let e = r.unsafe(a).pipe(w.catchIf((e) => Mt(a, e), () => w.succeed([])), w.tapError((e) => w.sync(() => {
796
+ nt.error(se("migrate: statement failed", a, e, 200));
797
797
  })));
798
- yield* (i && n !== void 0 && Pt(a, t) ? e.pipe(w.retry(It((e) => n(e) === "retry"))) : e).pipe(w.mapError((e) => new Lt(a, e)));
798
+ yield* (i && n !== void 0 && Nt(a, t) ? e.pipe(w.retry(Ft((e) => n(e) === "retry"))) : e).pipe(w.mapError((e) => new It(a, e)));
799
799
  }
800
- }), zt = (e, t, n, r) => {
801
- let i = n === "turso" ? Rt(t, n, r) : e.withTransaction(Rt(t, n, r)), a = (e) => e instanceof Lt ? e.error : e;
802
- return (r !== void 0 && Be(n) === "plan-transactional" ? i.pipe(w.retry(It((e) => r(a(e)) === "retry"))) : i).pipe(w.orDieWith((e) => e instanceof Lt ? Error(ce("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
803
- }, Bt = (e) => {
800
+ }), Rt = (e, t, n, r) => {
801
+ let i = n === "turso" ? Lt(t, n, r) : e.withTransaction(Lt(t, n, r)), a = (e) => e instanceof It ? e.error : e;
802
+ return (r !== void 0 && ze(n) === "plan-transactional" ? i.pipe(w.retry(Ft((e) => r(a(e)) === "retry"))) : i).pipe(w.orDieWith((e) => e instanceof It ? Error(se("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
803
+ }, zt = (e) => {
804
804
  let t = [], n = "", r = !1;
805
805
  for (let i = 0; i < e.length; i++) {
806
806
  if (e.slice(i, i + 2) === "$$") {
@@ -815,30 +815,78 @@ BEGIN
815
815
  }
816
816
  let i = n.trim();
817
817
  return i.length > 0 && t.push(i), t;
818
- }, Vt = async (e, t, n = "postgres", r = {}) => {
819
- await w.runPromise(Mt(e, n, void 0, r).pipe(w.provide(t)));
820
- }, Ht = (e, t, n = "postgres", r = {}) => w.gen(function* () {
821
- let i = At(e, n, t), a = yield* T.SqlClient;
822
- yield* Le(a, zt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
823
- }), Ut = async (e, t, n, r = "postgres", i = {}) => {
824
- await w.runPromise(Ht(e, t, r, i).pipe(w.provide(n))), await f({
818
+ }, Bt = async (e, t, n = "postgres", r = {}) => {
819
+ await w.runPromise(jt(e, n, void 0, r).pipe(w.provide(t)));
820
+ }, Vt = (e, t, n = "postgres", r = {}) => w.gen(function* () {
821
+ let i = kt(e, n, t), a = yield* E.SqlClient;
822
+ yield* Ie(a, Rt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
823
+ }), Ht = async (e, t, n, r = "postgres", i = {}) => {
824
+ await w.runPromise(Vt(e, t, r, i).pipe(w.provide(n))), await f({
825
825
  namespace: t,
826
826
  dialect: r
827
827
  });
828
- }, Wt = async (e, t, n = "postgres", r = {}) => {
828
+ }, Ut = async (e, t, n = "postgres", r = {}) => {
829
829
  await w.runPromise(w.gen(function* () {
830
- let t = jt(e, n), i = yield* T.SqlClient;
831
- yield* Le(i, zt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
830
+ let t = At(e, n), i = yield* E.SqlClient;
831
+ yield* Ie(i, Rt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
832
832
  }).pipe(w.provide(t)));
833
- }, Gt = /'(?:''|[^'])*'|"(?:""|[^"])*"|\[(?:\]\]|[^\]])*\]|`(?:``|[^`])*`|[A-Za-z_][A-Za-z_0-9$]*|\d+(?:\.\d+)?|::|<>|!=|<=|>=|\|\||[^\s]/g, Kt = (e) => {
833
+ }, I = (e) => {
834
+ if (typeof e != "object" || !e) return JSON.stringify(e);
835
+ if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
836
+ let t = e;
837
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
838
+ }, Wt = (e) => {
839
+ if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
840
+ let t = e.defaultValue;
841
+ if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
842
+ if (typeof t == "number") return String(t);
843
+ if (typeof t != "string") return I(t);
844
+ let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
845
+ if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
846
+ let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
847
+ if (o) try {
848
+ return I(JSON.parse(o[1]));
849
+ } catch {}
850
+ let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
851
+ if (s) try {
852
+ return I(JSON.parse(s[1]));
853
+ } catch {}
854
+ if (a.startsWith("{") || a.startsWith("[")) try {
855
+ return I(JSON.parse(a));
856
+ } catch {}
857
+ return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
858
+ }, Gt = (e) => {
859
+ let t = Wt(e);
860
+ return t === "1" || t === "true" ? "__BOOL_TRUE__" : t === "0" || t === "false" ? "__BOOL_FALSE__" : t;
861
+ }, Kt = (e) => typeof e.defaultValue == "string" && /^nextval\(.+::regclass\)$/i.test(e.defaultValue.trim()), qt = (e) => {
862
+ if (!e) return null;
863
+ let t = (e) => e === "restrict" ? "noAction" : e;
864
+ return {
865
+ table: e.table,
866
+ column: e.column,
867
+ onDelete: t(e.onDelete),
868
+ onUpdate: t(e.onUpdate)
869
+ };
870
+ }, Jt = (e, t, n) => {
871
+ if (t === "mssql") {
872
+ let t = tt(e, n);
873
+ if (t !== void 0) return t;
874
+ }
875
+ try {
876
+ let n = /^N?VARCHAR\((\d+)\)$/i.exec(M(e, t).trim());
877
+ return n ? Number(n[1]) : void 0;
878
+ } catch {
879
+ return;
880
+ }
881
+ }, Yt = /'(?:''|[^'])*'|"(?:""|[^"])*"|\[(?:\]\]|[^\]])*\]|`(?:``|[^`])*`|[A-Za-z_][A-Za-z_0-9$]*|\d+(?:\.\d+)?|::|<>|!=|<=|>=|\|\||[^\s]/g, Xt = (e) => {
834
882
  let t = 0;
835
- for (let n of e.matchAll(Gt)) if (n[0] === "(" && t++, n[0] === ")" && t--, t === 0 && n[0].toLowerCase() === "where") return e.slice(n.index + n[0].length).trim().replace(/;$/, "").trim();
836
- }, qt = (e) => {
883
+ for (let n of e.matchAll(Yt)) if (n[0] === "(" && t++, n[0] === ")" && t--, t === 0 && n[0].toLowerCase() === "where") return e.slice(n.index + n[0].length).trim().replace(/;$/, "").trim();
884
+ }, Zt = (e) => {
837
885
  if (e === void 0) return;
838
- let t = e.match(Gt) ?? [], n = "(?:'(?:''|[^'])*'(?:\\s*::\\s*text)?|[0-9]+)", r = RegExp(`^\\s*${n}(?:\\s*,\\s*${n})*\\s*$`, "i");
886
+ let t = e.match(Yt) ?? [], n = "(?:'(?:''|[^'])*'(?:\\s*::\\s*text)?|[0-9]+)", r = RegExp(`^\\s*${n}(?:\\s*,\\s*${n})*\\s*$`, "i");
839
887
  for (let e = 0; e < t.length - 5; e++) {
840
888
  let n = t[e + 4];
841
- t[e] === "=" && t[e + 1]?.toLowerCase() === "any" && t[e + 2] === "(" && t[e + 3]?.toLowerCase() === "array" && n.startsWith("[") && n.endsWith("]") && t[e + 5] === ")" && r.test(n.slice(1, -1)) && t.splice(e, 6, "in", "(", ...n.slice(1, -1).match(Gt) ?? [], ")");
889
+ t[e] === "=" && t[e + 1]?.toLowerCase() === "any" && t[e + 2] === "(" && t[e + 3]?.toLowerCase() === "array" && n.startsWith("[") && n.endsWith("]") && t[e + 5] === ")" && r.test(n.slice(1, -1)) && t.splice(e, 6, "in", "(", ...n.slice(1, -1).match(Yt) ?? [], ")");
842
890
  }
843
891
  let i = t.filter((e, n) => !(e === "::" && t[n - 1]?.startsWith("'") && t[n + 1]?.toLowerCase() === "text" || e.toLowerCase() === "text" && t[n - 1] === "::" && t[n - 2]?.startsWith("'"))).map((e) => {
844
892
  if (e.startsWith("'")) return e;
@@ -876,31 +924,40 @@ BEGIN
876
924
  return r;
877
925
  };
878
926
  return JSON.stringify(a(i));
879
- }, Jt = (e) => {
927
+ }, Qt = (e) => {
880
928
  if (e == null) return e;
881
- if (Array.isArray(e)) return e.map(Jt);
929
+ if (Array.isArray(e)) return e.map(Qt);
882
930
  if (typeof e != "object") return e;
883
931
  let t = {};
884
932
  for (let n of Object.keys(e).sort()) {
885
933
  let r = e[n];
886
- r !== void 0 && (t[n] = Jt(r));
934
+ r !== void 0 && (t[n] = Qt(r));
887
935
  }
888
936
  return t;
889
- }, Yt = (e) => {
937
+ }, $t = (e) => {
890
938
  if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs) return e;
891
939
  let { idScheme: t, sensitive: n, safe: r, generatedAs: i, ...a } = e;
892
940
  return a;
893
- }, Xt = (e) => [...e].map(Yt).sort((e, t) => e.name.localeCompare(t.name)), Zt = (e) => [...e].map((e) => e.where === void 0 ? e : {
941
+ }, en = (e) => {
942
+ let t = $t(e), { references: n, defaultValue: r, hasDefault: i, oneOf: a, ...o } = t, s = t.type === "id" && Kt(t) ? null : Gt(t), c = qt(t.references);
943
+ return {
944
+ ...o,
945
+ hasDefault: s !== null,
946
+ ...s === null ? {} : { defaultValue: s },
947
+ ...c === null ? {} : { references: c },
948
+ ...t.oneOf !== void 0 && t.oneOf.length > 0 ? { oneOf: [...t.oneOf].sort() } : {}
949
+ };
950
+ }, tn = (e) => e.filter((e) => !x(e.name)).map(en).sort((e, t) => e.name.localeCompare(t.name)), nn = (e) => [...e].map((e) => e.where === void 0 ? e : {
894
951
  ...e,
895
- where: qt(e.where)
896
- }).sort((e, t) => e.name.localeCompare(t.name)), Qt = (e) => [...e].map((e) => ({
952
+ where: Zt(e.where)
953
+ }).sort((e, t) => e.name.localeCompare(t.name)), rn = (e) => [...e].map((e) => ({
897
954
  name: e.name,
898
- columns: Xt(e.columns),
899
- indexes: Zt(e.indexes)
900
- })).sort((e, t) => e.name.localeCompare(t.name)), $t = (e) => {
901
- let t = { tables: Qt(e.tables) }, n = JSON.stringify(Jt(t));
902
- return re("sha256").update(n).digest("hex");
903
- }, en = (e) => e.slice(0, 16), tn = (e, t) => {
955
+ columns: tn(e.columns),
956
+ indexes: nn(e.indexes)
957
+ })).sort((e, t) => e.name.localeCompare(t.name)), L = (e) => {
958
+ let t = { tables: rn(e.tables) }, n = JSON.stringify(Qt(t));
959
+ return ne("sha256").update(n).digest("hex");
960
+ }, an = (e) => e.slice(0, 16), on = (e, t) => {
904
961
  let n = t.references ? {
905
962
  table: t.references().tableName,
906
963
  column: t.referenceColumn ?? "id",
@@ -940,7 +997,7 @@ BEGIN
940
997
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
941
998
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
942
999
  };
943
- }, nn = (e) => {
1000
+ }, sn = (e) => {
944
1001
  let t = [], n = /* @__PURE__ */ new Set(), i = (e) => {
945
1002
  n.has(e.name) || (n.add(e.name), t.push(e));
946
1003
  }, a = e.appliedPrimaryKey ?? [];
@@ -988,11 +1045,11 @@ BEGIN
988
1045
  });
989
1046
  }
990
1047
  return t;
991
- }, rn = (e) => {
1048
+ }, cn = (e) => {
992
1049
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
993
1050
  for (let [r, i] of Object.entries(e.fields)) {
994
1051
  if (i.dropped) continue;
995
- let e = tn(r, i);
1052
+ let e = on(r, i);
996
1053
  n.push(t.has(r) ? {
997
1054
  ...e,
998
1055
  unique: !0
@@ -1002,30 +1059,43 @@ BEGIN
1002
1059
  return {
1003
1060
  name: e.tableName,
1004
1061
  columns: n,
1005
- indexes: nn(e),
1062
+ indexes: sn(e),
1006
1063
  ...r.length > 0 ? { primaryKey: [...r] } : {},
1007
1064
  ...i === void 0 ? {} : { renamedFrom: i }
1008
1065
  };
1009
- }, an = (e) => {
1066
+ }, ln = (e) => {
1010
1067
  let t = /* @__PURE__ */ new Map();
1011
1068
  for (let n of e) for (let e of n.indexes) {
1012
1069
  let r = t.get(e.name);
1013
1070
  if (r !== void 0 && r !== n.name) throw Error(`duplicate index name '${e.name}' across tables '${r}' and '${n.name}'. Index names must be unique per SCHEMA, not just per table — the DB creates only one, so the other never applies and 'db plan' re-emits it forever. Give each an explicit, table-prefixed name (e.g. '${n.name}_${e.name}').`);
1014
1071
  t.set(e.name, n.name);
1015
1072
  }
1016
- }, F = (e, t) => {
1017
- let n = e.filter((e) => !c(e.tableName)).map((e) => rn(me(e, t)));
1073
+ }, R = (e, t) => {
1074
+ let n = e.filter((e) => !c(e.tableName)).map((e) => cn(pe(e, t)));
1018
1075
  if (t === "mysql" || t === "mariadb") {
1019
1076
  for (let e of n) for (let n of e.indexes) if (n.where !== void 0) throw Error(`Partial index '${n.name}' on '${e.name}' is not supported by ${t}. Use uniqueActive for portable conditional uniqueness.`);
1020
1077
  }
1021
- return an(n), { tables: n };
1022
- }, on = (e, t, n = k) => w.gen(function* () {
1078
+ return ln(n), { tables: t === void 0 ? n : n.map((e) => un(e, t)) };
1079
+ }, un = (e, t) => {
1080
+ let n = new Set(e.indexes.flatMap((e) => e.columns));
1081
+ return {
1082
+ ...e,
1083
+ columns: e.columns.map((e) => {
1084
+ if (e.maxLength !== void 0) return e;
1085
+ let r = Jt(e, t, n.has(e.name) || e.unique);
1086
+ return r === void 0 ? e : {
1087
+ ...e,
1088
+ maxLength: r
1089
+ };
1090
+ })
1091
+ };
1092
+ }, dn = (e, t, n = A) => w.gen(function* () {
1023
1093
  let r = (yield* e`
1024
1094
  SELECT p.prosrc
1025
1095
  FROM pg_proc p
1026
1096
  JOIN pg_namespace n ON n.oid = p.pronamespace
1027
1097
  WHERE n.nspname = current_schema()
1028
- AND p.proname = ${et(n)}
1098
+ AND p.proname = ${$e(n)}
1029
1099
  `)[0]?.prosrc, i = r !== void 0 && !r.includes("voltro:notify:v2"), a = t.filter((e) => !e.tableName.startsWith("_voltro_"));
1030
1100
  if (a.length === 0) return {
1031
1101
  missing: [],
@@ -1039,10 +1109,10 @@ BEGIN
1039
1109
  JOIN pg_namespace n ON n.oid = c.relnamespace
1040
1110
  WHERE NOT t.tgisinternal
1041
1111
  AND n.nspname = current_schema()
1042
- AND t.tgname LIKE ${`${Qe}%`}
1112
+ AND t.tgname LIKE ${`${Ze}%`}
1043
1113
  `, s = new Set(o.map((e) => e.tgname)), c = [], l = [];
1044
1114
  for (let e of a) {
1045
- let t = s.has($e(e.tableName, n)), r = e.isReactive !== !1;
1115
+ let t = s.has(Qe(e.tableName, n)), r = e.isReactive !== !1;
1046
1116
  r && !t && c.push(e.tableName), !r && t && l.push(e.tableName);
1047
1117
  }
1048
1118
  return {
@@ -1050,7 +1120,7 @@ BEGIN
1050
1120
  stale: l.sort(),
1051
1121
  functionOutdated: i
1052
1122
  };
1053
- }), sn = (e) => {
1123
+ }), fn = (e) => {
1054
1124
  let t = [];
1055
1125
  if (e.missing.length > 0) {
1056
1126
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -1061,19 +1131,19 @@ BEGIN
1061
1131
  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.`);
1062
1132
  }
1063
1133
  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;
1064
- }, cn = {
1134
+ }, pn = {
1065
1135
  postgres: !0,
1066
1136
  mysql: !0,
1067
1137
  mariadb: !0,
1068
1138
  mssql: !0,
1069
1139
  sqlite: !0
1070
- }, ln = {
1140
+ }, mn = {
1071
1141
  postgres: !0,
1072
1142
  mysql: !1,
1073
1143
  mariadb: !1,
1074
1144
  mssql: !0,
1075
1145
  sqlite: !0
1076
- }, un = (e) => {
1146
+ }, hn = (e) => {
1077
1147
  switch (e) {
1078
1148
  case "add-column":
1079
1149
  case "drop-column":
@@ -1083,80 +1153,33 @@ BEGIN
1083
1153
  case "add-foreign-key":
1084
1154
  case "add-unique":
1085
1155
  case "add-unique-composite":
1086
- case "add-check": return ln;
1087
- default: return cn;
1156
+ case "add-check": return mn;
1157
+ default: return pn;
1088
1158
  }
1089
- }, dn = (e, t) => {
1159
+ }, gn = (e, t) => {
1090
1160
  let n = new Map(t.tables.map((e) => [e.name, e]));
1091
1161
  return new Map(e.map((e) => [e.tableName, {
1092
1162
  table: e,
1093
1163
  snapshot: n.get(e.tableName),
1094
1164
  columnDefs: e.fields
1095
1165
  }]));
1096
- }, I = (e) => {
1097
- if (typeof e != "object" || !e) return JSON.stringify(e);
1098
- if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
1099
- let t = e;
1100
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
1101
- }, fn = (e) => {
1102
- if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1103
- let t = e.defaultValue;
1104
- if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1105
- if (typeof t == "number") return String(t);
1106
- if (typeof t != "string") return I(t);
1107
- let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1108
- if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1109
- let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
1110
- if (o) try {
1111
- return I(JSON.parse(o[1]));
1112
- } catch {}
1113
- let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1114
- if (s) try {
1115
- return I(JSON.parse(s[1]));
1116
- } catch {}
1117
- if (a.startsWith("{") || a.startsWith("[")) try {
1118
- return I(JSON.parse(a));
1119
- } catch {}
1120
- return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1121
- }, pn = (e, t) => {
1122
- let n = fn(e), r = fn(t);
1166
+ }, _n = (e, t) => {
1167
+ let n = Wt(e), r = Wt(t);
1123
1168
  if (n === r) return !0;
1124
- let i = (e) => typeof e.defaultValue == "string" && /^nextval\(.+::regclass\)$/i.test(e.defaultValue.trim()), a = (e) => e.type === "id" && e.idScheme?.kind === "numeric";
1125
- if (e.type === "id" && t.type === "id" && (a(e) && n === null && i(t) || a(t) && r === null && i(e))) return !0;
1126
- let o = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1127
- return o(n) === o(r);
1128
- }, mn = (e) => {
1129
- if (!e) return null;
1130
- let t = (e) => e === "restrict" ? "noAction" : e;
1131
- return {
1132
- table: e.table,
1133
- column: e.column,
1134
- onDelete: t(e.onDelete),
1135
- onUpdate: t(e.onUpdate)
1136
- };
1137
- }, hn = (e, t) => {
1169
+ let i = Kt, a = (e) => e.type === "id" && e.idScheme?.kind === "numeric";
1170
+ return e.type === "id" && t.type === "id" && (a(e) && n === null && i(t) || a(t) && r === null && i(e)) ? !0 : Gt(e) === Gt(t);
1171
+ }, vn = (e, t) => {
1138
1172
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1139
1173
  if (!n && !r) return !0;
1140
1174
  if (!n || !r || n.length !== r.length) return !1;
1141
1175
  let i = [...n].sort(), a = [...r].sort();
1142
1176
  return i.every((e, t) => e === a[t]);
1143
- }, gn = (e, t, n) => {
1144
- if (t === "mssql") {
1145
- let t = nt(e, n);
1146
- if (t !== void 0) return t;
1147
- }
1148
- try {
1149
- let n = /\((\d+)\)/.exec(j(e, t));
1150
- return n ? Number(n[1]) : void 0;
1151
- } catch {
1152
- return;
1153
- }
1154
- }, _n = (e, t, n, r) => n === void 0 || m(n) ? !0 : e.type !== "text" || t.type !== "text" || gn(e, n, r) === t.maxLength, vn = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && pn(e, t) && _n(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(mn(e.references)) === JSON.stringify(mn(t.references)) && hn(e.oneOf, t.oneOf), yn = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1177
+ }, yn = (e, t, n, r) => n === void 0 || m(n) ? !0 : e.type !== "text" || t.type !== "text" || Jt(e, n, r) === t.maxLength, bn = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && _n(e, t) && yn(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(qt(e.references)) === JSON.stringify(qt(t.references)) && vn(e.oneOf, t.oneOf), xn = (e, t) => t.oneOf && t.oneOf.length > 0 ? z({
1155
1178
  kind: "add-check",
1156
1179
  table: e,
1157
1180
  column: t.name,
1158
1181
  values: t.oneOf
1159
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, bn = (e, t) => e.unique === t.unique && e.valid !== !1 && t.valid !== !1 && qt(e.where) === qt(t.where) && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), xn = (e, t, n) => {
1182
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, Sn = (e, t) => e.unique === t.unique && e.valid !== !1 && t.valid !== !1 && Zt(e.where) === Zt(t.where) && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), Cn = (e, t, n) => {
1160
1183
  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));
1161
1184
  for (let t of e.columns) {
1162
1185
  let e = r.get(t.name);
@@ -1164,7 +1187,7 @@ BEGIN
1164
1187
  a.push(t);
1165
1188
  continue;
1166
1189
  }
1167
- vn(t, e, n, c.has(t.name) || t.unique) || s.push({
1190
+ bn(t, e, n, c.has(t.name) || t.unique) || s.push({
1168
1191
  declared: t,
1169
1192
  live: e
1170
1193
  });
@@ -1175,50 +1198,50 @@ BEGIN
1175
1198
  removed: o,
1176
1199
  changed: s
1177
1200
  };
1178
- }, Sn = (e, t, n) => {
1201
+ }, wn = (e, t, n) => {
1179
1202
  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 = [];
1180
1203
  for (let t of e.indexes) {
1181
1204
  let e = i.get(r(t.name));
1182
- (!e || !bn(t, e)) && o.push(t);
1205
+ (!e || !Sn(t, e)) && o.push(t);
1183
1206
  }
1184
1207
  for (let e of t.indexes) {
1185
1208
  let t = a.get(r(e.name));
1186
- (!t || (e.where !== void 0 || t.where !== void 0) && !bn(t, e)) && s.push(e);
1209
+ (!t || (e.where !== void 0 || t.where !== void 0) && !Sn(t, e)) && s.push(e);
1187
1210
  }
1188
1211
  return {
1189
1212
  added: o,
1190
1213
  removed: s
1191
1214
  };
1192
- }, L = (e, t, n, r) => ({
1215
+ }, z = (e, t, n, r) => ({
1193
1216
  op: e,
1194
1217
  classification: t,
1195
- atomicByDialect: un(e.kind),
1218
+ atomicByDialect: hn(e.kind),
1196
1219
  ...n ? { reason: n } : {},
1197
1220
  ...r ? { blocked: r } : {}
1198
- }), Cn = (e, t, n) => {
1221
+ }), Tn = (e, t, n) => {
1199
1222
  let r = {
1200
1223
  kind: "add-column",
1201
1224
  table: e,
1202
1225
  column: t
1203
1226
  };
1204
- return t.nullable ? L(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? L(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? L(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : L(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` });
1205
- }, wn = (e, t, n) => {
1227
+ return t.nullable ? z(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? z(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? z(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : z(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1228
+ }, En = (e, t, n) => {
1206
1229
  let r = {
1207
1230
  kind: "drop-column",
1208
1231
  table: e,
1209
1232
  column: t.name
1210
1233
  };
1211
- return n?.dropped ? L(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : L(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1212
- }, Tn = (e, t, n, r, i) => L({
1234
+ return n?.dropped ? z(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : z(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1235
+ }, Dn = (e, t, n, r, i) => z({
1213
1236
  kind: "create-table",
1214
1237
  table: e,
1215
1238
  columns: t,
1216
1239
  indexes: n,
1217
1240
  ...r && r.length > 0 ? { primaryKey: r } : {}
1218
- }, "safe", i ?? "new table — no data to preserve"), En = (e) => L({
1241
+ }, "safe", i ?? "new table — no data to preserve"), On = (e) => z({
1219
1242
  kind: "drop-table",
1220
1243
  table: e
1221
- }, "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" }), Dn = 5e4, On = (e, t, n, r) => {
1244
+ }, "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" }), kn = 5e4, An = (e, t, n, r) => {
1222
1245
  let i = (n ?? 0) >= r, a;
1223
1246
  return a = !t.unique || t.where !== void 0 ? {
1224
1247
  kind: "add-index",
@@ -1233,16 +1256,16 @@ BEGIN
1233
1256
  table: e,
1234
1257
  name: t.name,
1235
1258
  fields: t.columns
1236
- }, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.where === void 0 ? t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index" : `add ${t.unique ? "unique " : ""}partial index`);
1237
- }, kn = (e, t) => t.unique && t.where === void 0 && t.columns.length > 1 ? L({
1259
+ }, i ? z(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(a, "safe", t.where === void 0 ? t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index" : `add ${t.unique ? "unique " : ""}partial index`);
1260
+ }, jn = (e, t) => t.unique && t.where === void 0 && t.columns.length > 1 ? z({
1238
1261
  kind: "drop-unique-composite",
1239
1262
  table: e,
1240
1263
  name: t.name
1241
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
1264
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : z({
1242
1265
  kind: "drop-index",
1243
1266
  table: e,
1244
1267
  index: t.name
1245
- }, "safe", "drop index (no data loss — index is derived data)"), An = (e, t) => {
1268
+ }, "safe", "drop index (no data loss — index is derived data)"), Mn = (e, t) => {
1246
1269
  let n = e.type;
1247
1270
  if (n === "reference") return e.referenceStorage === "numeric" ? "bigint" : "text";
1248
1271
  switch (t) {
@@ -1251,10 +1274,10 @@ BEGIN
1251
1274
  case "mssql": return n === "json" ? "text" : n;
1252
1275
  default: return n;
1253
1276
  }
1254
- }, jn = (e, t, n) => {
1277
+ }, Nn = (e, t, n) => {
1255
1278
  let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
1256
1279
  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`;
1257
- }, Mn = (e, t, n, r, i, a) => {
1280
+ }, Pn = (e, t, n, r, i, a) => {
1258
1281
  let o = [];
1259
1282
  if (t.nullable !== n.nullable) {
1260
1283
  let n = {
@@ -1263,7 +1286,7 @@ BEGIN
1263
1286
  column: t.name,
1264
1287
  toNullable: t.nullable
1265
1288
  };
1266
- o.push(t.nullable ? L(n, "safe", `loosen ${e}.${t.name} to nullable`) : L(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1289
+ o.push(t.nullable ? z(n, "safe", `loosen ${e}.${t.name} to nullable`) : z(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1267
1290
  }
1268
1291
  if (t.unique !== n.unique) {
1269
1292
  if (t.unique) {
@@ -1272,14 +1295,14 @@ BEGIN
1272
1295
  table: e,
1273
1296
  column: t.name
1274
1297
  }, r = (i ?? 0) >= a;
1275
- o.push(r ? L(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1276
- } else o.push(L({
1298
+ o.push(r ? z(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1299
+ } else o.push(z({
1277
1300
  kind: "drop-unique",
1278
1301
  table: e,
1279
1302
  column: t.name
1280
1303
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1281
1304
  }
1282
- if (An(t, r) !== An(n, r)) {
1305
+ if (Mn(t, r) !== Mn(n, r)) {
1283
1306
  let i = t.narrowedFrom;
1284
1307
  if (i && i.from === n.type) {
1285
1308
  let r = {
@@ -1290,7 +1313,7 @@ BEGIN
1290
1313
  to: t.type,
1291
1314
  ...i.using === void 0 ? {} : { using: i.using }
1292
1315
  };
1293
- o.push(L(r, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${i.from}') declared` + (i.using ? ` with USING ${i.using}` : " (implicit cast)")));
1316
+ o.push(z(r, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${i.from}') declared` + (i.using ? ` with USING ${i.using}` : " (implicit cast)")));
1294
1317
  } else {
1295
1318
  let i = {
1296
1319
  kind: "alter-column-type",
@@ -1299,12 +1322,12 @@ BEGIN
1299
1322
  from: n.type,
1300
1323
  to: t.type
1301
1324
  };
1302
- o.push(L(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: jn(n.type, t, r) }));
1325
+ o.push(z(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: Nn(n.type, t, r) }));
1303
1326
  }
1304
1327
  }
1305
1328
  if (t.type === "text" && n.type === "text" && !m(r ?? "postgres") && t.maxLength !== n.maxLength) {
1306
1329
  let r = t.maxLength === void 0 || n.maxLength !== void 0 && t.maxLength > n.maxLength, i = n.maxLength === void 0 ? "unbounded" : `varchar(${n.maxLength})`, a = t.maxLength === void 0 ? "unbounded" : `varchar(${t.maxLength})`;
1307
- o.push(L({
1330
+ o.push(z({
1308
1331
  kind: "alter-column-type",
1309
1332
  table: e,
1310
1333
  column: t.name,
@@ -1312,7 +1335,7 @@ BEGIN
1312
1335
  to: "text"
1313
1336
  }, 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)}`));
1314
1337
  }
1315
- if (!pn(t, n)) {
1338
+ if (!_n(t, n)) {
1316
1339
  let n = {
1317
1340
  kind: "alter-column-default",
1318
1341
  table: e,
@@ -1320,23 +1343,23 @@ BEGIN
1320
1343
  hasDefault: t.hasDefault,
1321
1344
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1322
1345
  };
1323
- o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1346
+ o.push(z(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1324
1347
  }
1325
- if (!hn(t.oneOf, n.oneOf)) {
1326
- n.oneOf && n.oneOf.length > 0 && o.push(L({
1348
+ if (!vn(t.oneOf, n.oneOf)) {
1349
+ n.oneOf && n.oneOf.length > 0 && o.push(z({
1327
1350
  kind: "drop-check",
1328
1351
  table: e,
1329
1352
  column: t.name
1330
1353
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1331
- let r = yn(e, t);
1354
+ let r = xn(e, t);
1332
1355
  r && o.push(r);
1333
1356
  }
1334
- return JSON.stringify(mn(t.references)) !== JSON.stringify(mn(n.references)) && (n.references && o.push(L({
1357
+ return JSON.stringify(qt(t.references)) !== JSON.stringify(qt(n.references)) && (n.references && o.push(z({
1335
1358
  kind: "drop-foreign-key",
1336
1359
  table: e,
1337
1360
  column: t.name
1338
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Nn(e, t))), o;
1339
- }, Nn = (e, t) => {
1361
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Fn(e, t))), o;
1362
+ }, Fn = (e, t) => {
1340
1363
  let n = [];
1341
1364
  if (!t.references) return n;
1342
1365
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1348,15 +1371,15 @@ BEGIN
1348
1371
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1349
1372
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1350
1373
  };
1351
- return i === "null" && !t.nullable ? n.push(L(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(L({
1374
+ return i === "null" && !t.nullable ? n.push(z(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(z({
1352
1375
  ...a,
1353
1376
  orphanPolicy: i
1354
- }, "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(L(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1355
- }, Pn = (e, t, n) => {
1377
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(z(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1378
+ }, In = (e, t, n) => {
1356
1379
  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));
1357
1380
  for (let [n, c] of Object.entries(t)) {
1358
1381
  let t = c.renamedFrom;
1359
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1382
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(z({
1360
1383
  kind: "rename-column",
1361
1384
  table: e.tableName,
1362
1385
  from: t,
@@ -1368,26 +1391,26 @@ BEGIN
1368
1391
  consumedAddedNames: i,
1369
1392
  consumedRemovedNames: a
1370
1393
  };
1371
- }, Fn = /* @__PURE__ */ new Set([
1394
+ }, Ln = /* @__PURE__ */ new Set([
1372
1395
  "postgres",
1373
1396
  "mysql",
1374
1397
  "mariadb",
1375
1398
  "mssql"
1376
- ]), In = {
1399
+ ]), Rn = {
1377
1400
  ops: [],
1378
1401
  consumedAddedNames: /* @__PURE__ */ new Set(),
1379
1402
  consumedRemovedNames: /* @__PURE__ */ new Set()
1380
- }, Ln = (e) => !e.unique && !e.expression && e.where === void 0, Rn = (e, t, n, r, i) => {
1381
- if (i === void 0 || !Fn.has(i)) return In;
1382
- let a = t.added.filter((e) => Ln(e) && !r.has(e.name));
1383
- if (a.length === 0) return In;
1403
+ }, zn = (e) => !e.unique && !e.expression && e.where === void 0, Bn = (e, t, n, r, i) => {
1404
+ if (i === void 0 || !Ln.has(i)) return Rn;
1405
+ let a = t.added.filter((e) => zn(e) && !r.has(e.name));
1406
+ if (a.length === 0) return Rn;
1384
1407
  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();
1385
1408
  for (let n of t.removed) {
1386
- if (!Ln(n)) continue;
1409
+ if (!zn(n)) continue;
1387
1410
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1388
1411
  if (r.length !== 1) continue;
1389
1412
  let i = r[0];
1390
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(L({
1413
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(z({
1391
1414
  kind: "rename-index",
1392
1415
  table: e,
1393
1416
  from: n.name,
@@ -1399,7 +1422,7 @@ BEGIN
1399
1422
  consumedAddedNames: l,
1400
1423
  consumedRemovedNames: u
1401
1424
  };
1402
- }, zn = (e, t, n) => {
1425
+ }, Vn = (e, t, n) => {
1403
1426
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1404
1427
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1405
1428
  for (let c of e.tables) {
@@ -1410,7 +1433,7 @@ BEGIN
1410
1433
  continue;
1411
1434
  }
1412
1435
  if (t.has(c.name)) {
1413
- r.push(L({
1436
+ r.push(z({
1414
1437
  kind: "rename-table",
1415
1438
  from: e,
1416
1439
  to: c.name
@@ -1418,14 +1441,14 @@ BEGIN
1418
1441
  continue;
1419
1442
  }
1420
1443
  if ((s.get(e) ?? 0) !== 1) {
1421
- r.push(L({
1444
+ r.push(z({
1422
1445
  kind: "rename-table",
1423
1446
  from: e,
1424
1447
  to: c.name
1425
1448
  }, "needs-rename-annotation", `.renamedFrom('${e}') is claimed by ${s.get(e)} tables — nothing says which receives its rows`, { fix: `remove the \`.renamedFrom('${e}')\` marker from all but one of them.` }));
1426
1449
  continue;
1427
1450
  }
1428
- i.set(c.name, e), a.add(e), r.push(L({
1451
+ i.set(c.name, e), a.add(e), r.push(z({
1429
1452
  kind: "rename-table",
1430
1453
  from: e,
1431
1454
  to: c.name
@@ -1439,19 +1462,19 @@ BEGIN
1439
1462
  claimedOldNames: c,
1440
1463
  refusals: o
1441
1464
  };
1442
- }, Bn = (e, t, n, r) => {
1465
+ }, Hn = (e, t, n, r) => {
1443
1466
  if (t === void 0) return {
1444
1467
  live: e,
1445
1468
  ops: []
1446
1469
  };
1447
- let i = r !== void 0 && Fn.has(r), a = [], o = e.indexes.map((e) => {
1470
+ let i = r !== void 0 && Ln.has(r), a = [], o = e.indexes.map((e) => {
1448
1471
  if (!e.name.startsWith(t)) return e;
1449
1472
  let r = `${n}${e.name.slice(t.length)}`;
1450
1473
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1451
1474
  ...e,
1452
1475
  name: r,
1453
1476
  table: n
1454
- } : i ? (a.push(L({
1477
+ } : i ? (a.push(z({
1455
1478
  kind: "rename-index",
1456
1479
  table: n,
1457
1480
  from: e.name,
@@ -1470,7 +1493,7 @@ BEGIN
1470
1493
  },
1471
1494
  ops: a
1472
1495
  };
1473
- }, Vn = (e) => {
1496
+ }, Un = (e) => {
1474
1497
  let t = {
1475
1498
  safe: 0,
1476
1499
  needsDefault: 0,
@@ -1503,51 +1526,69 @@ BEGIN
1503
1526
  case "multi-step": t.multiStep++;
1504
1527
  }
1505
1528
  return t;
1506
- }, Hn = (e) => {
1507
- let t = F(e.declared, e.dialect), n = dn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Dn, a = [], o = zn(t, r, n);
1529
+ }, Wn = (e) => {
1530
+ let t = R(e.declared, e.dialect), n = gn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? kn, a = [], o = Vn(t, r, n);
1508
1531
  a.push(...o.ops);
1509
1532
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1510
- a.push(Tn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1533
+ a.push(Dn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1511
1534
  for (let t of e.columns) {
1512
- let n = yn(e.name, t);
1535
+ let n = xn(e.name, t);
1513
1536
  n && a.push(n);
1514
1537
  }
1515
1538
  }
1516
- let s = new Set(e.ignoreTables ?? []);
1517
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || _(t.name) || x(t.name) || s.has(t.name) || a.push(En(t.name));
1539
+ let s = new Set(e.ignoreTables ?? []), c = [];
1540
+ for (let t of e.live.tables) if (!n.has(t.name)) {
1541
+ if (o.claimedOldNames.has(t.name)) {
1542
+ c.push(t.name);
1543
+ continue;
1544
+ }
1545
+ if (_(t.name)) {
1546
+ c.push(t.name);
1547
+ continue;
1548
+ }
1549
+ if (x(t.name)) {
1550
+ c.push(t.name);
1551
+ continue;
1552
+ }
1553
+ if (s.has(t.name)) {
1554
+ c.push(t.name);
1555
+ continue;
1556
+ }
1557
+ a.push(On(t.name));
1558
+ }
1518
1559
  for (let s of t.tables) {
1519
1560
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1520
1561
  if (!c) continue;
1521
- let l = Bn(c, t, s.name, e.dialect);
1562
+ let l = Hn(c, t, s.name, e.dialect);
1522
1563
  a.push(...l.ops);
1523
- let u = l.live, d = n.get(s.name), f = xn(s, u, e.dialect), p = Sn(s, u, e.dialect), m = Pn(d.table, d.columnDefs, f);
1564
+ let u = l.live, d = n.get(s.name), f = Cn(s, u, e.dialect), p = wn(s, u, e.dialect), m = In(d.table, d.columnDefs, f);
1524
1565
  a.push(...m.ops);
1525
1566
  for (let e of f.removed) {
1526
1567
  if (m.consumedRemovedNames.has(e.name) || x(e.name)) continue;
1527
1568
  let t = d.columnDefs[e.name];
1528
- a.push(wn(s.name, e, t));
1569
+ a.push(En(s.name, e, t));
1529
1570
  }
1530
1571
  for (let e of f.added) {
1531
1572
  if (m.consumedAddedNames.has(e.name)) continue;
1532
1573
  let t = d.columnDefs[e.name];
1533
- a.push(Cn(s.name, e, t));
1534
- let n = yn(s.name, e);
1535
- n && a.push(n), a.push(...Nn(s.name, e));
1574
+ a.push(Tn(s.name, e, t));
1575
+ let n = xn(s.name, e);
1576
+ n && a.push(n), a.push(...Fn(s.name, e));
1536
1577
  }
1537
- let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Rn(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1578
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Bn(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1538
1579
  a.push(...g.ops);
1539
- for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(On(s.name, e, u.rowCount, i));
1540
- for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(kn(s.name, e));
1541
- for (let { declared: t, live: n } of f.changed) a.push(...Mn(s.name, t, n, e.dialect, u.rowCount, i));
1580
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(An(s.name, e, u.rowCount, i));
1581
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(jn(s.name, e));
1582
+ for (let { declared: t, live: n } of f.changed) a.push(...Pn(s.name, t, n, e.dialect, u.rowCount, i));
1542
1583
  }
1543
- 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) => {
1544
- let t = l.get(e);
1545
- return t ? t.columns.flatMap((e) => e.references && c.has(e.references.table) ? [{
1584
+ let l = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), u = new Map(t.tables.map((e) => [e.name, e])), d = (e) => {
1585
+ let t = u.get(e);
1586
+ return t ? t.columns.flatMap((e) => e.references && l.has(e.references.table) ? [{
1546
1587
  column: e.name,
1547
1588
  target: e.references.table
1548
1589
  }] : []) : [];
1549
- }, d = he([...c], u), f = [];
1550
- 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)) && f.push(L({
1590
+ }, f = me([...l], d), p = [];
1591
+ for (let e of t.tables) if (l.has(e.name)) for (let t of e.columns) t.references && f.has(D(e.name, t.name)) && p.push(z({
1551
1592
  kind: "add-foreign-key",
1552
1593
  table: e.name,
1553
1594
  column: t.name,
@@ -1556,14 +1597,14 @@ BEGIN
1556
1597
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1557
1598
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1558
1599
  }, "safe", `deferred FK ${e.name}.${t.name} → ${t.references.table} — breaks a create-time table cycle`));
1559
- if (d.size > 0) {
1600
+ if (f.size > 0) {
1560
1601
  let e = (e) => e.references ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "references")) : e;
1561
1602
  for (let t = 0; t < a.length; t += 1) {
1562
1603
  let n = a[t];
1563
1604
  if (n.op.kind !== "create-table") continue;
1564
1605
  let r = n.op;
1565
- if (!r.columns.some((e) => d.has(E(r.table, e.name)))) continue;
1566
- let i = r.columns.map((t) => d.has(E(r.table, t.name)) ? e(t) : t);
1606
+ if (!r.columns.some((e) => f.has(D(r.table, e.name)))) continue;
1607
+ let i = r.columns.map((t) => f.has(D(r.table, t.name)) ? e(t) : t);
1567
1608
  a[t] = {
1568
1609
  ...n,
1569
1610
  op: {
@@ -1572,24 +1613,24 @@ BEGIN
1572
1613
  }
1573
1614
  };
1574
1615
  }
1575
- a.push(...f);
1616
+ a.push(...p);
1576
1617
  }
1577
- let p = new Map(t.tables.map((e) => [e.name, e])), m = /* @__PURE__ */ new Map(), h = (e, t = /* @__PURE__ */ new Set()) => {
1578
- let n = m.get(e);
1618
+ let m = new Map(t.tables.map((e) => [e.name, e])), h = /* @__PURE__ */ new Map(), g = (e, t = /* @__PURE__ */ new Set()) => {
1619
+ let n = h.get(e);
1579
1620
  if (n !== void 0) return n;
1580
1621
  if (t.has(e)) return 0;
1581
- let r = p.get(e);
1622
+ let r = m.get(e);
1582
1623
  if (!r) return 0;
1583
1624
  let i = new Set(t).add(e), a = 0;
1584
1625
  for (let t of r.columns) {
1585
1626
  let n = t.references?.table;
1586
- n && n !== e && !d.has(E(e, t.name)) && (a = Math.max(a, h(n, i) + 1));
1627
+ n && n !== e && !f.has(D(e, t.name)) && (a = Math.max(a, g(n, i) + 1));
1587
1628
  }
1588
- return m.set(e, a), a;
1589
- }, g = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, v = (e) => {
1629
+ return h.set(e, a), a;
1630
+ }, v = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, y = (e) => {
1590
1631
  let t = "table" in e ? e.table : "";
1591
- return e.kind === "create-table" ? h(t) : e.kind === "drop-table" ? -h(t) : 0;
1592
- }, y = {
1632
+ return e.kind === "create-table" ? g(t) : e.kind === "drop-table" ? -g(t) : 0;
1633
+ }, b = {
1593
1634
  "add-column": 0,
1594
1635
  "rename-column": 1,
1595
1636
  "rename-index": 1,
@@ -1607,23 +1648,34 @@ BEGIN
1607
1648
  "add-unique-composite": 5,
1608
1649
  "add-foreign-key": 5,
1609
1650
  "add-check": 5
1610
- }, b = (e) => y[e] ?? 9, S = [...a].sort((e, t) => {
1611
- let n = g(e.op.kind), r = g(t.op.kind);
1651
+ }, S = (e) => b[e] ?? 9, C = [...a].sort((e, t) => {
1652
+ let n = v(e.op.kind), r = v(t.op.kind);
1612
1653
  if (n !== r) return n - r;
1613
- let i = v(e.op), a = v(t.op);
1654
+ let i = y(e.op), a = y(t.op);
1614
1655
  if (i !== a) return i - a;
1615
1656
  let o = "table" in e.op ? e.op.table : "", s = "table" in t.op ? t.op.table : "";
1616
1657
  if (o !== s) return o.localeCompare(s);
1617
- let c = b(e.op.kind), l = b(t.op.kind);
1658
+ let c = S(e.op.kind), l = S(t.op.kind);
1618
1659
  return c === l ? e.op.kind.localeCompare(t.op.kind) : c - l;
1619
- });
1660
+ }), w = /* @__PURE__ */ new Set();
1661
+ for (let e of C) "table" in e.op && w.add(e.op.table);
1662
+ let T = [];
1663
+ for (let e of t.tables) {
1664
+ if (w.has(e.name) || o.renamedInto.has(e.name)) continue;
1665
+ let t = r.get(e.name);
1666
+ t !== void 0 && L({ tables: [t] }) !== L({ tables: [e] }) && T.push(e.name);
1667
+ }
1620
1668
  return {
1621
- operations: S,
1622
- fromFingerprint: $t(e.live),
1623
- toFingerprint: $t(t),
1624
- summary: Vn(S)
1669
+ operations: C,
1670
+ fromFingerprint: L(e.live),
1671
+ toFingerprint: L(t),
1672
+ summary: Un(C),
1673
+ fingerprintDivergence: {
1674
+ outsideDiff: c,
1675
+ diffEquivalent: T
1676
+ }
1625
1677
  };
1626
- }, Un = (e) => {
1678
+ }, Gn = (e) => {
1627
1679
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1628
1680
  if (!t) return null;
1629
1681
  let n = [...e.replace(/\\'/g, "'").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
@@ -1631,7 +1683,7 @@ BEGIN
1631
1683
  column: t[1],
1632
1684
  values: n
1633
1685
  };
1634
- }, Wn = (e, t) => {
1686
+ }, Kn = (e, t) => {
1635
1687
  if (t === "vector") return "vector";
1636
1688
  switch (e) {
1637
1689
  case "text":
@@ -1658,10 +1710,10 @@ BEGIN
1658
1710
  case "USER-DEFINED": return "text";
1659
1711
  default: return "text";
1660
1712
  }
1661
- }, Gn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1713
+ }, qn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1662
1714
  expr: e,
1663
1715
  stored: t
1664
- } }, R = (e) => {
1716
+ } }, B = (e) => {
1665
1717
  switch (e.toUpperCase()) {
1666
1718
  case "CASCADE": return "cascade";
1667
1719
  case "RESTRICT": return "restrict";
@@ -1669,25 +1721,25 @@ BEGIN
1669
1721
  case "SET DEFAULT": return "noAction";
1670
1722
  default: return "noAction";
1671
1723
  }
1672
- }, Kn = (e, t) => {
1724
+ }, Jn = (e, t) => {
1673
1725
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1674
1726
  return Number.isInteger(n) && n > 0 ? n : t;
1675
- }, qn = () => Kn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Jn = 300, Yn = () => {
1727
+ }, Yn = () => Jn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Xn = 300, Zn = () => {
1676
1728
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1677
- return e !== void 0 && e.trim() === "0" ? 0 : Kn(e, 3e4);
1678
- }, Xn = (e, t) => {
1729
+ return e !== void 0 && e.trim() === "0" ? 0 : Jn(e, 3e4);
1730
+ }, Qn = (e, t) => {
1679
1731
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1680
1732
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1681
1733
  return r;
1682
- }, Zn = (e) => {
1683
- let t = Yn(), n = w.gen(function* () {
1734
+ }, $n = (e) => {
1735
+ let t = Zn(), n = w.gen(function* () {
1684
1736
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1685
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = qn(), a = (e, t) => w.gen(function* () {
1737
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Yn(), a = (e, t) => w.gen(function* () {
1686
1738
  let r = [];
1687
- for (let a of Xn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1739
+ for (let a of Qn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1688
1740
  return r;
1689
1741
  }), o = [];
1690
- for (let t = 0;; t += Jn) {
1742
+ for (let t = 0;; t += Xn) {
1691
1743
  let n = yield* e`
1692
1744
  SELECT c.relname AS table_name,
1693
1745
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1695,9 +1747,9 @@ BEGIN
1695
1747
  JOIN pg_namespace n ON n.oid = c.relnamespace
1696
1748
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1697
1749
  ORDER BY c.relname
1698
- LIMIT ${r(Jn)} OFFSET ${r(t)}
1750
+ LIMIT ${r(Xn)} OFFSET ${r(t)}
1699
1751
  `;
1700
- if (o.push(...n), n.length < Jn) break;
1752
+ if (o.push(...n), n.length < Xn) break;
1701
1753
  }
1702
1754
  let s = /* @__PURE__ */ new Set(), c = [];
1703
1755
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1830,27 +1882,27 @@ BEGIN
1830
1882
  let n = t.get(e.index_name);
1831
1883
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1832
1884
  }
1833
- let ee = [];
1885
+ let T = [];
1834
1886
  for (let e of c) {
1835
1887
  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) => {
1836
- 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" : Wn(t.data_type, t.udt_name), c = a ? {
1888
+ 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" : Kn(t.data_type, t.udt_name), c = a ? {
1837
1889
  table: a.target_table,
1838
1890
  column: a.target_column,
1839
- onDelete: R(a.delete_rule),
1840
- onUpdate: R(a.update_rule)
1891
+ onDelete: B(a.delete_rule),
1892
+ onUpdate: B(a.update_rule)
1841
1893
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1842
1894
  return {
1843
1895
  name: t.column_name,
1844
1896
  type: s,
1845
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1897
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1846
1898
  nullable: t.is_nullable === "YES",
1847
1899
  unique: i.has(t.column_name) || n && t.column_name === "id",
1848
1900
  hasDefault: t.column_default !== null,
1849
1901
  ...t.column_default === null ? {} : { defaultValue: t.column_default },
1850
1902
  ...c ? { references: c } : {},
1851
- ...a ? { referenceStorage: ["integer", "bigint"].includes(Wn(t.data_type, t.udt_name)) ? "numeric" : "text" } : {},
1903
+ ...a ? { referenceStorage: ["integer", "bigint"].includes(Kn(t.data_type, t.udt_name)) ? "numeric" : "text" } : {},
1852
1904
  ...l ? { oneOf: l } : {},
1853
- ...Gn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1905
+ ...qn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1854
1906
  };
1855
1907
  }), l = [], u = S.get(e.table_name);
1856
1908
  if (u) for (let [t, n] of u) {
@@ -1878,20 +1930,20 @@ BEGIN
1878
1930
  unique: !0
1879
1931
  });
1880
1932
  let d = Number(e.row_count ?? 0);
1881
- ee.push({
1933
+ T.push({
1882
1934
  name: e.table_name,
1883
1935
  columns: c,
1884
1936
  indexes: l,
1885
1937
  ...d > 0 ? { rowCount: d } : {}
1886
1938
  });
1887
1939
  }
1888
- return { tables: ee };
1940
+ return { tables: T };
1889
1941
  });
1890
1942
  return (t > 0 ? e.withTransaction(n) : n).pipe(w.catchAll((e) => {
1891
1943
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1892
1944
  return n.includes("statement timeout") || n.includes("57014") ? w.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.`)) : w.fail(e);
1893
1945
  }));
1894
- }, Qn = (e, t) => {
1946
+ }, er = (e, t) => {
1895
1947
  switch (e.toLowerCase()) {
1896
1948
  case "varchar":
1897
1949
  case "char":
@@ -1923,21 +1975,21 @@ BEGIN
1923
1975
  case "json": return "json";
1924
1976
  default: return "text";
1925
1977
  }
1926
- }, z = (e) => e.map((e) => {
1978
+ }, tr = (e) => e.map((e) => {
1927
1979
  let t = e, n = {};
1928
1980
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1929
1981
  return n;
1930
- }), $n = (e) => w.gen(function* () {
1931
- let t = z(yield* e`
1982
+ }), nr = (e) => w.gen(function* () {
1983
+ let t = tr(yield* e`
1932
1984
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1933
1985
  FROM information_schema.tables
1934
1986
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1935
- ORDER BY table_name`), n = z(yield* e`
1987
+ ORDER BY table_name`), n = tr(yield* e`
1936
1988
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1937
1989
  character_maximum_length, generation_expression, extra
1938
1990
  FROM information_schema.columns
1939
1991
  WHERE table_schema = DATABASE()
1940
- ORDER BY table_name, ordinal_position`), r = z(yield* e`
1992
+ ORDER BY table_name, ordinal_position`), r = tr(yield* e`
1941
1993
  SELECT k.table_name AS source_table,
1942
1994
  k.column_name AS source_column,
1943
1995
  k.referenced_table_name AS target_table,
@@ -1947,7 +1999,7 @@ BEGIN
1947
1999
  JOIN information_schema.referential_constraints r
1948
2000
  ON k.constraint_name = r.constraint_name
1949
2001
  AND k.table_schema = r.constraint_schema
1950
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
2002
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = tr(yield* e`
1951
2003
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1952
2004
  FROM information_schema.statistics
1953
2005
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
@@ -1960,14 +2012,14 @@ BEGIN
1960
2012
  JOIN information_schema.table_constraints tc
1961
2013
  ON tc.constraint_schema = cc.constraint_schema
1962
2014
  AND tc.constraint_name = cc.constraint_name
1963
- WHERE cc.constraint_schema = DATABASE()`.unprepared, s = z(yield* a.pipe(w.orElse(() => o), w.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
2015
+ WHERE cc.constraint_schema = DATABASE()`.unprepared, s = tr(yield* a.pipe(w.orElse(() => o), w.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
1964
2016
  for (let e of s) {
1965
2017
  let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
1966
2018
  if (t) {
1967
2019
  c.add(`${e.table_name}.${t[1]}`);
1968
2020
  continue;
1969
2021
  }
1970
- let n = Un(e.check_clause);
2022
+ let n = Gn(e.check_clause);
1971
2023
  n && l.set(`${e.table_name}.${n.column}`, n.values);
1972
2024
  }
1973
2025
  let u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
@@ -1990,24 +2042,24 @@ BEGIN
1990
2042
  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);
1991
2043
  if (o) for (let e of o.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1992
2044
  let s = t.map((t) => {
1993
- 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" : Qn(t.data_type, t.column_type), u = o ? {
2045
+ 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" : er(t.data_type, t.column_type), u = o ? {
1994
2046
  table: o.target_table,
1995
2047
  column: o.target_column,
1996
- onDelete: R(o.delete_rule),
1997
- onUpdate: R(o.update_rule)
2048
+ onDelete: B(o.delete_rule),
2049
+ onUpdate: B(o.update_rule)
1998
2050
  } : void 0, d = a.has(t.column_name) || n && t.column_name === "id", f = t.column_default === "NULL" ? null : t.column_default, p = l.get(`${e.table_name}.${t.column_name}`);
1999
2051
  return {
2000
2052
  name: t.column_name,
2001
2053
  type: s,
2002
2054
  nullable: t.is_nullable === "YES",
2003
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2055
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2004
2056
  unique: d,
2005
2057
  hasDefault: f !== null,
2006
2058
  ...f === null ? {} : { defaultValue: f },
2007
2059
  ...u ? { references: u } : {},
2008
- ...o ? { referenceStorage: ["integer", "bigint"].includes(Qn(t.data_type, t.column_type)) ? "numeric" : "text" } : {},
2060
+ ...o ? { referenceStorage: ["integer", "bigint"].includes(er(t.data_type, t.column_type)) ? "numeric" : "text" } : {},
2009
2061
  ...p ? { oneOf: p } : {},
2010
- ...Gn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
2062
+ ...qn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
2011
2063
  };
2012
2064
  }), m = new Set(n.map((e) => e.source_column)), h = [];
2013
2065
  if (o) for (let [t, n] of o) {
@@ -2034,10 +2086,10 @@ BEGIN
2034
2086
  });
2035
2087
  }
2036
2088
  return { tables: p };
2037
- }), er = (e) => {
2089
+ }), rr = (e) => {
2038
2090
  let t = e.toUpperCase();
2039
2091
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
2040
- }, tr = (e) => e === 1 || e === !0, nr = (e) => w.gen(function* () {
2092
+ }, ir = (e) => e === 1 || e === !0, ar = (e) => w.gen(function* () {
2041
2093
  let t = yield* e`
2042
2094
  SELECT name, sql FROM sqlite_master
2043
2095
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -2051,18 +2103,18 @@ BEGIN
2051
2103
  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 Map(), m = /* @__PURE__ */ new Set();
2052
2104
  for (let t of c) {
2053
2105
  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);
2054
- if (f.set(t.name, r), t.partial !== void 0 && tr(t.partial)) {
2055
- let n = Kt((yield* e`SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ${t.name}`)[0]?.sql ?? "");
2106
+ if (f.set(t.name, r), t.partial !== void 0 && ir(t.partial)) {
2107
+ let n = Xt((yield* e`SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ${t.name}`)[0]?.sql ?? "");
2056
2108
  n !== void 0 && p.set(t.name, n);
2057
2109
  }
2058
- !p.has(t.name) && tr(t.unique) && r.length === 1 && m.add(r[0]);
2110
+ !p.has(t.name) && ir(t.unique) && r.length === 1 && m.add(r[0]);
2059
2111
  }
2060
2112
  let h = o.map((e) => {
2061
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : er(e.type), a = r ? {
2113
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : rr(e.type), a = r ? {
2062
2114
  table: r.table,
2063
2115
  column: r.to,
2064
- onDelete: R(r.on_delete),
2065
- onUpdate: R(r.on_update)
2116
+ onDelete: B(r.on_delete),
2117
+ onUpdate: B(r.on_update)
2066
2118
  } : void 0, o = t.get(e.name);
2067
2119
  return {
2068
2120
  name: e.name,
@@ -2072,19 +2124,19 @@ BEGIN
2072
2124
  hasDefault: e.dflt_value !== null,
2073
2125
  ...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
2074
2126
  ...a ? { references: a } : {},
2075
- ...r ? { referenceStorage: ["integer", "bigint"].includes(er(e.type)) ? "numeric" : "text" } : {},
2127
+ ...r ? { referenceStorage: ["integer", "bigint"].includes(rr(e.type)) ? "numeric" : "text" } : {},
2076
2128
  ...o ? { oneOf: o } : {},
2077
- ...Gn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2129
+ ...qn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2078
2130
  };
2079
2131
  }), g = new Set(s.map((e) => e.from)), _ = [];
2080
2132
  for (let e of c) {
2081
2133
  if (e.origin === "pk") continue;
2082
2134
  let t = f.get(e.name) ?? [], n = p.get(e.name);
2083
- n === void 0 && t.length === 1 && tr(e.unique) || (n !== void 0 || t.length !== 1 || tr(e.unique) || !g.has(t[0]) || e.name === `${i}_${t[0]}_idx`) && _.push({
2135
+ n === void 0 && t.length === 1 && ir(e.unique) || (n !== void 0 || t.length !== 1 || ir(e.unique) || !g.has(t[0]) || e.name === `${i}_${t[0]}_idx`) && _.push({
2084
2136
  name: e.name,
2085
2137
  table: i,
2086
2138
  columns: t,
2087
- unique: tr(e.unique),
2139
+ unique: ir(e.unique),
2088
2140
  ...n === void 0 ? {} : { where: n }
2089
2141
  });
2090
2142
  }
@@ -2100,7 +2152,7 @@ BEGIN
2100
2152
  });
2101
2153
  }
2102
2154
  return { tables: r };
2103
- }), rr = (e) => {
2155
+ }), or = (e) => {
2104
2156
  switch (e.toLowerCase()) {
2105
2157
  case "int":
2106
2158
  case "smallint":
@@ -2122,7 +2174,7 @@ BEGIN
2122
2174
  case "image": return "bytes";
2123
2175
  default: return "text";
2124
2176
  }
2125
- }, B = (e) => e === !0 || e === 1, ir = (e) => w.gen(function* () {
2177
+ }, V = (e) => e === !0 || e === 1, sr = (e) => w.gen(function* () {
2126
2178
  let t = yield* e`
2127
2179
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2128
2180
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -2185,39 +2237,39 @@ BEGIN
2185
2237
  let t = l.get(e) ?? [], n = u.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), a = new Set(n.map((e) => e.source_column)), o = d.get(e), s = [], p = /* @__PURE__ */ new Set();
2186
2238
  if (o) for (let [, e] of o) {
2187
2239
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2188
- if (B(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2189
- else t[0].predicate == null && B(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2240
+ if (V(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2241
+ else t[0].predicate == null && V(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2190
2242
  }
2191
2243
  let m = t.map((t) => {
2192
- 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" : rr(t.data_type), l = a ? {
2244
+ 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" : or(t.data_type), l = a ? {
2193
2245
  table: a.target_table,
2194
2246
  column: a.target_column,
2195
- onDelete: ar(a.delete_rule),
2196
- onUpdate: ar(a.update_rule)
2197
- } : void 0, u = t.column_default === null ? null : or(t.column_default), d = c.get(`${e}.${t.column_name}`);
2247
+ onDelete: cr(a.delete_rule),
2248
+ onUpdate: cr(a.update_rule)
2249
+ } : void 0, u = t.column_default === null ? null : lr(t.column_default), d = c.get(`${e}.${t.column_name}`);
2198
2250
  return {
2199
2251
  name: t.column_name,
2200
2252
  type: o,
2201
2253
  nullable: t.is_nullable === "YES",
2202
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2254
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2203
2255
  unique: p.has(t.column_name) || n && t.column_name === "id",
2204
2256
  hasDefault: u !== null,
2205
2257
  ...u === null ? {} : { defaultValue: u },
2206
2258
  ...l ? { references: l } : {},
2207
- ...a ? { referenceStorage: ["integer", "bigint"].includes(rr(t.data_type)) ? "numeric" : "text" } : {},
2259
+ ...a ? { referenceStorage: ["integer", "bigint"].includes(or(t.data_type)) ? "numeric" : "text" } : {},
2208
2260
  ...d ? { oneOf: d } : {},
2209
- ...Gn(i.get(`${e}.${t.column_name}`)?.definition ?? null, B(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2261
+ ...qn(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2210
2262
  };
2211
2263
  }), h = [];
2212
2264
  if (o) for (let [t, n] of o) {
2213
2265
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2214
- if (B(r[0].is_primary)) continue;
2266
+ if (V(r[0].is_primary)) continue;
2215
2267
  let i = r[0].predicate ?? void 0;
2216
- i === void 0 && r.length === 1 && B(r[0].is_unique) || (i !== void 0 || r.length !== 1 || B(r[0].is_unique) || !a.has(r[0].column_name) || t === `${e}_${r[0].column_name}_idx`) && h.push({
2268
+ i === void 0 && r.length === 1 && V(r[0].is_unique) || (i !== void 0 || r.length !== 1 || V(r[0].is_unique) || !a.has(r[0].column_name) || t === `${e}_${r[0].column_name}_idx`) && h.push({
2217
2269
  name: t,
2218
2270
  table: e,
2219
2271
  columns: r.map((e) => e.column_name),
2220
- unique: B(r[0].is_unique),
2272
+ unique: V(r[0].is_unique),
2221
2273
  ...i === void 0 ? {} : { where: i }
2222
2274
  });
2223
2275
  }
@@ -2233,90 +2285,90 @@ BEGIN
2233
2285
  });
2234
2286
  }
2235
2287
  return { tables: f };
2236
- }), ar = (e) => {
2288
+ }), cr = (e) => {
2237
2289
  switch (e.toUpperCase().replace(/_/g, " ")) {
2238
2290
  case "CASCADE": return "cascade";
2239
2291
  case "SET NULL": return "setNull";
2240
2292
  case "SET DEFAULT": return "noAction";
2241
2293
  default: return "noAction";
2242
2294
  }
2243
- }, or = (e) => {
2295
+ }, lr = (e) => {
2244
2296
  let t = e.trim();
2245
2297
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2246
2298
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2247
- }, sr = /* @__PURE__ */ new Set([
2299
+ }, ur = /* @__PURE__ */ new Set([
2248
2300
  "character varying",
2249
2301
  "varchar",
2250
2302
  "nvarchar",
2251
2303
  "char",
2252
2304
  "character",
2253
2305
  "nchar"
2254
- ]), V = (e, t) => {
2255
- if (!sr.has(e.toLowerCase())) return;
2306
+ ]), H = (e, t) => {
2307
+ if (!ur.has(e.toLowerCase())) return;
2256
2308
  let n = Number(t);
2257
2309
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2258
- }, cr = /* @__PURE__ */ new Set([O]), lr = (e) => e.onDialectOrElse({
2259
- mysql: () => $n(e),
2260
- mssql: () => ir(e),
2261
- sqlite: () => nr(e),
2262
- orElse: () => Zn(e)
2310
+ }, dr = /* @__PURE__ */ new Set([k]), fr = (e) => e.onDialectOrElse({
2311
+ mysql: () => nr(e),
2312
+ mssql: () => sr(e),
2313
+ sqlite: () => ar(e),
2314
+ orElse: () => $n(e)
2263
2315
  }).pipe(w.map((e) => ({
2264
2316
  ...e,
2265
- tables: e.tables.filter((e) => !cr.has(e.name))
2266
- }))), ur = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", dr = /* @__PURE__ */ new WeakMap(), H = (e) => w.suspend(() => {
2267
- let t = dr.get(e);
2268
- return t === void 0 ? fr(e).pipe(w.tap((t) => w.sync(() => dr.set(e, t)))) : w.succeed(t);
2269
- }), fr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(w.map((e) => {
2317
+ tables: e.tables.filter((e) => !dr.has(e.name))
2318
+ }))), pr = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", mr = /* @__PURE__ */ new WeakMap(), hr = (e) => w.suspend(() => {
2319
+ let t = mr.get(e);
2320
+ return t === void 0 ? gr(e).pipe(w.tap((t) => w.sync(() => mr.set(e, t)))) : w.succeed(t);
2321
+ }), gr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(w.map((e) => {
2270
2322
  let t = e[0]?.v;
2271
- return typeof t == "string" ? ur(t) : "mysql";
2272
- }), w.catchAll(() => w.succeed("mysql"))), pr = (e) => {
2323
+ return typeof t == "string" ? pr(t) : "mysql";
2324
+ }), w.catchAll(() => w.succeed("mysql"))), _r = (e) => {
2273
2325
  let t = e;
2274
2326
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2275
2327
  let e = t;
2276
2328
  if (typeof e.errno == "number") return e.errno;
2277
2329
  t = e.cause;
2278
2330
  }
2279
- }, mr = (e) => {
2331
+ }, vr = (e) => {
2280
2332
  let t = [], n = e;
2281
2333
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2282
2334
  let e = n;
2283
2335
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2284
2336
  }
2285
2337
  return t.join(" | ");
2286
- }, hr = (e, t) => {
2338
+ }, yr = (e, t) => {
2287
2339
  if (t.length === 0) return !1;
2288
- let n = pr(e), r = mr(e);
2340
+ let n = _r(e), r = vr(e);
2289
2341
  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)));
2290
- }, gr = {
2342
+ }, br = {
2291
2343
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2292
2344
  errno: [1061]
2293
- }, _r = {
2345
+ }, xr = {
2294
2346
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2295
2347
  errno: [1091]
2296
- }, vr = {
2348
+ }, Sr = {
2297
2349
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2298
2350
  messageIncludes: ["no such column"]
2299
- }, yr = {
2351
+ }, Cr = {
2300
2352
  why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
2301
2353
  errno: [1091, 3940]
2302
2354
  }, U = (e, t) => e.onDialectOrElse({
2303
2355
  mysql: () => w.succeed(t.replace("T", " ").replace("Z", "")),
2304
2356
  orElse: () => w.succeed(t)
2305
- }), br = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, xr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), Sr = (e, t) => {
2306
- if ((e.type !== "text" || e.maxLength === void 0) && !xr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2357
+ }), wr = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, Tr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), Er = (e, t) => {
2358
+ if ((e.type !== "text" || e.maxLength === void 0) && !Tr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2307
2359
  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;
2308
2360
  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.`);
2309
- return j(e, t);
2310
- }, Cr = (e) => {
2311
- let t = Sr(e, "postgres");
2312
- return t === void 0 ? wr(e) : t;
2313
- }, wr = (e) => {
2361
+ return M(e, t);
2362
+ }, Dr = (e) => {
2363
+ let t = Er(e, "postgres");
2364
+ return t === void 0 ? Or(e) : t;
2365
+ }, Or = (e) => {
2314
2366
  switch (e.type) {
2315
2367
  case "id": return "text";
2316
2368
  case "text": return "text";
2317
2369
  case "integer": return "integer";
2318
2370
  case "real": return "double precision";
2319
- case "decimal": return br(e, "NUMERIC");
2371
+ case "decimal": return wr(e, "NUMERIC");
2320
2372
  case "bigint": return "bigint";
2321
2373
  case "boolean": return "boolean";
2322
2374
  case "timestamp": return "timestamptz";
@@ -2330,15 +2382,15 @@ BEGIN
2330
2382
  case "interval": return "interval";
2331
2383
  case "raw": return e.rawDdl ?? "text";
2332
2384
  }
2333
- }, Tr = (e) => {
2334
- let t = Sr(e, "mariadb");
2385
+ }, kr = (e) => {
2386
+ let t = Er(e, "mariadb");
2335
2387
  if (t !== void 0) return t;
2336
2388
  switch (e.type) {
2337
2389
  case "id": return "VARCHAR(64)";
2338
2390
  case "text": return "LONGTEXT";
2339
2391
  case "integer": return "INT";
2340
2392
  case "real": return "DOUBLE";
2341
- case "decimal": return br(e, "DECIMAL");
2393
+ case "decimal": return wr(e, "DECIMAL");
2342
2394
  case "bigint": return "BIGINT";
2343
2395
  case "boolean": return "TINYINT(1)";
2344
2396
  case "timestamp": return "DATETIME(6)";
@@ -2352,38 +2404,38 @@ BEGIN
2352
2404
  case "interval": return "BIGINT";
2353
2405
  case "raw": return e.rawDdl ?? "LONGTEXT";
2354
2406
  }
2355
- }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, Er = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", Dr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, Or = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, kr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Ar = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${ai(t)}`)};`, jr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Nr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Mr = (e, t) => {
2407
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, Ar = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", jr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, Mr = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, Nr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Pr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${li(t)}`)};`, Fr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Lr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Ir = (e, t) => {
2356
2408
  let { defaultFactory: n, ...r } = e;
2357
- return j(e, t) !== j({
2409
+ return M(e, t) !== M({
2358
2410
  ...r,
2359
2411
  hasDefault: !1
2360
2412
  }, t);
2361
- }, Nr = (e, t) => {
2413
+ }, Lr = (e, t) => {
2362
2414
  let n = t(e.defaultValue);
2363
2415
  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.`);
2364
2416
  return n;
2365
- }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Pr = (e, t, n) => {
2417
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Rr = (e, t, n) => {
2366
2418
  let r = K(e, t, n);
2367
- return r ? tn(n, r) : void 0;
2368
- }, Fr = (e, t, n) => {
2369
- let r = n ?? e.nullable, i = it(e, "mariadb");
2419
+ return r ? on(n, r) : void 0;
2420
+ }, zr = (e, t, n) => {
2421
+ let r = n ?? e.nullable, i = rt(e, "mariadb");
2370
2422
  return [
2371
2423
  G(t),
2372
- j(e, "mariadb"),
2424
+ M(e, "mariadb"),
2373
2425
  r ? null : "NOT NULL",
2374
2426
  i
2375
2427
  ].filter(Boolean).join(" ");
2376
- }, Ir = (e, t) => e == null ? null : Array.isArray(e) ? Lr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, Lr = (e, t, n) => at(e, t ?? { type: "json" }, n), Rr = (e, t) => e == null ? null : Array.isArray(e) ? Lr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, zr = (e, t) => {
2428
+ }, Br = (e, t) => e == null ? null : Array.isArray(e) ? Vr(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, Vr = (e, t, n) => it(e, t ?? { type: "json" }, n), Hr = (e, t) => e == null ? null : Array.isArray(e) ? Vr(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, Ur = (e, t) => {
2377
2429
  if (!e.generatedAs) return null;
2378
2430
  let { expr: n, stored: r } = e.generatedAs;
2379
2431
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2380
- }, Br = (e) => {
2381
- if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2382
- let t = zr(e, "postgres");
2383
- if (t) return `${W(e.name)} ${Cr(e)} ${t}`;
2384
- let n = [W(e.name), Cr(e)];
2432
+ }, Wr = (e) => {
2433
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "postgres");
2434
+ let t = Ur(e, "postgres");
2435
+ if (t) return `${W(e.name)} ${Dr(e)} ${t}`;
2436
+ let n = [W(e.name), Dr(e)];
2385
2437
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2386
- let t = Rr(e.defaultValue, e);
2438
+ let t = Hr(e.defaultValue, e);
2387
2439
  t && n.push(t);
2388
2440
  }
2389
2441
  return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
@@ -2392,24 +2444,24 @@ BEGIN
2392
2444
  setNull: "SET NULL",
2393
2445
  noAction: "NO ACTION"
2394
2446
  }[e.references.onDelete]}`)), n.join(" ");
2395
- }, Vr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Hr = (e) => {
2396
- let t = e.columns.map((e) => ` ${Br(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Vr(e, W)}\n)`];
2397
- 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(ui).join(", ")})${Y(t)}`);
2447
+ }, Gr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Kr = (e) => {
2448
+ let t = e.columns.map((e) => ` ${Wr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Gr(e, W)}\n)`];
2449
+ 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(mi).join(", ")})${Y(t)}`);
2398
2450
  return n;
2399
- }, Ur = 191, Wr = (e) => {
2400
- let t = Tr(e).toUpperCase();
2451
+ }, qr = 191, Jr = (e) => {
2452
+ let t = kr(e).toUpperCase();
2401
2453
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2402
- }, Gr = (e) => {
2403
- if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2404
- let t = zr(e, "mariadb");
2405
- if (t) return `${G(e.name)} ${Tr(e)} ${t}`;
2406
- let n = [G(e.name), Tr(e)];
2407
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Wr(e) && n.push("UNIQUE"), e.hasDefault) {
2408
- let t = Ir(e.defaultValue, e);
2454
+ }, Yr = (e) => {
2455
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mariadb");
2456
+ let t = Ur(e, "mariadb");
2457
+ if (t) return `${G(e.name)} ${kr(e)} ${t}`;
2458
+ let n = [G(e.name), kr(e)];
2459
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Jr(e) && n.push("UNIQUE"), e.hasDefault) {
2460
+ let t = Br(e.defaultValue, e);
2409
2461
  t && n.push(t);
2410
2462
  }
2411
2463
  return n.join(" ");
2412
- }, Kr = (e) => e.columns.flatMap((t) => {
2464
+ }, Xr = (e) => e.columns.flatMap((t) => {
2413
2465
  if (!t.references) return [];
2414
2466
  let n = t.references.onDelete ? ` ON DELETE ${{
2415
2467
  cascade: "CASCADE",
@@ -2418,27 +2470,27 @@ BEGIN
2418
2470
  noAction: "NO ACTION"
2419
2471
  }[t.references.onDelete]}` : "";
2420
2472
  return [` CONSTRAINT ${G(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${G(t.name)}) REFERENCES ${G(t.references.table)} (${G(t.references.column)})${n}`];
2421
- }), qr = (e, t = "mariadb") => {
2422
- for (let n of e.indexes) pi(n, t);
2473
+ }), Zr = (e, t = "mariadb") => {
2474
+ for (let n of e.indexes) _i(n, t);
2423
2475
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2424
- let t = ci(n.get(e));
2476
+ let t = fi(n.get(e));
2425
2477
  return t === void 0 ? G(e) : `${G(e)}(${t})`;
2426
- }, i = e.columns.map((e) => ` ${Gr(e)}`).join(",\n"), a = Kr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Vr(e, r)}\n)`];
2427
- for (let n of e.columns) n.unique && n.type !== "id" && Wr(n) && s.push(`CREATE UNIQUE INDEX ${Er(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2428
- for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Er(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2478
+ }, i = e.columns.map((e) => ` ${Yr(e)}`).join(",\n"), a = Xr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Gr(e, r)}\n)`];
2479
+ for (let n of e.columns) n.unique && n.type !== "id" && Jr(n) && s.push(`CREATE UNIQUE INDEX ${Ar(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2480
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Ar(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2429
2481
  return s;
2430
- }, Jr = {
2482
+ }, Qr = {
2431
2483
  cascade: "CASCADE",
2432
2484
  restrict: "RESTRICT",
2433
2485
  setNull: "SET NULL",
2434
2486
  noAction: "NO ACTION"
2435
- }, Yr = {
2487
+ }, $r = {
2436
2488
  cascade: "CASCADE",
2437
2489
  restrict: "NO ACTION",
2438
2490
  setNull: "SET NULL",
2439
2491
  noAction: "NO ACTION"
2440
- }, Xr = (e) => {
2441
- let t = Sr(e, "sqlite");
2492
+ }, ei = (e) => {
2493
+ let t = Er(e, "sqlite");
2442
2494
  if (t !== void 0) return t;
2443
2495
  switch (e.type) {
2444
2496
  case "integer":
@@ -2450,29 +2502,29 @@ BEGIN
2450
2502
  case "bytes": return "BLOB";
2451
2503
  default: return "TEXT";
2452
2504
  }
2453
- }, Zr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Qr = (e) => {
2454
- if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2455
- let t = zr(e, "sqlite");
2456
- if (t) return `${W(e.name)} ${Xr(e)} ${t}`;
2457
- let n = [W(e.name), Xr(e)];
2505
+ }, ti = (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, ni = (e) => {
2506
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "sqlite");
2507
+ let t = Ur(e, "sqlite");
2508
+ if (t) return `${W(e.name)} ${ei(e)} ${t}`;
2509
+ let n = [W(e.name), ei(e)];
2458
2510
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2459
- let t = Zr(e.defaultValue, "CURRENT_TIMESTAMP");
2511
+ let t = ti(e.defaultValue, "CURRENT_TIMESTAMP");
2460
2512
  t && n.push(t);
2461
2513
  }
2462
- if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Jr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2514
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Qr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2463
2515
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2464
2516
  n.push(`CHECK (${W(e.name)} IN (${t}))`);
2465
2517
  }
2466
2518
  return n.join(" ");
2467
- }, $r = (e) => {
2468
- let t = e.columns.map((e) => ` ${Qr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Vr(e, W)}\n)`];
2519
+ }, ri = (e) => {
2520
+ let t = e.columns.map((e) => ` ${ni(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Gr(e, W)}\n)`];
2469
2521
  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(", ")})${Y(t)}`);
2470
2522
  return n;
2471
2523
  }, q = (e, t) => {
2472
2524
  let n = t.find((t) => t.tableName === e);
2473
2525
  if (!n) return [];
2474
- let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2475
- ...$r({
2526
+ let r = R([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2527
+ ...ri({
2476
2528
  kind: "create-table",
2477
2529
  table: i,
2478
2530
  columns: r.columns,
@@ -2485,25 +2537,25 @@ BEGIN
2485
2537
  ];
2486
2538
  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(", ")})${Y(t)}`);
2487
2539
  return o;
2488
- }, ei = (e, t, n, r) => {
2540
+ }, ii = (e, t, n, r) => {
2489
2541
  let i = r ?? e.nullable;
2490
- return `ALTER TABLE ${J(n)} ALTER COLUMN ${J(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2491
- }, ti = (e, t) => {
2542
+ return `ALTER TABLE ${J(n)} ALTER COLUMN ${J(t)} ${M(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2543
+ }, ai = (e, t) => {
2492
2544
  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 ${J(e.table)} DROP CONSTRAINT [' + @dc + ']');` + (t ? ` ${t}` : "");
2493
2545
  if (!e.hasDefault) return n;
2494
- let r = Zr(e.defaultValue, "SYSUTCDATETIME()");
2546
+ let r = ti(e.defaultValue, "SYSUTCDATETIME()");
2495
2547
  if (!r) return n;
2496
2548
  let i = r.replace(/^DEFAULT\s+/i, "");
2497
2549
  return `${n} ALTER TABLE ${J(e.table)} ADD DEFAULT ${i} FOR ${J(e.column)};`;
2498
- }, J = (e) => `[${e.replace(/]/g, "]]")}]`, ni = (e) => {
2499
- let t = Sr(e, "mssql");
2550
+ }, J = (e) => `[${e.replace(/]/g, "]]")}]`, oi = (e) => {
2551
+ let t = Er(e, "mssql");
2500
2552
  if (t !== void 0) return t;
2501
2553
  switch (e.type) {
2502
2554
  case "id": return "NVARCHAR(64)";
2503
2555
  case "reference": return e.referenceStorage === "numeric" ? "BIGINT" : "NVARCHAR(64)";
2504
2556
  case "integer": return "INT";
2505
2557
  case "real": return "FLOAT";
2506
- case "decimal": return br(e, "DECIMAL");
2558
+ case "decimal": return wr(e, "DECIMAL");
2507
2559
  case "bigint": return "BIGINT";
2508
2560
  case "boolean": return "BIT";
2509
2561
  case "timestamp": return "DATETIME2(6)";
@@ -2511,46 +2563,46 @@ BEGIN
2511
2563
  case "bytes": return "VARBINARY(MAX)";
2512
2564
  default: return "NVARCHAR(MAX)";
2513
2565
  }
2514
- }, ri = (e, t) => {
2515
- if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2516
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : ni(e), r = zr(e, "mssql");
2566
+ }, si = (e, t) => {
2567
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mssql");
2568
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : oi(e), r = Ur(e, "mssql");
2517
2569
  if (r) return `${J(e.name)} ${r}`;
2518
2570
  let i = [J(e.name), n];
2519
2571
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2520
- let t = Zr(e.defaultValue, "SYSUTCDATETIME()");
2572
+ let t = ti(e.defaultValue, "SYSUTCDATETIME()");
2521
2573
  t && i.push(t);
2522
2574
  }
2523
- return e.references && (i.push(`REFERENCES ${J(e.references.table)} (${J(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Yr[e.references.onDelete]}`)), i.join(" ");
2524
- }, ii = (e) => {
2525
- 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) => ` ${ri(e, n)}`).join(",\n"), i = `CREATE TABLE ${J(e.table)} (\n${r}${Vr(e, J)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2575
+ return e.references && (i.push(`REFERENCES ${J(e.references.table)} (${J(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${$r[e.references.onDelete]}`)), i.join(" ");
2576
+ }, ci = (e) => {
2577
+ 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) => ` ${si(e, n)}`).join(",\n"), i = `CREATE TABLE ${J(e.table)} (\n${r}${Gr(e, J)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2526
2578
  for (let n of e.indexes) {
2527
2579
  if (n.name === `${e.table}_pkey`) continue;
2528
2580
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${J(n.name)} ON ${J(e.table)} (${n.columns.map(J).join(", ")})${Y(n)}`;
2529
2581
  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)}')`);
2530
2582
  }
2531
2583
  return a;
2532
- }, ai = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, oi = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, si = (e, t, n) => {
2533
- let r = `${e.table}${ai(t)}`;
2584
+ }, li = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, ui = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, di = (e, t, n) => {
2585
+ let r = `${e.table}${li(t)}`;
2534
2586
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2535
- }, ci = (e) => {
2536
- if (e === void 0 || !Wr(e)) return;
2587
+ }, fi = (e) => {
2588
+ if (e === void 0 || !Jr(e)) return;
2537
2589
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2538
- return t === void 0 ? Ur : Math.min(Ur, t);
2539
- }, li = (e, t, n) => {
2540
- let r = ci(Pr(e, t, n));
2590
+ return t === void 0 ? qr : Math.min(qr, t);
2591
+ }, pi = (e, t, n) => {
2592
+ let r = fi(Rr(e, t, n));
2541
2593
  return r === void 0 ? G(n) : `${G(n)}(${r})`;
2542
- }, ui = (e) => e.startsWith("(") ? e : W(e), Y = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, di = (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(ui).join(", ")})${Y(e.index)};`, fi = (e, t, n = "mariadb") => (pi(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Er(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => li(t, e.table, n)).join(", ")});`), pi = (e, t) => {
2594
+ }, mi = (e) => e.startsWith("(") ? e : W(e), Y = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, hi = (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(mi).join(", ")})${Y(e.index)};`, gi = (e, t, n = "mariadb") => (_i(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Ar(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => pi(t, e.table, n)).join(", ")});`), _i = (e, t) => {
2543
2595
  if (e.where !== void 0) throw Error(`Partial index '${e.name}' is not supported by ${t}; uniqueActive must be lowered before applying the plan.`);
2544
- }, mi = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, hi = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, gi = (e) => `DROP INDEX IF EXISTS ${J(e.index)} ON ${J(e.table)};`, _i = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, vi = (e) => {
2596
+ }, vi = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, yi = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, bi = (e) => `DROP INDEX IF EXISTS ${J(e.index)} ON ${J(e.table)};`, xi = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Si = (e) => {
2545
2597
  let t = (e) => e.replace(/'/g, "''");
2546
2598
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2547
- }, yi = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, bi = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, xi = (e) => {
2599
+ }, Ci = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, wi = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, Ti = (e) => {
2548
2600
  let t = (e) => e.replace(/'/g, "''");
2549
2601
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2550
- }, Si = (e) => {
2602
+ }, Ei = (e) => {
2551
2603
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${J(e.index.name)} ON ${J(e.table)} (${e.index.columns.map(J).join(", ")})${Y(e.index)}`;
2552
2604
  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)}');`;
2553
- }, Ci = (e, t, n) => {
2605
+ }, Di = (e, t, n) => {
2554
2606
  let r = n.find((t) => t.tableName === e);
2555
2607
  if (!r) return [];
2556
2608
  let i = [];
@@ -2559,13 +2611,13 @@ BEGIN
2559
2611
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${J(e)} ALTER COLUMN ${J(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2560
2612
  }
2561
2613
  return i;
2562
- }, wi = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, Ti = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${li(t, e.table, e.column)});`, Ei = (e) => {
2614
+ }, Oi = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, ki = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${pi(t, e.table, e.column)});`, Ai = (e) => {
2563
2615
  let t = e.fields.map((e) => W(e)).join(", ");
2564
2616
  return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2565
- }, Di = (e, t) => {
2566
- let n = e.fields.map((n) => li(t, e.table, n)).join(", ");
2617
+ }, ji = (e, t) => {
2618
+ let n = e.fields.map((n) => pi(t, e.table, n)).join(", ");
2567
2619
  return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2568
- }, Oi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, ki = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, Ai = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, ji = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Mi = (e, t) => {
2620
+ }, Mi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, Ni = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, Pi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, Fi = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Ii = (e, t) => {
2569
2621
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2570
2622
  if (e.orphanPolicy) {
2571
2623
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2583,10 +2635,10 @@ BEGIN
2583
2635
  setNull: "SET NULL",
2584
2636
  noAction: "NO ACTION"
2585
2637
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2586
- }, Ni = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Pi = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, Fi = (e, t) => {
2638
+ }, Li = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Ri = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, zi = (e, t) => {
2587
2639
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2588
2640
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2589
- }, Ii = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Li = (e, t) => w.gen(function* () {
2641
+ }, Bi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Vi = (e, t) => w.gen(function* () {
2590
2642
  let n = yield* e`
2591
2643
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2592
2644
  FROM information_schema.check_constraints cc
@@ -2599,18 +2651,18 @@ BEGIN
2599
2651
  WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), w.orElseSucceed(() => []));
2600
2652
  for (let e of n) {
2601
2653
  let n = String(e.n ?? "");
2602
- if (n !== "" && Un(String(e.c ?? ""))?.column === t.column) return n;
2654
+ if (n !== "" && Gn(String(e.c ?? ""))?.column === t.column) return n;
2603
2655
  }
2604
- }), Ri = (e, t, n) => w.gen(function* () {
2605
- let r = yield* Li(e, t);
2606
- r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [yr]));
2607
- let i = yield* Li(e, t);
2656
+ }), Hi = (e, t, n) => w.gen(function* () {
2657
+ let r = yield* Vi(e, t);
2658
+ r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [Cr]));
2659
+ let i = yield* Vi(e, t);
2608
2660
  if (i === void 0) return;
2609
2661
  let a = K(n, t.table, t.column);
2610
2662
  if (!a) return yield* w.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.`));
2611
- yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Fr(a, t.column)};`, t.kind);
2612
- }), zi = (e, t, n, r) => {
2613
- let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? J : W, s = a ? Tr(i) : r === "mssql" ? ni(i) : r === "sqlite" ? Xr(i) : Cr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Ir(e, i) : r === "mssql" ? Zr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Zr(e, "CURRENT_TIMESTAMP") : Rr(e, i), u = zr(i, r);
2663
+ yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${zr(a, t.column)};`, t.kind);
2664
+ }), Ui = (e, t, n, r) => {
2665
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? J : W, s = a ? kr(i) : r === "mssql" ? oi(i) : r === "sqlite" ? ei(i) : Dr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Br(e, i) : r === "mssql" ? ti(e, "SYSUTCDATETIME()") : r === "sqlite" ? ti(e, "CURRENT_TIMESTAMP") : Hr(e, i), u = Ur(i, r);
2614
2666
  if (u) {
2615
2667
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2616
2668
  return {
@@ -2638,7 +2690,7 @@ BEGIN
2638
2690
  post: f ? [f] : []
2639
2691
  };
2640
2692
  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;
2641
- }, Bi = (e) => {
2693
+ }, Wi = (e) => {
2642
2694
  let t = new Map(e.map((e) => [e.tableName, e]));
2643
2695
  return (e, n) => {
2644
2696
  let r = t.get(e);
@@ -2658,47 +2710,47 @@ BEGIN
2658
2710
  ...o
2659
2711
  };
2660
2712
  };
2661
- }, X = (e, t, n, r = []) => e.unsafe(t).pipe(w.catchIf((e) => hr(e, r), () => w.void), w.tapError((e) => w.sync(() => {
2662
- process.stderr.write(ce(`applier: statement failed (op=${n})`, t, e, 400));
2713
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(w.catchIf((e) => yr(e, r), () => w.void), w.tapError((e) => w.sync(() => {
2714
+ process.stderr.write(se(`applier: statement failed (op=${n})`, t, e, 400));
2663
2715
  })), w.mapError((e) => {
2664
- let r = ce(`applier: statement failed (op=${n})`, t, e, 400).trim();
2716
+ let r = se(`applier: statement failed (op=${n})`, t, e, 400).trim();
2665
2717
  return Object.assign(e, { message: r });
2666
- }), w.map(() => void 0)), Z = (e, t, n) => w.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 ? "*" : o(r, t)} FROM ${o(n, t)} WHERE 1=0`).pipe(w.as(!0), w.catchAll(() => w.succeed(!1))), Vi = (e, t) => w.gen(function* () {
2667
- let n = F([Ve], t).tables[0];
2718
+ }), w.map(() => void 0)), Z = (e, t, n) => w.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 ? "*" : o(r, t)} FROM ${o(n, t)} WHERE 1=0`).pipe(w.as(!0), w.catchAll(() => w.succeed(!1))), Gi = (e, t) => w.gen(function* () {
2719
+ let n = R([Be], t).tables[0];
2668
2720
  if (!n) return yield* w.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2669
2721
  let r = {
2670
2722
  kind: "create-table",
2671
- table: O,
2723
+ table: k,
2672
2724
  columns: n.columns,
2673
2725
  indexes: []
2674
2726
  }, i = yield* e.onDialectOrElse({
2675
- mysql: () => H(e).pipe(w.map((e) => qr(r, e))),
2676
- mssql: () => w.succeed(ii(r)),
2677
- sqlite: () => w.succeed($r(r)),
2678
- orElse: () => w.succeed(Hr(r))
2727
+ mysql: () => hr(e).pipe(w.map((e) => Zr(r, e))),
2728
+ mssql: () => w.succeed(ci(r)),
2729
+ sqlite: () => w.succeed(ri(r)),
2730
+ orElse: () => w.succeed(Kr(r))
2679
2731
  });
2680
2732
  yield* w.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2681
- }), Hi = (e) => e`
2733
+ }), Ki = (e) => e`
2682
2734
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2683
2735
  ${e("status")}, ${e("payload")}
2684
- FROM ${e(O)}
2685
- `, Ui = (e, t, n, r) => w.gen(function* () {
2736
+ FROM ${e(k)}
2737
+ `, qi = (e, t, n, r) => w.gen(function* () {
2686
2738
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2687
2739
  yield* w.forEach(r, ({ index: r, planned: a }) => e`
2688
- INSERT INTO ${e(O)}
2740
+ INSERT INTO ${e(k)}
2689
2741
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2690
2742
  ${e("opKind")}, ${e("opTarget")}, ${e("status")}, ${e("payload")},
2691
2743
  ${e("createdAt")})
2692
2744
  VALUES
2693
2745
  (${`mop_${t}_${r}`}, ${t}, ${n}, ${r},
2694
- ${a.op.kind}, ${Ue(a.op)}, ${"pending"},
2746
+ ${a.op.kind}, ${He(a.op)}, ${"pending"},
2695
2747
  ${JSON.stringify(a)}, ${i})
2696
2748
  `, { discard: !0 });
2697
- }), Wi = (e, t, n, r, i) => w.gen(function* () {
2749
+ }), Ji = (e, t, n, r, i) => w.gen(function* () {
2698
2750
  let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2699
2751
  if (r === "applied") {
2700
2752
  yield* e`
2701
- UPDATE ${e(O)}
2753
+ UPDATE ${e(k)}
2702
2754
  SET ${e("status")} = ${r}, ${e("appliedAt")} = ${a},
2703
2755
  ${e("durationMs")} = ${i ?? null}
2704
2756
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
@@ -2706,50 +2758,50 @@ BEGIN
2706
2758
  return;
2707
2759
  }
2708
2760
  yield* e`
2709
- UPDATE ${e(O)}
2761
+ UPDATE ${e(k)}
2710
2762
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2711
2763
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2712
2764
  `;
2713
- }), Gi = (e, t, n, r) => w.gen(function* () {
2765
+ }), Yi = (e, t, n, r) => w.gen(function* () {
2714
2766
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2715
2767
  r.length > 0 && (yield* e`
2716
- UPDATE ${e(O)}
2768
+ UPDATE ${e(k)}
2717
2769
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
2718
2770
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(r)}
2719
2771
  `), n.length > 0 && (yield* e`
2720
- UPDATE ${e(O)}
2772
+ UPDATE ${e(k)}
2721
2773
  SET ${e("status")} = ${"pending"}
2722
2774
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2723
2775
  `);
2724
- }), Ki = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(w.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(w.asVoid), qi = (e, t, n) => w.gen(function* () {
2725
- if (Ze(n.op, n.classification, t) !== "artefact-repair") return "clean";
2776
+ }), Xi = (e, t) => t === void 0 ? e`DELETE FROM ${e(k)}`.pipe(w.asVoid) : e`DELETE FROM ${e(k)} WHERE ${e("runId")} = ${t}`.pipe(w.asVoid), Zi = (e, t, n) => w.gen(function* () {
2777
+ if (Xe(n.op, n.classification, t) !== "artefact-repair") return "clean";
2726
2778
  let r = n.op, i = (e) => o(e, t);
2727
2779
  if (t === "sqlite" || t === "turso") {
2728
2780
  if (!("table" in r)) return "clean";
2729
- let n = `${r.table}${Ke}`;
2781
+ let n = `${r.table}${Ge}`;
2730
2782
  return (yield* $(e, t, n)) ? ((yield* $(e, t, r.table)) ? yield* X(e, `DROP TABLE ${i(n)}`, "resume-repair") : yield* X(e, `ALTER TABLE ${i(n)} RENAME TO ${i(r.table)}`, "resume-repair"), yield* w.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
2731
2783
  }
2732
2784
  if (r.kind !== "alter-column-type") return "clean";
2733
- let a = `${r.column}${qe}`, s = `${r.column}${Je}`, c = yield* $(e, t, r.table, r.column), l = yield* $(e, t, r.table, a), u = yield* $(e, t, r.table, s), d = (e) => w.logWarning(`migration resume: ${e}`).pipe(w.annotateLogs({ scope: "voltro:migrate" }));
2785
+ let a = `${r.column}${Ke}`, s = `${r.column}${qe}`, c = yield* $(e, t, r.table, r.column), l = yield* $(e, t, r.table, a), u = yield* $(e, t, r.table, s), d = (e) => w.logWarning(`migration resume: ${e}`).pipe(w.annotateLogs({ scope: "voltro:migrate" }));
2734
2786
  return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(a)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${r.table}.${a}' — replaying the type change`), "outstanding") : !c && l && u ? (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(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${r.table}.${s}'`), "applied") : yield* w.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${a}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2735
- }), Ji = (e, t, n, r = "fresh") => w.gen(function* () {
2736
- let i = process.hrtime.bigint(), a = Bi(n.declared), o = t.op;
2787
+ }), Qi = (e, t, n, r = "fresh") => w.gen(function* () {
2788
+ let i = process.hrtime.bigint(), a = Wi(n.declared), o = t.op;
2737
2789
  switch (o.kind) {
2738
2790
  case "create-table": {
2739
2791
  let t = yield* e.onDialectOrElse({
2740
- mysql: () => H(e).pipe(w.map((e) => qr(o, e))),
2741
- mssql: () => w.succeed(ii(o)),
2742
- sqlite: () => w.succeed($r(o)),
2743
- orElse: () => w.succeed(Hr(o))
2792
+ mysql: () => hr(e).pipe(w.map((e) => Zr(o, e))),
2793
+ mssql: () => w.succeed(ci(o)),
2794
+ sqlite: () => w.succeed(ri(o)),
2795
+ orElse: () => w.succeed(Kr(o))
2744
2796
  }), n = yield* e.onDialectOrElse({
2745
- mysql: () => w.succeed([gr]),
2797
+ mysql: () => w.succeed([br]),
2746
2798
  orElse: () => w.succeed([])
2747
2799
  });
2748
2800
  for (let r of t) yield* X(e, r, o.kind, n);
2749
2801
  break;
2750
2802
  }
2751
2803
  case "drop-table": {
2752
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? si(o, n, e) : oi(o, e);
2804
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? di(o, n, e) : ui(o, e);
2753
2805
  yield* e.onDialectOrElse({
2754
2806
  mysql: () => X(e, r(G), o.kind),
2755
2807
  orElse: () => X(e, r(W), o.kind)
@@ -2759,93 +2811,93 @@ BEGIN
2759
2811
  case "drop-column": {
2760
2812
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2761
2813
  yield* e.onDialectOrElse({
2762
- mysql: () => H(e).pipe(w.flatMap((r) => X(e, t ? Ar(o, n, G) : Or(o, r), o.kind, t ? [] : [_r]))),
2763
- sqlite: () => X(e, t ? Ar(o, n, W) : Dr(o, W, !1), o.kind, t ? [] : [vr]),
2764
- orElse: () => X(e, t ? Ar(o, n, W) : Dr(o, W), o.kind)
2814
+ mysql: () => hr(e).pipe(w.flatMap((r) => X(e, t ? Pr(o, n, G) : Mr(o, r), o.kind, t ? [] : [xr]))),
2815
+ sqlite: () => X(e, t ? Pr(o, n, W) : jr(o, W, !1), o.kind, t ? [] : [Sr]),
2816
+ orElse: () => X(e, t ? Pr(o, n, W) : jr(o, W), o.kind)
2765
2817
  });
2766
2818
  break;
2767
2819
  }
2768
2820
  case "rename-column":
2769
2821
  yield* e.onDialectOrElse({
2770
- mysql: () => X(e, kr(o, G), o.kind),
2822
+ mysql: () => X(e, Nr(o, G), o.kind),
2771
2823
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2772
- orElse: () => X(e, kr(o, W), o.kind)
2824
+ orElse: () => X(e, Nr(o, W), o.kind)
2773
2825
  });
2774
2826
  break;
2775
2827
  case "add-index":
2776
2828
  yield* e.onDialectOrElse({
2777
- sqlite: () => X(e, di(o, !1), o.kind),
2778
- mysql: () => H(e).pipe(w.flatMap((t) => X(e, fi(o, n.declared, t), o.kind, [gr]))),
2779
- mssql: () => Z(e, [...Ci(o.table, o.index.columns, n.declared), Si(o)], o.kind),
2780
- orElse: () => X(e, di(o, t.classification === "online-required"), o.kind)
2829
+ sqlite: () => X(e, hi(o, !1), o.kind),
2830
+ mysql: () => hr(e).pipe(w.flatMap((t) => X(e, gi(o, n.declared, t), o.kind, [br]))),
2831
+ mssql: () => Z(e, [...Di(o.table, o.index.columns, n.declared), Ei(o)], o.kind),
2832
+ orElse: () => X(e, hi(o, t.classification === "online-required"), o.kind)
2781
2833
  });
2782
2834
  break;
2783
2835
  case "drop-index":
2784
2836
  yield* e.onDialectOrElse({
2785
- mysql: () => X(e, hi(o), o.kind),
2786
- mssql: () => X(e, gi(o), o.kind),
2787
- orElse: () => X(e, mi(o), o.kind)
2837
+ mysql: () => X(e, yi(o), o.kind),
2838
+ mssql: () => X(e, bi(o), o.kind),
2839
+ orElse: () => X(e, vi(o), o.kind)
2788
2840
  });
2789
2841
  break;
2790
2842
  case "rename-table":
2791
2843
  yield* e.onDialectOrElse({
2792
- mysql: () => X(e, _i(o, G), o.kind),
2793
- mssql: () => X(e, vi(o), o.kind),
2794
- orElse: () => X(e, _i(o, W), o.kind)
2844
+ mysql: () => X(e, xi(o, G), o.kind),
2845
+ mssql: () => X(e, Si(o), o.kind),
2846
+ orElse: () => X(e, xi(o, W), o.kind)
2795
2847
  });
2796
2848
  break;
2797
2849
  case "rename-index":
2798
2850
  yield* e.onDialectOrElse({
2799
- mysql: () => X(e, bi(o), o.kind),
2800
- mssql: () => X(e, xi(o), o.kind),
2801
- orElse: () => X(e, yi(o), o.kind)
2851
+ mysql: () => X(e, wi(o), o.kind),
2852
+ mssql: () => X(e, Ti(o), o.kind),
2853
+ orElse: () => X(e, Ci(o), o.kind)
2802
2854
  });
2803
2855
  break;
2804
2856
  case "add-unique":
2805
2857
  yield* e.onDialectOrElse({
2806
- mysql: () => X(e, Ti(o, n.declared), o.kind),
2858
+ mysql: () => X(e, ki(o, n.declared), o.kind),
2807
2859
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2808
- mssql: () => Z(e, [...Ci(o.table, [o.column], n.declared), wi(o)], o.kind),
2809
- orElse: () => X(e, wi(o), o.kind)
2860
+ mssql: () => Z(e, [...Di(o.table, [o.column], n.declared), Oi(o)], o.kind),
2861
+ orElse: () => X(e, Oi(o), o.kind)
2810
2862
  });
2811
2863
  break;
2812
2864
  case "drop-unique":
2813
2865
  yield* e.onDialectOrElse({
2814
- mysql: () => X(e, ji(o), o.kind),
2866
+ mysql: () => X(e, Fi(o), o.kind),
2815
2867
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2816
- orElse: () => X(e, Ai(o), o.kind)
2868
+ orElse: () => X(e, Pi(o), o.kind)
2817
2869
  });
2818
2870
  break;
2819
2871
  case "add-unique-composite":
2820
2872
  yield* e.onDialectOrElse({
2821
- mysql: () => X(e, Di(o, n.declared), o.kind),
2873
+ mysql: () => X(e, ji(o, n.declared), o.kind),
2822
2874
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2823
- mssql: () => Z(e, [...Ci(o.table, o.fields, n.declared), Ei(o)], o.kind),
2824
- orElse: () => X(e, Ei(o), o.kind)
2875
+ mssql: () => Z(e, [...Di(o.table, o.fields, n.declared), Ai(o)], o.kind),
2876
+ orElse: () => X(e, Ai(o), o.kind)
2825
2877
  });
2826
2878
  break;
2827
2879
  case "drop-unique-composite":
2828
2880
  yield* e.onDialectOrElse({
2829
- mysql: () => X(e, ki(o), o.kind),
2881
+ mysql: () => X(e, Ni(o), o.kind),
2830
2882
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2831
- orElse: () => X(e, Oi(o), o.kind)
2883
+ orElse: () => X(e, Mi(o), o.kind)
2832
2884
  });
2833
2885
  break;
2834
2886
  case "add-foreign-key":
2835
2887
  yield* e.onDialectOrElse({
2836
- mysql: () => Z(e, Mi(o, G), o.kind),
2888
+ mysql: () => Z(e, Ii(o, G), o.kind),
2837
2889
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2838
- orElse: () => Z(e, Mi(o, W), o.kind)
2890
+ orElse: () => Z(e, Ii(o, W), o.kind)
2839
2891
  });
2840
2892
  break;
2841
2893
  case "add-column": {
2842
- let n = zi(o, t, a, yield* e.onDialectOrElse({
2894
+ let n = Ui(o, t, a, yield* e.onDialectOrElse({
2843
2895
  mysql: () => w.succeed("mariadb"),
2844
2896
  mssql: () => w.succeed("mssql"),
2845
2897
  sqlite: () => w.succeed("sqlite"),
2846
2898
  orElse: () => w.succeed("postgres")
2847
2899
  }));
2848
- if (!(r === "resume" && (yield* $(e, Re(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2900
+ if (!(r === "resume" && (yield* $(e, Le(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2849
2901
  if (n.backfillKind === "sql" && n.backfillSql) {
2850
2902
  if (t.classification !== "online-required" && n.batchSize === void 0) yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql}`;
2851
2903
  else {
@@ -2886,43 +2938,43 @@ BEGIN
2886
2938
  yield* e.onDialectOrElse({
2887
2939
  mysql: () => {
2888
2940
  let t = K(n.declared, o.table, o.column);
2889
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(t, o.column, o.toNullable)};`, o.kind) : w.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.`));
2941
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${zr(t, o.column, o.toNullable)};`, o.kind) : w.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.`));
2890
2942
  },
2891
2943
  mssql: () => {
2892
2944
  let t = K(n.declared, o.table, o.column);
2893
- return t ? X(e, ei(t, o.column, o.table, o.toNullable), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2945
+ return t ? X(e, ii(t, o.column, o.table, o.toNullable), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2894
2946
  },
2895
2947
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2896
2948
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2897
2949
  });
2898
2950
  break;
2899
2951
  case "alter-column-default": {
2900
- let t = Pr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Mr(r, e) ? r : void 0;
2952
+ let t = Rr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Ir(r, e) ? r : void 0;
2901
2953
  yield* e.onDialectOrElse({
2902
2954
  mysql: () => {
2903
2955
  let n = i("mariadb");
2904
- return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(n, o.column)};` : jr(o, G, (e) => Ir(e, t)), o.kind);
2956
+ return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${zr(n, o.column)};` : Fr(o, G, (e) => Br(e, t)), o.kind);
2905
2957
  },
2906
2958
  mssql: () => {
2907
2959
  let t = i("mssql");
2908
- return X(e, ti(o, t ? ei(t, o.column, o.table) : void 0), o.kind);
2960
+ return X(e, ai(o, t ? ii(t, o.column, o.table) : void 0), o.kind);
2909
2961
  },
2910
2962
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2911
- orElse: () => X(e, jr(o, W, (e) => Rr(e, t)), o.kind)
2963
+ orElse: () => X(e, Fr(o, W, (e) => Hr(e, t)), o.kind)
2912
2964
  });
2913
2965
  break;
2914
2966
  }
2915
2967
  case "alter-column-type": {
2916
- let r = Cr(Pr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2968
+ let r = Dr(Rr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2917
2969
  if (t.classification !== "online-required") {
2918
2970
  yield* e.onDialectOrElse({
2919
2971
  mysql: () => {
2920
2972
  let t = K(n.declared, o.table, o.column);
2921
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(t, o.column)};`, o.kind) : w.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.`));
2973
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${zr(t, o.column)};`, o.kind) : w.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.`));
2922
2974
  },
2923
2975
  mssql: () => {
2924
2976
  let t = K(n.declared, o.table, o.column);
2925
- return t ? X(e, ei(t, o.column, o.table), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2977
+ return t ? X(e, ii(t, o.column, o.table), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2926
2978
  },
2927
2979
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2928
2980
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
@@ -2946,22 +2998,22 @@ BEGIN
2946
2998
  }
2947
2999
  case "drop-foreign-key":
2948
3000
  yield* e.onDialectOrElse({
2949
- mysql: () => X(e, Pi(o), o.kind),
3001
+ mysql: () => X(e, Ri(o), o.kind),
2950
3002
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2951
- orElse: () => X(e, Ni(o), o.kind)
3003
+ orElse: () => X(e, Li(o), o.kind)
2952
3004
  });
2953
3005
  break;
2954
3006
  case "add-check":
2955
3007
  yield* e.onDialectOrElse({
2956
- mysql: () => X(e, Fi(o, G), o.kind),
3008
+ mysql: () => X(e, zi(o, G), o.kind),
2957
3009
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2958
- orElse: () => X(e, Fi(o, W), o.kind)
3010
+ orElse: () => X(e, zi(o, W), o.kind)
2959
3011
  });
2960
3012
  break;
2961
3013
  case "drop-check": yield* e.onDialectOrElse({
2962
- mysql: () => Ri(e, o, n.declared),
3014
+ mysql: () => Hi(e, o, n.declared),
2963
3015
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2964
- orElse: () => X(e, Ii(o), o.kind)
3016
+ orElse: () => X(e, Bi(o), o.kind)
2965
3017
  });
2966
3018
  }
2967
3019
  return {
@@ -2969,32 +3021,32 @@ BEGIN
2969
3021
  status: "applied",
2970
3022
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2971
3023
  };
2972
- }), Yi = (e, t, n, r) => w.gen(function* () {
3024
+ }), $i = (e, t, n, r) => w.gen(function* () {
2973
3025
  let i = [...new Set(r.map((e) => e.runId))];
2974
- if (i.length > 1) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
3026
+ if (i.length > 1) return yield* w.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.`));
2975
3027
  let a = i[0], o = [...r].map((e) => ({
2976
3028
  index: Number(e.opIndex),
2977
3029
  status: e.status,
2978
3030
  planned: JSON.parse(e.payload)
2979
3031
  })).sort((e, t) => e.index - t.index), s = o.find((e) => e.status === "started"), c = o.filter((e) => e.status === "started").length;
2980
- if (c > 1) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${O}\` by hand before re-running.`));
2981
- if (yield* w.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${Ue(s.planned.op)}` : ""}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
3032
+ if (c > 1) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${k}\` by hand before re-running.`));
3033
+ if (yield* w.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${He(s.planned.op)}` : ""}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2982
3034
  kind: "discard",
2983
3035
  runId: a,
2984
3036
  why: "no operation had started — no DDL ran"
2985
3037
  };
2986
- let l = s ? yield* qi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
3038
+ let l = s ? yield* Zi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2987
3039
  if (u !== n.toFingerprint) return {
2988
3040
  kind: "discard",
2989
3041
  runId: a,
2990
3042
  why: `the declared schema changed since the interruption (recorded target ${u.slice(0, 12)}…, current ${n.toFingerprint.slice(0, 12)}…) — applying the freshly-diffed plan instead`
2991
3043
  };
2992
- let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : Ge(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
3044
+ let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : We(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2993
3045
  return f.length === 0 ? {
2994
3046
  kind: "discard",
2995
3047
  runId: a,
2996
3048
  why: "every recorded operation had already taken effect"
2997
- } : (yield* Gi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* w.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), {
3049
+ } : (yield* Yi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* w.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), {
2998
3050
  kind: "resume",
2999
3051
  runId: a,
3000
3052
  ops: f.map((e) => ({
@@ -3002,7 +3054,7 @@ BEGIN
3002
3054
  planned: e.planned
3003
3055
  }))
3004
3056
  });
3005
- }), Xi = (e, t, n) => w.gen(function* () {
3057
+ }), ea = (e, t, n) => w.gen(function* () {
3006
3058
  for (let r of t.operations) {
3007
3059
  let i = r.op;
3008
3060
  if (i.kind !== "add-index" || !i.index.unique || i.index.where === void 0 || t.operations.some((e) => e.op.kind === "rename-table" ? e.op.to === i.table : e.op.table === i.table && [
@@ -3013,7 +3065,7 @@ BEGIN
3013
3065
  let a = i.index.columns.map((e) => e.startsWith("(") ? e : o(e, n)), s = n === "mssql" ? "" : a.map((e) => ` AND ${e} IS NOT NULL`).join(""), c = n === "mssql" ? "SELECT TOP (1) 1" : "SELECT 1", l = n === "mssql" ? "" : " LIMIT 1";
3014
3066
  if ((yield* e.unsafe(`${c} FROM ${o(i.table, n)} WHERE (${i.index.where})${s} GROUP BY ${a.join(", ")} HAVING COUNT(*) > 1${l}`)).length > 0) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: partial unique index '${i.index.name}' on '${i.table}' conflicts with existing qualifying rows. No schema or row changes were applied. Resolve the conflicting data explicitly before retrying.`));
3015
3067
  }
3016
- }), Zi = (e) => {
3068
+ }), ta = (e) => {
3017
3069
  let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
3018
3070
  return [
3019
3071
  t.kind,
@@ -3022,13 +3074,13 @@ BEGIN
3022
3074
  n("name"),
3023
3075
  n("to")
3024
3076
  ].join("\0");
3025
- }, Qi = (e, t, n) => w.acquireUseRelease(Ie(e, { schema: n.lockSchema }), () => $i(e, t, n), (e) => e.release.pipe(w.orDie)), $i = (e, t, n) => w.gen(function* () {
3077
+ }, na = (e, t, n) => w.acquireUseRelease(Fe(e, { schema: n.lockSchema }), () => ra(e, t, n), (e) => e.release.pipe(w.orDie)), ra = (e, t, n) => w.gen(function* () {
3026
3078
  let r = t.operations.filter((e) => e.blocked);
3027
3079
  if (r.length > 0) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
3028
- let i = Date.now(), a = [], o = Re(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => Zi(e))), l = {
3080
+ let i = Date.now(), a = [], o = Le(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => ta(e))), l = {
3029
3081
  ...s,
3030
3082
  operations: s.operations.map((e) => {
3031
- if (!e.blocked || !c.has(Zi(e))) return e;
3083
+ if (!e.blocked || !c.has(ta(e))) return e;
3032
3084
  let { blocked: t, ...n } = e;
3033
3085
  return n;
3034
3086
  })
@@ -3036,47 +3088,47 @@ BEGIN
3036
3088
  (l.operations.length !== t.operations.length || l.toFingerprint !== t.toFingerprint) && (yield* w.logInfo(`migration: re-planned under the lock — ${t.operations.length} operation(s) became ${l.operations.length}. Another writer changed the schema while this plan waited.`).pipe(w.annotateLogs({ scope: "voltro:migrate" })));
3037
3089
  let u = l.operations.filter((e) => e.blocked);
3038
3090
  if (u.length > 0) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — re-planning under the migration lock found ${u.length} blocked operation(s). Run \`voltro db plan\` to see the fixes.`));
3039
- let d = Be(o) === "plan-transactional", f = d ? l.operations.filter((e) => e.classification !== "online-required") : [], p = d ? l.operations.filter((e) => e.classification === "online-required") : l.operations, m = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, h = p.map((e, t) => ({
3091
+ let d = ze(o) === "plan-transactional", f = d ? l.operations.filter((e) => e.classification !== "online-required") : [], p = d ? l.operations.filter((e) => e.classification === "online-required") : l.operations, m = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, h = p.map((e, t) => ({
3040
3092
  index: t,
3041
3093
  planned: e
3042
3094
  })), _ = "fresh";
3043
- yield* Xi(e, l, o), yield* Vi(e, o);
3044
- let v = yield* Hi(e);
3095
+ yield* ea(e, l, o), yield* Gi(e, o);
3096
+ let v = yield* Ki(e);
3045
3097
  if (v.length > 0) {
3046
- let t = yield* Yi(e, o, l, v);
3047
- t.kind === "resume" ? (m = t.runId, h = t.ops, _ = "resume") : (yield* w.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), yield* Ki(e, t.runId));
3098
+ let t = yield* $i(e, o, l, v);
3099
+ t.kind === "resume" ? (m = t.runId, h = t.ops, _ = "resume") : (yield* w.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), yield* Xi(e, t.runId));
3048
3100
  }
3049
- _ === "fresh" && h.length > 0 && (yield* Ui(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(w.gen(function* () {
3050
- let e = yield* T.SqlClient;
3051
- for (let t of f) a.push(yield* Ji(e, t, n));
3101
+ _ === "fresh" && h.length > 0 && (yield* qi(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(w.gen(function* () {
3102
+ let e = yield* E.SqlClient;
3103
+ for (let t of f) a.push(yield* Qi(e, t, n));
3052
3104
  })));
3053
3105
  for (let { index: t, planned: r } of h) {
3054
- yield* Wi(e, m, t, "started");
3055
- let i = a.length, o = yield* Ji(e, r, n, _).pipe(w.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`) })));
3056
- a.push(o), yield* Wi(e, m, t, "applied", o.durationMs);
3106
+ yield* Ji(e, m, t, "started");
3107
+ let i = a.length, o = yield* Qi(e, r, n, _).pipe(w.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`) })));
3108
+ a.push(o), yield* Ji(e, m, t, "applied", o.durationMs);
3057
3109
  }
3058
3110
  let y = yield* n.replan(e);
3059
3111
  if (y.operations.length > 0) {
3060
3112
  let e = y.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");
3061
3113
  return yield* w.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 ${y.operations.length}:\n${e}${y.operations.length > 10 ? `\n … and ${y.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.`));
3062
3114
  }
3063
- let b = a.filter((e) => e.status === "applied").length, x = Date.now() - i, S = m, C = (/* @__PURE__ */ new Date()).toISOString(), ee = yield* U(e, C), te = [...f, ...h.map((e) => e.planned)];
3115
+ let b = a.filter((e) => e.status === "applied").length, x = Date.now() - i, S = m, C = (/* @__PURE__ */ new Date()).toISOString(), T = yield* U(e, C), ee = [...f, ...h.map((e) => e.planned)];
3064
3116
  yield* e`
3065
3117
  INSERT INTO ${e("_voltro_migration_plans")}
3066
3118
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
3067
3119
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
3068
3120
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
3069
3121
  VALUES
3070
- (${S}, ${l.toFingerprint}, ${y.fromFingerprint}, ${JSON.stringify(te)},
3122
+ (${S}, ${l.toFingerprint}, ${y.fromFingerprint}, ${JSON.stringify(ee)},
3071
3123
  ${n.appliedBy}, ${n.environment}, ${n.source},
3072
- ${x}, ${ee}, ${n.notes ?? null})
3073
- `, yield* Ki(e, m);
3074
- let ne = [...new Set(te.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
3075
- return yield* w.promise(() => g({ changedTables: ne }).catch(() => {})), {
3124
+ ${x}, ${T}, ${n.notes ?? null})
3125
+ `, yield* Xi(e, m);
3126
+ let te = [...new Set(ee.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
3127
+ return yield* w.promise(() => g({ changedTables: te }).catch(() => {})), {
3076
3128
  id: S,
3077
3129
  appliedAt: C,
3078
3130
  fingerprint: l.toFingerprint,
3079
- operations: te,
3131
+ operations: ee,
3080
3132
  appliedBy: n.appliedBy,
3081
3133
  environment: n.environment,
3082
3134
  durationMs: x,
@@ -3084,13 +3136,13 @@ BEGIN
3084
3136
  source: n.source,
3085
3137
  ...n.notes ? { notes: n.notes } : {}
3086
3138
  };
3087
- }), ea = (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"), ta = (e) => e`
3139
+ }), ia = (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"), aa = (e) => e`
3088
3140
  SELECT fingerprint
3089
3141
  FROM _voltro_migration_plans
3090
3142
  ORDER BY ${e("appliedAt")} DESC
3091
3143
  LIMIT 1
3092
- `.pipe(w.map((e) => e.length > 0 ? e[0].fingerprint : void 0), w.catchAll(() => w.succeed(void 0))), na = (e, t, n) => w.gen(function* () {
3093
- if ((yield* ta(e)) === t.toFingerprint) return "already-current";
3144
+ `.pipe(w.map((e) => e.length > 0 ? e[0].fingerprint : void 0), w.catchAll(() => w.succeed(void 0))), oa = (e, t, n) => w.gen(function* () {
3145
+ if ((yield* aa(e)) === t.toFingerprint) return "already-current";
3094
3146
  let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3095
3147
  return yield* e`
3096
3148
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3102,8 +3154,8 @@ BEGIN
3102
3154
  ${n.appliedBy}, ${n.environment}, ${n.source},
3103
3155
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
3104
3156
  `, "recorded";
3105
- }).pipe(w.catchAll(() => w.succeed("already-current"))), ra = (e, t) => w.gen(function* () {
3106
- let n = $t(F(t, Re(e))), r = yield* ta(e);
3157
+ }).pipe(w.catchAll(() => w.succeed("already-current"))), sa = (e, t) => w.gen(function* () {
3158
+ let n = L(R(t, Le(e))), r = yield* aa(e);
3107
3159
  return r === n ? {
3108
3160
  kind: "up-to-date",
3109
3161
  fingerprint: n
@@ -3112,23 +3164,23 @@ BEGIN
3112
3164
  expected: n,
3113
3165
  ...r === void 0 ? {} : { actual: r }
3114
3166
  };
3115
- }), ia = [
3167
+ }), ca = [
3116
3168
  "pgeagertest_",
3117
3169
  "mig_e2e_",
3118
3170
  "mig_test_",
3119
3171
  "mysqleagertest_",
3120
3172
  "mssqleagertest_",
3121
3173
  "sqliteeagertest_"
3122
- ], aa = (e) => ia.some((t) => e.startsWith(t)), oa = (e, t) => w.gen(function* () {
3174
+ ], la = (e) => ca.some((t) => e.startsWith(t)), ua = (e, t) => w.gen(function* () {
3123
3175
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
3124
- let n = t.filter((e) => aa(e.name)).map((e) => e.name);
3176
+ let n = t.filter((e) => la(e.name)).map((e) => e.name);
3125
3177
  if (n.length === 0) return [];
3126
3178
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(w.catchAll(() => w.void));
3127
3179
  return n;
3128
- }), sa = () => {
3180
+ }), da = () => {
3129
3181
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
3130
3182
  return e.length > 0 ? { ignoreTables: e } : {};
3131
- }, ca = (e) => {
3183
+ }, fa = (e) => {
3132
3184
  if (e === void 0) return;
3133
3185
  let t = e.trim();
3134
3186
  if (t === "") return;
@@ -3138,34 +3190,34 @@ BEGIN
3138
3190
  kind: "tables",
3139
3191
  tables: new Set(n)
3140
3192
  } : void 0;
3141
- }, la = (e) => typeof e.table == "string" ? e.table : void 0, ua = (e, t = { kind: "all" }) => ({
3193
+ }, pa = (e) => typeof e.table == "string" ? e.table : void 0, ma = (e, t = { kind: "all" }) => ({
3142
3194
  ...e,
3143
3195
  operations: e.operations.map((e) => {
3144
3196
  if (!e.blocked || e.classification !== "lossy") return e;
3145
3197
  if (t?.kind === "tables") {
3146
- let n = la(e.op);
3198
+ let n = pa(e.op);
3147
3199
  if (n === void 0 || !t.tables.has(n)) return e;
3148
3200
  }
3149
3201
  let { blocked: n, ...r } = e;
3150
3202
  return r;
3151
3203
  })
3152
- }), da = (e, t, n) => t === "postgres" ? on(e, n).pipe(w.flatMap((e) => {
3153
- let t = sn(e);
3204
+ }), ha = (e, t, n) => t === "postgres" ? dn(e, n).pipe(w.flatMap((e) => {
3205
+ let t = fn(e);
3154
3206
  return t === void 0 ? w.void : w.logWarning(`auto-migrate: ${t}`).pipe(w.annotateLogs({ scope: "voltro:migrate" }));
3155
- }), w.catchAll(() => w.void)) : w.void, fa = (e, t, n) => w.gen(function* () {
3156
- let r = Re(e), a = t;
3207
+ }), w.catchAll(() => w.void)) : w.void, ga = (e, t, n) => w.gen(function* () {
3208
+ let r = Le(e), a = t;
3157
3209
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
3158
- let t = $t(F(a, r));
3159
- if ((yield* ta(e)) === t) return yield* da(e, r, a), {
3210
+ let t = L(R(a, r));
3211
+ if ((yield* aa(e)) === t) return yield* ha(e, r, a), {
3160
3212
  kind: "up-to-date",
3161
3213
  fingerprint: t
3162
3214
  };
3163
3215
  }
3164
- let o = yield* lr(e), s = yield* oa(e, o.tables);
3216
+ let o = yield* fr(e), s = yield* ua(e, o.tables);
3165
3217
  s.length > 0 && (yield* w.logInfo(`auto-migrate: reaped ${s.length} test-fixture leftover(s)`).pipe(w.annotateLogs({
3166
3218
  scope: "voltro:migrate",
3167
3219
  count: s.length
3168
- })), o = yield* lr(e));
3220
+ })), o = yield* fr(e));
3169
3221
  {
3170
3222
  let e = n.softDropRetentionDays ?? 7, t = p(o, { retentionDays: e });
3171
3223
  t.length > 0 && (yield* w.logWarning(`auto-migrate: ${i(t, e)}`).pipe(w.annotateLogs({
@@ -3173,20 +3225,20 @@ BEGIN
3173
3225
  snapshots: t.map((e) => e.name)
3174
3226
  })));
3175
3227
  }
3176
- let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !_(e.name) || c.has(e.name)), u = Hn({
3228
+ let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !_(e.name) || c.has(e.name)), u = Wn({
3177
3229
  declared: a,
3178
3230
  live: { tables: l(o.tables) },
3179
3231
  dialect: r,
3180
- ...sa()
3232
+ ...da()
3181
3233
  });
3182
3234
  if (u.summary.blocked > 0) {
3183
- let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = ca(process.env.VOLTRO_DESTRUCTIVE_OK);
3184
- if (t === void 0 || !e || (u = ua(u, t), u.operations.some((e) => e.blocked))) return {
3235
+ let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = fa(process.env.VOLTRO_DESTRUCTIVE_OK);
3236
+ if (t === void 0 || !e || (u = ma(u, t), u.operations.some((e) => e.blocked))) return {
3185
3237
  kind: "refused-blocked",
3186
3238
  plan: u
3187
3239
  };
3188
3240
  }
3189
- return u.operations.length === 0 ? (yield* na(e, u, {
3241
+ return u.operations.length === 0 ? (yield* oa(e, u, {
3190
3242
  appliedBy: n.appliedBy,
3191
3243
  environment: n.environment === "prod" ? "dev" : n.environment,
3192
3244
  source: "auto-diff"
@@ -3195,37 +3247,37 @@ BEGIN
3195
3247
  fingerprint: u.toFingerprint
3196
3248
  }) : {
3197
3249
  kind: "applied",
3198
- applied: yield* Qi(e, u, {
3250
+ applied: yield* na(e, u, {
3199
3251
  declared: t,
3200
3252
  appliedBy: n.appliedBy,
3201
3253
  environment: n.environment === "prod" ? "dev" : n.environment,
3202
3254
  source: "auto-diff",
3203
3255
  replan: (e) => w.gen(function* () {
3204
- let t = yield* lr(e);
3205
- return Hn({
3256
+ let t = yield* fr(e);
3257
+ return Wn({
3206
3258
  declared: a,
3207
3259
  live: { tables: l(t.tables) },
3208
3260
  dialect: r,
3209
- ...sa()
3261
+ ...da()
3210
3262
  });
3211
3263
  })
3212
3264
  }),
3213
3265
  plan: u
3214
3266
  };
3215
- }), pa = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? w.succeed({
3267
+ }), _a = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? w.succeed({
3216
3268
  kind: "skipped",
3217
3269
  reason: "VOLTRO_AUTO_MIGRATE=0"
3218
- }) : n.environment === "prod" ? ra(e, t) : fa(e, t, n), ma = (e, t) => {
3270
+ }) : n.environment === "prod" ? sa(e, t) : ga(e, t, n), va = (e, t) => {
3219
3271
  switch (e.kind) {
3220
3272
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
3221
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${en(e.fingerprint)})`;
3273
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${an(e.fingerprint)})`;
3222
3274
  case "applied": {
3223
3275
  let t = e.plan.summary;
3224
- 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=${en(e.applied.fingerprint)}`;
3276
+ 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=${an(e.applied.fingerprint)}`;
3225
3277
  }
3226
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${en(e.expected)}` + (e.actual ? ` live=${en(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3278
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${an(e.expected)}` + (e.actual ? ` live=${an(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3227
3279
  case "refused-blocked": {
3228
- 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` + ea(e.plan), c = [""];
3280
+ 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` + ia(e.plan), c = [""];
3229
3281
  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) {
3230
3282
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3231
3283
  for (let r of e.plan.operations) {
@@ -3242,7 +3294,7 @@ BEGIN
3242
3294
  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");
3243
3295
  }
3244
3296
  }
3245
- }, ha = ie({ scope: "voltro:migrate" }), ga = /* @__PURE__ */ new Set([
3297
+ }, ya = re({ scope: "voltro:migrate" }), ba = /* @__PURE__ */ new Set([
3246
3298
  "node_modules",
3247
3299
  "dist",
3248
3300
  "build",
@@ -3251,12 +3303,12 @@ BEGIN
3251
3303
  ".next",
3252
3304
  ".git",
3253
3305
  ".framework"
3254
- ]), _a = async (e) => {
3306
+ ]), xa = async (e) => {
3255
3307
  let t = [], n = async (e) => {
3256
- let r = await ae.readdir(e, { withFileTypes: !0 }).catch(() => []);
3308
+ let r = await ie.readdir(e, { withFileTypes: !0 }).catch(() => []);
3257
3309
  for (let i of r) {
3258
- if (ga.has(i.name)) continue;
3259
- let r = oe(e, i.name);
3310
+ if (ba.has(i.name)) continue;
3311
+ let r = ae(e, i.name);
3260
3312
  i.isDirectory() ? await n(r) : i.isFile() && S.test(i.name) && t.push(r);
3261
3313
  }
3262
3314
  };
@@ -3264,12 +3316,12 @@ BEGIN
3264
3316
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3265
3317
  return n.localeCompare(r);
3266
3318
  });
3267
- }, va = async (e) => {
3319
+ }, Sa = async (e) => {
3268
3320
  let t = [];
3269
3321
  for (let n of e) {
3270
- let e = (await import(se(n).href)).default;
3322
+ let e = (await import(oe(n).href)).default;
3271
3323
  if (!u(e)) {
3272
- ha.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3324
+ ya.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3273
3325
  continue;
3274
3326
  }
3275
3327
  t.push({
@@ -3278,11 +3330,11 @@ BEGIN
3278
3330
  });
3279
3331
  }
3280
3332
  return t;
3281
- }, ya = (e) => e`
3333
+ }, Ca = (e) => e`
3282
3334
  SELECT ${e("id")}
3283
3335
  FROM ${e("_voltro_migration_plans")}
3284
3336
  WHERE ${e("source")} = 'file'
3285
- `.pipe(w.map((e) => e.map((e) => e.id)), w.catchAll(() => w.succeed([]))), ba = class extends Error {
3337
+ `.pipe(w.map((e) => e.map((e) => e.id)), w.catchAll(() => w.succeed([]))), wa = class extends Error {
3286
3338
  migrationId;
3287
3339
  file;
3288
3340
  cause;
@@ -3290,7 +3342,7 @@ BEGIN
3290
3342
  constructor(e, t, n) {
3291
3343
  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";
3292
3344
  }
3293
- }, xa = (e, t, n, r) => w.gen(function* () {
3345
+ }, Ta = (e, t, n, r) => w.gen(function* () {
3294
3346
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3295
3347
  sql: e,
3296
3348
  log: {
@@ -3324,10 +3376,10 @@ BEGIN
3324
3376
  }])},
3325
3377
  ${r}, ${n}, ${"file"},
3326
3378
  ${c}, ${l}, ${t.migration.description})
3327
- `.pipe(w.mapError((e) => new ba(t.migration.id, t.file, e))), { durationMs: c };
3328
- }), Sa = (e, t) => w.gen(function* () {
3379
+ `.pipe(w.mapError((e) => new wa(t.migration.id, t.file, e))), { durationMs: c };
3380
+ }), Ea = (e, t) => w.gen(function* () {
3329
3381
  let n = yield* w.tryPromise({
3330
- try: () => _a(oe(t, "migrations")),
3382
+ try: () => xa(ae(t, "migrations")),
3331
3383
  catch: (e) => e
3332
3384
  });
3333
3385
  if (n.length === 0) return {
@@ -3335,25 +3387,25 @@ BEGIN
3335
3387
  skipped: []
3336
3388
  };
3337
3389
  let r = yield* w.tryPromise({
3338
- try: () => va(n),
3390
+ try: () => Sa(n),
3339
3391
  catch: (e) => e
3340
3392
  });
3341
3393
  if (r.length === 0) return {
3342
3394
  pending: [],
3343
3395
  skipped: []
3344
3396
  };
3345
- let i = new Set(yield* ya(e));
3397
+ let i = new Set(yield* Ca(e));
3346
3398
  return {
3347
3399
  pending: r.filter((e) => !i.has(e.migration.id)),
3348
3400
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3349
3401
  };
3350
- }), Ca = (e, t) => Sa(e, t).pipe(w.map((e) => e.pending.map((e) => e.migration.id))), wa = (e, t) => w.gen(function* () {
3351
- let { pending: n, skipped: r } = yield* Sa(e, t.projectRoot);
3402
+ }), Da = (e, t) => Ea(e, t).pipe(w.map((e) => e.pending.map((e) => e.migration.id))), Oa = (e, t) => w.gen(function* () {
3403
+ let { pending: n, skipped: r } = yield* Ea(e, t.projectRoot);
3352
3404
  return n.length === 0 ? {
3353
3405
  applied: [],
3354
3406
  skipped: r
3355
3407
  } : {
3356
- applied: yield* w.acquireUseRelease(Ie(e, { schema: t.lockSchema }), () => w.gen(function* () {
3408
+ applied: yield* w.acquireUseRelease(Fe(e, { schema: t.lockSchema }), () => w.gen(function* () {
3357
3409
  let r = [];
3358
3410
  for (let i of n) {
3359
3411
  yield* w.logInfo("file-based migration applying").pipe(w.annotateLogs({
@@ -3361,7 +3413,7 @@ BEGIN
3361
3413
  id: i.migration.id,
3362
3414
  file: i.file
3363
3415
  }));
3364
- let { durationMs: n } = yield* xa(e, i, t.env, t.appliedBy);
3416
+ let { durationMs: n } = yield* Ta(e, i, t.env, t.appliedBy);
3365
3417
  r.push({
3366
3418
  id: i.migration.id,
3367
3419
  durationMs: n
@@ -3375,21 +3427,21 @@ BEGIN
3375
3427
  }), (e) => e.release.pipe(w.orDie)),
3376
3428
  skipped: r
3377
3429
  };
3378
- }), Ta = (e, t) => e`
3430
+ }), ka = (e, t) => e`
3379
3431
  SELECT ${e("id")}
3380
3432
  FROM ${e("_voltro_migration_plans")}
3381
3433
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3382
3434
  LIMIT 1
3383
- `, Ea = (e, t) => w.gen(function* () {
3384
- if (!(yield* Ta(e, t.id))[0]) return yield* w.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3435
+ `, Aa = (e, t) => w.gen(function* () {
3436
+ if (!(yield* ka(e, t.id))[0]) return yield* w.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3385
3437
  let n = yield* w.tryPromise({
3386
- try: () => _a(oe(t.projectRoot, "migrations")),
3438
+ try: () => xa(ae(t.projectRoot, "migrations")),
3387
3439
  catch: (e) => e
3388
3440
  }), r = (yield* w.tryPromise({
3389
- try: () => va(n),
3441
+ try: () => Sa(n),
3390
3442
  catch: (e) => e
3391
3443
  })).find((e) => e.migration.id === t.id);
3392
- return r ? yield* w.acquireUseRelease(Ie(e, { schema: t.lockSchema }), () => w.gen(function* () {
3444
+ return r ? yield* w.acquireUseRelease(Fe(e, { schema: t.lockSchema }), () => w.gen(function* () {
3393
3445
  let n = Date.now(), i = {
3394
3446
  sql: e,
3395
3447
  log: {
@@ -3414,8 +3466,8 @@ BEGIN
3414
3466
  durationMs: o
3415
3467
  };
3416
3468
  }), (e) => e.release.pipe(w.orDie)) : yield* w.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3417
- }), Da = (e) => w.gen(function* () {
3418
- let t = yield* T.SqlClient, n = yield* t`
3469
+ }), ja = (e) => w.gen(function* () {
3470
+ let t = yield* E.SqlClient, n = yield* t`
3419
3471
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3420
3472
  WHERE source = 'auto-diff'
3421
3473
  AND squashedAt IS NULL
@@ -3459,7 +3511,7 @@ BEGIN
3459
3511
  snapshotFingerprint: e.fingerprint,
3460
3512
  snapshotId: i
3461
3513
  };
3462
- }), Oa = { safe: !0 }, ka = (e) => {
3514
+ }), Ma = { safe: !0 }, Na = (e) => {
3463
3515
  switch (e.kind) {
3464
3516
  case "drop-column": return {
3465
3517
  safe: !1,
@@ -3486,7 +3538,7 @@ BEGIN
3486
3538
  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`,
3487
3539
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3488
3540
  };
3489
- case "alter-column-nullability": return e.toNullable ? Oa : {
3541
+ case "alter-column-nullability": return e.toNullable ? Ma : {
3490
3542
  safe: !1,
3491
3543
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3492
3544
  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)`
@@ -3516,12 +3568,12 @@ BEGIN
3516
3568
  case "drop-unique":
3517
3569
  case "drop-unique-composite":
3518
3570
  case "drop-foreign-key":
3519
- case "drop-check": return Oa;
3571
+ case "drop-check": return Ma;
3520
3572
  }
3521
- }, Aa = (e) => {
3573
+ }, Pa = (e) => {
3522
3574
  let t = [];
3523
3575
  for (let n of e) {
3524
- let e = ka(n.op);
3576
+ let e = Na(n.op);
3525
3577
  e.safe || t.push({
3526
3578
  op: n,
3527
3579
  reason: e.reason,
@@ -3529,7 +3581,7 @@ BEGIN
3529
3581
  });
3530
3582
  }
3531
3583
  return t;
3532
- }, ja = (e) => {
3584
+ }, Fa = (e) => {
3533
3585
  if (!e.enabled || e.unsafeCount === 0) return {
3534
3586
  refuse: !1,
3535
3587
  warnForced: !1,
@@ -3545,18 +3597,18 @@ BEGIN
3545
3597
  warnForced: !1,
3546
3598
  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.`
3547
3599
  };
3548
- }, Ma = (e) => {
3600
+ }, Ia = (e) => {
3549
3601
  let t = e.table;
3550
3602
  if (typeof t == "string") return t;
3551
3603
  let n = e.from;
3552
3604
  return typeof n == "string" ? n : void 0;
3553
- }, Na = (e) => ({
3605
+ }, La = (e) => ({
3554
3606
  kind: e.op.kind,
3555
- table: Ma(e.op),
3607
+ table: Ia(e.op),
3556
3608
  classification: e.classification,
3557
3609
  reason: e.reason,
3558
3610
  blockedFix: e.blocked?.fix
3559
- }), Pa = (e) => e.operations.map(Na), Fa = async (e) => {
3611
+ }), Ra = (e) => e.operations.map(La), za = async (e) => {
3560
3612
  let t = e.log ?? (() => {}), n = {
3561
3613
  branchId: e.branchId,
3562
3614
  mechanism: e.mechanism,
@@ -3575,10 +3627,10 @@ BEGIN
3575
3627
  applied: !1,
3576
3628
  converged: !1,
3577
3629
  residual: r,
3578
- infidelity: Pa(o)
3630
+ infidelity: Ra(o)
3579
3631
  };
3580
3632
  else {
3581
- let i = await e.plan(), o = Pa(i), s = o.filter((e) => e.classification === "lossy"), c = ua(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Na);
3633
+ let i = await e.plan(), o = Ra(i), s = o.filter((e) => e.classification === "lossy"), c = ma(i), l = c.operations.filter((e) => e.blocked !== void 0).map(La);
3582
3634
  if (l.length > 0) a = {
3583
3635
  ...n,
3584
3636
  outcome: "blocked",
@@ -3603,7 +3655,7 @@ BEGIN
3603
3655
  };
3604
3656
  else {
3605
3657
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3606
- let i = Pa(await e.replan());
3658
+ let i = Ra(await e.replan());
3607
3659
  a = {
3608
3660
  ...n,
3609
3661
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3641,7 +3693,7 @@ BEGIN
3641
3693
  ...a,
3642
3694
  tornDown: o
3643
3695
  };
3644
- }, Ia = (e) => {
3696
+ }, Ba = (e) => {
3645
3697
  switch (e.outcome) {
3646
3698
  case "clean": return 0;
3647
3699
  case "lossy": return 2;
@@ -3650,22 +3702,22 @@ BEGIN
3650
3702
  case "infidelity": return 1;
3651
3703
  case "failed": return 1;
3652
3704
  }
3653
- }, La = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Ra = (e) => {
3705
+ }, Va = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Ha = (e) => {
3654
3706
  let t = [];
3655
3707
  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"}`);
3656
3708
  else if (e.outcome === "infidelity") {
3657
3709
  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:");
3658
- for (let n of e.infidelity) t.push(La(n));
3710
+ for (let n of e.infidelity) t.push(Va(n));
3659
3711
  } else {
3660
3712
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3661
- for (let n of e.operations) t.push(La(n));
3662
- 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(La(n));
3713
+ for (let n of e.operations) t.push(Va(n));
3714
+ 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(Va(n));
3663
3715
  }
3664
3716
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3665
- }, za = (e, ...t) => ({
3717
+ }, Ua = (e, ...t) => ({
3666
3718
  _tag: "RawSqlFragment",
3667
3719
  strings: [...e],
3668
3720
  values: [...t]
3669
- }), Ba = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3721
+ }), Wa = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3670
3722
  //#endregion
3671
- export { k as DEFAULT_CDC_CHANNEL, S as FILE_MIGRATION_PATTERN, ba as FileMigrationLedgerError, Qe as REACTIVE_TRIGGER_PREFIX, ge as VOLTRO_MIGRATION_LOCK_KEY, Ie as acquireMigrationLock, U as appliedAtValue, Ht as applyNamespacedSchema, Qi as applyPlan, Mt as applySchema, ja as assessRollingDeployGate, Ia as branchRehearsalExitCode, Xn as chunkTables, ka as classifyRollingDeploySafety, F as declaredSnapshot, at as defaultArrayClause, it as defaultClause, M as defaultJsonClause, ma as describeOutcome, ca as destructiveScope, on as detectReactiveTriggerDrift, fi as emitAddIndexMysql, qr as emitCreateTableMysql, Dr as emitDropColumnDdl, Or as emitDropColumnDdlMysql, jt as emitFrameworkBootstrapSql, kt as emitNamespaceProvisionDdl, At as emitNamespacedSchemaSql, Ot as emitSchemaSql, ur as engineFromVersion, $t as fingerprintSchema, Se as fnv1a64, Ra as formatBranchRehearsal, sn as formatReactiveTriggerDrift, sa as ignoreTablesFromEnv, lr as introspectSchema, hr as isAlreadySatisfied, u as isFileMigration, Ba as isRawSqlFragment, Pt as isReRunSafeDdl, Wn as mapPgType, d as migration, Ce as migrationLockKeyForSchema, we as migrationLockNameForSchema, ci as mysqlIndexPrefixFor, et as notifyFunctionName, N as numericIdSql, Un as parseEnumCheck, Ca as pendingFileMigrationIds, Hn as planMigrations, Ut as provisionTenantNamespace, $e as reactiveTriggerName, yt as reactiveTriggerRepairSql, na as recordUpToDate, Fa as rehearseMigrationOnBranch, Na as rehearsedOperation, Gr as renderColumnMysql, Br as renderColumnPg, ve as resolveMigrationLockSchema, H as resolveMysqlEngine, Ea as rollbackFileBasedMigration, Aa as rollingDeployUnsafeOps, wa as runFileBasedMigrations, Wt as runFrameworkBootstrap, Vt as runMigrate, pa as runPlannedMigrations, en as shortFingerprint, tn as snapshotColumn, za as sql, j as sqlType, Da as squashMigrationPlans, ua as unblockLossy, Le as withMigrationLock };
3723
+ export { A as DEFAULT_CDC_CHANNEL, S as FILE_MIGRATION_PATTERN, wa as FileMigrationLedgerError, Ze as REACTIVE_TRIGGER_PREFIX, he as VOLTRO_MIGRATION_LOCK_KEY, Fe as acquireMigrationLock, U as appliedAtValue, Vt as applyNamespacedSchema, na as applyPlan, jt as applySchema, Fa as assessRollingDeployGate, Ba as branchRehearsalExitCode, Qn as chunkTables, Na as classifyRollingDeploySafety, R as declaredSnapshot, it as defaultArrayClause, rt as defaultClause, N as defaultJsonClause, va as describeOutcome, fa as destructiveScope, dn as detectReactiveTriggerDrift, gi as emitAddIndexMysql, Zr as emitCreateTableMysql, jr as emitDropColumnDdl, Mr as emitDropColumnDdlMysql, At as emitFrameworkBootstrapSql, Ot as emitNamespaceProvisionDdl, kt as emitNamespacedSchemaSql, Dt as emitSchemaSql, pr as engineFromVersion, L as fingerprintSchema, xe as fnv1a64, Ha as formatBranchRehearsal, fn as formatReactiveTriggerDrift, da as ignoreTablesFromEnv, fr as introspectSchema, yr as isAlreadySatisfied, u as isFileMigration, Wa as isRawSqlFragment, Nt as isReRunSafeDdl, Kn as mapPgType, d as migration, Se as migrationLockKeyForSchema, Ce as migrationLockNameForSchema, fi as mysqlIndexPrefixFor, $e as notifyFunctionName, P as numericIdSql, Gn as parseEnumCheck, Da as pendingFileMigrationIds, Wn as planMigrations, Ht as provisionTenantNamespace, Qe as reactiveTriggerName, vt as reactiveTriggerRepairSql, oa as recordUpToDate, za as rehearseMigrationOnBranch, La as rehearsedOperation, Yr as renderColumnMysql, Wr as renderColumnPg, _e as resolveMigrationLockSchema, hr as resolveMysqlEngine, Aa as rollbackFileBasedMigration, Pa as rollingDeployUnsafeOps, Oa as runFileBasedMigrations, Ut as runFrameworkBootstrap, Bt as runMigrate, _a as runPlannedMigrations, an as shortFingerprint, on as snapshotColumn, Ua as sql, M as sqlType, ja as squashMigrationPlans, ma as unblockLossy, Ie as withMigrationLock };