@voltro/database 0.68.0 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sql.js CHANGED
@@ -1,13 +1,13 @@
1
- import { 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";
1
+ import { C as e, Jt as t, Ot as n, St as r, a as i, an as a, at as o, b as s, c, ct as l, d as u, f as d, h as f, i as p, it as m, lt as h, m as g, o as _, on as v, qt as y, rt as b, s as x, u as S, y as C } from "./frameworkLiveTables-CWbTSnjk.js";
2
+ import { Effect as w, Exit as ee, Schedule as te, Scope as ne } from "effect";
3
+ import { createHash as re } from "node:crypto";
4
+ import { createLogger as ie } from "@voltro/logger";
5
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";
6
+ import { promises as ae } from "node:fs";
7
+ import { join as oe } from "node:path";
8
+ import { pathToFileURL as se } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var oe = (e, t, n, r = 400) => {
10
+ var ce = (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 = le(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
+ }, le = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, ue = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, de = (e) => e.replace(/"/g, "`"), fe = (e) => typeof e == "string" ? e : e.name ?? String(e), pe = (e, t) => `_ua_${t}_${e}`.slice(0, 64), me = (e, t) => {
44
+ if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(ue)) return e;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!ce(t)) {
47
+ if (!ue(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = le(t.where), o = [];
51
+ let a = de(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = ue(r);
53
+ let i = fe(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 = pe(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,7 +75,7 @@ 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
+ }, E = (e, t) => `${e}::${t}`, he = (e, t) => {
79
79
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
80
80
  n.add(e);
81
81
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
@@ -84,77 +84,73 @@ var oe = (e, t, n, r = 400) => {
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, me = 6322741009312437n, he = (e) => {
87
+ }, D = (e, t) => e.executeUnprepared(t, [], void 0), ge = 6322741009312437n, _e = (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
+ }, ve = (e) => e?.schema === void 0 ? _e(process.env.DB_SCHEMA) : _e(e.schema), ye = 14695981039346656037n, be = 1099511628211n, xe = 18446744073709551615n, Se = (e) => {
91
+ let t = ye;
92
+ for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * be & xe;
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
+ }, Ce = (e) => {
95
+ let t = _e(e);
96
+ return t === void 0 ? ge : Se(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
+ }, we = (e) => {
98
+ let t = `voltro_migration_${ge.toString(36)}`, n = _e(e);
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${(Se(`voltro_migration_lock:${n}`) & xe).toString(16)}`;
102
+ }, Te = 250, Ee = () => {
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
+ }, De = (e, t) => w.gen(function* () {
106
+ let n = Ee(), 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* D(e, `SELECT pg_try_advisory_lock(${t.toString()}::bigint) AS got`))[0]?.got) return;
109
+ Date.now() - r >= n && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(n / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* w.sleep(`${Te} millis`);
110
+ }
111
+ }), Oe = (e, t) => w.asVoid(D(e, `SELECT pg_advisory_unlock(${t.toString()}::bigint)`)), ke = 30, Ae = (e, t) => w.gen(function* () {
112
+ (yield* D(e, `SELECT GET_LOCK('${t}', ${String(ke)}) AS got`))[0]?.got !== 1 && (yield* w.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${ke}s (another migration is in progress, or a prior one left it held).`)));
113
+ }), je = (e, t) => w.asVoid(D(e, `SELECT RELEASE_LOCK('${t}')`)), Me = 3e4, Ne = (e, t) => w.gen(function* () {
114
+ let n = yield* D(e, `
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(Me)};
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
+ }), Pe = (e, t) => w.asVoid(D(e, `EXEC sp_releaseapplock @Resource = '${t}', @LockOwner = 'Session'`)), Fe = w.void, Ie = (e, t) => w.gen(function* () {
121
+ let n = ve(t), r = we(n), i = Ce(n);
122
+ if (!e.onDialectOrElse({
123
+ mysql: () => !0,
124
+ mssql: () => !0,
125
+ sqlite: () => !1,
126
+ orElse: () => !0
127
+ })) return { release: Fe };
128
+ let a = yield* ne.make(), o = yield* w.provideService(e.reserve, ne.Scope, a), s = ne.close(a, ee.void);
129
+ return yield* e.onDialectOrElse({
130
+ mysql: () => Ae(o, r),
131
+ mssql: () => Ne(o, r),
132
+ sqlite: () => Fe,
133
+ orElse: () => De(o, i)
134
+ }).pipe(w.onExit((e) => ee.isSuccess(e) ? w.void : s)), { release: e.onDialectOrElse({
135
+ mysql: () => je(o, r),
136
+ mssql: () => Pe(o, r),
137
+ sqlite: () => Fe,
138
+ orElse: () => Oe(o, i)
139
+ }).pipe(w.ensuring(s)) };
140
+ }), Le = (e, t, n) => w.acquireUseRelease(Ie(e, n), () => t, (e) => e.release.pipe(w.orDie)), Re = (e) => e.onDialectOrElse({
145
141
  pg: () => "postgres",
146
142
  mysql: () => "mysql",
147
143
  mssql: () => "mssql",
148
144
  sqlite: () => "sqlite",
149
145
  orElse: () => "sqlite"
150
- }), Ie = {
146
+ }), ze = {
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
+ }, Be = (e) => ze[e], O = "_voltro_migration_ops", Ve = l(O, {
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
+ }), He = (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
+ }, Ue = (e) => [...He(e)].join(" "), We = (e, t) => {
194
+ let n = He(t);
195
+ for (let t of He(e)) if (n.has(t)) return !0;
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
+ }, Ge = (e, t) => e.operations.some((e) => We(e.op, t)), Ke = "__voltro_rebuild", qe = "__shadow", Je = "__old", Ye = /* @__PURE__ */ new Set([
202
198
  "add-unique",
203
199
  "drop-unique",
204
200
  "add-unique-composite",
@@ -210,21 +206,21 @@ 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
+ ]), Xe = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ze = (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 && Ye.has(e.kind) ? "artefact-repair" : Xe.has(e.kind) ? "idempotent" : "probe-then-replay";
216
212
  };
217
- Object.keys(Ie);
213
+ Object.keys(ze);
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 k = "framework_changes", Qe = "framework_changes_", $e = (e, t) => t === "framework_changes" ? `${Qe}${e}` : `${Qe}${t}_${e}`, et = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, tt = "voltro:notify:v2", nt = (e, t) => {
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*/, ""));
227
- }, M = (e, t) => {
221
+ }, rt = ie({ scope: "voltro:migrate" }), A = (e) => {
222
+ rt.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
223
+ }, j = (e, t) => {
228
224
  let n = e.type;
229
225
  if (e.spatial) {
230
226
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -235,7 +231,7 @@ var A = "framework_changes", Ye = "framework_changes_", Xe = (e, t) => t === "fr
235
231
  return e.rawDdl;
236
232
  }
237
233
  if (n === "array" && e.arrayElement) {
238
- if (t === "postgres") return `${M({
234
+ if (t === "postgres") return `${j({
239
235
  ...e,
240
236
  type: e.arrayElement,
241
237
  arrayElement: void 0
@@ -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 = nt(e, !1);
310
306
  return t === void 0 ? "NVARCHAR(MAX)" : `NVARCHAR(${t})`;
311
307
  }
312
308
  case "integer": return "INT";
@@ -338,22 +334,22 @@ 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
+ }, it = (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) => {
346
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return N(e, n);
347
- let r = M({
340
+ return n === "now" ? m(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? at(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
341
+ }, at = (e, t, n) => {
342
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return M(e, n);
343
+ let r = j({
348
344
  ...t,
349
345
  type: t.arrayElement,
350
346
  arrayElement: void 0
351
347
  }, n);
352
348
  return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
353
- }, N = (e, t) => {
349
+ }, M = (e, t) => {
354
350
  let n = JSON.stringify(e).replace(/'/g, "''");
355
351
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CONVERT('${n}' USING utf8mb4))` : `DEFAULT '${n}'`;
356
- }, P = (e, t) => {
352
+ }, N = (e, t) => {
357
353
  switch (t) {
358
354
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
359
355
  case "mysql":
@@ -362,7 +358,7 @@ var A = "framework_changes", Ye = "framework_changes_", Xe = (e, t) => t === "fr
362
358
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
363
359
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
364
360
  }
365
- }, F = (e, t) => {
361
+ }, P = (e, t) => {
366
362
  if (e === "restrict" && t === "mssql") return "NO ACTION";
367
363
  switch (e) {
368
364
  case "cascade": return "CASCADE";
@@ -370,42 +366,42 @@ 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
+ }, ot = (e, t, n) => n === null ? o(e, t) : `${o(n, t)}.${o(e, t)}`, st = 191, ct = (e, t) => {
374
370
  if (!e || t !== "mysql" && t !== "mariadb") return !1;
375
- let n = M(e, t).toUpperCase();
371
+ let n = j(e, t).toUpperCase();
376
372
  return n.endsWith("TEXT") || n.endsWith("BLOB");
377
- }, ot = (e, t, n) => {
373
+ }, lt = (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
- let a = M(i, n).toUpperCase();
383
- return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${it})` : r;
384
- }, st = (e, t) => {
378
+ let a = j(i, n).toUpperCase();
379
+ return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${st})` : r;
380
+ }, ut = (e, t) => {
385
381
  if (!e.generatedAs) return null;
386
382
  let { expr: n, stored: r } = e.generatedAs;
387
- if (t === "postgres") return r || j("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
383
+ if (t === "postgres") return r || A("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
388
384
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
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) => {
393
- 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];
388
+ }, dt = (e, t, n, r, i = !1, a = !1) => {
389
+ if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, n);
390
+ let s = n === "mssql" ? nt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? j(t, n) : `NVARCHAR(${s})`, l = [o(e, n), c];
395
391
  t.type === "id" && !a && l.push("PRIMARY KEY");
396
- let u = st(t, n);
392
+ let u = ut(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" && !ct(t, n) && l.push("UNIQUE");
396
+ let e = it(t, n);
401
397
  e && l.push(e);
402
398
  }
403
399
  if (t.type === "reference" && t.references && !i && !b(n)) {
404
400
  let e = t.references();
405
401
  l.push(`REFERENCES ${o(e.tableName, n)} (${o(t.referenceColumn ?? "id", n)})`);
406
- let r = F(t.onDelete ?? "restrict", n);
402
+ let r = P(t.onDelete ?? "restrict", n);
407
403
  l.push(`ON DELETE ${r}`);
408
- let i = F(t.refOnUpdate ?? "noAction", n);
404
+ let i = P(t.refOnUpdate ?? "noAction", n);
409
405
  i !== "NO ACTION" && l.push(`ON UPDATE ${i}`);
410
406
  }
411
407
  if (t.oneOf && t.oneOf.length > 0) {
@@ -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
+ }, ft = (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]) => ` ${dt(e, n, t, i, r?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((n) => {
429
+ let r = n.fields.map((n) => lt(n, e.fields, t)).join(", ");
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) => lt(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
- 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}`}`];
433
+ let s = a.references(), c = P(a.onDelete ?? "restrict", t), l = P(a.refOnUpdate ?? "noAction", t);
434
+ return [` CONSTRAINT ${o(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${o(i, t)}) REFERENCES ${ot(s.tableName, t, n)} (${o(a.referenceColumn ?? "id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
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 = ot(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
+ }, pt = (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
+ }, mt = (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: "",
@@ -466,21 +462,21 @@ var A = "framework_changes", Ye = "framework_changes_", Xe = (e, t) => t === "fr
466
462
  using: " USING GIST",
467
463
  withSuffix: "",
468
464
  skip: !1
469
- } : (j(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
465
+ } : (A(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
470
466
  if (r === "gin") return t === "postgres" ? {
471
467
  using: " USING GIN",
472
468
  withSuffix: "",
473
469
  skip: !1
474
- } : t === "mysql" || t === "mariadb" ? (j(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
470
+ } : t === "mysql" || t === "mariadb" ? (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
475
471
  using: "",
476
472
  withSuffix: "",
477
473
  skip: !0
478
- }) : (j(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
474
+ }) : (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
479
475
  if (r === "brin") return t === "postgres" ? {
480
476
  using: " USING BRIN",
481
477
  withSuffix: "",
482
478
  skip: !1
483
- } : (j(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
479
+ } : (A(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
484
480
  if (r === "hnsw") {
485
481
  if (t === "postgres") {
486
482
  let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? h(i?.hnsw?.distance);
@@ -491,7 +487,7 @@ var A = "framework_changes", Ye = "framework_changes_", Xe = (e, t) => t === "fr
491
487
  skip: !1
492
488
  };
493
489
  }
494
- return j(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
490
+ return A(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
495
491
  using: "",
496
492
  withSuffix: "",
497
493
  skip: !0
@@ -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 lt(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 = ot(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" || !ct(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,15 +525,15 @@ 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(...pt(e.tableName, n, t)) : A(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
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
- 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(...).`);
531
+ A(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
536
532
  continue;
537
533
  }
538
534
  if (n.unique && n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${n.name}' on '${e.tableName}' cannot be expressed on ${t} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${t}, or move this table to postgres/sqlite/mssql.`);
539
535
  let o = "";
540
- n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? j(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : o = ` WHERE ${n.where}`);
536
+ n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? A(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : o = ` WHERE ${n.where}`);
541
537
  let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, o, n.unique === !0);
542
538
  s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && i.add(a(n.fields));
543
539
  }
@@ -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
+ }, ht = (e, t, n = k) => {
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 ? [] : [gt(n), ...r.map((e) => vt(e, n))];
550
+ }, gt = (e) => `
551
+ CREATE OR REPLACE FUNCTION ${et(e)}() RETURNS trigger AS $$
556
552
  DECLARE
557
553
  payload TEXT;
558
554
  pk JSONB;
559
555
  BEGIN
560
- -- ${Qe}
556
+ -- ${tt}
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(), _t = (e, t) => {
611
+ let n = $e(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 ${et(t)}()`
620
616
  ];
621
- }, ht = (e, t) => mt(e, t).map((e) => `${e};`).join("\n"), gt = (e) => {
617
+ }, vt = (e, t) => _t(e, t).map((e) => `${e};`).join("\n"), yt = (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(gt(t));
621
+ for (let e of i) r.push(..._t(n.get(e), t));
622
+ for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${$e(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
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
+ }, bt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), xt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), St = (e) => {
625
+ let t = new Map(e.map((e) => [e.tableName, e])), n = he(e.map((e) => e.tableName), (e) => {
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 [];
@@ -663,8 +659,8 @@ $$ LANGUAGE plpgsql;
663
659
  sorted: o,
664
660
  cyclic: r
665
661
  };
666
- }, bt = (e, t, n = null) => {
667
- 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}`;
662
+ }, Ct = (e, t, n = null) => {
663
+ let r = (e) => n ? `${o(n, t)}.${o(e, t)}` : o(e, t), i = `${e.table}_${e.column}_fkey`, a = P(e.onDelete, t), s = P(e.onUpdate, t), c = ` ON DELETE ${a}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${o(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${o(e.column, t)}) REFERENCES ${r(e.targetTable)} (${o(e.targetColumn, t)})${c}`;
668
664
  switch (t) {
669
665
  case "postgres": return [
670
666
  "DO $$ BEGIN",
@@ -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
+ }, wt = (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
+ }, Tt = (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
+ }, Et = (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
+ }, Dt = (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
+ }, Ot = (t, n, r = k) => {
723
+ let { tables: i, views: a } = Dt(t), { sorted: o, cyclic: s } = St(i.map((e) => me(e, n))), c = wt(s, n), l = [];
724
+ n === "postgres" && bt(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && xt(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
725
+ let u = Et(o, n);
730
726
  u && l.push(u);
731
- let d = St(o, n);
727
+ let d = Tt(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(ft(e, n, null, c.get(e.tableName)));
730
+ if (!m(n)) for (let e of s) l.push(Ct(e, n));
735
731
  for (let e of o) {
736
- let t = dt(e, n);
732
+ let t = mt(e, n);
737
733
  t && l.push(t);
738
734
  }
739
- l.push(...ft(o, n, r));
735
+ l.push(...ht(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
+ }, kt = (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
+ }, At = (e, t, n, r) => {
749
+ let i = kt(n, t, r), a = o(n, t);
750
+ if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Ot(e, t)}`;
751
+ if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Ot(e, t)}`;
752
+ let { sorted: s, cyclic: c } = St(e), l = wt(c, t), u = [i];
753
+ for (let e of s) u.push(ft(e, t, n, l.get(e.tableName)));
754
+ if (!m(t)) for (let e of c) u.push(Ct(e, t, n));
759
755
  for (let e of s) {
760
- let r = dt(e, t, n);
756
+ let r = mt(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
+ }, jt = (e, t, n = k) => {
761
+ let { sorted: r, cyclic: i } = St(e), a = wt(i, t), o = [], s = Et(r, t);
766
762
  s && o.push(s);
767
- let c = St(r, t);
763
+ let c = Tt(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* () {
765
+ for (let e of r) o.push(ft(e, t, null, a.get(e.tableName)));
766
+ for (let e of i) o.push(Ct(e, t));
767
+ return o.push(...ht(r, t, n)), o.join("\n\n") + "\n";
768
+ }, Mt = (e, t = "postgres", n = k, r = {}) => w.gen(function* () {
773
769
  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) => {
770
+ yield* Le(i, zt(i, Ot(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
771
+ }), Nt = (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
+ }, Pt = (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
+ }, Ft = () => {
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
+ }, It = (e) => ({
785
781
  while: e,
786
- times: Mt(),
787
- schedule: w.jittered(w.exponential("50 millis"))
788
- }), Pt = class {
782
+ times: Ft(),
783
+ schedule: te.jittered(te.exponential("50 millis"))
784
+ }), Lt = 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
+ }, Rt = (e, t, n) => w.gen(function* () {
792
+ let r = yield* T.SqlClient, i = n !== void 0 && Be(t) === "per-operation";
793
+ for (let a of Bt(e)) {
794
+ process.env.VOLTRO_MIGRATE_DEBUG === "1" && rt.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
795
+ let e = r.unsafe(a).pipe(w.catchIf((e) => Nt(a, e), () => w.succeed([])), w.tapError((e) => w.sync(() => {
796
+ rt.error(ce("migrate: statement failed", a, e, 200));
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 && Pt(a, t) ? e.pipe(w.retry(It((e) => n(e) === "retry"))) : e).pipe(w.mapError((e) => new Lt(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
+ }), zt = (e, t, n, r) => {
801
+ let i = n === "turso" ? Rt(t, n, r) : e.withTransaction(Rt(t, n, r)), a = (e) => e instanceof Lt ? e.error : e;
802
+ return (r !== void 0 && Be(n) === "plan-transactional" ? i.pipe(w.retry(It((e) => r(a(e)) === "retry"))) : i).pipe(w.orDieWith((e) => e instanceof Lt ? Error(ce("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
803
+ }, Bt = (e) => {
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,30 @@ 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
+ }, Vt = async (e, t, n = "postgres", r = {}) => {
819
+ await w.runPromise(Mt(e, n, void 0, r).pipe(w.provide(t)));
820
+ }, Ht = (e, t, n = "postgres", r = {}) => w.gen(function* () {
821
+ let i = At(e, n, t), a = yield* T.SqlClient;
822
+ yield* Le(a, zt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
823
+ }), Ut = async (e, t, n, r = "postgres", i = {}) => {
824
+ await w.runPromise(Ht(e, t, r, i).pipe(w.provide(n))), await f({
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) => {
828
+ }, Wt = async (e, t, n = "postgres", r = {}) => {
829
+ await w.runPromise(w.gen(function* () {
830
+ let t = jt(e, n), i = yield* T.SqlClient;
831
+ yield* Le(i, zt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(w.orDie);
832
+ }).pipe(w.provide(t)));
833
+ }, Gt = /'(?:''|[^'])*'|"(?:""|[^"])*"|\[(?:\]\]|[^\]])*\]|`(?:``|[^`])*`|[A-Za-z_][A-Za-z_0-9$]*|\d+(?:\.\d+)?|::|<>|!=|<=|>=|\|\||[^\s]/g, Kt = (e) => {
838
834
  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();
840
- }, Wt = (e) => {
835
+ for (let n of e.matchAll(Gt)) if (n[0] === "(" && t++, n[0] === ")" && t--, t === 0 && n[0].toLowerCase() === "where") return e.slice(n.index + n[0].length).trim().replace(/;$/, "").trim();
836
+ }, qt = (e) => {
841
837
  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");
838
+ let t = e.match(Gt) ?? [], n = "(?:'(?:''|[^'])*'(?:\\s*::\\s*text)?|[0-9]+)", r = RegExp(`^\\s*${n}(?:\\s*,\\s*${n})*\\s*$`, "i");
843
839
  for (let e = 0; e < t.length - 5; e++) {
844
840
  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) ?? [], ")");
841
+ t[e] === "=" && t[e + 1]?.toLowerCase() === "any" && t[e + 2] === "(" && t[e + 3]?.toLowerCase() === "array" && n.startsWith("[") && n.endsWith("]") && t[e + 5] === ")" && r.test(n.slice(1, -1)) && t.splice(e, 6, "in", "(", ...n.slice(1, -1).match(Gt) ?? [], ")");
846
842
  }
847
843
  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
844
  if (e.startsWith("'")) return e;
@@ -880,31 +876,31 @@ BEGIN
880
876
  return r;
881
877
  };
882
878
  return JSON.stringify(a(i));
883
- }, Gt = (e) => {
879
+ }, Jt = (e) => {
884
880
  if (e == null) return e;
885
- if (Array.isArray(e)) return e.map(Gt);
881
+ if (Array.isArray(e)) return e.map(Jt);
886
882
  if (typeof e != "object") return e;
887
883
  let t = {};
888
884
  for (let n of Object.keys(e).sort()) {
889
885
  let r = e[n];
890
- r !== void 0 && (t[n] = Gt(r));
886
+ r !== void 0 && (t[n] = Jt(r));
891
887
  }
892
888
  return t;
893
- }, Kt = (e) => {
889
+ }, Yt = (e) => {
894
890
  if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs) return e;
895
891
  let { idScheme: t, sensitive: n, safe: r, generatedAs: i, ...a } = e;
896
892
  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 : {
893
+ }, Xt = (e) => [...e].map(Yt).sort((e, t) => e.name.localeCompare(t.name)), Zt = (e) => [...e].map((e) => e.where === void 0 ? e : {
898
894
  ...e,
899
- where: Wt(e.where)
900
- }).sort((e, t) => e.name.localeCompare(t.name)), Yt = (e) => [...e].map((e) => ({
895
+ where: qt(e.where)
896
+ }).sort((e, t) => e.name.localeCompare(t.name)), Qt = (e) => [...e].map((e) => ({
901
897
  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) => {
898
+ columns: Xt(e.columns),
899
+ indexes: Zt(e.indexes)
900
+ })).sort((e, t) => e.name.localeCompare(t.name)), $t = (e) => {
901
+ let t = { tables: Qt(e.tables) }, n = JSON.stringify(Jt(t));
902
+ return re("sha256").update(n).digest("hex");
903
+ }, en = (e) => e.slice(0, 16), tn = (e, t) => {
908
904
  let n = t.references ? {
909
905
  table: t.references().tableName,
910
906
  column: t.referenceColumn ?? "id",
@@ -944,7 +940,7 @@ BEGIN
944
940
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
945
941
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
946
942
  };
947
- }, $t = (e) => {
943
+ }, nn = (e) => {
948
944
  let t = [], n = /* @__PURE__ */ new Set(), i = (e) => {
949
945
  n.has(e.name) || (n.add(e.name), t.push(e));
950
946
  }, a = e.appliedPrimaryKey ?? [];
@@ -992,11 +988,11 @@ BEGIN
992
988
  });
993
989
  }
994
990
  return t;
995
- }, en = (e) => {
991
+ }, rn = (e) => {
996
992
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
997
993
  for (let [r, i] of Object.entries(e.fields)) {
998
994
  if (i.dropped) continue;
999
- let e = Qt(r, i);
995
+ let e = tn(r, i);
1000
996
  n.push(t.has(r) ? {
1001
997
  ...e,
1002
998
  unique: !0
@@ -1006,30 +1002,30 @@ BEGIN
1006
1002
  return {
1007
1003
  name: e.tableName,
1008
1004
  columns: n,
1009
- indexes: $t(e),
1005
+ indexes: nn(e),
1010
1006
  ...r.length > 0 ? { primaryKey: [...r] } : {},
1011
1007
  ...i === void 0 ? {} : { renamedFrom: i }
1012
1008
  };
1013
- }, tn = (e) => {
1009
+ }, an = (e) => {
1014
1010
  let t = /* @__PURE__ */ new Map();
1015
1011
  for (let n of e) for (let e of n.indexes) {
1016
1012
  let r = t.get(e.name);
1017
1013
  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
1014
  t.set(e.name, n.name);
1019
1015
  }
1020
- }, I = (e, t) => {
1021
- let n = e.filter((e) => !c(e.tableName)).map((e) => en(fe(e, t)));
1016
+ }, F = (e, t) => {
1017
+ let n = e.filter((e) => !c(e.tableName)).map((e) => rn(me(e, t)));
1022
1018
  if (t === "mysql" || t === "mariadb") {
1023
1019
  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
1020
  }
1025
- return tn(n), { tables: n };
1026
- }, nn = (e, t, n = A) => C.gen(function* () {
1021
+ return an(n), { tables: n };
1022
+ }, on = (e, t, n = k) => w.gen(function* () {
1027
1023
  let r = (yield* e`
1028
1024
  SELECT p.prosrc
1029
1025
  FROM pg_proc p
1030
1026
  JOIN pg_namespace n ON n.oid = p.pronamespace
1031
1027
  WHERE n.nspname = current_schema()
1032
- AND p.proname = ${Ze(n)}
1028
+ AND p.proname = ${et(n)}
1033
1029
  `)[0]?.prosrc, i = r !== void 0 && !r.includes("voltro:notify:v2"), a = t.filter((e) => !e.tableName.startsWith("_voltro_"));
1034
1030
  if (a.length === 0) return {
1035
1031
  missing: [],
@@ -1043,10 +1039,10 @@ BEGIN
1043
1039
  JOIN pg_namespace n ON n.oid = c.relnamespace
1044
1040
  WHERE NOT t.tgisinternal
1045
1041
  AND n.nspname = current_schema()
1046
- AND t.tgname LIKE ${`${Ye}%`}
1042
+ AND t.tgname LIKE ${`${Qe}%`}
1047
1043
  `, s = new Set(o.map((e) => e.tgname)), c = [], l = [];
1048
1044
  for (let e of a) {
1049
- let t = s.has(Xe(e.tableName, n)), r = e.isReactive !== !1;
1045
+ let t = s.has($e(e.tableName, n)), r = e.isReactive !== !1;
1050
1046
  r && !t && c.push(e.tableName), !r && t && l.push(e.tableName);
1051
1047
  }
1052
1048
  return {
@@ -1054,7 +1050,7 @@ BEGIN
1054
1050
  stale: l.sort(),
1055
1051
  functionOutdated: i
1056
1052
  };
1057
- }), rn = (e) => {
1053
+ }), sn = (e) => {
1058
1054
  let t = [];
1059
1055
  if (e.missing.length > 0) {
1060
1056
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -1065,19 +1061,19 @@ BEGIN
1065
1061
  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
1062
  }
1067
1063
  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 = {
1064
+ }, cn = {
1069
1065
  postgres: !0,
1070
1066
  mysql: !0,
1071
1067
  mariadb: !0,
1072
1068
  mssql: !0,
1073
1069
  sqlite: !0
1074
- }, on = {
1070
+ }, ln = {
1075
1071
  postgres: !0,
1076
1072
  mysql: !1,
1077
1073
  mariadb: !1,
1078
1074
  mssql: !0,
1079
1075
  sqlite: !0
1080
- }, sn = (e) => {
1076
+ }, un = (e) => {
1081
1077
  switch (e) {
1082
1078
  case "add-column":
1083
1079
  case "drop-column":
@@ -1087,49 +1083,49 @@ BEGIN
1087
1083
  case "add-foreign-key":
1088
1084
  case "add-unique":
1089
1085
  case "add-unique-composite":
1090
- case "add-check": return on;
1091
- default: return an;
1086
+ case "add-check": return ln;
1087
+ default: return cn;
1092
1088
  }
1093
- }, cn = (e, t) => {
1089
+ }, dn = (e, t) => {
1094
1090
  let n = new Map(t.tables.map((e) => [e.name, e]));
1095
1091
  return new Map(e.map((e) => [e.tableName, {
1096
1092
  table: e,
1097
1093
  snapshot: n.get(e.tableName),
1098
1094
  columnDefs: e.fields
1099
1095
  }]));
1100
- }, L = (e) => {
1096
+ }, I = (e) => {
1101
1097
  if (typeof e != "object" || !e) return JSON.stringify(e);
1102
- if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1098
+ if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
1103
1099
  let t = e;
1104
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1105
- }, ln = (e) => {
1100
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
1101
+ }, fn = (e) => {
1106
1102
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1107
1103
  let t = e.defaultValue;
1108
1104
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1109
1105
  if (typeof t == "number") return String(t);
1110
- if (typeof t != "string") return L(t);
1106
+ if (typeof t != "string") return I(t);
1111
1107
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1112
1108
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1113
1109
  let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
1114
1110
  if (o) try {
1115
- return L(JSON.parse(o[1]));
1111
+ return I(JSON.parse(o[1]));
1116
1112
  } catch {}
1117
1113
  let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1118
1114
  if (s) try {
1119
- return L(JSON.parse(s[1]));
1115
+ return I(JSON.parse(s[1]));
1120
1116
  } catch {}
1121
1117
  if (a.startsWith("{") || a.startsWith("[")) try {
1122
- return L(JSON.parse(a));
1118
+ return I(JSON.parse(a));
1123
1119
  } catch {}
1124
1120
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1125
- }, un = (e, t) => {
1126
- let n = ln(e), r = ln(t);
1121
+ }, pn = (e, t) => {
1122
+ let n = fn(e), r = fn(t);
1127
1123
  if (n === r) return !0;
1128
1124
  let i = (e) => typeof e.defaultValue == "string" && /^nextval\(.+::regclass\)$/i.test(e.defaultValue.trim()), a = (e) => e.type === "id" && e.idScheme?.kind === "numeric";
1129
1125
  if (e.type === "id" && t.type === "id" && (a(e) && n === null && i(t) || a(t) && r === null && i(e))) return !0;
1130
1126
  let o = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1131
1127
  return o(n) === o(r);
1132
- }, dn = (e) => {
1128
+ }, mn = (e) => {
1133
1129
  if (!e) return null;
1134
1130
  let t = (e) => e === "restrict" ? "noAction" : e;
1135
1131
  return {
@@ -1138,29 +1134,29 @@ BEGIN
1138
1134
  onDelete: t(e.onDelete),
1139
1135
  onUpdate: t(e.onUpdate)
1140
1136
  };
1141
- }, fn = (e, t) => {
1137
+ }, hn = (e, t) => {
1142
1138
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1143
1139
  if (!n && !r) return !0;
1144
1140
  if (!n || !r || n.length !== r.length) return !1;
1145
1141
  let i = [...n].sort(), a = [...r].sort();
1146
1142
  return i.every((e, t) => e === a[t]);
1147
- }, pn = (e, t, n) => {
1143
+ }, gn = (e, t, n) => {
1148
1144
  if (t === "mssql") {
1149
- let t = $e(e, n);
1145
+ let t = nt(e, n);
1150
1146
  if (t !== void 0) return t;
1151
1147
  }
1152
1148
  try {
1153
- let n = /\((\d+)\)/.exec(M(e, t));
1149
+ let n = /\((\d+)\)/.exec(j(e, t));
1154
1150
  return n ? Number(n[1]) : void 0;
1155
1151
  } catch {
1156
1152
  return;
1157
1153
  }
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({
1154
+ }, _n = (e, t, n, r) => n === void 0 || m(n) ? !0 : e.type !== "text" || t.type !== "text" || gn(e, n, r) === t.maxLength, vn = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && pn(e, t) && _n(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(mn(e.references)) === JSON.stringify(mn(t.references)) && hn(e.oneOf, t.oneOf), yn = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1159
1155
  kind: "add-check",
1160
1156
  table: e,
1161
1157
  column: t.name,
1162
1158
  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) => {
1159
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, bn = (e, t) => e.unique === t.unique && e.valid !== !1 && t.valid !== !1 && qt(e.where) === qt(t.where) && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), xn = (e, t, n) => {
1164
1160
  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
1161
  for (let t of e.columns) {
1166
1162
  let e = r.get(t.name);
@@ -1168,7 +1164,7 @@ BEGIN
1168
1164
  a.push(t);
1169
1165
  continue;
1170
1166
  }
1171
- hn(t, e, n, c.has(t.name) || t.unique) || s.push({
1167
+ vn(t, e, n, c.has(t.name) || t.unique) || s.push({
1172
1168
  declared: t,
1173
1169
  live: e
1174
1170
  });
@@ -1179,50 +1175,50 @@ BEGIN
1179
1175
  removed: o,
1180
1176
  changed: s
1181
1177
  };
1182
- }, yn = (e, t, n) => {
1178
+ }, Sn = (e, t, n) => {
1183
1179
  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
1180
  for (let t of e.indexes) {
1185
1181
  let e = i.get(r(t.name));
1186
- (!e || !_n(t, e)) && o.push(t);
1182
+ (!e || !bn(t, e)) && o.push(t);
1187
1183
  }
1188
1184
  for (let e of t.indexes) {
1189
1185
  let t = a.get(r(e.name));
1190
- (!t || (e.where !== void 0 || t.where !== void 0) && !_n(t, e)) && s.push(e);
1186
+ (!t || (e.where !== void 0 || t.where !== void 0) && !bn(t, e)) && s.push(e);
1191
1187
  }
1192
1188
  return {
1193
1189
  added: o,
1194
1190
  removed: s
1195
1191
  };
1196
- }, R = (e, t, n, r) => ({
1192
+ }, L = (e, t, n, r) => ({
1197
1193
  op: e,
1198
1194
  classification: t,
1199
- atomicByDialect: sn(e.kind),
1195
+ atomicByDialect: un(e.kind),
1200
1196
  ...n ? { reason: n } : {},
1201
1197
  ...r ? { blocked: r } : {}
1202
- }), bn = (e, t, n) => {
1198
+ }), Cn = (e, t, n) => {
1203
1199
  let r = {
1204
1200
  kind: "add-column",
1205
1201
  table: e,
1206
1202
  column: t
1207
1203
  };
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) => {
1204
+ return t.nullable ? L(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? L(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? L(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : L(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1205
+ }, wn = (e, t, n) => {
1210
1206
  let r = {
1211
1207
  kind: "drop-column",
1212
1208
  table: e,
1213
1209
  column: t.name
1214
1210
  };
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({
1211
+ return n?.dropped ? L(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : L(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1212
+ }, Tn = (e, t, n, r, i) => L({
1217
1213
  kind: "create-table",
1218
1214
  table: e,
1219
1215
  columns: t,
1220
1216
  indexes: n,
1221
1217
  ...r && r.length > 0 ? { primaryKey: r } : {}
1222
- }, "safe", i ?? "new table — no data to preserve"), Cn = (e) => R({
1218
+ }, "safe", i ?? "new table — no data to preserve"), En = (e) => L({
1223
1219
  kind: "drop-table",
1224
1220
  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) => {
1221
+ }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), Dn = 5e4, On = (e, t, n, r) => {
1226
1222
  let i = (n ?? 0) >= r, a;
1227
1223
  return a = !t.unique || t.where !== void 0 ? {
1228
1224
  kind: "add-index",
@@ -1237,16 +1233,16 @@ BEGIN
1237
1233
  table: e,
1238
1234
  name: t.name,
1239
1235
  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({
1236
+ }, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.where === void 0 ? t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index" : `add ${t.unique ? "unique " : ""}partial index`);
1237
+ }, kn = (e, t) => t.unique && t.where === void 0 && t.columns.length > 1 ? L({
1242
1238
  kind: "drop-unique-composite",
1243
1239
  table: e,
1244
1240
  name: t.name
1245
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
1241
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
1246
1242
  kind: "drop-index",
1247
1243
  table: e,
1248
1244
  index: t.name
1249
- }, "safe", "drop index (no data loss — index is derived data)"), Dn = (e, t) => {
1245
+ }, "safe", "drop index (no data loss — index is derived data)"), An = (e, t) => {
1250
1246
  let n = e.type;
1251
1247
  if (n === "reference") return e.referenceStorage === "numeric" ? "bigint" : "text";
1252
1248
  switch (t) {
@@ -1255,10 +1251,10 @@ BEGIN
1255
1251
  case "mssql": return n === "json" ? "text" : n;
1256
1252
  default: return n;
1257
1253
  }
1258
- }, On = (e, t, n) => {
1254
+ }, jn = (e, t, n) => {
1259
1255
  let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
1260
1256
  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) => {
1257
+ }, Mn = (e, t, n, r, i, a) => {
1262
1258
  let o = [];
1263
1259
  if (t.nullable !== n.nullable) {
1264
1260
  let n = {
@@ -1267,7 +1263,7 @@ BEGIN
1267
1263
  column: t.name,
1268
1264
  toNullable: t.nullable
1269
1265
  };
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`));
1266
+ o.push(t.nullable ? L(n, "safe", `loosen ${e}.${t.name} to nullable`) : L(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1271
1267
  }
1272
1268
  if (t.unique !== n.unique) {
1273
1269
  if (t.unique) {
@@ -1276,14 +1272,14 @@ BEGIN
1276
1272
  table: e,
1277
1273
  column: t.name
1278
1274
  }, 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({
1275
+ o.push(r ? L(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1276
+ } else o.push(L({
1281
1277
  kind: "drop-unique",
1282
1278
  table: e,
1283
1279
  column: t.name
1284
1280
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1285
1281
  }
1286
- if (Dn(t, r) !== Dn(n, r)) {
1282
+ if (An(t, r) !== An(n, r)) {
1287
1283
  let i = t.narrowedFrom;
1288
1284
  if (i && i.from === n.type) {
1289
1285
  let r = {
@@ -1294,7 +1290,7 @@ BEGIN
1294
1290
  to: t.type,
1295
1291
  ...i.using === void 0 ? {} : { using: i.using }
1296
1292
  };
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)")));
1293
+ o.push(L(r, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${i.from}') declared` + (i.using ? ` with USING ${i.using}` : " (implicit cast)")));
1298
1294
  } else {
1299
1295
  let i = {
1300
1296
  kind: "alter-column-type",
@@ -1303,12 +1299,12 @@ BEGIN
1303
1299
  from: n.type,
1304
1300
  to: t.type
1305
1301
  };
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) }));
1302
+ o.push(L(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: jn(n.type, t, r) }));
1307
1303
  }
1308
1304
  }
1309
1305
  if (t.type === "text" && n.type === "text" && !m(r ?? "postgres") && t.maxLength !== n.maxLength) {
1310
1306
  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({
1307
+ o.push(L({
1312
1308
  kind: "alter-column-type",
1313
1309
  table: e,
1314
1310
  column: t.name,
@@ -1316,7 +1312,7 @@ BEGIN
1316
1312
  to: "text"
1317
1313
  }, 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
1314
  }
1319
- if (!un(t, n)) {
1315
+ if (!pn(t, n)) {
1320
1316
  let n = {
1321
1317
  kind: "alter-column-default",
1322
1318
  table: e,
@@ -1324,23 +1320,23 @@ BEGIN
1324
1320
  hasDefault: t.hasDefault,
1325
1321
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1326
1322
  };
1327
- o.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1323
+ o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1328
1324
  }
1329
- if (!fn(t.oneOf, n.oneOf)) {
1330
- n.oneOf && n.oneOf.length > 0 && o.push(R({
1325
+ if (!hn(t.oneOf, n.oneOf)) {
1326
+ n.oneOf && n.oneOf.length > 0 && o.push(L({
1331
1327
  kind: "drop-check",
1332
1328
  table: e,
1333
1329
  column: t.name
1334
1330
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1335
- let r = gn(e, t);
1331
+ let r = yn(e, t);
1336
1332
  r && o.push(r);
1337
1333
  }
1338
- return JSON.stringify(dn(t.references)) !== JSON.stringify(dn(n.references)) && (n.references && o.push(R({
1334
+ return JSON.stringify(mn(t.references)) !== JSON.stringify(mn(n.references)) && (n.references && o.push(L({
1339
1335
  kind: "drop-foreign-key",
1340
1336
  table: e,
1341
1337
  column: t.name
1342
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...An(e, t))), o;
1343
- }, An = (e, t) => {
1338
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Nn(e, t))), o;
1339
+ }, Nn = (e, t) => {
1344
1340
  let n = [];
1345
1341
  if (!t.references) return n;
1346
1342
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1352,15 +1348,15 @@ BEGIN
1352
1348
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1353
1349
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1354
1350
  };
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({
1351
+ return i === "null" && !t.nullable ? n.push(L(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(L({
1356
1352
  ...a,
1357
1353
  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) => {
1354
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(L(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1355
+ }, Pn = (e, t, n) => {
1360
1356
  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
1357
  for (let [n, c] of Object.entries(t)) {
1362
1358
  let t = c.renamedFrom;
1363
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1359
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1364
1360
  kind: "rename-column",
1365
1361
  table: e.tableName,
1366
1362
  from: t,
@@ -1372,26 +1368,26 @@ BEGIN
1372
1368
  consumedAddedNames: i,
1373
1369
  consumedRemovedNames: a
1374
1370
  };
1375
- }, Mn = /* @__PURE__ */ new Set([
1371
+ }, Fn = /* @__PURE__ */ new Set([
1376
1372
  "postgres",
1377
1373
  "mysql",
1378
1374
  "mariadb",
1379
1375
  "mssql"
1380
- ]), Nn = {
1376
+ ]), In = {
1381
1377
  ops: [],
1382
1378
  consumedAddedNames: /* @__PURE__ */ new Set(),
1383
1379
  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;
1380
+ }, Ln = (e) => !e.unique && !e.expression && e.where === void 0, Rn = (e, t, n, r, i) => {
1381
+ if (i === void 0 || !Fn.has(i)) return In;
1382
+ let a = t.added.filter((e) => Ln(e) && !r.has(e.name));
1383
+ if (a.length === 0) return In;
1388
1384
  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
1385
  for (let n of t.removed) {
1390
- if (!Pn(n)) continue;
1386
+ if (!Ln(n)) continue;
1391
1387
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1392
1388
  if (r.length !== 1) continue;
1393
1389
  let i = r[0];
1394
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1390
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(L({
1395
1391
  kind: "rename-index",
1396
1392
  table: e,
1397
1393
  from: n.name,
@@ -1403,7 +1399,7 @@ BEGIN
1403
1399
  consumedAddedNames: l,
1404
1400
  consumedRemovedNames: u
1405
1401
  };
1406
- }, In = (e, t, n) => {
1402
+ }, zn = (e, t, n) => {
1407
1403
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1408
1404
  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
1405
  for (let c of e.tables) {
@@ -1414,7 +1410,7 @@ BEGIN
1414
1410
  continue;
1415
1411
  }
1416
1412
  if (t.has(c.name)) {
1417
- r.push(R({
1413
+ r.push(L({
1418
1414
  kind: "rename-table",
1419
1415
  from: e,
1420
1416
  to: c.name
@@ -1422,14 +1418,14 @@ BEGIN
1422
1418
  continue;
1423
1419
  }
1424
1420
  if ((s.get(e) ?? 0) !== 1) {
1425
- r.push(R({
1421
+ r.push(L({
1426
1422
  kind: "rename-table",
1427
1423
  from: e,
1428
1424
  to: c.name
1429
1425
  }, "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
1426
  continue;
1431
1427
  }
1432
- i.set(c.name, e), a.add(e), r.push(R({
1428
+ i.set(c.name, e), a.add(e), r.push(L({
1433
1429
  kind: "rename-table",
1434
1430
  from: e,
1435
1431
  to: c.name
@@ -1443,19 +1439,19 @@ BEGIN
1443
1439
  claimedOldNames: c,
1444
1440
  refusals: o
1445
1441
  };
1446
- }, Ln = (e, t, n, r) => {
1442
+ }, Bn = (e, t, n, r) => {
1447
1443
  if (t === void 0) return {
1448
1444
  live: e,
1449
1445
  ops: []
1450
1446
  };
1451
- let i = r !== void 0 && Mn.has(r), a = [], o = e.indexes.map((e) => {
1447
+ let i = r !== void 0 && Fn.has(r), a = [], o = e.indexes.map((e) => {
1452
1448
  if (!e.name.startsWith(t)) return e;
1453
1449
  let r = `${n}${e.name.slice(t.length)}`;
1454
1450
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1455
1451
  ...e,
1456
1452
  name: r,
1457
1453
  table: n
1458
- } : i ? (a.push(R({
1454
+ } : i ? (a.push(L({
1459
1455
  kind: "rename-index",
1460
1456
  table: n,
1461
1457
  from: e.name,
@@ -1474,7 +1470,7 @@ BEGIN
1474
1470
  },
1475
1471
  ops: a
1476
1472
  };
1477
- }, Rn = (e) => {
1473
+ }, Vn = (e) => {
1478
1474
  let t = {
1479
1475
  safe: 0,
1480
1476
  needsDefault: 0,
@@ -1507,42 +1503,42 @@ BEGIN
1507
1503
  case "multi-step": t.multiStep++;
1508
1504
  }
1509
1505
  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);
1506
+ }, Hn = (e) => {
1507
+ let t = F(e.declared, e.dialect), n = dn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Dn, a = [], o = zn(t, r, n);
1512
1508
  a.push(...o.ops);
1513
1509
  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)));
1510
+ a.push(Tn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1515
1511
  for (let t of e.columns) {
1516
- let n = gn(e.name, t);
1512
+ let n = yn(e.name, t);
1517
1513
  n && a.push(n);
1518
1514
  }
1519
1515
  }
1520
1516
  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));
1517
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || _(t.name) || x(t.name) || s.has(t.name) || a.push(En(t.name));
1522
1518
  for (let s of t.tables) {
1523
1519
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1524
1520
  if (!c) continue;
1525
- let l = Ln(c, t, s.name, e.dialect);
1521
+ let l = Bn(c, t, s.name, e.dialect);
1526
1522
  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);
1523
+ let u = l.live, d = n.get(s.name), f = xn(s, u, e.dialect), p = Sn(s, u, e.dialect), m = Pn(d.table, d.columnDefs, f);
1528
1524
  a.push(...m.ops);
1529
1525
  for (let e of f.removed) {
1530
1526
  if (m.consumedRemovedNames.has(e.name) || x(e.name)) continue;
1531
1527
  let t = d.columnDefs[e.name];
1532
- a.push(xn(s.name, e, t));
1528
+ a.push(wn(s.name, e, t));
1533
1529
  }
1534
1530
  for (let e of f.added) {
1535
1531
  if (m.consumedAddedNames.has(e.name)) continue;
1536
1532
  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));
1533
+ a.push(Cn(s.name, e, t));
1534
+ let n = yn(s.name, e);
1535
+ n && a.push(n), a.push(...Nn(s.name, e));
1540
1536
  }
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);
1537
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Rn(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1542
1538
  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));
1539
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(On(s.name, e, u.rowCount, i));
1540
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(kn(s.name, e));
1541
+ for (let { declared: t, live: n } of f.changed) a.push(...Mn(s.name, t, n, e.dialect, u.rowCount, i));
1546
1542
  }
1547
1543
  let c = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), l = new Map(t.tables.map((e) => [e.name, e])), u = (e) => {
1548
1544
  let t = l.get(e);
@@ -1550,8 +1546,8 @@ BEGIN
1550
1546
  column: e.name,
1551
1547
  target: e.references.table
1552
1548
  }] : []) : [];
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({
1549
+ }, d = he([...c], u), f = [];
1550
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) t.references && d.has(E(e.name, t.name)) && f.push(L({
1555
1551
  kind: "add-foreign-key",
1556
1552
  table: e.name,
1557
1553
  column: t.name,
@@ -1623,11 +1619,11 @@ BEGIN
1623
1619
  });
1624
1620
  return {
1625
1621
  operations: S,
1626
- fromFingerprint: Xt(e.live),
1627
- toFingerprint: Xt(t),
1628
- summary: Rn(S)
1622
+ fromFingerprint: $t(e.live),
1623
+ toFingerprint: $t(t),
1624
+ summary: Vn(S)
1629
1625
  };
1630
- }, Bn = (e) => {
1626
+ }, Un = (e) => {
1631
1627
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1632
1628
  if (!t) return null;
1633
1629
  let n = [...e.replace(/\\'/g, "'").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
@@ -1635,7 +1631,7 @@ BEGIN
1635
1631
  column: t[1],
1636
1632
  values: n
1637
1633
  };
1638
- }, Vn = (e, t) => {
1634
+ }, Wn = (e, t) => {
1639
1635
  if (t === "vector") return "vector";
1640
1636
  switch (e) {
1641
1637
  case "text":
@@ -1662,10 +1658,10 @@ BEGIN
1662
1658
  case "USER-DEFINED": return "text";
1663
1659
  default: return "text";
1664
1660
  }
1665
- }, Hn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1661
+ }, Gn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1666
1662
  expr: e,
1667
1663
  stored: t
1668
- } }, z = (e) => {
1664
+ } }, R = (e) => {
1669
1665
  switch (e.toUpperCase()) {
1670
1666
  case "CASCADE": return "cascade";
1671
1667
  case "RESTRICT": return "restrict";
@@ -1673,25 +1669,25 @@ BEGIN
1673
1669
  case "SET DEFAULT": return "noAction";
1674
1670
  default: return "noAction";
1675
1671
  }
1676
- }, Un = (e, t) => {
1672
+ }, Kn = (e, t) => {
1677
1673
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1678
1674
  return Number.isInteger(n) && n > 0 ? n : t;
1679
- }, Wn = () => Un(process.env.VOLTRO_INTROSPECT_BATCH, 20), Gn = 300, Kn = () => {
1675
+ }, qn = () => Kn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Jn = 300, Yn = () => {
1680
1676
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1681
- return e !== void 0 && e.trim() === "0" ? 0 : Un(e, 3e4);
1682
- }, qn = (e, t) => {
1677
+ return e !== void 0 && e.trim() === "0" ? 0 : Kn(e, 3e4);
1678
+ }, Xn = (e, t) => {
1683
1679
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1684
1680
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1685
1681
  return r;
1686
- }, Jn = (e) => {
1687
- let t = Kn(), n = C.gen(function* () {
1682
+ }, Zn = (e) => {
1683
+ let t = Yn(), n = w.gen(function* () {
1688
1684
  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* () {
1685
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = qn(), a = (e, t) => w.gen(function* () {
1690
1686
  let r = [];
1691
- for (let a of qn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1687
+ for (let a of Xn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1692
1688
  return r;
1693
1689
  }), o = [];
1694
- for (let t = 0;; t += Gn) {
1690
+ for (let t = 0;; t += Jn) {
1695
1691
  let n = yield* e`
1696
1692
  SELECT c.relname AS table_name,
1697
1693
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1699,9 +1695,9 @@ BEGIN
1699
1695
  JOIN pg_namespace n ON n.oid = c.relnamespace
1700
1696
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1701
1697
  ORDER BY c.relname
1702
- LIMIT ${r(Gn)} OFFSET ${r(t)}
1698
+ LIMIT ${r(Jn)} OFFSET ${r(t)}
1703
1699
  `;
1704
- if (o.push(...n), n.length < Gn) break;
1700
+ if (o.push(...n), n.length < Jn) break;
1705
1701
  }
1706
1702
  let s = /* @__PURE__ */ new Set(), c = [];
1707
1703
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1798,18 +1794,18 @@ BEGIN
1798
1794
  let t = v.get(e.table_name);
1799
1795
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1800
1796
  }
1801
- let ee = /* @__PURE__ */ new Map();
1797
+ let C = /* @__PURE__ */ new Map();
1802
1798
  for (let e of f) {
1803
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = ee.get(t);
1799
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = C.get(t);
1804
1800
  n || (n = {
1805
1801
  table: e.table_name,
1806
1802
  columns: []
1807
- }, ee.set(t, n)), n.columns.push({
1803
+ }, C.set(t, n)), n.columns.push({
1808
1804
  name: e.column_name,
1809
1805
  position: e.position
1810
1806
  });
1811
1807
  }
1812
- for (let [e, t] of ee) {
1808
+ for (let [e, t] of C) {
1813
1809
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1814
1810
  if (n.length === 1) {
1815
1811
  let e = y.get(t.table);
@@ -1834,27 +1830,27 @@ BEGIN
1834
1830
  let n = t.get(e.index_name);
1835
1831
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1836
1832
  }
1837
- let w = [];
1833
+ let ee = [];
1838
1834
  for (let e of c) {
1839
1835
  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 ? {
1836
+ let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Wn(t.data_type, t.udt_name), c = a ? {
1841
1837
  table: a.target_table,
1842
1838
  column: a.target_column,
1843
- onDelete: z(a.delete_rule),
1844
- onUpdate: z(a.update_rule)
1839
+ onDelete: R(a.delete_rule),
1840
+ onUpdate: R(a.update_rule)
1845
1841
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1846
1842
  return {
1847
1843
  name: t.column_name,
1848
1844
  type: s,
1849
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1845
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1850
1846
  nullable: t.is_nullable === "YES",
1851
1847
  unique: i.has(t.column_name) || n && t.column_name === "id",
1852
1848
  hasDefault: t.column_default !== null,
1853
1849
  ...t.column_default === null ? {} : { defaultValue: t.column_default },
1854
1850
  ...c ? { references: c } : {},
1855
- ...a ? { referenceStorage: ["integer", "bigint"].includes(Vn(t.data_type, t.udt_name)) ? "numeric" : "text" } : {},
1851
+ ...a ? { referenceStorage: ["integer", "bigint"].includes(Wn(t.data_type, t.udt_name)) ? "numeric" : "text" } : {},
1856
1852
  ...l ? { oneOf: l } : {},
1857
- ...Hn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1853
+ ...Gn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1858
1854
  };
1859
1855
  }), l = [], u = S.get(e.table_name);
1860
1856
  if (u) for (let [t, n] of u) {
@@ -1882,20 +1878,20 @@ BEGIN
1882
1878
  unique: !0
1883
1879
  });
1884
1880
  let d = Number(e.row_count ?? 0);
1885
- w.push({
1881
+ ee.push({
1886
1882
  name: e.table_name,
1887
1883
  columns: c,
1888
1884
  indexes: l,
1889
1885
  ...d > 0 ? { rowCount: d } : {}
1890
1886
  });
1891
1887
  }
1892
- return { tables: w };
1888
+ return { tables: ee };
1893
1889
  });
1894
- return (t > 0 ? e.withTransaction(n) : n).pipe(C.catchAll((e) => {
1890
+ return (t > 0 ? e.withTransaction(n) : n).pipe(w.catchAll((e) => {
1895
1891
  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);
1892
+ 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
1893
  }));
1898
- }, Yn = (e, t) => {
1894
+ }, Qn = (e, t) => {
1899
1895
  switch (e.toLowerCase()) {
1900
1896
  case "varchar":
1901
1897
  case "char":
@@ -1927,21 +1923,21 @@ BEGIN
1927
1923
  case "json": return "json";
1928
1924
  default: return "text";
1929
1925
  }
1930
- }, B = (e) => e.map((e) => {
1926
+ }, z = (e) => e.map((e) => {
1931
1927
  let t = e, n = {};
1932
1928
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1933
1929
  return n;
1934
- }), Xn = (e) => C.gen(function* () {
1935
- let t = B(yield* e`
1930
+ }), $n = (e) => w.gen(function* () {
1931
+ let t = z(yield* e`
1936
1932
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1937
1933
  FROM information_schema.tables
1938
1934
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1939
- ORDER BY table_name`), n = B(yield* e`
1935
+ ORDER BY table_name`), n = z(yield* e`
1940
1936
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1941
1937
  character_maximum_length, generation_expression, extra
1942
1938
  FROM information_schema.columns
1943
1939
  WHERE table_schema = DATABASE()
1944
- ORDER BY table_name, ordinal_position`), r = B(yield* e`
1940
+ ORDER BY table_name, ordinal_position`), r = z(yield* e`
1945
1941
  SELECT k.table_name AS source_table,
1946
1942
  k.column_name AS source_column,
1947
1943
  k.referenced_table_name AS target_table,
@@ -1951,7 +1947,7 @@ BEGIN
1951
1947
  JOIN information_schema.referential_constraints r
1952
1948
  ON k.constraint_name = r.constraint_name
1953
1949
  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`
1950
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
1955
1951
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1956
1952
  FROM information_schema.statistics
1957
1953
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
@@ -1964,14 +1960,14 @@ BEGIN
1964
1960
  JOIN information_schema.table_constraints tc
1965
1961
  ON tc.constraint_schema = cc.constraint_schema
1966
1962
  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();
1963
+ WHERE cc.constraint_schema = DATABASE()`.unprepared, s = z(yield* a.pipe(w.orElse(() => o), w.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
1968
1964
  for (let e of s) {
1969
1965
  let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
1970
1966
  if (t) {
1971
1967
  c.add(`${e.table_name}.${t[1]}`);
1972
1968
  continue;
1973
1969
  }
1974
- let n = Bn(e.check_clause);
1970
+ let n = Un(e.check_clause);
1975
1971
  n && l.set(`${e.table_name}.${n.column}`, n.values);
1976
1972
  }
1977
1973
  let u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
@@ -1994,24 +1990,24 @@ BEGIN
1994
1990
  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
1991
  if (o) for (let e of o.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1996
1992
  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 ? {
1993
+ let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = o ? "reference" : n && t.column_name === "id" ? "id" : c.has(`${e.table_name}.${t.column_name}`) ? "json" : Qn(t.data_type, t.column_type), u = o ? {
1998
1994
  table: o.target_table,
1999
1995
  column: o.target_column,
2000
- onDelete: z(o.delete_rule),
2001
- onUpdate: z(o.update_rule)
1996
+ onDelete: R(o.delete_rule),
1997
+ onUpdate: R(o.update_rule)
2002
1998
  } : 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
1999
  return {
2004
2000
  name: t.column_name,
2005
2001
  type: s,
2006
2002
  nullable: t.is_nullable === "YES",
2007
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2003
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2008
2004
  unique: d,
2009
2005
  hasDefault: f !== null,
2010
2006
  ...f === null ? {} : { defaultValue: f },
2011
2007
  ...u ? { references: u } : {},
2012
- ...o ? { referenceStorage: ["integer", "bigint"].includes(Yn(t.data_type, t.column_type)) ? "numeric" : "text" } : {},
2008
+ ...o ? { referenceStorage: ["integer", "bigint"].includes(Qn(t.data_type, t.column_type)) ? "numeric" : "text" } : {},
2013
2009
  ...p ? { oneOf: p } : {},
2014
- ...Hn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
2010
+ ...Gn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
2015
2011
  };
2016
2012
  }), m = new Set(n.map((e) => e.source_column)), h = [];
2017
2013
  if (o) for (let [t, n] of o) {
@@ -2038,10 +2034,10 @@ BEGIN
2038
2034
  });
2039
2035
  }
2040
2036
  return { tables: p };
2041
- }), Zn = (e) => {
2037
+ }), er = (e) => {
2042
2038
  let t = e.toUpperCase();
2043
2039
  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* () {
2040
+ }, tr = (e) => e === 1 || e === !0, nr = (e) => w.gen(function* () {
2045
2041
  let t = yield* e`
2046
2042
  SELECT name, sql FROM sqlite_master
2047
2043
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -2055,18 +2051,18 @@ BEGIN
2055
2051
  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
2052
  for (let t of c) {
2057
2053
  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 ?? "");
2054
+ if (f.set(t.name, r), t.partial !== void 0 && tr(t.partial)) {
2055
+ let n = Kt((yield* e`SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ${t.name}`)[0]?.sql ?? "");
2060
2056
  n !== void 0 && p.set(t.name, n);
2061
2057
  }
2062
- !p.has(t.name) && Qn(t.unique) && r.length === 1 && m.add(r[0]);
2058
+ !p.has(t.name) && tr(t.unique) && r.length === 1 && m.add(r[0]);
2063
2059
  }
2064
2060
  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 ? {
2061
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : er(e.type), a = r ? {
2066
2062
  table: r.table,
2067
2063
  column: r.to,
2068
- onDelete: z(r.on_delete),
2069
- onUpdate: z(r.on_update)
2064
+ onDelete: R(r.on_delete),
2065
+ onUpdate: R(r.on_update)
2070
2066
  } : void 0, o = t.get(e.name);
2071
2067
  return {
2072
2068
  name: e.name,
@@ -2076,19 +2072,19 @@ BEGIN
2076
2072
  hasDefault: e.dflt_value !== null,
2077
2073
  ...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
2078
2074
  ...a ? { references: a } : {},
2079
- ...r ? { referenceStorage: ["integer", "bigint"].includes(Zn(e.type)) ? "numeric" : "text" } : {},
2075
+ ...r ? { referenceStorage: ["integer", "bigint"].includes(er(e.type)) ? "numeric" : "text" } : {},
2080
2076
  ...o ? { oneOf: o } : {},
2081
- ...Hn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2077
+ ...Gn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2082
2078
  };
2083
2079
  }), g = new Set(s.map((e) => e.from)), _ = [];
2084
2080
  for (let e of c) {
2085
2081
  if (e.origin === "pk") continue;
2086
2082
  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({
2083
+ n === void 0 && t.length === 1 && tr(e.unique) || (n !== void 0 || t.length !== 1 || tr(e.unique) || !g.has(t[0]) || e.name === `${i}_${t[0]}_idx`) && _.push({
2088
2084
  name: e.name,
2089
2085
  table: i,
2090
2086
  columns: t,
2091
- unique: Qn(e.unique),
2087
+ unique: tr(e.unique),
2092
2088
  ...n === void 0 ? {} : { where: n }
2093
2089
  });
2094
2090
  }
@@ -2104,7 +2100,7 @@ BEGIN
2104
2100
  });
2105
2101
  }
2106
2102
  return { tables: r };
2107
- }), er = (e) => {
2103
+ }), rr = (e) => {
2108
2104
  switch (e.toLowerCase()) {
2109
2105
  case "int":
2110
2106
  case "smallint":
@@ -2126,14 +2122,14 @@ BEGIN
2126
2122
  case "image": return "bytes";
2127
2123
  default: return "text";
2128
2124
  }
2129
- }, V = (e) => e === !0 || e === 1, tr = (e) => C.gen(function* () {
2125
+ }, B = (e) => e === !0 || e === 1, ir = (e) => w.gen(function* () {
2130
2126
  let t = yield* e`
2131
2127
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2132
2128
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
2133
2129
  SELECT TABLE_NAME AS table_name, COLUMN_NAME AS column_name, DATA_TYPE AS data_type,
2134
2130
  IS_NULLABLE AS is_nullable, COLUMN_DEFAULT AS column_default,
2135
2131
  CHARACTER_MAXIMUM_LENGTH AS character_maximum_length
2136
- FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* C.orElseSucceed(e`
2132
+ FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* w.orElseSucceed(e`
2137
2133
  SELECT t.name AS table_name, c.name AS column_name, cc.definition AS definition,
2138
2134
  cc.is_persisted AS is_persisted
2139
2135
  FROM sys.computed_columns cc
@@ -2189,39 +2185,39 @@ BEGIN
2189
2185
  let t = l.get(e) ?? [], n = u.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), a = new Set(n.map((e) => e.source_column)), o = d.get(e), s = [], p = /* @__PURE__ */ new Set();
2190
2186
  if (o) for (let [, e] of o) {
2191
2187
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2192
- if (V(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2193
- else t[0].predicate == null && V(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2188
+ if (B(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2189
+ else t[0].predicate == null && B(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2194
2190
  }
2195
2191
  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 ? {
2192
+ let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : rr(t.data_type), l = a ? {
2197
2193
  table: a.target_table,
2198
2194
  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}`);
2195
+ onDelete: ar(a.delete_rule),
2196
+ onUpdate: ar(a.update_rule)
2197
+ } : void 0, u = t.column_default === null ? null : or(t.column_default), d = c.get(`${e}.${t.column_name}`);
2202
2198
  return {
2203
2199
  name: t.column_name,
2204
2200
  type: o,
2205
2201
  nullable: t.is_nullable === "YES",
2206
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2202
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2207
2203
  unique: p.has(t.column_name) || n && t.column_name === "id",
2208
2204
  hasDefault: u !== null,
2209
2205
  ...u === null ? {} : { defaultValue: u },
2210
2206
  ...l ? { references: l } : {},
2211
- ...a ? { referenceStorage: ["integer", "bigint"].includes(er(t.data_type)) ? "numeric" : "text" } : {},
2207
+ ...a ? { referenceStorage: ["integer", "bigint"].includes(rr(t.data_type)) ? "numeric" : "text" } : {},
2212
2208
  ...d ? { oneOf: d } : {},
2213
- ...Hn(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2209
+ ...Gn(i.get(`${e}.${t.column_name}`)?.definition ?? null, B(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2214
2210
  };
2215
2211
  }), h = [];
2216
2212
  if (o) for (let [t, n] of o) {
2217
2213
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2218
- if (V(r[0].is_primary)) continue;
2214
+ if (B(r[0].is_primary)) continue;
2219
2215
  let i = r[0].predicate ?? void 0;
2220
- i === void 0 && r.length === 1 && V(r[0].is_unique) || (i !== void 0 || r.length !== 1 || V(r[0].is_unique) || !a.has(r[0].column_name) || t === `${e}_${r[0].column_name}_idx`) && h.push({
2216
+ i === void 0 && r.length === 1 && B(r[0].is_unique) || (i !== void 0 || r.length !== 1 || B(r[0].is_unique) || !a.has(r[0].column_name) || t === `${e}_${r[0].column_name}_idx`) && h.push({
2221
2217
  name: t,
2222
2218
  table: e,
2223
2219
  columns: r.map((e) => e.column_name),
2224
- unique: V(r[0].is_unique),
2220
+ unique: B(r[0].is_unique),
2225
2221
  ...i === void 0 ? {} : { where: i }
2226
2222
  });
2227
2223
  }
@@ -2237,90 +2233,90 @@ BEGIN
2237
2233
  });
2238
2234
  }
2239
2235
  return { tables: f };
2240
- }), nr = (e) => {
2236
+ }), ar = (e) => {
2241
2237
  switch (e.toUpperCase().replace(/_/g, " ")) {
2242
2238
  case "CASCADE": return "cascade";
2243
2239
  case "SET NULL": return "setNull";
2244
2240
  case "SET DEFAULT": return "noAction";
2245
2241
  default: return "noAction";
2246
2242
  }
2247
- }, rr = (e) => {
2243
+ }, or = (e) => {
2248
2244
  let t = e.trim();
2249
2245
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2250
2246
  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([
2247
+ }, sr = /* @__PURE__ */ new Set([
2252
2248
  "character varying",
2253
2249
  "varchar",
2254
2250
  "nvarchar",
2255
2251
  "char",
2256
2252
  "character",
2257
2253
  "nchar"
2258
- ]), H = (e, t) => {
2259
- if (!ir.has(e.toLowerCase())) return;
2254
+ ]), V = (e, t) => {
2255
+ if (!sr.has(e.toLowerCase())) return;
2260
2256
  let n = Number(t);
2261
2257
  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) => ({
2258
+ }, cr = /* @__PURE__ */ new Set([O]), lr = (e) => e.onDialectOrElse({
2259
+ mysql: () => $n(e),
2260
+ mssql: () => ir(e),
2261
+ sqlite: () => nr(e),
2262
+ orElse: () => Zn(e)
2263
+ }).pipe(w.map((e) => ({
2268
2264
  ...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) => {
2265
+ tables: e.tables.filter((e) => !cr.has(e.name))
2266
+ }))), ur = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", dr = /* @__PURE__ */ new WeakMap(), H = (e) => w.suspend(() => {
2267
+ let t = dr.get(e);
2268
+ return t === void 0 ? fr(e).pipe(w.tap((t) => w.sync(() => dr.set(e, t)))) : w.succeed(t);
2269
+ }), fr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(w.map((e) => {
2274
2270
  let t = e[0]?.v;
2275
- return typeof t == "string" ? sr(t) : "mysql";
2276
- }), C.catchAll(() => C.succeed("mysql"))), dr = (e) => {
2271
+ return typeof t == "string" ? ur(t) : "mysql";
2272
+ }), w.catchAll(() => w.succeed("mysql"))), pr = (e) => {
2277
2273
  let t = e;
2278
2274
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2279
2275
  let e = t;
2280
2276
  if (typeof e.errno == "number") return e.errno;
2281
2277
  t = e.cause;
2282
2278
  }
2283
- }, fr = (e) => {
2279
+ }, mr = (e) => {
2284
2280
  let t = [], n = e;
2285
2281
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2286
2282
  let e = n;
2287
2283
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2288
2284
  }
2289
2285
  return t.join(" | ");
2290
- }, pr = (e, t) => {
2286
+ }, hr = (e, t) => {
2291
2287
  if (t.length === 0) return !1;
2292
- let n = dr(e), r = fr(e);
2288
+ let n = pr(e), r = mr(e);
2293
2289
  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 = {
2290
+ }, gr = {
2295
2291
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2296
2292
  errno: [1061]
2297
- }, hr = {
2293
+ }, _r = {
2298
2294
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2299
2295
  errno: [1091]
2300
- }, gr = {
2296
+ }, vr = {
2301
2297
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2302
2298
  messageIncludes: ["no such column"]
2303
- }, _r = {
2299
+ }, yr = {
2304
2300
  why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
2305
2301
  errno: [1091, 3940]
2306
2302
  }, 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;
2303
+ mysql: () => w.succeed(t.replace("T", " ").replace("Z", "")),
2304
+ orElse: () => w.succeed(t)
2305
+ }), br = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, xr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), Sr = (e, t) => {
2306
+ if ((e.type !== "text" || e.maxLength === void 0) && !xr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2311
2307
  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
2308
  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
- return M(e, t);
2314
- }, xr = (e) => {
2315
- let t = br(e, "postgres");
2316
- return t === void 0 ? Sr(e) : t;
2317
- }, Sr = (e) => {
2309
+ return j(e, t);
2310
+ }, Cr = (e) => {
2311
+ let t = Sr(e, "postgres");
2312
+ return t === void 0 ? wr(e) : t;
2313
+ }, wr = (e) => {
2318
2314
  switch (e.type) {
2319
2315
  case "id": return "text";
2320
2316
  case "text": return "text";
2321
2317
  case "integer": return "integer";
2322
2318
  case "real": return "double precision";
2323
- case "decimal": return vr(e, "NUMERIC");
2319
+ case "decimal": return br(e, "NUMERIC");
2324
2320
  case "bigint": return "bigint";
2325
2321
  case "boolean": return "boolean";
2326
2322
  case "timestamp": return "timestamptz";
@@ -2334,15 +2330,15 @@ BEGIN
2334
2330
  case "interval": return "interval";
2335
2331
  case "raw": return e.rawDdl ?? "text";
2336
2332
  }
2337
- }, Cr = (e) => {
2338
- let t = br(e, "mariadb");
2333
+ }, Tr = (e) => {
2334
+ let t = Sr(e, "mariadb");
2339
2335
  if (t !== void 0) return t;
2340
2336
  switch (e.type) {
2341
2337
  case "id": return "VARCHAR(64)";
2342
2338
  case "text": return "LONGTEXT";
2343
2339
  case "integer": return "INT";
2344
2340
  case "real": return "DOUBLE";
2345
- case "decimal": return vr(e, "DECIMAL");
2341
+ case "decimal": return br(e, "DECIMAL");
2346
2342
  case "bigint": return "BIGINT";
2347
2343
  case "boolean": return "TINYINT(1)";
2348
2344
  case "timestamp": return "DATETIME(6)";
@@ -2356,38 +2352,38 @@ BEGIN
2356
2352
  case "interval": return "BIGINT";
2357
2353
  case "raw": return e.rawDdl ?? "LONGTEXT";
2358
2354
  }
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) => {
2355
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, Er = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", Dr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, Or = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, kr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Ar = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${ai(t)}`)};`, jr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Nr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Mr = (e, t) => {
2360
2356
  let { defaultFactory: n, ...r } = e;
2361
- return M(e, t) !== M({
2357
+ return j(e, t) !== j({
2362
2358
  ...r,
2363
2359
  hasDefault: !1
2364
2360
  }, t);
2365
- }, jr = (e, t) => {
2361
+ }, Nr = (e, t) => {
2366
2362
  let n = t(e.defaultValue);
2367
2363
  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
2364
  return n;
2369
- }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Mr = (e, t, n) => {
2365
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Pr = (e, t, n) => {
2370
2366
  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");
2367
+ return r ? tn(n, r) : void 0;
2368
+ }, Fr = (e, t, n) => {
2369
+ let r = n ?? e.nullable, i = it(e, "mariadb");
2374
2370
  return [
2375
2371
  G(t),
2376
- M(e, "mariadb"),
2372
+ j(e, "mariadb"),
2377
2373
  r ? null : "NOT NULL",
2378
2374
  i
2379
2375
  ].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) => {
2376
+ }, Ir = (e, t) => e == null ? null : Array.isArray(e) ? Lr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, Lr = (e, t, n) => at(e, t ?? { type: "json" }, n), Rr = (e, t) => e == null ? null : Array.isArray(e) ? Lr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, zr = (e, t) => {
2381
2377
  if (!e.generatedAs) return null;
2382
2378
  let { expr: n, stored: r } = e.generatedAs;
2383
2379
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2384
- }, Rr = (e) => {
2385
- 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)];
2380
+ }, Br = (e) => {
2381
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2382
+ let t = zr(e, "postgres");
2383
+ if (t) return `${W(e.name)} ${Cr(e)} ${t}`;
2384
+ let n = [W(e.name), Cr(e)];
2389
2385
  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);
2386
+ let t = Rr(e.defaultValue, e);
2391
2387
  t && n.push(t);
2392
2388
  }
2393
2389
  return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
@@ -2396,24 +2392,24 @@ BEGIN
2396
2392
  setNull: "SET NULL",
2397
2393
  noAction: "NO ACTION"
2398
2394
  }[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)}`);
2395
+ }, Vr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Hr = (e) => {
2396
+ let t = e.columns.map((e) => ` ${Br(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Vr(e, W)}\n)`];
2397
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(ui).join(", ")})${Y(t)}`);
2402
2398
  return n;
2403
- }, Vr = 191, Hr = (e) => {
2404
- let t = Cr(e).toUpperCase();
2399
+ }, Ur = 191, Wr = (e) => {
2400
+ let t = Tr(e).toUpperCase();
2405
2401
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2406
- }, Ur = (e) => {
2407
- 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);
2402
+ }, Gr = (e) => {
2403
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2404
+ let t = zr(e, "mariadb");
2405
+ if (t) return `${G(e.name)} ${Tr(e)} ${t}`;
2406
+ let n = [G(e.name), Tr(e)];
2407
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Wr(e) && n.push("UNIQUE"), e.hasDefault) {
2408
+ let t = Ir(e.defaultValue, e);
2413
2409
  t && n.push(t);
2414
2410
  }
2415
2411
  return n.join(" ");
2416
- }, Wr = (e) => e.columns.flatMap((t) => {
2412
+ }, Kr = (e) => e.columns.flatMap((t) => {
2417
2413
  if (!t.references) return [];
2418
2414
  let n = t.references.onDelete ? ` ON DELETE ${{
2419
2415
  cascade: "CASCADE",
@@ -2422,27 +2418,27 @@ BEGIN
2422
2418
  noAction: "NO ACTION"
2423
2419
  }[t.references.onDelete]}` : "";
2424
2420
  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);
2421
+ }), qr = (e, t = "mariadb") => {
2422
+ for (let n of e.indexes) pi(n, t);
2427
2423
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2428
- let t = oi(n.get(e));
2424
+ let t = ci(n.get(e));
2429
2425
  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(", ")})`);
2426
+ }, i = e.columns.map((e) => ` ${Gr(e)}`).join(",\n"), a = Kr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Vr(e, r)}\n)`];
2427
+ for (let n of e.columns) n.unique && n.type !== "id" && Wr(n) && s.push(`CREATE UNIQUE INDEX ${Er(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2428
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Er(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2433
2429
  return s;
2434
- }, Kr = {
2430
+ }, Jr = {
2435
2431
  cascade: "CASCADE",
2436
2432
  restrict: "RESTRICT",
2437
2433
  setNull: "SET NULL",
2438
2434
  noAction: "NO ACTION"
2439
- }, qr = {
2435
+ }, Yr = {
2440
2436
  cascade: "CASCADE",
2441
2437
  restrict: "NO ACTION",
2442
2438
  setNull: "SET NULL",
2443
2439
  noAction: "NO ACTION"
2444
- }, Jr = (e) => {
2445
- let t = br(e, "sqlite");
2440
+ }, Xr = (e) => {
2441
+ let t = Sr(e, "sqlite");
2446
2442
  if (t !== void 0) return t;
2447
2443
  switch (e.type) {
2448
2444
  case "integer":
@@ -2454,29 +2450,29 @@ BEGIN
2454
2450
  case "bytes": return "BLOB";
2455
2451
  default: return "TEXT";
2456
2452
  }
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) => {
2458
- 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)];
2453
+ }, Zr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Qr = (e) => {
2454
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2455
+ let t = zr(e, "sqlite");
2456
+ if (t) return `${W(e.name)} ${Xr(e)} ${t}`;
2457
+ let n = [W(e.name), Xr(e)];
2462
2458
  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");
2459
+ let t = Zr(e.defaultValue, "CURRENT_TIMESTAMP");
2464
2460
  t && n.push(t);
2465
2461
  }
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) {
2462
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Jr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2467
2463
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2468
2464
  n.push(`CHECK (${W(e.name)} IN (${t}))`);
2469
2465
  }
2470
2466
  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)`];
2467
+ }, $r = (e) => {
2468
+ let t = e.columns.map((e) => ` ${Qr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Vr(e, W)}\n)`];
2473
2469
  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
2470
  return n;
2475
2471
  }, q = (e, t) => {
2476
2472
  let n = t.find((t) => t.tableName === e);
2477
2473
  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({
2474
+ let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2475
+ ...$r({
2480
2476
  kind: "create-table",
2481
2477
  table: i,
2482
2478
  columns: r.columns,
@@ -2489,25 +2485,25 @@ BEGIN
2489
2485
  ];
2490
2486
  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
2487
  return o;
2492
- }, Qr = (e, t, n, r) => {
2488
+ }, ei = (e, t, n, r) => {
2493
2489
  let i = r ?? e.nullable;
2494
- return `ALTER TABLE ${J(n)} ALTER COLUMN ${J(t)} ${M(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2495
- }, $r = (e, t) => {
2490
+ return `ALTER TABLE ${J(n)} ALTER COLUMN ${J(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2491
+ }, ti = (e, t) => {
2496
2492
  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
2493
  if (!e.hasDefault) return n;
2498
- let r = Yr(e.defaultValue, "SYSUTCDATETIME()");
2494
+ let r = Zr(e.defaultValue, "SYSUTCDATETIME()");
2499
2495
  if (!r) return n;
2500
2496
  let i = r.replace(/^DEFAULT\s+/i, "");
2501
2497
  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");
2498
+ }, J = (e) => `[${e.replace(/]/g, "]]")}]`, ni = (e) => {
2499
+ let t = Sr(e, "mssql");
2504
2500
  if (t !== void 0) return t;
2505
2501
  switch (e.type) {
2506
2502
  case "id": return "NVARCHAR(64)";
2507
2503
  case "reference": return e.referenceStorage === "numeric" ? "BIGINT" : "NVARCHAR(64)";
2508
2504
  case "integer": return "INT";
2509
2505
  case "real": return "FLOAT";
2510
- case "decimal": return vr(e, "DECIMAL");
2506
+ case "decimal": return br(e, "DECIMAL");
2511
2507
  case "bigint": return "BIGINT";
2512
2508
  case "boolean": return "BIT";
2513
2509
  case "timestamp": return "DATETIME2(6)";
@@ -2515,46 +2511,46 @@ BEGIN
2515
2511
  case "bytes": return "VARBINARY(MAX)";
2516
2512
  default: return "NVARCHAR(MAX)";
2517
2513
  }
2518
- }, ti = (e, t) => {
2519
- 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");
2514
+ }, ri = (e, t) => {
2515
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2516
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : ni(e), r = zr(e, "mssql");
2521
2517
  if (r) return `${J(e.name)} ${r}`;
2522
2518
  let i = [J(e.name), n];
2523
2519
  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()");
2520
+ let t = Zr(e.defaultValue, "SYSUTCDATETIME()");
2525
2521
  t && i.push(t);
2526
2522
  }
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)}')`];
2523
+ return e.references && (i.push(`REFERENCES ${J(e.references.table)} (${J(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Yr[e.references.onDelete]}`)), i.join(" ");
2524
+ }, ii = (e) => {
2525
+ let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((e) => ` ${ri(e, n)}`).join(",\n"), i = `CREATE TABLE ${J(e.table)} (\n${r}${Vr(e, J)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2530
2526
  for (let n of e.indexes) {
2531
2527
  if (n.name === `${e.table}_pkey`) continue;
2532
2528
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${J(n.name)} ON ${J(e.table)} (${n.columns.map(J).join(", ")})${Y(n)}`;
2533
2529
  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
2530
  }
2535
2531
  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)}`;
2532
+ }, ai = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, oi = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, si = (e, t, n) => {
2533
+ let r = `${e.table}${ai(t)}`;
2538
2534
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2539
- }, oi = (e) => {
2540
- if (e === void 0 || !Hr(e)) return;
2535
+ }, ci = (e) => {
2536
+ if (e === void 0 || !Wr(e)) return;
2541
2537
  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));
2538
+ return t === void 0 ? Ur : Math.min(Ur, t);
2539
+ }, li = (e, t, n) => {
2540
+ let r = ci(Pr(e, t, n));
2545
2541
  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) => {
2542
+ }, ui = (e) => e.startsWith("(") ? e : W(e), Y = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, di = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map(ui).join(", ")})${Y(e.index)};`, fi = (e, t, n = "mariadb") => (pi(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Er(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => li(t, e.table, n)).join(", ")});`), pi = (e, t) => {
2547
2543
  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) => {
2544
+ }, mi = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, hi = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, gi = (e) => `DROP INDEX IF EXISTS ${J(e.index)} ON ${J(e.table)};`, _i = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, vi = (e) => {
2549
2545
  let t = (e) => e.replace(/'/g, "''");
2550
2546
  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) => {
2547
+ }, yi = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, bi = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, xi = (e) => {
2552
2548
  let t = (e) => e.replace(/'/g, "''");
2553
2549
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2554
- }, bi = (e) => {
2550
+ }, Si = (e) => {
2555
2551
  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
2552
  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) => {
2553
+ }, Ci = (e, t, n) => {
2558
2554
  let r = n.find((t) => t.tableName === e);
2559
2555
  if (!r) return [];
2560
2556
  let i = [];
@@ -2563,13 +2559,13 @@ BEGIN
2563
2559
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${J(e)} ALTER COLUMN ${J(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2564
2560
  }
2565
2561
  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) => {
2562
+ }, wi = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, Ti = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${li(t, e.table, e.column)});`, Ei = (e) => {
2567
2563
  let t = e.fields.map((e) => W(e)).join(", ");
2568
2564
  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(", ");
2565
+ }, Di = (e, t) => {
2566
+ let n = e.fields.map((n) => li(t, e.table, n)).join(", ");
2571
2567
  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) => {
2568
+ }, Oi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, ki = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, Ai = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, ji = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Mi = (e, t) => {
2573
2569
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2574
2570
  if (e.orphanPolicy) {
2575
2571
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2587,34 +2583,34 @@ BEGIN
2587
2583
  setNull: "SET NULL",
2588
2584
  noAction: "NO ACTION"
2589
2585
  }[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) => {
2586
+ }, Ni = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Pi = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, Fi = (e, t) => {
2591
2587
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2592
2588
  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* () {
2589
+ }, Ii = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Li = (e, t) => w.gen(function* () {
2594
2590
  let n = yield* e`
2595
2591
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2596
2592
  FROM information_schema.check_constraints cc
2597
- WHERE cc.constraint_schema = DATABASE() AND cc.table_name = ${t.table}`.pipe(C.orElse(() => e`
2593
+ WHERE cc.constraint_schema = DATABASE() AND cc.table_name = ${t.table}`.pipe(w.orElse(() => e`
2598
2594
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2599
2595
  FROM information_schema.check_constraints cc
2600
2596
  JOIN information_schema.table_constraints tc
2601
2597
  ON tc.constraint_schema = cc.constraint_schema
2602
2598
  AND tc.constraint_name = cc.constraint_name
2603
- WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), C.orElseSucceed(() => []));
2599
+ WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), w.orElseSucceed(() => []));
2604
2600
  for (let e of n) {
2605
2601
  let n = String(e.n ?? "");
2606
- if (n !== "" && Bn(String(e.c ?? ""))?.column === t.column) return n;
2602
+ if (n !== "" && Un(String(e.c ?? ""))?.column === t.column) return n;
2607
2603
  }
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);
2604
+ }), Ri = (e, t, n) => w.gen(function* () {
2605
+ let r = yield* Li(e, t);
2606
+ r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [yr]));
2607
+ let i = yield* Li(e, t);
2612
2608
  if (i === void 0) return;
2613
2609
  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);
2610
+ if (!a) return yield* w.die(/* @__PURE__ */ Error(`applier: cannot drop the CHECK on '${t.table}.${t.column}' — it is column-level (catalog name '${i}'), which this family removes only by redefining the column, and the declared column is not available to redefine it from.`));
2611
+ yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Fr(a, t.column)};`, t.kind);
2612
+ }), zi = (e, t, n, r) => {
2613
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? J : W, s = a ? Tr(i) : r === "mssql" ? ni(i) : r === "sqlite" ? Xr(i) : Cr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Ir(e, i) : r === "mssql" ? Zr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Zr(e, "CURRENT_TIMESTAMP") : Rr(e, i), u = zr(i, r);
2618
2614
  if (u) {
2619
2615
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2620
2616
  return {
@@ -2642,7 +2638,7 @@ BEGIN
2642
2638
  post: f ? [f] : []
2643
2639
  };
2644
2640
  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) => {
2641
+ }, Bi = (e) => {
2646
2642
  let t = new Map(e.map((e) => [e.tableName, e]));
2647
2643
  return (e, n) => {
2648
2644
  let r = t.get(e);
@@ -2662,47 +2658,47 @@ BEGIN
2662
2658
  ...o
2663
2659
  };
2664
2660
  };
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();
2661
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(w.catchIf((e) => hr(e, r), () => w.void), w.tapError((e) => w.sync(() => {
2662
+ process.stderr.write(ce(`applier: statement failed (op=${n})`, t, e, 400));
2663
+ })), w.mapError((e) => {
2664
+ let r = ce(`applier: statement failed (op=${n})`, t, e, 400).trim();
2669
2665
  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."));
2666
+ }), w.map(() => void 0)), Z = (e, t, n) => w.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : o(r, t)} FROM ${o(n, t)} WHERE 1=0`).pipe(w.as(!0), w.catchAll(() => w.succeed(!1))), Vi = (e, t) => w.gen(function* () {
2667
+ let n = F([Ve], t).tables[0];
2668
+ if (!n) return yield* w.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2673
2669
  let r = {
2674
2670
  kind: "create-table",
2675
- table: k,
2671
+ table: O,
2676
2672
  columns: n.columns,
2677
2673
  indexes: []
2678
2674
  }, 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))
2675
+ mysql: () => H(e).pipe(w.map((e) => qr(r, e))),
2676
+ mssql: () => w.succeed(ii(r)),
2677
+ sqlite: () => w.succeed($r(r)),
2678
+ orElse: () => w.succeed(Hr(r))
2683
2679
  });
2684
- yield* C.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2685
- }), Bi = (e) => e`
2680
+ yield* w.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2681
+ }), Hi = (e) => e`
2686
2682
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2687
2683
  ${e("status")}, ${e("payload")}
2688
- FROM ${e(k)}
2689
- `, Vi = (e, t, n, r) => C.gen(function* () {
2684
+ FROM ${e(O)}
2685
+ `, Ui = (e, t, n, r) => w.gen(function* () {
2690
2686
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2691
- yield* C.forEach(r, ({ index: r, planned: a }) => e`
2692
- INSERT INTO ${e(k)}
2687
+ yield* w.forEach(r, ({ index: r, planned: a }) => e`
2688
+ INSERT INTO ${e(O)}
2693
2689
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2694
2690
  ${e("opKind")}, ${e("opTarget")}, ${e("status")}, ${e("payload")},
2695
2691
  ${e("createdAt")})
2696
2692
  VALUES
2697
2693
  (${`mop_${t}_${r}`}, ${t}, ${n}, ${r},
2698
- ${a.op.kind}, ${Be(a.op)}, ${"pending"},
2694
+ ${a.op.kind}, ${Ue(a.op)}, ${"pending"},
2699
2695
  ${JSON.stringify(a)}, ${i})
2700
2696
  `, { discard: !0 });
2701
- }), Hi = (e, t, n, r, i) => C.gen(function* () {
2697
+ }), Wi = (e, t, n, r, i) => w.gen(function* () {
2702
2698
  let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2703
2699
  if (r === "applied") {
2704
2700
  yield* e`
2705
- UPDATE ${e(k)}
2701
+ UPDATE ${e(O)}
2706
2702
  SET ${e("status")} = ${r}, ${e("appliedAt")} = ${a},
2707
2703
  ${e("durationMs")} = ${i ?? null}
2708
2704
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
@@ -2710,50 +2706,50 @@ BEGIN
2710
2706
  return;
2711
2707
  }
2712
2708
  yield* e`
2713
- UPDATE ${e(k)}
2709
+ UPDATE ${e(O)}
2714
2710
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2715
2711
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2716
2712
  `;
2717
- }), Ui = (e, t, n, r) => C.gen(function* () {
2713
+ }), Gi = (e, t, n, r) => w.gen(function* () {
2718
2714
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2719
2715
  r.length > 0 && (yield* e`
2720
- UPDATE ${e(k)}
2716
+ UPDATE ${e(O)}
2721
2717
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
2722
2718
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(r)}
2723
2719
  `), n.length > 0 && (yield* e`
2724
- UPDATE ${e(k)}
2720
+ UPDATE ${e(O)}
2725
2721
  SET ${e("status")} = ${"pending"}
2726
2722
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2727
2723
  `);
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";
2724
+ }), Ki = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(w.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(w.asVoid), qi = (e, t, n) => w.gen(function* () {
2725
+ if (Ze(n.op, n.classification, t) !== "artefact-repair") return "clean";
2730
2726
  let r = n.op, i = (e) => o(e, t);
2731
2727
  if (t === "sqlite" || t === "turso") {
2732
2728
  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";
2729
+ let n = `${r.table}${Ke}`;
2730
+ 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
2731
  }
2736
2732
  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;
2733
+ let a = `${r.column}${qe}`, s = `${r.column}${Je}`, c = yield* $(e, t, r.table, r.column), l = yield* $(e, t, r.table, a), u = yield* $(e, t, r.table, s), d = (e) => w.logWarning(`migration resume: ${e}`).pipe(w.annotateLogs({ scope: "voltro:migrate" }));
2734
+ return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(a)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${r.table}.${a}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* X(e, `ALTER TABLE ${i(r.table)} RENAME COLUMN ${i(a)} TO ${i(r.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${r.table}.${s}'`), "applied") : yield* w.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${a}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2735
+ }), Ji = (e, t, n, r = "fresh") => w.gen(function* () {
2736
+ let i = process.hrtime.bigint(), a = Bi(n.declared), o = t.op;
2741
2737
  switch (o.kind) {
2742
2738
  case "create-table": {
2743
2739
  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))
2740
+ mysql: () => H(e).pipe(w.map((e) => qr(o, e))),
2741
+ mssql: () => w.succeed(ii(o)),
2742
+ sqlite: () => w.succeed($r(o)),
2743
+ orElse: () => w.succeed(Hr(o))
2748
2744
  }), n = yield* e.onDialectOrElse({
2749
- mysql: () => C.succeed([mr]),
2750
- orElse: () => C.succeed([])
2745
+ mysql: () => w.succeed([gr]),
2746
+ orElse: () => w.succeed([])
2751
2747
  });
2752
2748
  for (let r of t) yield* X(e, r, o.kind, n);
2753
2749
  break;
2754
2750
  }
2755
2751
  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);
2752
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? si(o, n, e) : oi(o, e);
2757
2753
  yield* e.onDialectOrElse({
2758
2754
  mysql: () => X(e, r(G), o.kind),
2759
2755
  orElse: () => X(e, r(W), o.kind)
@@ -2763,93 +2759,93 @@ BEGIN
2763
2759
  case "drop-column": {
2764
2760
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2765
2761
  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)
2762
+ mysql: () => H(e).pipe(w.flatMap((r) => X(e, t ? Ar(o, n, G) : Or(o, r), o.kind, t ? [] : [_r]))),
2763
+ sqlite: () => X(e, t ? Ar(o, n, W) : Dr(o, W, !1), o.kind, t ? [] : [vr]),
2764
+ orElse: () => X(e, t ? Ar(o, n, W) : Dr(o, W), o.kind)
2769
2765
  });
2770
2766
  break;
2771
2767
  }
2772
2768
  case "rename-column":
2773
2769
  yield* e.onDialectOrElse({
2774
- mysql: () => X(e, Dr(o, G), o.kind),
2770
+ mysql: () => X(e, kr(o, G), o.kind),
2775
2771
  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)
2772
+ orElse: () => X(e, kr(o, W), o.kind)
2777
2773
  });
2778
2774
  break;
2779
2775
  case "add-index":
2780
2776
  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)
2777
+ sqlite: () => X(e, di(o, !1), o.kind),
2778
+ mysql: () => H(e).pipe(w.flatMap((t) => X(e, fi(o, n.declared, t), o.kind, [gr]))),
2779
+ mssql: () => Z(e, [...Ci(o.table, o.index.columns, n.declared), Si(o)], o.kind),
2780
+ orElse: () => X(e, di(o, t.classification === "online-required"), o.kind)
2785
2781
  });
2786
2782
  break;
2787
2783
  case "drop-index":
2788
2784
  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)
2785
+ mysql: () => X(e, hi(o), o.kind),
2786
+ mssql: () => X(e, gi(o), o.kind),
2787
+ orElse: () => X(e, mi(o), o.kind)
2792
2788
  });
2793
2789
  break;
2794
2790
  case "rename-table":
2795
2791
  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)
2792
+ mysql: () => X(e, _i(o, G), o.kind),
2793
+ mssql: () => X(e, vi(o), o.kind),
2794
+ orElse: () => X(e, _i(o, W), o.kind)
2799
2795
  });
2800
2796
  break;
2801
2797
  case "rename-index":
2802
2798
  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)
2799
+ mysql: () => X(e, bi(o), o.kind),
2800
+ mssql: () => X(e, xi(o), o.kind),
2801
+ orElse: () => X(e, yi(o), o.kind)
2806
2802
  });
2807
2803
  break;
2808
2804
  case "add-unique":
2809
2805
  yield* e.onDialectOrElse({
2810
- mysql: () => X(e, Ci(o, n.declared), o.kind),
2806
+ mysql: () => X(e, Ti(o, n.declared), o.kind),
2811
2807
  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)
2808
+ mssql: () => Z(e, [...Ci(o.table, [o.column], n.declared), wi(o)], o.kind),
2809
+ orElse: () => X(e, wi(o), o.kind)
2814
2810
  });
2815
2811
  break;
2816
2812
  case "drop-unique":
2817
2813
  yield* e.onDialectOrElse({
2818
- mysql: () => X(e, ki(o), o.kind),
2814
+ mysql: () => X(e, ji(o), o.kind),
2819
2815
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2820
- orElse: () => X(e, Oi(o), o.kind)
2816
+ orElse: () => X(e, Ai(o), o.kind)
2821
2817
  });
2822
2818
  break;
2823
2819
  case "add-unique-composite":
2824
2820
  yield* e.onDialectOrElse({
2825
- mysql: () => X(e, Ti(o, n.declared), o.kind),
2821
+ mysql: () => X(e, Di(o, n.declared), o.kind),
2826
2822
  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)
2823
+ mssql: () => Z(e, [...Ci(o.table, o.fields, n.declared), Ei(o)], o.kind),
2824
+ orElse: () => X(e, Ei(o), o.kind)
2829
2825
  });
2830
2826
  break;
2831
2827
  case "drop-unique-composite":
2832
2828
  yield* e.onDialectOrElse({
2833
- mysql: () => X(e, Di(o), o.kind),
2829
+ mysql: () => X(e, ki(o), o.kind),
2834
2830
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2835
- orElse: () => X(e, Ei(o), o.kind)
2831
+ orElse: () => X(e, Oi(o), o.kind)
2836
2832
  });
2837
2833
  break;
2838
2834
  case "add-foreign-key":
2839
2835
  yield* e.onDialectOrElse({
2840
- mysql: () => Z(e, Ai(o, G), o.kind),
2836
+ mysql: () => Z(e, Mi(o, G), o.kind),
2841
2837
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2842
- orElse: () => Z(e, Ai(o, W), o.kind)
2838
+ orElse: () => Z(e, Mi(o, W), o.kind)
2843
2839
  });
2844
2840
  break;
2845
2841
  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")
2842
+ let n = zi(o, t, a, yield* e.onDialectOrElse({
2843
+ mysql: () => w.succeed("mariadb"),
2844
+ mssql: () => w.succeed("mssql"),
2845
+ sqlite: () => w.succeed("sqlite"),
2846
+ orElse: () => w.succeed("postgres")
2851
2847
  }));
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);
2848
+ if (!(r === "resume" && (yield* $(e, Re(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2853
2849
  if (n.backfillKind === "sql" && n.backfillSql) {
2854
2850
  if (t.classification !== "online-required" && n.batchSize === void 0) yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql}`;
2855
2851
  else {
@@ -2858,10 +2854,10 @@ BEGIN
2858
2854
  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
2855
  if (s.length === 0) break;
2860
2856
  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({
2857
+ 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
2858
  scope: "voltro:migrate",
2863
2859
  mode: "sql-batched"
2864
- })), i = s[s.length - 1].id, r > 0 && (yield* C.sleep(`${r} millis`));
2860
+ })), i = s[s.length - 1].id, r > 0 && (yield* w.sleep(`${r} millis`));
2865
2861
  }
2866
2862
  }
2867
2863
  } else if (n.backfillKind === "js" && n.backfillJs) {
@@ -2870,17 +2866,17 @@ BEGIN
2870
2866
  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
2867
  if (s.length === 0) break;
2872
2868
  for (let t of s) {
2873
- let r = yield* C.tryPromise({
2869
+ let r = yield* w.tryPromise({
2874
2870
  try: () => Promise.resolve(n.backfillJs({ id: t.id })),
2875
2871
  catch: (e) => e
2876
- }).pipe(C.orDie);
2872
+ }).pipe(w.orDie);
2877
2873
  yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${r} WHERE ${e("id")} = ${t.id}`;
2878
2874
  }
2879
- a += s.length, yield* C.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(C.annotateLogs({
2875
+ a += s.length, yield* w.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(w.annotateLogs({
2880
2876
  scope: "voltro:migrate",
2881
2877
  table: o.table,
2882
2878
  column: o.column.name
2883
- })), i = s[s.length - 1].id, r > 0 && (yield* C.sleep(`${r} millis`));
2879
+ })), i = s[s.length - 1].id, r > 0 && (yield* w.sleep(`${r} millis`));
2884
2880
  }
2885
2881
  }
2886
2882
  for (let t of n.post) yield* X(e, t, o.kind);
@@ -2890,43 +2886,43 @@ BEGIN
2890
2886
  yield* e.onDialectOrElse({
2891
2887
  mysql: () => {
2892
2888
  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.`));
2889
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(t, o.column, o.toNullable)};`, o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2894
2890
  },
2895
2891
  mssql: () => {
2896
2892
  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}'.`));
2893
+ return t ? X(e, ei(t, o.column, o.table, o.toNullable), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2898
2894
  },
2899
2895
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2900
2896
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2901
2897
  });
2902
2898
  break;
2903
2899
  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;
2900
+ let t = Pr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Mr(r, e) ? r : void 0;
2905
2901
  yield* e.onDialectOrElse({
2906
2902
  mysql: () => {
2907
2903
  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);
2904
+ return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(n, o.column)};` : jr(o, G, (e) => Ir(e, t)), o.kind);
2909
2905
  },
2910
2906
  mssql: () => {
2911
2907
  let t = i("mssql");
2912
- return X(e, $r(o, t ? Qr(t, o.column, o.table) : void 0), o.kind);
2908
+ return X(e, ti(o, t ? ei(t, o.column, o.table) : void 0), o.kind);
2913
2909
  },
2914
2910
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2915
- orElse: () => X(e, kr(o, W, (e) => Ir(e, t)), o.kind)
2911
+ orElse: () => X(e, jr(o, W, (e) => Rr(e, t)), o.kind)
2916
2912
  });
2917
2913
  break;
2918
2914
  }
2919
2915
  case "alter-column-type": {
2920
- let r = xr(Mr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2916
+ let r = Cr(Pr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2921
2917
  if (t.classification !== "online-required") {
2922
2918
  yield* e.onDialectOrElse({
2923
2919
  mysql: () => {
2924
2920
  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.`));
2921
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Fr(t, o.column)};`, o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2926
2922
  },
2927
2923
  mssql: () => {
2928
2924
  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}'.`));
2925
+ return t ? X(e, ei(t, o.column, o.table), o.kind) : w.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2930
2926
  },
2931
2927
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2932
2928
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
@@ -2934,8 +2930,8 @@ BEGIN
2934
2930
  break;
2935
2931
  }
2936
2932
  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
2933
+ 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.`)),
2934
+ orElse: () => w.void
2939
2935
  });
2940
2936
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2941
2937
  yield* e.unsafe(`ALTER TABLE ${W(o.table)} ADD COLUMN ${W(a)} ${r}`);
@@ -2945,27 +2941,27 @@ BEGIN
2945
2941
  if (t.length === 0) break;
2946
2942
  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
2943
  }
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)}`);
2944
+ 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
2945
  break;
2950
2946
  }
2951
2947
  case "drop-foreign-key":
2952
2948
  yield* e.onDialectOrElse({
2953
- mysql: () => X(e, Mi(o), o.kind),
2949
+ mysql: () => X(e, Pi(o), o.kind),
2954
2950
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2955
- orElse: () => X(e, ji(o), o.kind)
2951
+ orElse: () => X(e, Ni(o), o.kind)
2956
2952
  });
2957
2953
  break;
2958
2954
  case "add-check":
2959
2955
  yield* e.onDialectOrElse({
2960
- mysql: () => X(e, Ni(o, G), o.kind),
2956
+ mysql: () => X(e, Fi(o, G), o.kind),
2961
2957
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2962
- orElse: () => X(e, Ni(o, W), o.kind)
2958
+ orElse: () => X(e, Fi(o, W), o.kind)
2963
2959
  });
2964
2960
  break;
2965
2961
  case "drop-check": yield* e.onDialectOrElse({
2966
- mysql: () => Ii(e, o, n.declared),
2962
+ mysql: () => Ri(e, o, n.declared),
2967
2963
  sqlite: () => Z(e, q(o.table, n.declared), o.kind),
2968
- orElse: () => X(e, Pi(o), o.kind)
2964
+ orElse: () => X(e, Ii(o), o.kind)
2969
2965
  });
2970
2966
  }
2971
2967
  return {
@@ -2973,32 +2969,32 @@ BEGIN
2973
2969
  status: "applied",
2974
2970
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2975
2971
  };
2976
- }), qi = (e, t, n, r) => C.gen(function* () {
2972
+ }), Yi = (e, t, n, r) => w.gen(function* () {
2977
2973
  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.`));
2974
+ if (i.length > 1) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2979
2975
  let a = i[0], o = [...r].map((e) => ({
2980
2976
  index: Number(e.opIndex),
2981
2977
  status: e.status,
2982
2978
  planned: JSON.parse(e.payload)
2983
2979
  })).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 {
2980
+ if (c > 1) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${O}\` by hand before re-running.`));
2981
+ if (yield* w.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${Ue(s.planned.op)}` : ""}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2986
2982
  kind: "discard",
2987
2983
  runId: a,
2988
2984
  why: "no operation had started — no DDL ran"
2989
2985
  };
2990
- let l = s ? yield* Gi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2986
+ let l = s ? yield* qi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2991
2987
  if (u !== n.toFingerprint) return {
2992
2988
  kind: "discard",
2993
2989
  runId: a,
2994
2990
  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
2991
  };
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));
2992
+ let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : Ge(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2997
2993
  return f.length === 0 ? {
2998
2994
  kind: "discard",
2999
2995
  runId: a,
3000
2996
  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" })), {
2997
+ } : (yield* Gi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* w.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), {
3002
2998
  kind: "resume",
3003
2999
  runId: a,
3004
3000
  ops: f.map((e) => ({
@@ -3006,7 +3002,7 @@ BEGIN
3006
3002
  planned: e.planned
3007
3003
  }))
3008
3004
  });
3009
- }), Ji = (e, t, n) => C.gen(function* () {
3005
+ }), Xi = (e, t, n) => w.gen(function* () {
3010
3006
  for (let r of t.operations) {
3011
3007
  let i = r.op;
3012
3008
  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 +3011,9 @@ BEGIN
3015
3011
  "rename-column"
3016
3012
  ].includes(e.op.kind))) continue;
3017
3013
  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.`));
3014
+ 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
3015
  }
3020
- }), Yi = (e) => {
3016
+ }), Zi = (e) => {
3021
3017
  let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
3022
3018
  return [
3023
3019
  t.kind,
@@ -3026,80 +3022,75 @@ BEGIN
3026
3022
  n("name"),
3027
3023
  n("to")
3028
3024
  ].join("\0");
3029
- }, Xi = (e, t, n) => C.gen(function* () {
3025
+ }, Qi = (e, t, n) => w.acquireUseRelease(Ie(e, { schema: n.lockSchema }), () => $i(e, t, n), (e) => e.release.pipe(w.orDie)), $i = (e, t, n) => w.gen(function* () {
3030
3026
  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 = {
3027
+ if (r.length > 0) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
3028
+ let i = Date.now(), a = [], o = Re(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => Zi(e))), l = {
3034
3029
  ...s,
3035
3030
  operations: s.operations.map((e) => {
3036
- if (!e.blocked || !c.has(Yi(e))) return e;
3031
+ if (!e.blocked || !c.has(Zi(e))) return e;
3037
3032
  let { blocked: t, ...n } = e;
3038
3033
  return n;
3039
3034
  })
3040
3035
  };
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" })));
3036
+ (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
3037
  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) => ({
3038
+ if (u.length > 0) return yield* w.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — re-planning under the migration lock found ${u.length} blocked operation(s). Run \`voltro db plan\` to see the fixes.`));
3039
+ let d = Be(o) === "plan-transactional", f = d ? l.operations.filter((e) => e.classification !== "online-required") : [], p = d ? l.operations.filter((e) => e.classification === "online-required") : l.operations, m = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, h = p.map((e, t) => ({
3045
3040
  index: t,
3046
3041
  planned: e
3047
3042
  })), _ = "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)];
3043
+ yield* Xi(e, l, o), yield* Vi(e, o);
3044
+ let v = yield* Hi(e);
3045
+ if (v.length > 0) {
3046
+ let t = yield* Yi(e, o, l, v);
3047
+ t.kind === "resume" ? (m = t.runId, h = t.ops, _ = "resume") : (yield* w.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(w.annotateLogs({ scope: "voltro:migrate" })), yield* Ki(e, t.runId));
3048
+ }
3049
+ _ === "fresh" && h.length > 0 && (yield* Ui(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(w.gen(function* () {
3050
+ let e = yield* T.SqlClient;
3051
+ for (let t of f) a.push(yield* Ji(e, t, n));
3052
+ })));
3053
+ for (let { index: t, planned: r } of h) {
3054
+ yield* Wi(e, m, t, "started");
3055
+ let i = a.length, o = yield* Ji(e, r, n, _).pipe(w.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${h.length + f.length} operation(s) applied before this one${f.length > 0 ? ` (${f.length} of them in a transaction)` : ""}.\n` + (d ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
3056
+ a.push(o), yield* Wi(e, m, t, "applied", o.durationMs);
3057
+ }
3058
+ let y = yield* n.replan(e);
3059
+ if (y.operations.length > 0) {
3060
+ let e = y.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
3061
+ return yield* w.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${l.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${y.operations.length}:\n${e}${y.operations.length > 10 ? `\n … and ${y.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
3062
+ }
3063
+ let b = a.filter((e) => e.status === "applied").length, x = Date.now() - i, S = m, C = (/* @__PURE__ */ new Date()).toISOString(), ee = yield* U(e, C), te = [...f, ...h.map((e) => e.planned)];
3073
3064
  yield* e`
3074
3065
  INSERT INTO ${e("_voltro_migration_plans")}
3075
3066
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
3076
3067
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
3077
3068
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
3078
3069
  VALUES
3079
- (${x}, ${l.toFingerprint}, ${v.fromFingerprint}, ${JSON.stringify(w)},
3070
+ (${S}, ${l.toFingerprint}, ${y.fromFingerprint}, ${JSON.stringify(te)},
3080
3071
  ${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,
3072
+ ${x}, ${ee}, ${n.notes ?? null})
3073
+ `, yield* Ki(e, m);
3074
+ let ne = [...new Set(te.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
3075
+ return yield* w.promise(() => g({ changedTables: ne }).catch(() => {})), {
3076
+ id: S,
3077
+ appliedAt: C,
3087
3078
  fingerprint: l.toFingerprint,
3088
- operations: w,
3079
+ operations: te,
3089
3080
  appliedBy: n.appliedBy,
3090
3081
  environment: n.environment,
3091
- durationMs: b,
3092
- appliedOps: y,
3082
+ durationMs: x,
3083
+ appliedOps: b,
3093
3084
  source: n.source,
3094
3085
  ...n.notes ? { notes: n.notes } : {}
3095
3086
  };
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`
3087
+ }), ea = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), ta = (e) => e`
3097
3088
  SELECT fingerprint
3098
3089
  FROM _voltro_migration_plans
3099
3090
  ORDER BY ${e("appliedAt")} DESC
3100
3091
  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";
3092
+ `.pipe(w.map((e) => e.length > 0 ? e[0].fingerprint : void 0), w.catchAll(() => w.succeed(void 0))), na = (e, t, n) => w.gen(function* () {
3093
+ if ((yield* ta(e)) === t.toFingerprint) return "already-current";
3103
3094
  let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3104
3095
  return yield* e`
3105
3096
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3111,8 +3102,8 @@ BEGIN
3111
3102
  ${n.appliedBy}, ${n.environment}, ${n.source},
3112
3103
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
3113
3104
  `, "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);
3105
+ }).pipe(w.catchAll(() => w.succeed("already-current"))), ra = (e, t) => w.gen(function* () {
3106
+ let n = $t(F(t, Re(e))), r = yield* ta(e);
3116
3107
  return r === n ? {
3117
3108
  kind: "up-to-date",
3118
3109
  fingerprint: n
@@ -3121,23 +3112,23 @@ BEGIN
3121
3112
  expected: n,
3122
3113
  ...r === void 0 ? {} : { actual: r }
3123
3114
  };
3124
- }), ta = [
3115
+ }), ia = [
3125
3116
  "pgeagertest_",
3126
3117
  "mig_e2e_",
3127
3118
  "mig_test_",
3128
3119
  "mysqleagertest_",
3129
3120
  "mssqleagertest_",
3130
3121
  "sqliteeagertest_"
3131
- ], na = (e) => ta.some((t) => e.startsWith(t)), ra = (e, t) => C.gen(function* () {
3122
+ ], aa = (e) => ia.some((t) => e.startsWith(t)), oa = (e, t) => w.gen(function* () {
3132
3123
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
3133
- let n = t.filter((e) => na(e.name)).map((e) => e.name);
3124
+ let n = t.filter((e) => aa(e.name)).map((e) => e.name);
3134
3125
  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));
3126
+ for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(w.catchAll(() => w.void));
3136
3127
  return n;
3137
- }), ia = () => {
3128
+ }), sa = () => {
3138
3129
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
3139
3130
  return e.length > 0 ? { ignoreTables: e } : {};
3140
- }, aa = (e) => {
3131
+ }, ca = (e) => {
3141
3132
  if (e === void 0) return;
3142
3133
  let t = e.trim();
3143
3134
  if (t === "") return;
@@ -3147,55 +3138,55 @@ BEGIN
3147
3138
  kind: "tables",
3148
3139
  tables: new Set(n)
3149
3140
  } : void 0;
3150
- }, oa = (e) => typeof e.table == "string" ? e.table : void 0, sa = (e, t = { kind: "all" }) => ({
3141
+ }, la = (e) => typeof e.table == "string" ? e.table : void 0, ua = (e, t = { kind: "all" }) => ({
3151
3142
  ...e,
3152
3143
  operations: e.operations.map((e) => {
3153
3144
  if (!e.blocked || e.classification !== "lossy") return e;
3154
3145
  if (t?.kind === "tables") {
3155
- let n = oa(e.op);
3146
+ let n = la(e.op);
3156
3147
  if (n === void 0 || !t.tables.has(n)) return e;
3157
3148
  }
3158
3149
  let { blocked: n, ...r } = e;
3159
3150
  return r;
3160
3151
  })
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;
3152
+ }), da = (e, t, n) => t === "postgres" ? on(e, n).pipe(w.flatMap((e) => {
3153
+ let t = sn(e);
3154
+ return t === void 0 ? w.void : w.logWarning(`auto-migrate: ${t}`).pipe(w.annotateLogs({ scope: "voltro:migrate" }));
3155
+ }), w.catchAll(() => w.void)) : w.void, fa = (e, t, n) => w.gen(function* () {
3156
+ let r = Re(e), a = t;
3166
3157
  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), {
3158
+ let t = $t(F(a, r));
3159
+ if ((yield* ta(e)) === t) return yield* da(e, r, a), {
3169
3160
  kind: "up-to-date",
3170
3161
  fingerprint: t
3171
3162
  };
3172
3163
  }
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({
3164
+ let o = yield* lr(e), s = yield* oa(e, o.tables);
3165
+ s.length > 0 && (yield* w.logInfo(`auto-migrate: reaped ${s.length} test-fixture leftover(s)`).pipe(w.annotateLogs({
3175
3166
  scope: "voltro:migrate",
3176
3167
  count: s.length
3177
- })), o = yield* or(e));
3168
+ })), o = yield* lr(e));
3178
3169
  {
3179
3170
  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({
3171
+ t.length > 0 && (yield* w.logWarning(`auto-migrate: ${i(t, e)}`).pipe(w.annotateLogs({
3181
3172
  scope: "voltro:migrate",
3182
3173
  snapshots: t.map((e) => e.name)
3183
3174
  })));
3184
3175
  }
3185
- let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !_(e.name) || c.has(e.name)), u = zn({
3176
+ let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !_(e.name) || c.has(e.name)), u = Hn({
3186
3177
  declared: a,
3187
3178
  live: { tables: l(o.tables) },
3188
3179
  dialect: r,
3189
- ...ia()
3180
+ ...sa()
3190
3181
  });
3191
3182
  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 {
3183
+ let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = ca(process.env.VOLTRO_DESTRUCTIVE_OK);
3184
+ if (t === void 0 || !e || (u = ua(u, t), u.operations.some((e) => e.blocked))) return {
3194
3185
  kind: "refused-blocked",
3195
3186
  plan: u
3196
3187
  };
3197
3188
  }
3198
- return u.operations.length === 0 ? (yield* $i(e, u, {
3189
+ return u.operations.length === 0 ? (yield* na(e, u, {
3199
3190
  appliedBy: n.appliedBy,
3200
3191
  environment: n.environment === "prod" ? "dev" : n.environment,
3201
3192
  source: "auto-diff"
@@ -3204,37 +3195,37 @@ BEGIN
3204
3195
  fingerprint: u.toFingerprint
3205
3196
  }) : {
3206
3197
  kind: "applied",
3207
- applied: yield* Xi(e, u, {
3198
+ applied: yield* Qi(e, u, {
3208
3199
  declared: t,
3209
3200
  appliedBy: n.appliedBy,
3210
3201
  environment: n.environment === "prod" ? "dev" : n.environment,
3211
3202
  source: "auto-diff",
3212
- replan: (e) => C.gen(function* () {
3213
- let t = yield* or(e);
3214
- return zn({
3203
+ replan: (e) => w.gen(function* () {
3204
+ let t = yield* lr(e);
3205
+ return Hn({
3215
3206
  declared: a,
3216
3207
  live: { tables: l(t.tables) },
3217
3208
  dialect: r,
3218
- ...ia()
3209
+ ...sa()
3219
3210
  });
3220
3211
  })
3221
3212
  }),
3222
3213
  plan: u
3223
3214
  };
3224
- }), ua = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? C.succeed({
3215
+ }), pa = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? w.succeed({
3225
3216
  kind: "skipped",
3226
3217
  reason: "VOLTRO_AUTO_MIGRATE=0"
3227
- }) : n.environment === "prod" ? ea(e, t) : la(e, t, n), da = (e, t) => {
3218
+ }) : n.environment === "prod" ? ra(e, t) : fa(e, t, n), ma = (e, t) => {
3228
3219
  switch (e.kind) {
3229
3220
  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)})`;
3221
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${en(e.fingerprint)})`;
3231
3222
  case "applied": {
3232
3223
  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)}`;
3224
+ return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${en(e.applied.fingerprint)}`;
3234
3225
  }
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.";
3226
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${en(e.expected)}` + (e.actual ? ` live=${en(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3236
3227
  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 = [""];
3228
+ let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + ea(e.plan), c = [""];
3238
3229
  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
3230
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3240
3231
  for (let r of e.plan.operations) {
@@ -3251,7 +3242,7 @@ BEGIN
3251
3242
  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
3243
  }
3253
3244
  }
3254
- }, fa = ne({ scope: "voltro:migrate" }), pa = /* @__PURE__ */ new Set([
3245
+ }, ha = ie({ scope: "voltro:migrate" }), ga = /* @__PURE__ */ new Set([
3255
3246
  "node_modules",
3256
3247
  "dist",
3257
3248
  "build",
@@ -3260,12 +3251,12 @@ BEGIN
3260
3251
  ".next",
3261
3252
  ".git",
3262
3253
  ".framework"
3263
- ]), ma = async (e) => {
3254
+ ]), _a = async (e) => {
3264
3255
  let t = [], n = async (e) => {
3265
- let r = await re.readdir(e, { withFileTypes: !0 }).catch(() => []);
3256
+ let r = await ae.readdir(e, { withFileTypes: !0 }).catch(() => []);
3266
3257
  for (let i of r) {
3267
- if (pa.has(i.name)) continue;
3268
- let r = ie(e, i.name);
3258
+ if (ga.has(i.name)) continue;
3259
+ let r = oe(e, i.name);
3269
3260
  i.isDirectory() ? await n(r) : i.isFile() && S.test(i.name) && t.push(r);
3270
3261
  }
3271
3262
  };
@@ -3273,12 +3264,12 @@ BEGIN
3273
3264
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3274
3265
  return n.localeCompare(r);
3275
3266
  });
3276
- }, ha = async (e) => {
3267
+ }, va = async (e) => {
3277
3268
  let t = [];
3278
3269
  for (let n of e) {
3279
- let e = (await import(ae(n).href)).default;
3270
+ let e = (await import(se(n).href)).default;
3280
3271
  if (!u(e)) {
3281
- fa.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3272
+ ha.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3282
3273
  continue;
3283
3274
  }
3284
3275
  t.push({
@@ -3287,11 +3278,11 @@ BEGIN
3287
3278
  });
3288
3279
  }
3289
3280
  return t;
3290
- }, ga = (e) => e`
3281
+ }, ya = (e) => e`
3291
3282
  SELECT ${e("id")}
3292
3283
  FROM ${e("_voltro_migration_plans")}
3293
3284
  WHERE ${e("source")} = 'file'
3294
- `.pipe(C.map((e) => e.map((e) => e.id)), C.catchAll(() => C.succeed([]))), _a = class extends Error {
3285
+ `.pipe(w.map((e) => e.map((e) => e.id)), w.catchAll(() => w.succeed([]))), ba = class extends Error {
3295
3286
  migrationId;
3296
3287
  file;
3297
3288
  cause;
@@ -3299,27 +3290,27 @@ BEGIN
3299
3290
  constructor(e, t, n) {
3300
3291
  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
3292
  }
3302
- }, va = (e, t, n, r) => C.gen(function* () {
3293
+ }, xa = (e, t, n, r) => w.gen(function* () {
3303
3294
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3304
3295
  sql: e,
3305
3296
  log: {
3306
- info: (e, n) => C.logInfo(e).pipe(C.annotateLogs({
3297
+ info: (e, n) => w.logInfo(e).pipe(w.annotateLogs({
3307
3298
  scope: `migrations:file:${t.migration.id}`,
3308
3299
  ...n ?? {}
3309
3300
  })),
3310
- warn: (e, n) => C.logWarning(e).pipe(C.annotateLogs({
3301
+ warn: (e, n) => w.logWarning(e).pipe(w.annotateLogs({
3311
3302
  scope: `migrations:file:${t.migration.id}`,
3312
3303
  ...n ?? {}
3313
3304
  }))
3314
3305
  },
3315
3306
  appliedAt: a
3316
3307
  }, s = t.migration.up(o);
3317
- C.isEffect(s) ? yield* s : yield* C.tryPromise({
3308
+ w.isEffect(s) ? yield* s : yield* w.tryPromise({
3318
3309
  try: () => s,
3319
3310
  catch: (e) => e
3320
3311
  });
3321
3312
  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}` })));
3313
+ !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
3314
  let l = yield* U(e, a);
3324
3315
  return yield* e`
3325
3316
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3333,106 +3324,97 @@ BEGIN
3333
3324
  }])},
3334
3325
  ${r}, ${n}, ${"file"},
3335
3326
  ${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")),
3327
+ `.pipe(w.mapError((e) => new ba(t.migration.id, t.file, e))), { durationMs: c };
3328
+ }), Sa = (e, t) => w.gen(function* () {
3329
+ let n = yield* w.tryPromise({
3330
+ try: () => _a(oe(t, "migrations")),
3340
3331
  catch: (e) => e
3341
3332
  });
3342
3333
  if (n.length === 0) return {
3343
3334
  pending: [],
3344
3335
  skipped: []
3345
3336
  };
3346
- let r = yield* C.tryPromise({
3347
- try: () => ha(n),
3337
+ let r = yield* w.tryPromise({
3338
+ try: () => va(n),
3348
3339
  catch: (e) => e
3349
3340
  });
3350
3341
  if (r.length === 0) return {
3351
3342
  pending: [],
3352
3343
  skipped: []
3353
3344
  };
3354
- let i = new Set(yield* ga(e));
3345
+ let i = new Set(yield* ya(e));
3355
3346
  return {
3356
3347
  pending: r.filter((e) => !i.has(e.migration.id)),
3357
3348
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3358
3349
  };
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 {
3350
+ }), Ca = (e, t) => Sa(e, t).pipe(w.map((e) => e.pending.map((e) => e.migration.id))), wa = (e, t) => w.gen(function* () {
3351
+ let { pending: n, skipped: r } = yield* Sa(e, t.projectRoot);
3352
+ return n.length === 0 ? {
3362
3353
  applied: [],
3363
3354
  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,
3355
+ } : {
3356
+ applied: yield* w.acquireUseRelease(Ie(e, { schema: t.lockSchema }), () => w.gen(function* () {
3357
+ let r = [];
3358
+ for (let i of n) {
3359
+ yield* w.logInfo("file-based migration applying").pipe(w.annotateLogs({
3360
+ scope: "voltro:migrate",
3361
+ id: i.migration.id,
3362
+ file: i.file
3363
+ }));
3364
+ let { durationMs: n } = yield* xa(e, i, t.env, t.appliedBy);
3365
+ r.push({
3366
+ id: i.migration.id,
3367
+ durationMs: n
3368
+ }), yield* w.logInfo("file-based migration applied").pipe(w.annotateLogs({
3369
+ scope: "voltro:migrate",
3370
+ id: i.migration.id,
3371
+ durationMs: n
3372
+ }));
3373
+ }
3374
+ return r;
3375
+ }), (e) => e.release.pipe(w.orDie)),
3389
3376
  skipped: r
3390
3377
  };
3391
- }), Sa = (e, t) => e`
3378
+ }), Ta = (e, t) => e`
3392
3379
  SELECT ${e("id")}
3393
3380
  FROM ${e("_voltro_migration_plans")}
3394
3381
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3395
3382
  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")),
3383
+ `, Ea = (e, t) => w.gen(function* () {
3384
+ if (!(yield* Ta(e, t.id))[0]) return yield* w.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3385
+ let n = yield* w.tryPromise({
3386
+ try: () => _a(oe(t.projectRoot, "migrations")),
3400
3387
  catch: (e) => e
3401
- }), r = (yield* C.tryPromise({
3402
- try: () => ha(n),
3388
+ }), r = (yield* w.tryPromise({
3389
+ try: () => va(n),
3403
3390
  catch: (e) => e
3404
3391
  })).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 = {
3392
+ return r ? yield* w.acquireUseRelease(Ie(e, { schema: t.lockSchema }), () => w.gen(function* () {
3393
+ let n = Date.now(), i = {
3410
3394
  sql: e,
3411
3395
  log: {
3412
- info: (e, n) => C.logInfo(e).pipe(C.annotateLogs({
3396
+ info: (e, n) => w.logInfo(e).pipe(w.annotateLogs({
3413
3397
  scope: `migrations:file:${t.id}`,
3414
3398
  ...n ?? {}
3415
3399
  })),
3416
- warn: (e, n) => C.logWarning(e).pipe(C.annotateLogs({
3400
+ warn: (e, n) => w.logWarning(e).pipe(w.annotateLogs({
3417
3401
  scope: `migrations:file:${t.id}`,
3418
3402
  ...n ?? {}
3419
3403
  }))
3420
3404
  },
3421
3405
  appliedAt: (/* @__PURE__ */ new Date()).toISOString()
3422
- }, a = r.migration.down(n);
3423
- C.isEffect(a) ? yield* a : yield* C.tryPromise({
3406
+ }, a = r.migration.down(i);
3407
+ w.isEffect(a) ? yield* a : yield* w.tryPromise({
3424
3408
  try: () => a,
3425
3409
  catch: (e) => e
3426
3410
  });
3427
- let o = Date.now() - i;
3411
+ let o = Date.now() - n;
3428
3412
  return yield* e`DELETE FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t.id} AND ${e("source")} = 'file'`, {
3429
3413
  id: t.id,
3430
3414
  durationMs: o
3431
3415
  };
3432
- } finally {
3433
- yield* O(e, { schema: t.lockSchema }).pipe(C.orDie);
3434
- }
3435
- }), wa = (e) => C.gen(function* () {
3416
+ }), (e) => e.release.pipe(w.orDie)) : yield* w.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3417
+ }), Da = (e) => w.gen(function* () {
3436
3418
  let t = yield* T.SqlClient, n = yield* t`
3437
3419
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3438
3420
  WHERE source = 'auto-diff'
@@ -3440,9 +3422,9 @@ BEGIN
3440
3422
  AND appliedAt < ${e.before}
3441
3423
  ORDER BY appliedAt DESC
3442
3424
  `;
3443
- if (n.length === 0) return yield* C.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3425
+ if (n.length === 0) return yield* w.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3444
3426
  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.`));
3427
+ 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
3428
  yield* t`
3447
3429
  UPDATE _voltro_migration_plans
3448
3430
  SET squashedAt = CURRENT_TIMESTAMP
@@ -3477,7 +3459,7 @@ BEGIN
3477
3459
  snapshotFingerprint: e.fingerprint,
3478
3460
  snapshotId: i
3479
3461
  };
3480
- }), Ta = { safe: !0 }, Ea = (e) => {
3462
+ }), Oa = { safe: !0 }, ka = (e) => {
3481
3463
  switch (e.kind) {
3482
3464
  case "drop-column": return {
3483
3465
  safe: !1,
@@ -3504,7 +3486,7 @@ BEGIN
3504
3486
  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
3487
  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
3488
  };
3507
- case "alter-column-nullability": return e.toNullable ? Ta : {
3489
+ case "alter-column-nullability": return e.toNullable ? Oa : {
3508
3490
  safe: !1,
3509
3491
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3510
3492
  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 +3516,12 @@ BEGIN
3534
3516
  case "drop-unique":
3535
3517
  case "drop-unique-composite":
3536
3518
  case "drop-foreign-key":
3537
- case "drop-check": return Ta;
3519
+ case "drop-check": return Oa;
3538
3520
  }
3539
- }, Da = (e) => {
3521
+ }, Aa = (e) => {
3540
3522
  let t = [];
3541
3523
  for (let n of e) {
3542
- let e = Ea(n.op);
3524
+ let e = ka(n.op);
3543
3525
  e.safe || t.push({
3544
3526
  op: n,
3545
3527
  reason: e.reason,
@@ -3547,7 +3529,7 @@ BEGIN
3547
3529
  });
3548
3530
  }
3549
3531
  return t;
3550
- }, Oa = (e) => {
3532
+ }, ja = (e) => {
3551
3533
  if (!e.enabled || e.unsafeCount === 0) return {
3552
3534
  refuse: !1,
3553
3535
  warnForced: !1,
@@ -3563,18 +3545,18 @@ BEGIN
3563
3545
  warnForced: !1,
3564
3546
  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
3547
  };
3566
- }, ka = (e) => {
3548
+ }, Ma = (e) => {
3567
3549
  let t = e.table;
3568
3550
  if (typeof t == "string") return t;
3569
3551
  let n = e.from;
3570
3552
  return typeof n == "string" ? n : void 0;
3571
- }, Aa = (e) => ({
3553
+ }, Na = (e) => ({
3572
3554
  kind: e.op.kind,
3573
- table: ka(e.op),
3555
+ table: Ma(e.op),
3574
3556
  classification: e.classification,
3575
3557
  reason: e.reason,
3576
3558
  blockedFix: e.blocked?.fix
3577
- }), ja = (e) => e.operations.map(Aa), Ma = async (e) => {
3559
+ }), Pa = (e) => e.operations.map(Na), Fa = async (e) => {
3578
3560
  let t = e.log ?? (() => {}), n = {
3579
3561
  branchId: e.branchId,
3580
3562
  mechanism: e.mechanism,
@@ -3593,10 +3575,10 @@ BEGIN
3593
3575
  applied: !1,
3594
3576
  converged: !1,
3595
3577
  residual: r,
3596
- infidelity: ja(o)
3578
+ infidelity: Pa(o)
3597
3579
  };
3598
3580
  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);
3581
+ let i = await e.plan(), o = Pa(i), s = o.filter((e) => e.classification === "lossy"), c = ua(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Na);
3600
3582
  if (l.length > 0) a = {
3601
3583
  ...n,
3602
3584
  outcome: "blocked",
@@ -3621,7 +3603,7 @@ BEGIN
3621
3603
  };
3622
3604
  else {
3623
3605
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3624
- let i = ja(await e.replan());
3606
+ let i = Pa(await e.replan());
3625
3607
  a = {
3626
3608
  ...n,
3627
3609
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3659,7 +3641,7 @@ BEGIN
3659
3641
  ...a,
3660
3642
  tornDown: o
3661
3643
  };
3662
- }, Na = (e) => {
3644
+ }, Ia = (e) => {
3663
3645
  switch (e.outcome) {
3664
3646
  case "clean": return 0;
3665
3647
  case "lossy": return 2;
@@ -3668,22 +3650,22 @@ BEGIN
3668
3650
  case "infidelity": return 1;
3669
3651
  case "failed": return 1;
3670
3652
  }
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) => {
3653
+ }, La = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Ra = (e) => {
3672
3654
  let t = [];
3673
3655
  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
3656
  else if (e.outcome === "infidelity") {
3675
3657
  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));
3658
+ for (let n of e.infidelity) t.push(La(n));
3677
3659
  } else {
3678
3660
  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));
3661
+ for (let n of e.operations) t.push(La(n));
3662
+ if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(La(n));
3681
3663
  }
3682
3664
  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) => ({
3665
+ }, za = (e, ...t) => ({
3684
3666
  _tag: "RawSqlFragment",
3685
3667
  strings: [...e],
3686
3668
  values: [...t]
3687
- }), La = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3669
+ }), Ba = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3688
3670
  //#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 };
3671
+ export { k as DEFAULT_CDC_CHANNEL, S as FILE_MIGRATION_PATTERN, ba as FileMigrationLedgerError, Qe as REACTIVE_TRIGGER_PREFIX, ge as VOLTRO_MIGRATION_LOCK_KEY, Ie as acquireMigrationLock, U as appliedAtValue, Ht as applyNamespacedSchema, Qi as applyPlan, Mt as applySchema, ja as assessRollingDeployGate, Ia as branchRehearsalExitCode, Xn as chunkTables, ka as classifyRollingDeploySafety, F as declaredSnapshot, at as defaultArrayClause, it as defaultClause, M as defaultJsonClause, ma as describeOutcome, ca as destructiveScope, on as detectReactiveTriggerDrift, fi as emitAddIndexMysql, qr as emitCreateTableMysql, Dr as emitDropColumnDdl, Or as emitDropColumnDdlMysql, jt as emitFrameworkBootstrapSql, kt as emitNamespaceProvisionDdl, At as emitNamespacedSchemaSql, Ot as emitSchemaSql, ur as engineFromVersion, $t as fingerprintSchema, Se as fnv1a64, Ra as formatBranchRehearsal, sn as formatReactiveTriggerDrift, sa as ignoreTablesFromEnv, lr as introspectSchema, hr as isAlreadySatisfied, u as isFileMigration, Ba as isRawSqlFragment, Pt as isReRunSafeDdl, Wn as mapPgType, d as migration, Ce as migrationLockKeyForSchema, we as migrationLockNameForSchema, ci as mysqlIndexPrefixFor, et as notifyFunctionName, N as numericIdSql, Un as parseEnumCheck, Ca as pendingFileMigrationIds, Hn as planMigrations, Ut as provisionTenantNamespace, $e as reactiveTriggerName, yt as reactiveTriggerRepairSql, na as recordUpToDate, Fa as rehearseMigrationOnBranch, Na as rehearsedOperation, Gr as renderColumnMysql, Br as renderColumnPg, ve as resolveMigrationLockSchema, H as resolveMysqlEngine, Ea as rollbackFileBasedMigration, Aa as rollingDeployUnsafeOps, wa as runFileBasedMigrations, Wt as runFrameworkBootstrap, Vt as runMigrate, pa as runPlannedMigrations, en as shortFingerprint, tn as snapshotColumn, za as sql, j as sqlType, Da as squashMigrationPlans, ua as unblockLossy, Le as withMigrationLock };