@voltro/database 0.68.0 → 0.69.1

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