@voltro/database 0.63.0 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sql.js CHANGED
@@ -1,13 +1,13 @@
1
- import { $ as e, $t as t, Ht as n, Ut as r, a as i, at as a, c as o, d as s, en as c, et as l, g as u, h as d, i as f, it as p, o as m, r as h, s as g, tt as _, u as v, vt as y, wt as b, y as x } from "./frameworkLiveTables-X6rOAleu.js";
2
- import { Effect as S, Schedule as C } from "effect";
3
- import { createHash as ee } from "node:crypto";
4
- import { createLogger as w } 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 ee } from "./frameworkLiveTables-BURogL9N.js";
2
+ import { Effect as C, Schedule as w } from "effect";
3
+ import { createHash as te } from "node:crypto";
4
+ import { createLogger as ne } from "@voltro/logger";
5
5
  import { SqlClient as T } from "@effect/sql";
6
- import { promises as te } from "node:fs";
7
- import { join as ne } from "node:path";
8
- import { pathToFileURL as re } from "node:url";
6
+ import { promises as re } from "node:fs";
7
+ import { join as ie } from "node:path";
8
+ import { pathToFileURL as ae } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var ie = (e, t, n, r = 400) => {
10
+ var oe = (e, t, n, r = 400) => {
11
11
  let i = n, a = i.cause ?? {}, o = (e) => {
12
12
  let t = a[e];
13
13
  return t == null || t === "" ? void 0 : String(t);
@@ -38,21 +38,21 @@ var ie = (e, t, n, r = 400) => {
38
38
  let t = o(e);
39
39
  t !== void 0 && s.push(`db.${e}: ${t}`);
40
40
  }
41
- let c = ae(o("code"));
41
+ let c = se(o("code"));
42
42
  return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
- }, ae = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, oe = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, se = (e) => e.replace(/"/g, "`"), ce = (e) => typeof e == "string" ? e : e.name ?? String(e), le = (e, t) => `_ua_${t}_${e}`.slice(0, 64), ue = (e, t) => {
44
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(oe)) return e;
43
+ }, 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;
45
45
  let n = { ...e.fields }, r = [], i = [];
46
46
  for (let t of e.appliedIndexes) {
47
- if (!oe(t)) {
47
+ if (!ce(t)) {
48
48
  r.push(t);
49
49
  continue;
50
50
  }
51
- let a = se(t.where), o = [];
51
+ let a = le(t.where), o = [];
52
52
  for (let r of t.fields) {
53
- let i = ce(r);
53
+ let i = ue(r);
54
54
  if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
55
- let s = le(t.name, i);
55
+ let s = de(t.name, i);
56
56
  o.push(s), n[s] = {
57
57
  type: "text",
58
58
  nullable: !0,
@@ -75,7 +75,7 @@ var ie = (e, t, n, r = 400) => {
75
75
  appliedIndexes: r,
76
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
77
77
  };
78
- }, E = (e, t) => `${e}::${t}`, de = (e, t) => {
78
+ }, E = (e, t) => `${e}::${t}`, pe = (e, t) => {
79
79
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
80
80
  n.add(e);
81
81
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
@@ -84,90 +84,90 @@ var ie = (e, t, n, r = 400) => {
84
84
  };
85
85
  for (let t of [...e].sort()) r.has(t) || a(t);
86
86
  return i;
87
- }, fe = 6322741009312437n, pe = (e) => {
87
+ }, me = 6322741009312437n, he = (e) => {
88
88
  let t = e?.trim();
89
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
90
- }, me = (e) => e?.schema === void 0 ? pe(process.env.DB_SCHEMA) : pe(e.schema), he = 14695981039346656037n, ge = 1099511628211n, _e = 18446744073709551615n, ve = (e) => {
91
- let t = he;
92
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * ge & _e;
90
+ }, 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;
93
93
  return t;
94
- }, ye = (e) => {
95
- let t = pe(e);
96
- return t === void 0 ? fe : ve(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
- }, D = (e) => {
98
- let t = `voltro_migration_${fe.toString(36)}`, n = pe(e);
94
+ }, xe = (e) => {
95
+ let t = he(e);
96
+ return t === void 0 ? me : be(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
+ }, Se = (e) => {
98
+ let t = `voltro_migration_${me.toString(36)}`, n = he(e);
99
99
  if (n === void 0) return t;
100
100
  let r = `${t}_${n}`;
101
- return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(ve(`voltro_migration_lock:${n}`) & _e).toString(16)}`;
102
- }, be = 250, xe = () => {
101
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(be(`voltro_migration_lock:${n}`) & ye).toString(16)}`;
102
+ }, Ce = 250, we = () => {
103
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
104
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
105
- }, Se = (e, t) => S.gen(function* () {
106
- let n = xe(), r = Date.now();
105
+ }, Te = (e, t) => C.gen(function* () {
106
+ let n = we(), r = Date.now();
107
107
  for (;;) {
108
108
  if ((yield* e`
109
109
  SELECT pg_try_advisory_lock(${t.toString()}::bigint) AS got`)[0]?.got) return;
110
- Date.now() - r >= n && (yield* S.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* S.sleep(`${be} millis`);
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(`${Ce} millis`);
111
111
  }
112
- }), Ce = (e, t) => S.gen(function* () {
112
+ }), Ee = (e, t) => C.gen(function* () {
113
113
  yield* e`SELECT pg_advisory_unlock(${t.toString()}::bigint)`;
114
- }), we = 30, Te = (e, t) => S.gen(function* () {
114
+ }), De = 30, Oe = (e, t) => C.gen(function* () {
115
115
  (yield* e`
116
- SELECT GET_LOCK(${t}, ${we}) AS got`)[0]?.got !== 1 && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${we}s (another migration is in progress, or a prior one left it held).`)));
117
- }), Ee = (e, t) => S.gen(function* () {
116
+ SELECT GET_LOCK(${t}, ${De}) AS got`)[0]?.got !== 1 && (yield* C.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' within ${De}s (another migration is in progress, or a prior one left it held).`)));
117
+ }), ke = (e, t) => C.gen(function* () {
118
118
  yield* e`SELECT RELEASE_LOCK(${t})`;
119
- }), De = 3e4, Oe = (e, t) => S.gen(function* () {
119
+ }), Ae = 3e4, je = (e, t) => C.gen(function* () {
120
120
  let n = yield* e`
121
121
  DECLARE @res int;
122
122
  EXEC @res = sp_getapplock @Resource = ${t}, @LockMode = 'Exclusive',
123
- @LockOwner = 'Session', @LockTimeout = ${De};
123
+ @LockOwner = 'Session', @LockTimeout = ${Ae};
124
124
  SELECT @res AS res`;
125
- (n[0]?.res ?? -999) < 0 && (yield* S.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' (sp_getapplock returned ${n[0]?.res ?? "no row"}; another migration is in progress).`)));
126
- }), ke = (e, t) => S.gen(function* () {
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
+ }), Me = (e, t) => C.gen(function* () {
127
127
  yield* e`EXEC sp_releaseapplock @Resource = ${t}, @LockOwner = 'Session'`;
128
- }), Ae = S.void, je = (e, t) => {
129
- let n = me(t);
128
+ }), Ne = C.void, Pe = (e, t) => {
129
+ let n = ge(t);
130
130
  return e.onDialectOrElse({
131
- mysql: () => Te(e, D(n)),
132
- mssql: () => Oe(e, D(n)),
133
- sqlite: () => Ae,
134
- orElse: () => Se(e, ye(n))
131
+ mysql: () => Oe(e, Se(n)),
132
+ mssql: () => je(e, Se(n)),
133
+ sqlite: () => Ne,
134
+ orElse: () => Te(e, xe(n))
135
135
  });
136
- }, O = (e, t) => {
137
- let n = me(t);
136
+ }, D = (e, t) => {
137
+ let n = ge(t);
138
138
  return e.onDialectOrElse({
139
- mysql: () => Ee(e, D(n)),
140
- mssql: () => ke(e, D(n)),
141
- sqlite: () => Ae,
142
- orElse: () => Ce(e, ye(n))
139
+ mysql: () => ke(e, Se(n)),
140
+ mssql: () => Me(e, Se(n)),
141
+ sqlite: () => Ne,
142
+ orElse: () => Ee(e, xe(n))
143
143
  });
144
- }, Me = (e, t, n) => S.acquireUseRelease(je(e, n), () => t, () => O(e, n).pipe(S.orDie)), Ne = (e) => e.onDialectOrElse({
144
+ }, Fe = (e, t, n) => C.acquireUseRelease(Pe(e, n), () => t, () => D(e, n).pipe(C.orDie)), Ie = (e) => e.onDialectOrElse({
145
145
  pg: () => "postgres",
146
146
  mysql: () => "mysql",
147
147
  mssql: () => "mssql",
148
148
  sqlite: () => "sqlite",
149
149
  orElse: () => "sqlite"
150
- }), Pe = {
150
+ }), Le = {
151
151
  postgres: "plan-transactional",
152
152
  mssql: "plan-transactional",
153
153
  mysql: "per-operation",
154
154
  mariadb: "per-operation",
155
155
  sqlite: "per-operation",
156
156
  turso: "per-operation"
157
- }, Fe = (e) => Pe[e], k = "_voltro_migration_ops", Ie = p(k, {
158
- id: n({ prefix: "mop" }),
159
- runId: t(),
160
- planFingerprint: t(),
161
- opIndex: r(),
162
- opKind: t(),
163
- opTarget: t(),
164
- status: t(),
165
- payload: t(),
166
- startedAt: c().nullable(),
167
- appliedAt: c().nullable(),
168
- durationMs: r().nullable(),
169
- createdAt: c().default("now")
170
- }), Le = (e) => {
157
+ }, Re = (e) => Le[e], O = "_voltro_migration_ops", ze = l(O, {
158
+ id: y({ prefix: "mop" }),
159
+ runId: a(),
160
+ planFingerprint: a(),
161
+ opIndex: t(),
162
+ opKind: a(),
163
+ opTarget: a(),
164
+ status: a(),
165
+ payload: a(),
166
+ startedAt: v().nullable(),
167
+ appliedAt: v().nullable(),
168
+ durationMs: t().nullable(),
169
+ createdAt: v().default("now")
170
+ }), Be = (e) => {
171
171
  switch (e.kind) {
172
172
  case "create-table": return /* @__PURE__ */ new Set([
173
173
  `table:${e.table}`,
@@ -194,11 +194,11 @@ var ie = (e, t, n, r = 400) => {
194
194
  case "add-unique-composite":
195
195
  case "drop-unique-composite": return /* @__PURE__ */ new Set([`unique:${e.table}.${e.name}`]);
196
196
  }
197
- }, Re = (e) => [...Le(e)].join(" "), ze = (e, t) => {
198
- let n = Le(t);
199
- for (let t of Le(e)) if (n.has(t)) return !0;
197
+ }, Ve = (e) => [...Be(e)].join(" "), He = (e, t) => {
198
+ let n = Be(t);
199
+ for (let t of Be(e)) if (n.has(t)) return !0;
200
200
  return !1;
201
- }, Be = (e, t) => e.operations.some((e) => ze(e.op, t)), Ve = "__voltro_rebuild", He = "__shadow", Ue = "__old", We = /* @__PURE__ */ new Set([
201
+ }, Ue = (e, t) => e.operations.some((e) => He(e.op, t)), We = "__voltro_rebuild", Ge = "__shadow", Ke = "__old", qe = /* @__PURE__ */ new Set([
202
202
  "add-unique",
203
203
  "drop-unique",
204
204
  "add-unique-composite",
@@ -210,21 +210,21 @@ var ie = (e, t, n, r = 400) => {
210
210
  "alter-column-nullability",
211
211
  "alter-column-type",
212
212
  "alter-column-default"
213
- ]), Ge = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ke = (e, t, n) => {
213
+ ]), Je = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Ye = (e, t, n) => {
214
214
  let r = n === "sqlite" || n === "turso";
215
- return e.kind === "alter-column-type" && t === "online-required" || r && We.has(e.kind) ? "artefact-repair" : Ge.has(e.kind) ? "idempotent" : "probe-then-replay";
215
+ return e.kind === "alter-column-type" && t === "online-required" || r && qe.has(e.kind) ? "artefact-repair" : Je.has(e.kind) ? "idempotent" : "probe-then-replay";
216
216
  };
217
- Object.keys(Pe);
217
+ Object.keys(Le);
218
218
  //#endregion
219
219
  //#region src/migrations/reactiveTriggerName.ts
220
- var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "framework_changes" ? `${qe}${e}` : `${qe}${t}_${e}`, Ye = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Xe = "voltro:notify:v2", Ze = (e, t) => {
220
+ var k = "framework_changes", Xe = "framework_changes_", Ze = (e, t) => t === "framework_changes" ? `${Xe}${e}` : `${Xe}${t}_${e}`, Qe = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, $e = "voltro:notify:v2", et = (e, t) => {
221
221
  if (e.type === "text" && e.generatedAs === void 0) {
222
222
  if (e.maxLength !== void 0) return e.maxLength;
223
223
  if (t || e.hasDefault && e.defaultFactory === void 0 || e.oneOf !== void 0 && e.oneOf.length > 0) return 450;
224
224
  }
225
- }, Qe = w({ scope: "voltro:migrate" }), j = (e) => {
226
- Qe.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
227
- }, M = (e, t) => {
225
+ }, tt = ne({ scope: "voltro:migrate" }), A = (e) => {
226
+ tt.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
227
+ }, j = (e, t) => {
228
228
  let n = e.type;
229
229
  if (e.spatial) {
230
230
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -235,14 +235,14 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
235
235
  return e.rawDdl;
236
236
  }
237
237
  if (n === "array" && e.arrayElement) {
238
- if (t === "postgres") return `${M({
238
+ if (t === "postgres") return `${j({
239
239
  ...e,
240
240
  type: e.arrayElement,
241
241
  arrayElement: void 0
242
242
  }, t)}[]`;
243
243
  if (t === "mysql" || t === "mariadb") return "JSON";
244
244
  if (t === "mssql") return "NVARCHAR(MAX)";
245
- if (l(t)) return "TEXT";
245
+ if (m(t)) return "TEXT";
246
246
  }
247
247
  if (n === "vector") {
248
248
  let n = e.vectorDim;
@@ -251,27 +251,27 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
251
251
  if (t === "postgres") return r ? `HALFVEC(${n})` : `VECTOR(${n})`;
252
252
  if (t === "mysql" || t === "mariadb") return `VECTOR(${n})`;
253
253
  if (t === "mssql") return "VARBINARY(MAX)";
254
- if (l(t)) return "BLOB";
254
+ if (m(t)) return "BLOB";
255
255
  }
256
256
  if (n === "interval") {
257
257
  if (t === "postgres") return "INTERVAL";
258
258
  if (t === "mysql" || t === "mariadb" || t === "mssql") return "BIGINT";
259
- if (l(t)) return "INTEGER";
259
+ if (m(t)) return "INTEGER";
260
260
  }
261
261
  if (n === "decimal") {
262
262
  let n = e.precision, r = e.scale ?? 0;
263
263
  if (n === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
264
- return l(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
264
+ return m(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
265
265
  }
266
- if (n === "bigint") return l(t) ? "INTEGER" : "BIGINT";
266
+ if (n === "bigint") return m(t) ? "INTEGER" : "BIGINT";
267
267
  if (n === "enum") {
268
268
  if (t === "postgres") return e.enumName ?? "TEXT";
269
269
  if (t === "mysql" || t === "mariadb") return `ENUM(${(e.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
270
270
  if (t === "mssql") return "NVARCHAR(255)";
271
- if (l(t)) return "TEXT";
271
+ if (m(t)) return "TEXT";
272
272
  }
273
- if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : l(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
274
- if (l(t)) switch (n) {
273
+ if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : m(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
274
+ if (m(t)) switch (n) {
275
275
  case "id": return "TEXT";
276
276
  case "text": return "TEXT";
277
277
  case "integer": return "INTEGER";
@@ -306,7 +306,7 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
306
306
  if (t === "mssql") switch (n) {
307
307
  case "id": return "NVARCHAR(64)";
308
308
  case "text": {
309
- let t = Ze(e, !1);
309
+ let t = et(e, !1);
310
310
  return t === void 0 ? "NVARCHAR(MAX)" : `NVARCHAR(${t})`;
311
311
  }
312
312
  case "integer": return "INT";
@@ -338,22 +338,22 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
338
338
  case "array": return "TEXT[]";
339
339
  case "interval": return "INTERVAL";
340
340
  }
341
- }, $e = (e, t) => {
341
+ }, nt = (e, t) => {
342
342
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
343
343
  let n = e.defaultValue;
344
- return n === "now" ? l(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? et(n, e, t) : typeof n == "object" && n ? N(n, t) : null;
345
- }, et = (e, t, n) => {
346
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return N(e, n);
347
- let r = M({
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) ? rt(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
345
+ }, rt = (e, t, n) => {
346
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return M(e, n);
347
+ let r = j({
348
348
  ...t,
349
349
  type: t.arrayElement,
350
350
  arrayElement: void 0
351
351
  }, n);
352
352
  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) => {
353
+ }, M = (e, t) => {
354
354
  let n = JSON.stringify(e).replace(/'/g, "''");
355
355
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CONVERT('${n}' USING utf8mb4))` : `DEFAULT '${n}'`;
356
- }, P = (e, t) => {
356
+ }, N = (e, t) => {
357
357
  switch (t) {
358
358
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
359
359
  case "mysql":
@@ -362,7 +362,7 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
362
362
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
363
363
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
364
364
  }
365
- }, F = (e, t) => {
365
+ }, P = (e, t) => {
366
366
  if (e === "restrict" && t === "mssql") return "NO ACTION";
367
367
  switch (e) {
368
368
  case "cascade": return "CASCADE";
@@ -370,118 +370,118 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
370
370
  case "setNull": return "SET NULL";
371
371
  case "noAction": return "NO ACTION";
372
372
  }
373
- }, tt = (e, t, n) => n === null ? _(e, t) : `${_(n, t)}.${_(e, t)}`, nt = 191, rt = (e, t) => {
373
+ }, it = (e, t, n) => n === null ? o(e, t) : `${o(n, t)}.${o(e, t)}`, at = 191, ot = (e, t) => {
374
374
  if (!e || t !== "mysql" && t !== "mariadb") return !1;
375
- let n = M(e, t).toUpperCase();
375
+ let n = j(e, t).toUpperCase();
376
376
  return n.endsWith("TEXT") || n.endsWith("BLOB");
377
- }, it = (e, t, n) => {
378
- let r = _(e, n);
377
+ }, st = (e, t, n) => {
378
+ let r = o(e, n);
379
379
  if (n !== "mysql" && n !== "mariadb") return r;
380
380
  let i = t[e];
381
381
  if (!i) return r;
382
- let a = M(i, n).toUpperCase();
383
- return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${nt})` : r;
384
- }, at = (e, t) => {
382
+ let a = j(i, n).toUpperCase();
383
+ return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${at})` : r;
384
+ }, ct = (e, t) => {
385
385
  if (!e.generatedAs) return null;
386
386
  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`;
387
+ 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
388
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
389
389
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
390
390
  if (t === "turso") throw Error("@voltro/sql-turso: generated columns (.generatedAs(...)) are not supported — Turso's MVCC mode (journal_mode=experimental_mvcc) rejects them. Drop the generated column, or use the 'sqlite' / 'postgres' dialect for this table.");
391
391
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
392
- }, ot = (t, n, r, i, a = !1, o = !1) => {
393
- if (n.type === "id" && n.idScheme?.kind === "numeric") return P(t, r);
394
- let s = r === "mssql" ? Ze(n, i?.has(t) ?? !1) : void 0, c = s === void 0 ? M(n, r) : `NVARCHAR(${s})`, u = [_(t, r), c];
395
- n.type === "id" && !o && u.push("PRIMARY KEY");
396
- let d = at(n, r);
397
- if (d) u.push(d);
392
+ }, lt = (e, t, n, r, i = !1, a = !1) => {
393
+ if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, n);
394
+ let s = n === "mssql" ? et(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? j(t, n) : `NVARCHAR(${s})`, l = [o(e, n), c];
395
+ t.type === "id" && !a && l.push("PRIMARY KEY");
396
+ let u = ct(t, n);
397
+ if (u) l.push(u);
398
398
  else {
399
- n.nullable || u.push("NOT NULL"), n.unique && n.type !== "id" && !rt(n, r) && u.push("UNIQUE");
400
- let e = $e(n, r);
401
- e && u.push(e);
402
- }
403
- if (n.type === "reference" && n.references && !a && !e(r)) {
404
- let e = n.references();
405
- u.push(`REFERENCES ${_(e.tableName, r)} (${_("id", r)})`);
406
- let t = F(n.onDelete ?? "restrict", r);
407
- u.push(`ON DELETE ${t}`);
408
- let i = F(n.refOnUpdate ?? "noAction", r);
409
- i !== "NO ACTION" && u.push(`ON UPDATE ${i}`);
410
- }
411
- if (n.oneOf && n.oneOf.length > 0) {
412
- let e = n.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
413
- u.push(`CHECK (${_(t, r)} IN (${e}))`);
414
- }
415
- if (n.checks && n.checks.length > 0) for (let e of n.checks) u.push(`CHECK (${e})`);
416
- if (n.type === "enum" && n.enumValues && n.enumValues.length > 0 && (r === "mssql" || l(r))) {
417
- let e = n.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
418
- u.push(`CHECK (${_(t, r)} IN (${e}))`);
419
- }
420
- if (n.type === "json" || n.type === "array") {
421
- let e = _(t, r);
422
- l(r) ? u.push(`CHECK (${e} IS NULL OR json_valid(${e}))`) : r === "mssql" && u.push(`CHECK (${e} IS NULL OR ISJSON(${e}) = 1)`);
423
- }
424
- return u.join(" ");
425
- }, st = (t, n, r = null, i) => {
426
- let a = /* @__PURE__ */ new Set();
427
- for (let e of t.appliedIndexes ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
428
- for (let e of t.appliedUniques ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
429
- for (let [e, n] of Object.entries(t.fields)) n.unique && a.add(e);
430
- let o = t.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(t.fields).map(([e, t]) => ` ${ot(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (t.appliedUniques ?? []).map((e) => {
431
- let r = e.fields.map((e) => it(e, t.fields, n)).join(", ");
432
- return ` CONSTRAINT ${_(e.name, n)} UNIQUE (${r})`;
433
- }), u = (t.appliedChecks ?? []).map((e) => ` CONSTRAINT ${_(e.name, n)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${o.map((e) => it(e, t.fields, n)).join(", ")})`] : [], f = e(n) ? Object.entries(t.fields).flatMap(([e, a]) => {
434
- if (a.type !== "reference" || !a.references || (i?.has(e) ?? !1)) return [];
435
- let o = a.references(), s = F(a.onDelete ?? "restrict", n), c = F(a.refOnUpdate ?? "noAction", n);
436
- return [` CONSTRAINT ${_(`${t.tableName}_${e}_fkey`, n)} FOREIGN KEY (${_(e, n)}) REFERENCES ${tt(o.tableName, n, r)} (${_("id", n)}) ON DELETE ${s}${c === "NO ACTION" ? "" : ` ON UPDATE ${c}`}`];
399
+ t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !ot(t, n) && l.push("UNIQUE");
400
+ let e = nt(t, n);
401
+ e && l.push(e);
402
+ }
403
+ if (t.type === "reference" && t.references && !i && !b(n)) {
404
+ let e = t.references();
405
+ l.push(`REFERENCES ${o(e.tableName, n)} (${o("id", n)})`);
406
+ let r = P(t.onDelete ?? "restrict", n);
407
+ l.push(`ON DELETE ${r}`);
408
+ let i = P(t.refOnUpdate ?? "noAction", n);
409
+ i !== "NO ACTION" && l.push(`ON UPDATE ${i}`);
410
+ }
411
+ if (t.oneOf && t.oneOf.length > 0) {
412
+ let r = t.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
413
+ l.push(`CHECK (${o(e, n)} IN (${r}))`);
414
+ }
415
+ if (t.checks && t.checks.length > 0) for (let e of t.checks) l.push(`CHECK (${e})`);
416
+ if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" || m(n))) {
417
+ let r = t.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
418
+ l.push(`CHECK (${o(e, n)} IN (${r}))`);
419
+ }
420
+ if (t.type === "json" || t.type === "array") {
421
+ let t = o(e, n);
422
+ 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
+ }
424
+ return l.join(" ");
425
+ }, ut = (e, t, n = null, r) => {
426
+ let i = /* @__PURE__ */ new Set();
427
+ for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
428
+ for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
429
+ for (let [t, n] of Object.entries(e.fields)) n.unique && i.add(t);
430
+ let a = e.appliedPrimaryKey ?? [], s = a.length > 0, c = Object.entries(e.fields).map(([e, n]) => ` ${lt(e, n, t, i, r?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((n) => {
431
+ let r = n.fields.map((n) => st(n, e.fields, t)).join(", ");
432
+ return ` CONSTRAINT ${o(n.name, t)} UNIQUE (${r})`;
433
+ }), u = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${o(e.name, t)} CHECK (${e.expr})`), d = s ? [` PRIMARY KEY (${a.map((n) => st(n, e.fields, t)).join(", ")})`] : [], f = b(t) ? Object.entries(e.fields).flatMap(([i, a]) => {
434
+ if (a.type !== "reference" || !a.references || (r?.has(i) ?? !1)) return [];
435
+ let s = a.references(), c = P(a.onDelete ?? "restrict", t), l = P(a.refOnUpdate ?? "noAction", t);
436
+ return [` CONSTRAINT ${o(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${o(i, t)}) REFERENCES ${it(s.tableName, t, n)} (${o("id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
437
437
  }) : [], p = [
438
438
  ...d,
439
439
  ...l,
440
440
  ...u,
441
441
  ...f
442
- ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = tt(t.tableName, n, r);
443
- if (n === "mssql") {
444
- let e = r === null ? t.tableName : `${r}.${t.tableName}`, n = `CREATE TABLE ${h} (\n${m}\n)`;
445
- return `IF OBJECT_ID('${e.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
442
+ ], m = p.length > 0 ? `${c},\n${p.join(",\n")}` : c, h = it(e.tableName, t, n);
443
+ if (t === "mssql") {
444
+ let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${h} (\n${m}\n)`;
445
+ return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
446
446
  }
447
447
  return [
448
448
  `CREATE TABLE IF NOT EXISTS ${h} (`,
449
449
  m,
450
450
  ");"
451
451
  ].join("\n");
452
- }, ct = (e, t, n) => {
453
- let r = `${e}_${t.name}_fts`, i = (e) => _(e, n), a = t.columns.map(i).join(", "), o = t.columns.map((e) => `new.${i(e)}`).join(", "), s = [];
454
- return s.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${i(r)} USING fts5(${a}, row_id UNINDEXED, tokenize='porter');`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ai`)} AFTER INSERT ON ${i(e)} BEGIN\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ad`)} AFTER DELETE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_au`)} AFTER UPDATE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s;
455
- }, lt = (e, t, n = null) => {
456
- let r = [], i = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, n, r, i) => {
457
- let o = {
452
+ }, dt = (e, t, n) => {
453
+ 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 = [];
454
+ 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;
455
+ }, ft = (e, t, n = null) => {
456
+ let r = [], i = /* @__PURE__ */ new Set(), a = (e) => e.join("\0"), s = (e, n, r, i) => {
457
+ let a = {
458
458
  using: "",
459
459
  withSuffix: "",
460
460
  skip: !1
461
461
  };
462
- if (r === void 0 || r === "btree") return o;
462
+ if (r === void 0 || r === "btree") return a;
463
463
  if (r === "gist") return t === "postgres" ? {
464
464
  using: " USING GIST",
465
465
  withSuffix: "",
466
466
  skip: !1
467
- } : (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.`), o);
467
+ } : (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);
468
468
  if (r === "gin") return t === "postgres" ? {
469
469
  using: " USING GIN",
470
470
  withSuffix: "",
471
471
  skip: !1
472
- } : 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(...).`), {
472
+ } : 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(...).`), {
473
473
  using: "",
474
474
  withSuffix: "",
475
475
  skip: !0
476
- }) : (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.`), o);
476
+ }) : (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);
477
477
  if (r === "brin") return t === "postgres" ? {
478
478
  using: " USING BRIN",
479
479
  withSuffix: "",
480
480
  skip: !1
481
- } : (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).`), o);
481
+ } : (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);
482
482
  if (r === "hnsw") {
483
483
  if (t === "postgres") {
484
- let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? a(i?.hnsw?.distance);
484
+ let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? h(i?.hnsw?.distance);
485
485
  return {
486
486
  using: " USING hnsw",
487
487
  withSuffix: ` WITH (m = ${e}, ef_construction = ${t})`,
@@ -489,73 +489,73 @@ var A = "framework_changes", qe = "framework_changes_", Je = (e, t) => t === "fr
489
489
  skip: !1
490
490
  };
491
491
  }
492
- 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.`), {
492
+ 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.`), {
493
493
  using: "",
494
494
  withSuffix: "",
495
495
  skip: !0
496
496
  };
497
497
  }
498
- return o;
498
+ return a;
499
499
  }, c = (n, r) => {
500
500
  let i = n.map((n) => {
501
- if (typeof n == "string") return it(n, e.fields, t);
501
+ if (typeof n == "string") return st(n, e.fields, t);
502
502
  if ("jsonPath" in n) {
503
503
  let { column: e, path: r, numeric: i } = n.jsonPath;
504
- return `(${d(e, r, t, { numeric: i })})`;
504
+ return `(${ee(e, r, t, { numeric: i })})`;
505
505
  }
506
506
  return `(${n.expr})`;
507
507
  });
508
508
  return r !== void 0 && i.length === 1 ? `${i[0]} ${r}` : i.join(", ");
509
- }, l = (e, r, i, a, o, l = "", u = !1) => {
510
- let d = s(e, r, a, o);
511
- if (d.skip) return "";
512
- let f = c(i, d.opclass), p = `${d.withSuffix}${l}`, m = tt(r, t, n), h = u ? "UNIQUE " : "";
513
- return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${h}INDEX ${_(e, t)} ON ${m}${d.using} (${f})${p};` : t === "mysql" ? `CREATE ${h}INDEX ${_(e, t)} ON ${m}${d.using} (${f})${p};` : `CREATE ${h}INDEX IF NOT EXISTS ${_(e, t)} ON ${m}${d.using} (${f})${p};`;
509
+ }, l = (e, r, i, a, l, u = "", d = !1) => {
510
+ let f = s(e, r, a, l);
511
+ if (f.skip) return "";
512
+ let p = c(i, f.opclass), m = `${f.withSuffix}${u}`, h = it(r, t, n), g = d ? "UNIQUE " : "";
513
+ 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};`;
514
514
  };
515
515
  if (t === "mysql" || t === "mariadb") for (let [n, i] of Object.entries(e.fields)) {
516
- if (!i.unique || i.type === "id" || !rt(i, t)) continue;
516
+ if (!i.unique || i.type === "id" || !ot(i, t)) continue;
517
517
  let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
518
518
  a && r.push(a);
519
519
  }
520
520
  for (let n of e.appliedFullText ?? []) if (t === "postgres") {
521
- let i = n.config ?? "english", a = `${n.name}_tsv`, o = n.columns.map((e) => {
521
+ let i = n.config ?? "english", a = `${n.name}_tsv`, s = n.columns.map((e) => {
522
522
  let r = n.weights?.[e] ?? "A";
523
- return `setweight(to_tsvector('${i}', coalesce(${_(e, t)}, '')), '${r}')`;
523
+ return `setweight(to_tsvector('${i}', coalesce(${o(e, t)}, '')), '${r}')`;
524
524
  }).join(" || ");
525
- r.push(`ALTER TABLE ${_(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${_(a, t)} tsvector GENERATED ALWAYS AS (${o}) STORED;`), r.push(`CREATE INDEX IF NOT EXISTS ${_(n.name, t)} ON ${_(e.tableName, t)} USING GIN (${_(a, t)});`);
525
+ r.push(`ALTER TABLE ${o(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${o(a, t)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), r.push(`CREATE INDEX IF NOT EXISTS ${o(n.name, t)} ON ${o(e.tableName, t)} USING GIN (${o(a, t)});`);
526
526
  } else if (t === "mysql" || t === "mariadb") {
527
- let i = n.columns.map((e) => _(e, t)).join(", ");
528
- r.push(`CREATE FULLTEXT INDEX ${_(n.name, t)} ON ${_(e.tableName, t)} (${i});`);
527
+ let i = n.columns.map((e) => o(e, t)).join(", ");
528
+ r.push(`CREATE FULLTEXT INDEX ${o(n.name, t)} ON ${o(e.tableName, t)} (${i});`);
529
529
  } else if (t === "turso") throw Error(`@voltro/sql-turso: full-text index '${n.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
530
- else t === "sqlite" ? r.push(...ct(e.tableName, n, t)) : j(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
530
+ else t === "sqlite" ? r.push(...dt(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).`);
531
531
  for (let n of e.appliedIndexes) {
532
532
  if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
533
- j(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
533
+ 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(...).`);
534
534
  continue;
535
535
  }
536
536
  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.`);
537
- let a = "";
538
- 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`) : a = ` WHERE ${n.where}`);
539
- let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, a, n.unique === !0);
540
- s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && i.add(o(n.fields));
537
+ let o = "";
538
+ 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}`);
539
+ let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, o, n.unique === !0);
540
+ s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && i.add(a(n.fields));
541
541
  }
542
542
  for (let [t, n] of Object.entries(e.fields)) {
543
- if (n.type !== "reference" || n.fkAutoIndex === !1 || i.has(o([t]))) continue;
544
- let a = `${e.tableName}_${t}_idx`;
545
- r.push(l(a, e.tableName, [t])), i.add(o([t]));
543
+ if (n.type !== "reference" || n.fkAutoIndex === !1 || i.has(a([t]))) continue;
544
+ let o = `${e.tableName}_${t}_idx`;
545
+ r.push(l(o, e.tableName, [t])), i.add(a([t]));
546
546
  }
547
547
  return r.join("\n");
548
- }, ut = (e, t, n = A) => {
548
+ }, pt = (e, t, n = k) => {
549
549
  if (t !== "postgres") return [];
550
550
  let r = e.filter((e) => e.isReactive !== !1);
551
- return r.length === 0 ? [] : [dt(n), ...r.map((e) => pt(e, n))];
552
- }, dt = (e) => `
553
- CREATE OR REPLACE FUNCTION ${Ye(e)}() RETURNS trigger AS $$
551
+ return r.length === 0 ? [] : [mt(n), ...r.map((e) => gt(e, n))];
552
+ }, mt = (e) => `
553
+ CREATE OR REPLACE FUNCTION ${Qe(e)}() RETURNS trigger AS $$
554
554
  DECLARE
555
555
  payload TEXT;
556
556
  pk JSONB;
557
557
  BEGIN
558
- -- ${Xe}
558
+ -- ${$e}
559
559
  payload := json_build_object(
560
560
  'table', TG_TABLE_NAME,
561
561
  -- The schema the write landed in. Under namespace isolation this is
@@ -609,22 +609,22 @@ BEGIN
609
609
  RETURN COALESCE(NEW, OLD);
610
610
  END;
611
611
  $$ LANGUAGE plpgsql;
612
- `.trim(), ft = (e, t) => {
613
- let n = Je(e.tableName, t);
612
+ `.trim(), ht = (e, t) => {
613
+ let n = Ze(e.tableName, t);
614
614
  return [
615
615
  `ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL`,
616
616
  `DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}"`,
617
- `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${Ye(t)}()`
617
+ `CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${Qe(t)}()`
618
618
  ];
619
- }, pt = (e, t) => ft(e, t).map((e) => `${e};`).join("\n"), mt = (e) => {
619
+ }, gt = (e, t) => ht(e, t).map((e) => `${e};`).join("\n"), _t = (e) => {
620
620
  if (e.dialect !== "postgres") return [];
621
621
  let t = e.channel ?? "framework_changes", n = new Map(e.tables.map((e) => [e.tableName, e])), r = [], i = e.missing.filter((e) => n.has(e));
622
- (i.length > 0 || e.functionOutdated === !0) && r.push(dt(t));
623
- for (let e of i) r.push(...ft(n.get(e), t));
624
- for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Je(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
622
+ (i.length > 0 || e.functionOutdated === !0) && r.push(mt(t));
623
+ for (let e of i) r.push(...ht(n.get(e), t));
624
+ for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Ze(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
625
625
  return r;
626
- }, ht = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), gt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), _t = (e) => {
627
- let t = new Map(e.map((e) => [e.tableName, e])), n = de(e.map((e) => e.tableName), (e) => {
626
+ }, vt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), yt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), bt = (e) => {
627
+ let t = new Map(e.map((e) => [e.tableName, e])), n = pe(e.map((e) => e.tableName), (e) => {
628
628
  let n = t.get(e);
629
629
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
630
630
  if (n.type !== "reference" || !n.references) return [];
@@ -660,30 +660,30 @@ $$ LANGUAGE plpgsql;
660
660
  sorted: o,
661
661
  cyclic: r
662
662
  };
663
- }, vt = (e, t, n = null) => {
664
- let r = (e) => n ? `${_(n, t)}.${_(e, t)}` : _(e, t), i = `${e.table}_${e.column}_fkey`, a = F(e.onDelete, t), o = F(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${_(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${_(e.column, t)}) REFERENCES ${r(e.targetTable)} (${_("id", t)})${s}`;
663
+ }, xt = (e, t, n = null) => {
664
+ 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("id", t)})${c}`;
665
665
  switch (t) {
666
666
  case "postgres": return [
667
667
  "DO $$ BEGIN",
668
668
  " IF NOT EXISTS (SELECT 1 FROM pg_constraint",
669
669
  ` WHERE conname = '${i}' AND conrelid = '${n ? `${n}.` : ""}${e.table}'::regclass) THEN`,
670
- ` ALTER TABLE ${r(e.table)} ${c(!1)};`,
670
+ ` ALTER TABLE ${r(e.table)} ${l(!1)};`,
671
671
  " END IF;",
672
672
  "END $$;"
673
673
  ].join("\n");
674
- case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${i}') ALTER TABLE ${r(e.table)} ${c(!1)};`;
675
- case "mariadb": return `ALTER TABLE ${r(e.table)} ${c(!0)};`;
676
- default: return `ALTER TABLE ${r(e.table)} ${c(!1)};`;
674
+ case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${i}') ALTER TABLE ${r(e.table)} ${l(!1)};`;
675
+ case "mariadb": return `ALTER TABLE ${r(e.table)} ${l(!0)};`;
676
+ default: return `ALTER TABLE ${r(e.table)} ${l(!1)};`;
677
677
  }
678
- }, yt = (e, t) => {
678
+ }, St = (e, t) => {
679
679
  let n = /* @__PURE__ */ new Map();
680
- if (l(t)) return n;
680
+ if (m(t)) return n;
681
681
  for (let t of e) {
682
682
  let e = n.get(t.table) ?? /* @__PURE__ */ new Set();
683
683
  e.add(t.column), n.set(t.table, e);
684
684
  }
685
685
  return n;
686
- }, bt = (e, t) => {
686
+ }, Ct = (e, t) => {
687
687
  if (t !== "postgres") return "";
688
688
  let n = /* @__PURE__ */ new Map();
689
689
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -699,45 +699,45 @@ $$ LANGUAGE plpgsql;
699
699
  r.push(`DO $$ BEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${e.replace(/'/g, "''")}') THEN\n CREATE TYPE "${e}" AS ENUM (${n});\n END IF;\nEND $$;`);
700
700
  }
701
701
  return r.join("\n\n");
702
- }, xt = (e, t) => {
702
+ }, wt = (e, t) => {
703
703
  if (t !== "postgres") return "";
704
- let n = /* @__PURE__ */ new Set();
705
- for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
706
- let r = [];
707
- for (let e of n) for (let { from: t, to: n } of b(e)) {
708
- let i = e.replace(/'/g, "''"), a = t.replace(/'/g, "''"), o = n.replace(/'/g, "''");
709
- r.push(`DO \$\$
704
+ let r = /* @__PURE__ */ new Set();
705
+ for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && r.add(e.enumName);
706
+ let i = [];
707
+ for (let e of r) for (let { from: t, to: r } of n(e)) {
708
+ let n = e.replace(/'/g, "''"), a = t.replace(/'/g, "''"), o = r.replace(/'/g, "''");
709
+ i.push(`DO \$\$
710
710
  DECLARE
711
711
  type_oid oid;
712
712
  BEGIN
713
- SELECT oid INTO type_oid FROM pg_type WHERE typname = '${i}';\n IF type_oid IS NOT NULL\n AND EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${a}')\n AND NOT EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${o}') THEN\n IF current_setting('server_version_num')::int >= 140000 THEN\n EXECUTE format('ALTER TYPE %I RENAME VALUE %L TO %L', '${i}', '${a}', '${o}');\n ELSE\n UPDATE pg_enum SET enumlabel = '${o}' WHERE enumtypid = type_oid AND enumlabel = '${a}';\n END IF;\n END IF;\nEND $$;`);
713
+ 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 $$;`);
714
714
  }
715
- return r.join("\n\n");
716
- }, St = (e) => {
715
+ return i.join("\n\n");
716
+ }, Tt = (e) => {
717
717
  let t = [], n = [];
718
- for (let r of e) u(r) ? n.push(r) : t.push(r);
718
+ for (let r of e) s(r) ? n.push(r) : t.push(r);
719
719
  return {
720
720
  tables: t,
721
721
  views: n
722
722
  };
723
- }, Ct = (e, t, n = A) => {
724
- let { tables: r, views: i } = St(e), { sorted: a, cyclic: o } = _t(r.map((e) => ue(e, t))), s = yt(o, t), c = [];
725
- t === "postgres" && ht(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && gt(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
726
- let u = xt(a, t);
727
- u && c.push(u);
728
- let d = bt(a, t);
729
- d && c.push(d);
730
- for (let e of a) c.push(st(e, t, null, s.get(e.tableName)));
731
- if (!l(t)) for (let e of o) c.push(vt(e, t));
732
- for (let e of a) {
733
- let n = lt(e, t);
734
- n && c.push(n);
735
- }
736
- c.push(...ut(a, t, n));
737
- for (let e of i) c.push(x(e, t));
738
- return c.join("\n\n") + "\n";
739
- }, wt = (e, t, n) => {
740
- let r = _(e, t);
723
+ }, Et = (t, n, r = k) => {
724
+ let { tables: i, views: a } = Tt(t), { sorted: o, cyclic: s } = bt(i.map((e) => fe(e, n))), c = St(s, n), l = [];
725
+ n === "postgres" && vt(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && yt(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
726
+ let u = wt(o, n);
727
+ u && l.push(u);
728
+ let d = Ct(o, n);
729
+ d && l.push(d);
730
+ for (let e of o) l.push(ut(e, n, null, c.get(e.tableName)));
731
+ if (!m(n)) for (let e of s) l.push(xt(e, n));
732
+ for (let e of o) {
733
+ let t = ft(e, n);
734
+ t && l.push(t);
735
+ }
736
+ l.push(...pt(o, n, r));
737
+ for (let t of a) l.push(e(t, n));
738
+ return l.join("\n\n") + "\n";
739
+ }, Dt = (e, t, n) => {
740
+ let r = o(e, t);
741
741
  switch (t) {
742
742
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
743
743
  case "mysql":
@@ -746,62 +746,62 @@ BEGIN
746
746
  case "turso":
747
747
  case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
748
748
  }
749
- }, Tt = (e, t, n, r) => {
750
- let i = wt(n, t, r), a = _(n, t);
751
- if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Ct(e, t)}`;
752
- if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Ct(e, t)}`;
753
- let { sorted: o, cyclic: s } = _t(e), c = yt(s, t), u = [i];
754
- for (let e of o) u.push(st(e, t, n, c.get(e.tableName)));
755
- if (!l(t)) for (let e of s) u.push(vt(e, t, n));
756
- for (let e of o) {
757
- let r = lt(e, t, n);
749
+ }, Ot = (e, t, n, r) => {
750
+ let i = Dt(n, t, r), a = o(n, t);
751
+ if (t === "postgres") return `${i}\n\nSET search_path TO ${a};\n\n${Et(e, t)}`;
752
+ if (t === "mysql" || t === "mariadb") return `${i}\n\nUSE ${a};\n\n${Et(e, t)}`;
753
+ let { sorted: s, cyclic: c } = bt(e), l = St(c, t), u = [i];
754
+ for (let e of s) u.push(ut(e, t, n, l.get(e.tableName)));
755
+ if (!m(t)) for (let e of c) u.push(xt(e, t, n));
756
+ for (let e of s) {
757
+ let r = ft(e, t, n);
758
758
  r && u.push(r);
759
759
  }
760
760
  return u.join("\n\n") + "\n";
761
- }, Et = (e, t, n = A) => {
762
- let { sorted: r, cyclic: i } = _t(e), a = yt(i, t), o = [], s = xt(r, t);
761
+ }, kt = (e, t, n = k) => {
762
+ let { sorted: r, cyclic: i } = bt(e), a = St(i, t), o = [], s = wt(r, t);
763
763
  s && o.push(s);
764
- let c = bt(r, t);
764
+ let c = Ct(r, t);
765
765
  c && o.push(c);
766
- for (let e of r) o.push(st(e, t, null, a.get(e.tableName)));
767
- for (let e of i) o.push(vt(e, t));
768
- return o.push(...ut(r, t, n)), o.join("\n\n") + "\n";
769
- }, Dt = (e, t = "postgres", n = A, r = {}) => S.gen(function* () {
766
+ for (let e of r) o.push(ut(e, t, null, a.get(e.tableName)));
767
+ for (let e of i) o.push(xt(e, t));
768
+ return o.push(...pt(r, t, n)), o.join("\n\n") + "\n";
769
+ }, At = (e, t = "postgres", n = k, r = {}) => C.gen(function* () {
770
770
  let i = yield* T.SqlClient;
771
- yield* Me(i, Pt(i, Ct(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
772
- }), Ot = (e, t) => {
771
+ yield* Fe(i, Lt(i, Et(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(C.orDie);
772
+ }), jt = (e, t) => {
773
773
  let n = t.cause ?? {};
774
774
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
775
- }, kt = (e, t) => {
775
+ }, Mt = (e, t) => {
776
776
  let n = e.trimStart();
777
777
  return !!(/\bIF NOT EXISTS\b/i.test(n) || /^CREATE OR REPLACE\b/i.test(n) || /^DROP\s[\s\S]*?\bIF EXISTS\b/i.test(n) || /^SET search_path\b/i.test(n) || /^USE[\s`"[]/i.test(n) || /^IF\s/i.test(n) || (t === "mysql" || t === "mariadb") && /^CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(n));
778
- }, At = () => {
778
+ }, Nt = () => {
779
779
  let e = Number(process.env.VOLTRO_MIGRATION_DDL_RETRIES);
780
780
  return Number.isInteger(e) && e >= 0 ? e : 4;
781
- }, jt = (e) => ({
781
+ }, Pt = (e) => ({
782
782
  while: e,
783
- times: At(),
784
- schedule: C.jittered(C.exponential("50 millis"))
785
- }), Mt = class {
783
+ times: Nt(),
784
+ schedule: w.jittered(w.exponential("50 millis"))
785
+ }), Ft = class {
786
786
  statement;
787
787
  error;
788
788
  _tag = "DdlStatementFailed";
789
789
  constructor(e, t) {
790
790
  this.statement = e, this.error = t;
791
791
  }
792
- }, Nt = (e, t, n) => S.gen(function* () {
793
- let r = yield* T.SqlClient, i = n !== void 0 && Fe(t) === "per-operation";
794
- for (let a of Ft(e)) {
795
- process.env.VOLTRO_MIGRATE_DEBUG === "1" && Qe.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
796
- let e = r.unsafe(a).pipe(S.catchIf((e) => Ot(a, e), () => S.succeed([])), S.tapError((e) => S.sync(() => {
797
- Qe.error(ie("migrate: statement failed", a, e, 200));
792
+ }, It = (e, t, n) => C.gen(function* () {
793
+ let r = yield* T.SqlClient, i = n !== void 0 && Re(t) === "per-operation";
794
+ for (let a of Rt(e)) {
795
+ process.env.VOLTRO_MIGRATE_DEBUG === "1" && tt.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
796
+ let e = r.unsafe(a).pipe(C.catchIf((e) => jt(a, e), () => C.succeed([])), C.tapError((e) => C.sync(() => {
797
+ tt.error(oe("migrate: statement failed", a, e, 200));
798
798
  })));
799
- yield* (i && n !== void 0 && kt(a, t) ? e.pipe(S.retry(jt((e) => n(e) === "retry"))) : e).pipe(S.mapError((e) => new Mt(a, e)));
799
+ yield* (i && n !== void 0 && Mt(a, t) ? e.pipe(C.retry(Pt((e) => n(e) === "retry"))) : e).pipe(C.mapError((e) => new Ft(a, e)));
800
800
  }
801
- }), Pt = (e, t, n, r) => {
802
- let i = n === "turso" ? Nt(t, n, r) : e.withTransaction(Nt(t, n, r)), a = (e) => e instanceof Mt ? e.error : e;
803
- return (r !== void 0 && Fe(n) === "plan-transactional" ? i.pipe(S.retry(jt((e) => r(a(e)) === "retry"))) : i).pipe(S.orDieWith((e) => e instanceof Mt ? Error(ie("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
804
- }, Ft = (e) => {
801
+ }), Lt = (e, t, n, r) => {
802
+ let i = n === "turso" ? It(t, n, r) : e.withTransaction(It(t, n, r)), a = (e) => e instanceof Ft ? e.error : e;
803
+ return (r !== void 0 && Re(n) === "plan-transactional" ? i.pipe(C.retry(Pt((e) => r(a(e)) === "retry"))) : i).pipe(C.orDieWith((e) => e instanceof Ft ? Error(oe("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
804
+ }, Rt = (e) => {
805
805
  let t = [], n = "", r = !1;
806
806
  for (let i = 0; i < e.length; i++) {
807
807
  if (e.slice(i, i + 2) === "$$") {
@@ -816,43 +816,43 @@ BEGIN
816
816
  }
817
817
  let i = n.trim();
818
818
  return i.length > 0 && t.push(i), t;
819
- }, It = async (e, t, n = "postgres", r = {}) => {
820
- await S.runPromise(Dt(e, n, void 0, r).pipe(S.provide(t)));
821
- }, Lt = (e, t, n = "postgres", r = {}) => S.gen(function* () {
822
- let i = Tt(e, n, t), a = yield* T.SqlClient;
823
- yield* Me(a, Pt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
824
- }), Rt = async (e, t, n, r = "postgres", i = {}) => {
825
- await S.runPromise(Lt(e, t, r, i).pipe(S.provide(n))), await s({
819
+ }, zt = async (e, t, n = "postgres", r = {}) => {
820
+ await C.runPromise(At(e, n, void 0, r).pipe(C.provide(t)));
821
+ }, Bt = (e, t, n = "postgres", r = {}) => C.gen(function* () {
822
+ let i = Ot(e, n, t), a = yield* T.SqlClient;
823
+ yield* Fe(a, Lt(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(C.orDie);
824
+ }), Vt = async (e, t, n, r = "postgres", i = {}) => {
825
+ await C.runPromise(Bt(e, t, r, i).pipe(C.provide(n))), await f({
826
826
  namespace: t,
827
827
  dialect: r
828
828
  });
829
- }, zt = async (e, t, n = "postgres", r = {}) => {
830
- await S.runPromise(S.gen(function* () {
831
- let t = Et(e, n), i = yield* T.SqlClient;
832
- yield* Me(i, Pt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(S.orDie);
833
- }).pipe(S.provide(t)));
834
- }, Bt = (e) => {
829
+ }, Ht = async (e, t, n = "postgres", r = {}) => {
830
+ await C.runPromise(C.gen(function* () {
831
+ let t = kt(e, n), i = yield* T.SqlClient;
832
+ yield* Fe(i, Lt(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(C.orDie);
833
+ }).pipe(C.provide(t)));
834
+ }, Ut = (e) => {
835
835
  if (e == null) return e;
836
- if (Array.isArray(e)) return e.map(Bt);
836
+ if (Array.isArray(e)) return e.map(Ut);
837
837
  if (typeof e != "object") return e;
838
838
  let t = {};
839
839
  for (let n of Object.keys(e).sort()) {
840
840
  let r = e[n];
841
- r !== void 0 && (t[n] = Bt(r));
841
+ r !== void 0 && (t[n] = Ut(r));
842
842
  }
843
843
  return t;
844
- }, Vt = (e) => {
844
+ }, Wt = (e) => {
845
845
  if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs) return e;
846
846
  let { idScheme: t, sensitive: n, safe: r, generatedAs: i, ...a } = e;
847
847
  return a;
848
- }, Ht = (e) => [...e].map(Vt).sort((e, t) => e.name.localeCompare(t.name)), Ut = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), Wt = (e) => [...e].map((e) => ({
848
+ }, Gt = (e) => [...e].map(Wt).sort((e, t) => e.name.localeCompare(t.name)), Kt = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), qt = (e) => [...e].map((e) => ({
849
849
  name: e.name,
850
- columns: Ht(e.columns),
851
- indexes: Ut(e.indexes)
852
- })).sort((e, t) => e.name.localeCompare(t.name)), Gt = (e) => {
853
- let t = { tables: Wt(e.tables) }, n = JSON.stringify(Bt(t));
854
- return ee("sha256").update(n).digest("hex");
855
- }, Kt = (e) => e.slice(0, 16), qt = (e, t) => {
850
+ columns: Gt(e.columns),
851
+ indexes: Kt(e.indexes)
852
+ })).sort((e, t) => e.name.localeCompare(t.name)), Jt = (e) => {
853
+ let t = { tables: qt(e.tables) }, n = JSON.stringify(Ut(t));
854
+ return te("sha256").update(n).digest("hex");
855
+ }, Yt = (e) => e.slice(0, 16), Xt = (e, t) => {
856
856
  let n = t.references ? {
857
857
  table: t.references().tableName,
858
858
  column: "id",
@@ -891,59 +891,59 @@ BEGIN
891
891
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
892
892
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
893
893
  };
894
- }, Jt = (e) => {
895
- let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
894
+ }, Zt = (e) => {
895
+ let t = [], n = /* @__PURE__ */ new Set(), i = (e) => {
896
896
  n.has(e.name) || (n.add(e.name), t.push(e));
897
- }, i = e.appliedPrimaryKey ?? [];
898
- i.length > 0 ? r({
897
+ }, a = e.appliedPrimaryKey ?? [];
898
+ a.length > 0 ? i({
899
899
  name: `${e.tableName}_pkey`,
900
900
  table: e.tableName,
901
- columns: [...i],
901
+ columns: [...a],
902
902
  unique: !0
903
- }) : e.fields.id && r({
903
+ }) : e.fields.id && i({
904
904
  name: `${e.tableName}_pkey`,
905
905
  table: e.tableName,
906
906
  columns: ["id"],
907
907
  unique: !0
908
908
  });
909
- let a = e.appliedIndexes ?? [];
910
- for (let t of a) {
909
+ let o = e.appliedIndexes ?? [];
910
+ for (let t of o) {
911
911
  if (t.unique && t.where) continue;
912
- let n = t.fields.map((e) => typeof e == "string" ? e : "jsonPath" in e ? `(json:${e.jsonPath.column}->${e.jsonPath.path.join(".")}${e.jsonPath.numeric ? "::num" : ""})` : `(${e.expr})`), i = t.fields.some((e) => typeof e != "string");
913
- r({
912
+ let n = t.fields.map((e) => typeof e == "string" ? e : "jsonPath" in e ? `(json:${e.jsonPath.column}->${e.jsonPath.path.join(".")}${e.jsonPath.numeric ? "::num" : ""})` : `(${e.expr})`), r = t.fields.some((e) => typeof e != "string");
913
+ i({
914
914
  name: t.name,
915
915
  table: e.tableName,
916
916
  columns: n,
917
917
  unique: !1,
918
- ...i ? { expression: !0 } : {}
918
+ ...r ? { expression: !0 } : {}
919
919
  });
920
920
  }
921
- let o = e.appliedUniques ?? [];
922
- for (let t of o) t.fields.length < 2 || r({
921
+ let s = e.appliedUniques ?? [];
922
+ for (let t of s) t.fields.length < 2 || i({
923
923
  name: t.name,
924
924
  table: e.tableName,
925
925
  columns: t.fields,
926
926
  unique: !0
927
927
  });
928
- let s = /* @__PURE__ */ new Set();
929
- for (let e of a) e.fields.every((e) => typeof e == "string") && s.add(e.fields.join("\0"));
928
+ let c = /* @__PURE__ */ new Set();
929
+ for (let e of o) e.fields.every((e) => typeof e == "string") && c.add(e.fields.join("\0"));
930
930
  for (let [t, n] of Object.entries(e.fields)) {
931
- let i = n;
932
- if (i.dropped || !i.references || i.fkAutoIndex === !1 || s.has(t)) continue;
933
- let a = `${e.tableName}_${t}_idx`;
934
- y(e.tableName, a, !0, [t]), r({
935
- name: a,
931
+ let a = n;
932
+ if (a.dropped || !a.references || a.fkAutoIndex === !1 || c.has(t)) continue;
933
+ let o = `${e.tableName}_${t}_idx`;
934
+ r(e.tableName, o, !0, [t]), i({
935
+ name: o,
936
936
  table: e.tableName,
937
937
  columns: [t],
938
938
  unique: !1
939
939
  });
940
940
  }
941
941
  return t;
942
- }, Yt = (e) => {
942
+ }, Qt = (e) => {
943
943
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
944
944
  for (let [r, i] of Object.entries(e.fields)) {
945
945
  if (i.dropped) continue;
946
- let e = qt(r, i);
946
+ let e = Xt(r, i);
947
947
  n.push(t.has(r) ? {
948
948
  ...e,
949
949
  unique: !0
@@ -953,27 +953,27 @@ BEGIN
953
953
  return {
954
954
  name: e.tableName,
955
955
  columns: n,
956
- indexes: Jt(e),
956
+ indexes: Zt(e),
957
957
  ...r.length > 0 ? { primaryKey: [...r] } : {},
958
958
  ...i === void 0 ? {} : { renamedFrom: i }
959
959
  };
960
- }, Xt = (e) => {
960
+ }, $t = (e) => {
961
961
  let t = /* @__PURE__ */ new Map();
962
962
  for (let n of e) for (let e of n.indexes) {
963
963
  let r = t.get(e.name);
964
964
  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}').`);
965
965
  t.set(e.name, n.name);
966
966
  }
967
- }, I = (e, t) => {
968
- let n = e.filter((e) => !i(e.tableName)).map((e) => Yt(ue(e, t)));
969
- return Xt(n), { tables: n };
970
- }, Zt = (e, t, n = A) => S.gen(function* () {
967
+ }, F = (e, t) => {
968
+ let n = e.filter((e) => !c(e.tableName)).map((e) => Qt(fe(e, t)));
969
+ return $t(n), { tables: n };
970
+ }, en = (e, t, n = k) => C.gen(function* () {
971
971
  let r = (yield* e`
972
972
  SELECT p.prosrc
973
973
  FROM pg_proc p
974
974
  JOIN pg_namespace n ON n.oid = p.pronamespace
975
975
  WHERE n.nspname = current_schema()
976
- AND p.proname = ${Ye(n)}
976
+ AND p.proname = ${Qe(n)}
977
977
  `)[0]?.prosrc, i = r !== void 0 && !r.includes("voltro:notify:v2"), a = t.filter((e) => !e.tableName.startsWith("_voltro_"));
978
978
  if (a.length === 0) return {
979
979
  missing: [],
@@ -987,10 +987,10 @@ BEGIN
987
987
  JOIN pg_namespace n ON n.oid = c.relnamespace
988
988
  WHERE NOT t.tgisinternal
989
989
  AND n.nspname = current_schema()
990
- AND t.tgname LIKE ${`${qe}%`}
990
+ AND t.tgname LIKE ${`${Xe}%`}
991
991
  `, s = new Set(o.map((e) => e.tgname)), c = [], l = [];
992
992
  for (let e of a) {
993
- let t = s.has(Je(e.tableName, n)), r = e.isReactive !== !1;
993
+ let t = s.has(Ze(e.tableName, n)), r = e.isReactive !== !1;
994
994
  r && !t && c.push(e.tableName), !r && t && l.push(e.tableName);
995
995
  }
996
996
  return {
@@ -998,7 +998,7 @@ BEGIN
998
998
  stale: l.sort(),
999
999
  functionOutdated: i
1000
1000
  };
1001
- }), Qt = (e) => {
1001
+ }), tn = (e) => {
1002
1002
  let t = [];
1003
1003
  if (e.missing.length > 0) {
1004
1004
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -1009,19 +1009,19 @@ BEGIN
1009
1009
  t.push(`${e.stale.length} .nonReactive() table(s) still carry a change trigger — ${n}. They keep paying REPLICA IDENTITY FULL and a NOTIFY on every write for a subscription nobody receives. \`voltro db apply\` removes them.`);
1010
1010
  }
1011
1011
  return e.functionOutdated && t.push("The change-notify function in this database is OLDER than the framework installed here. Its triggers fire, so nothing looks wrong — but a row too large for a NOTIFY payload (postgres caps it at 8000 bytes) is emitted without its primary key, and a change that carries no key cannot be re-read: it reaches subscriptions as a re-query and reaches every TAP — search index, analytics mirror, cdc-out, row history — as nothing at all. Run `voltro db apply` to replace it."), t.length > 0 ? t.join("\n") : void 0;
1012
- }, $t = {
1012
+ }, nn = {
1013
1013
  postgres: !0,
1014
1014
  mysql: !0,
1015
1015
  mariadb: !0,
1016
1016
  mssql: !0,
1017
1017
  sqlite: !0
1018
- }, en = {
1018
+ }, rn = {
1019
1019
  postgres: !0,
1020
1020
  mysql: !1,
1021
1021
  mariadb: !1,
1022
1022
  mssql: !0,
1023
1023
  sqlite: !0
1024
- }, tn = (e) => {
1024
+ }, an = (e) => {
1025
1025
  switch (e) {
1026
1026
  case "add-column":
1027
1027
  case "drop-column":
@@ -1031,47 +1031,47 @@ BEGIN
1031
1031
  case "add-foreign-key":
1032
1032
  case "add-unique":
1033
1033
  case "add-unique-composite":
1034
- case "add-check": return en;
1035
- default: return $t;
1034
+ case "add-check": return rn;
1035
+ default: return nn;
1036
1036
  }
1037
- }, nn = (e, t) => {
1037
+ }, on = (e, t) => {
1038
1038
  let n = new Map(t.tables.map((e) => [e.name, e]));
1039
1039
  return new Map(e.map((e) => [e.tableName, {
1040
1040
  table: e,
1041
1041
  snapshot: n.get(e.tableName),
1042
1042
  columnDefs: e.fields
1043
1043
  }]));
1044
- }, L = (e) => {
1044
+ }, I = (e) => {
1045
1045
  if (typeof e != "object" || !e) return JSON.stringify(e);
1046
- if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1046
+ if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
1047
1047
  let t = e;
1048
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1049
- }, rn = (e) => {
1048
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
1049
+ }, sn = (e) => {
1050
1050
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1051
1051
  let t = e.defaultValue;
1052
1052
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1053
1053
  if (typeof t == "number") return String(t);
1054
- if (typeof t != "string") return L(t);
1054
+ if (typeof t != "string") return I(t);
1055
1055
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1056
1056
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1057
1057
  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);
1058
1058
  if (o) try {
1059
- return L(JSON.parse(o[1]));
1059
+ return I(JSON.parse(o[1]));
1060
1060
  } catch {}
1061
1061
  let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1062
1062
  if (s) try {
1063
- return L(JSON.parse(s[1]));
1063
+ return I(JSON.parse(s[1]));
1064
1064
  } catch {}
1065
1065
  if (a.startsWith("{") || a.startsWith("[")) try {
1066
- return L(JSON.parse(a));
1066
+ return I(JSON.parse(a));
1067
1067
  } catch {}
1068
1068
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1069
- }, an = (e, t) => {
1070
- let n = rn(e), r = rn(t);
1069
+ }, cn = (e, t) => {
1070
+ let n = sn(e), r = sn(t);
1071
1071
  if (n === r) return !0;
1072
1072
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1073
1073
  return i(n) === i(r);
1074
- }, on = (e) => {
1074
+ }, ln = (e) => {
1075
1075
  if (!e) return null;
1076
1076
  let t = (e) => e === "restrict" ? "noAction" : e;
1077
1077
  return {
@@ -1080,29 +1080,29 @@ BEGIN
1080
1080
  onDelete: t(e.onDelete),
1081
1081
  onUpdate: t(e.onUpdate)
1082
1082
  };
1083
- }, sn = (e, t) => {
1083
+ }, un = (e, t) => {
1084
1084
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1085
1085
  if (!n && !r) return !0;
1086
1086
  if (!n || !r || n.length !== r.length) return !1;
1087
1087
  let i = [...n].sort(), a = [...r].sort();
1088
1088
  return i.every((e, t) => e === a[t]);
1089
- }, cn = (e, t, n) => {
1089
+ }, dn = (e, t, n) => {
1090
1090
  if (t === "mssql") {
1091
- let t = Ze(e, n);
1091
+ let t = et(e, n);
1092
1092
  if (t !== void 0) return t;
1093
1093
  }
1094
1094
  try {
1095
- let n = /\((\d+)\)/.exec(M(e, t));
1095
+ let n = /\((\d+)\)/.exec(j(e, t));
1096
1096
  return n ? Number(n[1]) : void 0;
1097
1097
  } catch {
1098
1098
  return;
1099
1099
  }
1100
- }, ln = (e, t, n, r) => n === void 0 || l(n) ? !0 : e.type !== "text" || t.type !== "text" || cn(e, n, r) === t.maxLength, un = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && an(e, t) && ln(e, t, n, r) && JSON.stringify(on(e.references)) === JSON.stringify(on(t.references)) && sn(e.oneOf, t.oneOf), dn = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1100
+ }, fn = (e, t, n, r) => n === void 0 || m(n) ? !0 : e.type !== "text" || t.type !== "text" || dn(e, n, r) === t.maxLength, pn = (e, t, n, r) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && cn(e, t) && fn(e, t, n, r) && JSON.stringify(ln(e.references)) === JSON.stringify(ln(t.references)) && un(e.oneOf, t.oneOf), mn = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1101
1101
  kind: "add-check",
1102
1102
  table: e,
1103
1103
  column: t.name,
1104
1104
  values: t.oneOf
1105
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, fn = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), pn = (e, t, n) => {
1105
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, hn = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), gn = (e, t, n) => {
1106
1106
  let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [], c = new Set(e.indexes.flatMap((e) => e.columns));
1107
1107
  for (let t of e.columns) {
1108
1108
  let e = r.get(t.name);
@@ -1110,7 +1110,7 @@ BEGIN
1110
1110
  a.push(t);
1111
1111
  continue;
1112
1112
  }
1113
- un(t, e, n, c.has(t.name) || t.unique) || s.push({
1113
+ pn(t, e, n, c.has(t.name) || t.unique) || s.push({
1114
1114
  declared: t,
1115
1115
  live: e
1116
1116
  });
@@ -1121,47 +1121,47 @@ BEGIN
1121
1121
  removed: o,
1122
1122
  changed: s
1123
1123
  };
1124
- }, mn = (e, t, n) => {
1124
+ }, _n = (e, t, n) => {
1125
1125
  let r = (e) => n === "turso" || n === "sqlite" ? e.toLowerCase() : e, i = new Map(t.indexes.map((e) => [r(e.name), e])), a = new Map(e.indexes.map((e) => [r(e.name), e])), o = [], s = [];
1126
1126
  for (let t of e.indexes) {
1127
1127
  let e = i.get(r(t.name));
1128
- (!e || !fn(t, e)) && o.push(t);
1128
+ (!e || !hn(t, e)) && o.push(t);
1129
1129
  }
1130
1130
  for (let e of t.indexes) a.has(r(e.name)) || s.push(e);
1131
1131
  return {
1132
1132
  added: o,
1133
1133
  removed: s
1134
1134
  };
1135
- }, R = (e, t, n, r) => ({
1135
+ }, L = (e, t, n, r) => ({
1136
1136
  op: e,
1137
1137
  classification: t,
1138
- atomicByDialect: tn(e.kind),
1138
+ atomicByDialect: an(e.kind),
1139
1139
  ...n ? { reason: n } : {},
1140
1140
  ...r ? { blocked: r } : {}
1141
- }), hn = (e, t, n) => {
1141
+ }), vn = (e, t, n) => {
1142
1142
  let r = {
1143
1143
  kind: "add-column",
1144
1144
  table: e,
1145
1145
  column: t
1146
1146
  };
1147
- return t.nullable ? R(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? R(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? R(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : R(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1148
- }, gn = (e, t, n) => {
1147
+ 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` });
1148
+ }, yn = (e, t, n) => {
1149
1149
  let r = {
1150
1150
  kind: "drop-column",
1151
1151
  table: e,
1152
1152
  column: t.name
1153
1153
  };
1154
- return n?.dropped ? R(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : R(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1155
- }, _n = (e, t, n, r, i) => R({
1154
+ 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` });
1155
+ }, bn = (e, t, n, r, i) => L({
1156
1156
  kind: "create-table",
1157
1157
  table: e,
1158
1158
  columns: t,
1159
1159
  indexes: n,
1160
1160
  ...r && r.length > 0 ? { primaryKey: r } : {}
1161
- }, "safe", i ?? "new table — no data to preserve"), vn = (e) => R({
1161
+ }, "safe", i ?? "new table — no data to preserve"), xn = (e) => L({
1162
1162
  kind: "drop-table",
1163
1163
  table: e
1164
- }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), yn = 5e4, bn = (e, t, n, r) => {
1164
+ }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), Sn = 5e4, Cn = (e, t, n, r) => {
1165
1165
  let i = (n ?? 0) >= r, a;
1166
1166
  return a = t.unique ? t.columns.length === 1 ? {
1167
1167
  kind: "add-unique",
@@ -1176,16 +1176,16 @@ BEGIN
1176
1176
  kind: "add-index",
1177
1177
  table: e,
1178
1178
  index: t
1179
- }, i ? R(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1180
- }, xn = (e, t) => t.unique && t.columns.length > 1 ? R({
1179
+ }, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1180
+ }, wn = (e, t) => t.unique && t.columns.length > 1 ? L({
1181
1181
  kind: "drop-unique-composite",
1182
1182
  table: e,
1183
1183
  name: t.name
1184
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
1184
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
1185
1185
  kind: "drop-index",
1186
1186
  table: e,
1187
1187
  index: t.name
1188
- }, "safe", "drop index (no data loss — index is derived data)"), Sn = (e, t) => {
1188
+ }, "safe", "drop index (no data loss — index is derived data)"), Tn = (e, t) => {
1189
1189
  if (e === "reference") return "text";
1190
1190
  switch (t) {
1191
1191
  case "sqlite":
@@ -1193,10 +1193,10 @@ BEGIN
1193
1193
  case "mssql": return e === "json" ? "text" : e;
1194
1194
  default: return e;
1195
1195
  }
1196
- }, Cn = (e, t, n) => {
1196
+ }, En = (e, t, n) => {
1197
1197
  let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
1198
1198
  return n === "postgres" ? `${r} — add \`{ using: '${t.name}::${t.type}' }\` when the cast is not implicit, or use a file-based migration` : `${r} — ${n === void 0 ? "this dialect" : n} converts in place (\`using\` is postgres-only and is ignored here), so verify the conversion is value-preserving for your data, or use a file-based migration`;
1199
- }, wn = (e, t, n, r, i, a) => {
1199
+ }, Dn = (e, t, n, r, i, a) => {
1200
1200
  let o = [];
1201
1201
  if (t.nullable !== n.nullable) {
1202
1202
  let n = {
@@ -1205,7 +1205,7 @@ BEGIN
1205
1205
  column: t.name,
1206
1206
  toNullable: t.nullable
1207
1207
  };
1208
- 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`));
1208
+ 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`));
1209
1209
  }
1210
1210
  if (t.unique !== n.unique) {
1211
1211
  if (t.unique) {
@@ -1214,14 +1214,14 @@ BEGIN
1214
1214
  table: e,
1215
1215
  column: t.name
1216
1216
  }, r = (i ?? 0) >= a;
1217
- 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)`));
1218
- } else o.push(R({
1217
+ 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)`));
1218
+ } else o.push(L({
1219
1219
  kind: "drop-unique",
1220
1220
  table: e,
1221
1221
  column: t.name
1222
1222
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1223
1223
  }
1224
- if (Sn(t.type, r) !== Sn(n.type, r)) {
1224
+ if (Tn(t.type, r) !== Tn(n.type, r)) {
1225
1225
  let i = t.narrowedFrom;
1226
1226
  if (i && i.from === n.type) {
1227
1227
  let r = {
@@ -1232,7 +1232,7 @@ BEGIN
1232
1232
  to: t.type,
1233
1233
  ...i.using === void 0 ? {} : { using: i.using }
1234
1234
  };
1235
- 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)")));
1235
+ 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)")));
1236
1236
  } else {
1237
1237
  let i = {
1238
1238
  kind: "alter-column-type",
@@ -1241,12 +1241,12 @@ BEGIN
1241
1241
  from: n.type,
1242
1242
  to: t.type
1243
1243
  };
1244
- o.push(R(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: Cn(n.type, t, r) }));
1244
+ o.push(L(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: En(n.type, t, r) }));
1245
1245
  }
1246
1246
  }
1247
- if (t.type === "text" && n.type === "text" && !l(r ?? "postgres") && t.maxLength !== n.maxLength) {
1247
+ if (t.type === "text" && n.type === "text" && !m(r ?? "postgres") && t.maxLength !== n.maxLength) {
1248
1248
  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})`;
1249
- o.push(R({
1249
+ o.push(L({
1250
1250
  kind: "alter-column-type",
1251
1251
  table: e,
1252
1252
  column: t.name,
@@ -1254,7 +1254,7 @@ BEGIN
1254
1254
  to: "text"
1255
1255
  }, r ? "safe" : "needs-backfill", r ? `text length ${i} → ${a} on ${e}.${t.name} — widening, no data can be lost` : `text length ${i} → ${a} on ${e}.${t.name} — NARROWING; the ALTER fails if any existing value is longer than ${String(t.maxLength)}. Check first: SELECT COUNT(*) FROM ${e} WHERE LENGTH(${t.name}) > ${String(t.maxLength)}`));
1256
1256
  }
1257
- if (!an(t, n)) {
1257
+ if (!cn(t, n)) {
1258
1258
  let n = {
1259
1259
  kind: "alter-column-default",
1260
1260
  table: e,
@@ -1262,23 +1262,23 @@ BEGIN
1262
1262
  hasDefault: t.hasDefault,
1263
1263
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1264
1264
  };
1265
- o.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1265
+ o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1266
1266
  }
1267
- if (!sn(t.oneOf, n.oneOf)) {
1268
- n.oneOf && n.oneOf.length > 0 && o.push(R({
1267
+ if (!un(t.oneOf, n.oneOf)) {
1268
+ n.oneOf && n.oneOf.length > 0 && o.push(L({
1269
1269
  kind: "drop-check",
1270
1270
  table: e,
1271
1271
  column: t.name
1272
1272
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1273
- let r = dn(e, t);
1273
+ let r = mn(e, t);
1274
1274
  r && o.push(r);
1275
1275
  }
1276
- return JSON.stringify(on(t.references)) !== JSON.stringify(on(n.references)) && (n.references && o.push(R({
1276
+ return JSON.stringify(ln(t.references)) !== JSON.stringify(ln(n.references)) && (n.references && o.push(L({
1277
1277
  kind: "drop-foreign-key",
1278
1278
  table: e,
1279
1279
  column: t.name
1280
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Tn(e, t))), o;
1281
- }, Tn = (e, t) => {
1280
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...On(e, t))), o;
1281
+ }, On = (e, t) => {
1282
1282
  let n = [];
1283
1283
  if (!t.references) return n;
1284
1284
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1290,15 +1290,15 @@ BEGIN
1290
1290
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1291
1291
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1292
1292
  };
1293
- 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({
1293
+ 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({
1294
1294
  ...a,
1295
1295
  orphanPolicy: i
1296
- }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(R(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1297
- }, En = (e, t, n) => {
1296
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(L(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1297
+ }, kn = (e, t, n) => {
1298
1298
  let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = new Set(n.removed.map((e) => e.name)), s = new Set(n.added.map((e) => e.name));
1299
1299
  for (let [n, c] of Object.entries(t)) {
1300
1300
  let t = c.renamedFrom;
1301
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1301
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1302
1302
  kind: "rename-column",
1303
1303
  table: e.tableName,
1304
1304
  from: t,
@@ -1310,26 +1310,26 @@ BEGIN
1310
1310
  consumedAddedNames: i,
1311
1311
  consumedRemovedNames: a
1312
1312
  };
1313
- }, Dn = /* @__PURE__ */ new Set([
1313
+ }, An = /* @__PURE__ */ new Set([
1314
1314
  "postgres",
1315
1315
  "mysql",
1316
1316
  "mariadb",
1317
1317
  "mssql"
1318
- ]), On = {
1318
+ ]), jn = {
1319
1319
  ops: [],
1320
1320
  consumedAddedNames: /* @__PURE__ */ new Set(),
1321
1321
  consumedRemovedNames: /* @__PURE__ */ new Set()
1322
- }, kn = (e) => !e.unique && !e.expression, An = (e, t, n, r, i) => {
1323
- if (i === void 0 || !Dn.has(i)) return On;
1324
- let a = t.added.filter((e) => kn(e) && !r.has(e.name));
1325
- if (a.length === 0) return On;
1322
+ }, Mn = (e) => !e.unique && !e.expression, Nn = (e, t, n, r, i) => {
1323
+ if (i === void 0 || !An.has(i)) return jn;
1324
+ let a = t.added.filter((e) => Mn(e) && !r.has(e.name));
1325
+ if (a.length === 0) return jn;
1326
1326
  let o = (e) => e.columns.map((e) => n.get(e) ?? e).join("\0"), s = (e) => e.columns.join("\0"), c = [], l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Set();
1327
1327
  for (let n of t.removed) {
1328
- if (!kn(n)) continue;
1328
+ if (!Mn(n)) continue;
1329
1329
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1330
1330
  if (r.length !== 1) continue;
1331
1331
  let i = r[0];
1332
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1332
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(L({
1333
1333
  kind: "rename-index",
1334
1334
  table: e,
1335
1335
  from: n.name,
@@ -1341,7 +1341,7 @@ BEGIN
1341
1341
  consumedAddedNames: l,
1342
1342
  consumedRemovedNames: u
1343
1343
  };
1344
- }, jn = (e, t, n) => {
1344
+ }, Pn = (e, t, n) => {
1345
1345
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1346
1346
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1347
1347
  for (let c of e.tables) {
@@ -1352,7 +1352,7 @@ BEGIN
1352
1352
  continue;
1353
1353
  }
1354
1354
  if (t.has(c.name)) {
1355
- r.push(R({
1355
+ r.push(L({
1356
1356
  kind: "rename-table",
1357
1357
  from: e,
1358
1358
  to: c.name
@@ -1360,14 +1360,14 @@ BEGIN
1360
1360
  continue;
1361
1361
  }
1362
1362
  if ((s.get(e) ?? 0) !== 1) {
1363
- r.push(R({
1363
+ r.push(L({
1364
1364
  kind: "rename-table",
1365
1365
  from: e,
1366
1366
  to: c.name
1367
1367
  }, "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.` }));
1368
1368
  continue;
1369
1369
  }
1370
- i.set(c.name, e), a.add(e), r.push(R({
1370
+ i.set(c.name, e), a.add(e), r.push(L({
1371
1371
  kind: "rename-table",
1372
1372
  from: e,
1373
1373
  to: c.name
@@ -1381,19 +1381,19 @@ BEGIN
1381
1381
  claimedOldNames: c,
1382
1382
  refusals: o
1383
1383
  };
1384
- }, Mn = (e, t, n, r) => {
1384
+ }, Fn = (e, t, n, r) => {
1385
1385
  if (t === void 0) return {
1386
1386
  live: e,
1387
1387
  ops: []
1388
1388
  };
1389
- let i = r !== void 0 && Dn.has(r), a = [], o = e.indexes.map((e) => {
1389
+ let i = r !== void 0 && An.has(r), a = [], o = e.indexes.map((e) => {
1390
1390
  if (!e.name.startsWith(t)) return e;
1391
1391
  let r = `${n}${e.name.slice(t.length)}`;
1392
1392
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1393
1393
  ...e,
1394
1394
  name: r,
1395
1395
  table: n
1396
- } : i ? (a.push(R({
1396
+ } : i ? (a.push(L({
1397
1397
  kind: "rename-index",
1398
1398
  table: n,
1399
1399
  from: e.name,
@@ -1412,7 +1412,7 @@ BEGIN
1412
1412
  },
1413
1413
  ops: a
1414
1414
  };
1415
- }, Nn = (e) => {
1415
+ }, In = (e) => {
1416
1416
  let t = {
1417
1417
  safe: 0,
1418
1418
  needsDefault: 0,
@@ -1445,42 +1445,42 @@ BEGIN
1445
1445
  case "multi-step": t.multiStep++;
1446
1446
  }
1447
1447
  return t;
1448
- }, Pn = (e) => {
1449
- let t = I(e.declared, e.dialect), n = nn(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? yn, a = [], o = jn(t, r, n);
1448
+ }, Ln = (e) => {
1449
+ let t = F(e.declared, e.dialect), n = on(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Sn, a = [], o = Pn(t, r, n);
1450
1450
  a.push(...o.ops);
1451
1451
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1452
- a.push(_n(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1452
+ a.push(bn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1453
1453
  for (let t of e.columns) {
1454
- let n = dn(e.name, t);
1454
+ let n = mn(e.name, t);
1455
1455
  n && a.push(n);
1456
1456
  }
1457
1457
  }
1458
1458
  let s = new Set(e.ignoreTables ?? []);
1459
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || h(t.name) || f(t.name) || s.has(t.name) || a.push(vn(t.name));
1459
+ 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(xn(t.name));
1460
1460
  for (let s of t.tables) {
1461
1461
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1462
1462
  if (!c) continue;
1463
- let l = Mn(c, t, s.name, e.dialect);
1463
+ let l = Fn(c, t, s.name, e.dialect);
1464
1464
  a.push(...l.ops);
1465
- let u = l.live, d = n.get(s.name), p = pn(s, u, e.dialect), m = mn(s, u, e.dialect), h = En(d.table, d.columnDefs, p);
1466
- a.push(...h.ops);
1467
- for (let e of p.removed) {
1468
- if (h.consumedRemovedNames.has(e.name) || f(e.name)) continue;
1465
+ let u = l.live, d = n.get(s.name), f = gn(s, u, e.dialect), p = _n(s, u, e.dialect), m = kn(d.table, d.columnDefs, f);
1466
+ a.push(...m.ops);
1467
+ for (let e of f.removed) {
1468
+ if (m.consumedRemovedNames.has(e.name) || x(e.name)) continue;
1469
1469
  let t = d.columnDefs[e.name];
1470
- a.push(gn(s.name, e, t));
1470
+ a.push(yn(s.name, e, t));
1471
1471
  }
1472
- for (let e of p.added) {
1473
- if (h.consumedAddedNames.has(e.name)) continue;
1472
+ for (let e of f.added) {
1473
+ if (m.consumedAddedNames.has(e.name)) continue;
1474
1474
  let t = d.columnDefs[e.name];
1475
- a.push(hn(s.name, e, t));
1476
- let n = dn(s.name, e);
1477
- n && a.push(n), a.push(...Tn(s.name, e));
1475
+ a.push(vn(s.name, e, t));
1476
+ let n = mn(s.name, e);
1477
+ n && a.push(n), a.push(...On(s.name, e));
1478
1478
  }
1479
- let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = An(s.name, m, g, new Set(u.indexes.map((e) => e.name)), e.dialect);
1480
- a.push(..._.ops);
1481
- for (let e of m.added) _.consumedAddedNames.has(e.name) || a.push(bn(s.name, e, u.rowCount, i));
1482
- for (let e of m.removed) _.consumedRemovedNames.has(e.name) || a.push(xn(s.name, e));
1483
- for (let { declared: t, live: n } of p.changed) a.push(...wn(s.name, t, n, e.dialect, u.rowCount, i));
1479
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Nn(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1480
+ a.push(...g.ops);
1481
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(Cn(s.name, e, u.rowCount, i));
1482
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(wn(s.name, e));
1483
+ for (let { declared: t, live: n } of f.changed) a.push(...Dn(s.name, t, n, e.dialect, u.rowCount, i));
1484
1484
  }
1485
1485
  let c = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), l = new Map(t.tables.map((e) => [e.name, e])), u = (e) => {
1486
1486
  let t = l.get(e);
@@ -1488,8 +1488,8 @@ BEGIN
1488
1488
  column: e.name,
1489
1489
  target: e.references.table
1490
1490
  }] : []) : [];
1491
- }, d = de([...c], u), p = [];
1492
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(E(e.name, t.name)) || p.push(R({
1491
+ }, d = pe([...c], u), f = [];
1492
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(E(e.name, t.name)) || f.push(L({
1493
1493
  kind: "add-foreign-key",
1494
1494
  table: e.name,
1495
1495
  column: t.name,
@@ -1514,24 +1514,24 @@ BEGIN
1514
1514
  }
1515
1515
  };
1516
1516
  }
1517
- a.push(...p);
1517
+ a.push(...f);
1518
1518
  }
1519
- let m = new Map(t.tables.map((e) => [e.name, e])), g = /* @__PURE__ */ new Map(), _ = (e, t = /* @__PURE__ */ new Set()) => {
1520
- let n = g.get(e);
1519
+ let p = new Map(t.tables.map((e) => [e.name, e])), m = /* @__PURE__ */ new Map(), h = (e, t = /* @__PURE__ */ new Set()) => {
1520
+ let n = m.get(e);
1521
1521
  if (n !== void 0) return n;
1522
1522
  if (t.has(e)) return 0;
1523
- let r = m.get(e);
1523
+ let r = p.get(e);
1524
1524
  if (!r) return 0;
1525
1525
  let i = new Set(t).add(e), a = 0;
1526
1526
  for (let t of r.columns) {
1527
1527
  let n = t.references?.table;
1528
- n && n !== e && !d.has(E(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1528
+ n && n !== e && !d.has(E(e, t.name)) && (a = Math.max(a, h(n, i) + 1));
1529
1529
  }
1530
- return g.set(e, a), a;
1531
- }, v = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, y = (e) => {
1530
+ return m.set(e, a), a;
1531
+ }, g = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, v = (e) => {
1532
1532
  let t = "table" in e ? e.table : "";
1533
- return e.kind === "create-table" ? _(t) : e.kind === "drop-table" ? -_(t) : 0;
1534
- }, b = {
1533
+ return e.kind === "create-table" ? h(t) : e.kind === "drop-table" ? -h(t) : 0;
1534
+ }, y = {
1535
1535
  "add-column": 0,
1536
1536
  "rename-column": 1,
1537
1537
  "rename-index": 1,
@@ -1549,23 +1549,23 @@ BEGIN
1549
1549
  "add-unique-composite": 5,
1550
1550
  "add-foreign-key": 5,
1551
1551
  "add-check": 5
1552
- }, x = (e) => b[e] ?? 9, S = [...a].sort((e, t) => {
1553
- let n = v(e.op.kind), r = v(t.op.kind);
1552
+ }, b = (e) => y[e] ?? 9, S = [...a].sort((e, t) => {
1553
+ let n = g(e.op.kind), r = g(t.op.kind);
1554
1554
  if (n !== r) return n - r;
1555
- let i = y(e.op), a = y(t.op);
1555
+ let i = v(e.op), a = v(t.op);
1556
1556
  if (i !== a) return i - a;
1557
1557
  let o = "table" in e.op ? e.op.table : "", s = "table" in t.op ? t.op.table : "";
1558
1558
  if (o !== s) return o.localeCompare(s);
1559
- let c = x(e.op.kind), l = x(t.op.kind);
1559
+ let c = b(e.op.kind), l = b(t.op.kind);
1560
1560
  return c === l ? e.op.kind.localeCompare(t.op.kind) : c - l;
1561
1561
  });
1562
1562
  return {
1563
1563
  operations: S,
1564
- fromFingerprint: Gt(e.live),
1565
- toFingerprint: Gt(t),
1566
- summary: Nn(S)
1564
+ fromFingerprint: Jt(e.live),
1565
+ toFingerprint: Jt(t),
1566
+ summary: In(S)
1567
1567
  };
1568
- }, Fn = (e) => {
1568
+ }, Rn = (e) => {
1569
1569
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1570
1570
  if (!t) return null;
1571
1571
  let n = [...e.replace(/\\'/g, "'").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
@@ -1573,7 +1573,7 @@ BEGIN
1573
1573
  column: t[1],
1574
1574
  values: n
1575
1575
  };
1576
- }, In = (e, t) => {
1576
+ }, zn = (e, t) => {
1577
1577
  if (t === "vector") return "vector";
1578
1578
  switch (e) {
1579
1579
  case "text":
@@ -1600,10 +1600,10 @@ BEGIN
1600
1600
  case "USER-DEFINED": return "text";
1601
1601
  default: return "text";
1602
1602
  }
1603
- }, Ln = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1603
+ }, Bn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1604
1604
  expr: e,
1605
1605
  stored: t
1606
- } }, z = (e) => {
1606
+ } }, R = (e) => {
1607
1607
  switch (e.toUpperCase()) {
1608
1608
  case "CASCADE": return "cascade";
1609
1609
  case "RESTRICT": return "restrict";
@@ -1611,25 +1611,25 @@ BEGIN
1611
1611
  case "SET DEFAULT": return "noAction";
1612
1612
  default: return "noAction";
1613
1613
  }
1614
- }, Rn = (e, t) => {
1614
+ }, Vn = (e, t) => {
1615
1615
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1616
1616
  return Number.isInteger(n) && n > 0 ? n : t;
1617
- }, zn = () => Rn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Bn = 300, Vn = () => {
1617
+ }, Hn = () => Vn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Un = 300, Wn = () => {
1618
1618
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1619
- return e !== void 0 && e.trim() === "0" ? 0 : Rn(e, 3e4);
1620
- }, Hn = (e, t) => {
1619
+ return e !== void 0 && e.trim() === "0" ? 0 : Vn(e, 3e4);
1620
+ }, Gn = (e, t) => {
1621
1621
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1622
1622
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1623
1623
  return r;
1624
- }, Un = (e) => {
1625
- let t = Vn(), n = S.gen(function* () {
1624
+ }, Kn = (e) => {
1625
+ let t = Wn(), n = C.gen(function* () {
1626
1626
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1627
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = zn(), a = (e, t) => S.gen(function* () {
1627
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Hn(), a = (e, t) => C.gen(function* () {
1628
1628
  let r = [];
1629
- for (let a of Hn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1629
+ for (let a of Gn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1630
1630
  return r;
1631
1631
  }), o = [];
1632
- for (let t = 0;; t += Bn) {
1632
+ for (let t = 0;; t += Un) {
1633
1633
  let n = yield* e`
1634
1634
  SELECT c.relname AS table_name,
1635
1635
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1637,9 +1637,9 @@ BEGIN
1637
1637
  JOIN pg_namespace n ON n.oid = c.relnamespace
1638
1638
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1639
1639
  ORDER BY c.relname
1640
- LIMIT ${r(Bn)} OFFSET ${r(t)}
1640
+ LIMIT ${r(Un)} OFFSET ${r(t)}
1641
1641
  `;
1642
- if (o.push(...n), n.length < Bn) break;
1642
+ if (o.push(...n), n.length < Un) break;
1643
1643
  }
1644
1644
  let s = /* @__PURE__ */ new Set(), c = [];
1645
1645
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1725,7 +1725,7 @@ BEGIN
1725
1725
  AND c.relname IN ${t}
1726
1726
  )
1727
1727
  SELECT * FROM ix ORDER BY table_name, index_name, position
1728
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map();
1728
+ `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
1729
1729
  for (let e of u) {
1730
1730
  let t = _.get(e.table_name);
1731
1731
  t || (t = [], _.set(e.table_name, t)), t.push(e);
@@ -1765,33 +1765,33 @@ BEGIN
1765
1765
  t || (t = [], x.set(e.source_table, t)), t.push(e);
1766
1766
  }
1767
1767
  for (let e of g) {
1768
- let t = C.get(e.table_name);
1769
- t || (t = /* @__PURE__ */ new Map(), C.set(e.table_name, t));
1768
+ let t = S.get(e.table_name);
1769
+ t || (t = /* @__PURE__ */ new Map(), S.set(e.table_name, t));
1770
1770
  let n = t.get(e.index_name);
1771
1771
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1772
1772
  }
1773
1773
  let w = [];
1774
1774
  for (let e of c) {
1775
1775
  let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = x.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1776
- let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : In(t.data_type, t.udt_name), c = a ? {
1776
+ let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : zn(t.data_type, t.udt_name), c = a ? {
1777
1777
  table: a.target_table,
1778
1778
  column: a.target_column,
1779
- onDelete: z(a.delete_rule),
1780
- onUpdate: z(a.update_rule)
1779
+ onDelete: R(a.delete_rule),
1780
+ onUpdate: R(a.update_rule)
1781
1781
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1782
1782
  return {
1783
1783
  name: t.column_name,
1784
1784
  type: s,
1785
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1785
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1786
1786
  nullable: t.is_nullable === "YES",
1787
1787
  unique: i.has(t.column_name) || n && t.column_name === "id",
1788
1788
  hasDefault: t.column_default !== null,
1789
1789
  ...t.column_default === null ? {} : { defaultValue: t.column_default },
1790
1790
  ...c ? { references: c } : {},
1791
1791
  ...l ? { oneOf: l } : {},
1792
- ...Ln(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1792
+ ...Bn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1793
1793
  };
1794
- }), l = [], u = C.get(e.table_name);
1794
+ }), l = [], u = S.get(e.table_name);
1795
1795
  if (u) for (let [t, n] of u) {
1796
1796
  let r = /* @__PURE__ */ new Set(), i = [...n].filter((e) => e.column_name !== null && e.position !== null).sort((e, t) => (e.position ?? 0) - (t.position ?? 0)).filter((e) => {
1797
1797
  let t = e.position;
@@ -1824,11 +1824,11 @@ BEGIN
1824
1824
  }
1825
1825
  return { tables: w };
1826
1826
  });
1827
- return (t > 0 ? e.withTransaction(n) : n).pipe(S.catchAll((e) => {
1827
+ return (t > 0 ? e.withTransaction(n) : n).pipe(C.catchAll((e) => {
1828
1828
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1829
- return n.includes("statement timeout") || n.includes("57014") ? S.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : S.fail(e);
1829
+ 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);
1830
1830
  }));
1831
- }, Wn = (e, t) => {
1831
+ }, qn = (e, t) => {
1832
1832
  switch (e.toLowerCase()) {
1833
1833
  case "varchar":
1834
1834
  case "char":
@@ -1860,21 +1860,21 @@ BEGIN
1860
1860
  case "json": return "json";
1861
1861
  default: return "text";
1862
1862
  }
1863
- }, B = (e) => e.map((e) => {
1863
+ }, z = (e) => e.map((e) => {
1864
1864
  let t = e, n = {};
1865
1865
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1866
1866
  return n;
1867
- }), Gn = (e) => S.gen(function* () {
1868
- let t = B(yield* e`
1867
+ }), Jn = (e) => C.gen(function* () {
1868
+ let t = z(yield* e`
1869
1869
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1870
1870
  FROM information_schema.tables
1871
1871
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1872
- ORDER BY table_name`), n = B(yield* e`
1872
+ ORDER BY table_name`), n = z(yield* e`
1873
1873
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1874
1874
  character_maximum_length, generation_expression, extra
1875
1875
  FROM information_schema.columns
1876
1876
  WHERE table_schema = DATABASE()
1877
- ORDER BY table_name, ordinal_position`), r = B(yield* e`
1877
+ ORDER BY table_name, ordinal_position`), r = z(yield* e`
1878
1878
  SELECT k.table_name AS source_table,
1879
1879
  k.column_name AS source_column,
1880
1880
  k.referenced_table_name AS target_table,
@@ -1884,7 +1884,7 @@ BEGIN
1884
1884
  JOIN information_schema.referential_constraints r
1885
1885
  ON k.constraint_name = r.constraint_name
1886
1886
  AND k.table_schema = r.constraint_schema
1887
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = B(yield* e`
1887
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
1888
1888
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1889
1889
  FROM information_schema.statistics
1890
1890
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
@@ -1897,14 +1897,14 @@ BEGIN
1897
1897
  JOIN information_schema.table_constraints tc
1898
1898
  ON tc.constraint_schema = cc.constraint_schema
1899
1899
  AND tc.constraint_name = cc.constraint_name
1900
- WHERE cc.constraint_schema = DATABASE()`.unprepared, s = B(yield* a.pipe(S.orElse(() => o), S.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
1900
+ WHERE cc.constraint_schema = DATABASE()`.unprepared, s = z(yield* a.pipe(C.orElse(() => o), C.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
1901
1901
  for (let e of s) {
1902
1902
  let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
1903
1903
  if (t) {
1904
1904
  c.add(`${e.table_name}.${t[1]}`);
1905
1905
  continue;
1906
1906
  }
1907
- let n = Fn(e.check_clause);
1907
+ let n = Rn(e.check_clause);
1908
1908
  n && l.set(`${e.table_name}.${n.column}`, n.values);
1909
1909
  }
1910
1910
  let u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
@@ -1927,23 +1927,23 @@ BEGIN
1927
1927
  let t = u.get(e.table_name) ?? [], n = d.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), o = f.get(e.table_name);
1928
1928
  if (o) for (let e of o.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1929
1929
  let s = t.map((t) => {
1930
- let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = o ? "reference" : n && t.column_name === "id" ? "id" : c.has(`${e.table_name}.${t.column_name}`) ? "json" : Wn(t.data_type, t.column_type), u = o ? {
1930
+ let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = o ? "reference" : n && t.column_name === "id" ? "id" : c.has(`${e.table_name}.${t.column_name}`) ? "json" : qn(t.data_type, t.column_type), u = o ? {
1931
1931
  table: o.target_table,
1932
1932
  column: o.target_column,
1933
- onDelete: z(o.delete_rule),
1934
- onUpdate: z(o.update_rule)
1933
+ onDelete: R(o.delete_rule),
1934
+ onUpdate: R(o.update_rule)
1935
1935
  } : 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}`);
1936
1936
  return {
1937
1937
  name: t.column_name,
1938
1938
  type: s,
1939
1939
  nullable: t.is_nullable === "YES",
1940
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1940
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1941
1941
  unique: d,
1942
1942
  hasDefault: f !== null,
1943
1943
  ...f === null ? {} : { defaultValue: f },
1944
1944
  ...u ? { references: u } : {},
1945
1945
  ...p ? { oneOf: p } : {},
1946
- ...Ln(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
1946
+ ...Bn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
1947
1947
  };
1948
1948
  }), m = new Set(n.map((e) => e.source_column)), h = [];
1949
1949
  if (o) for (let [t, n] of o) {
@@ -1970,10 +1970,10 @@ BEGIN
1970
1970
  });
1971
1971
  }
1972
1972
  return { tables: p };
1973
- }), Kn = (e) => {
1973
+ }), Yn = (e) => {
1974
1974
  let t = e.toUpperCase();
1975
1975
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1976
- }, qn = (e) => e === 1 || e === !0, Jn = (e) => S.gen(function* () {
1976
+ }, Xn = (e) => e === 1 || e === !0, Zn = (e) => C.gen(function* () {
1977
1977
  let t = yield* e`
1978
1978
  SELECT name, sql FROM sqlite_master
1979
1979
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1987,14 +1987,14 @@ BEGIN
1987
1987
  let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = new Map(o.map((e) => [e.name.toLowerCase(), e.name])), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set();
1988
1988
  for (let t of c) {
1989
1989
  let r = (yield* e.unsafe(`PRAGMA index_info(${n(t.name)})`)).map((e) => e.name).filter((e) => e !== null).map((e) => d.get(e.toLowerCase()) ?? e);
1990
- f.set(t.name, r), qn(t.unique) && r.length === 1 && p.add(r[0]);
1990
+ f.set(t.name, r), Xn(t.unique) && r.length === 1 && p.add(r[0]);
1991
1991
  }
1992
1992
  let m = o.map((e) => {
1993
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Kn(e.type), a = r ? {
1993
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Yn(e.type), a = r ? {
1994
1994
  table: r.table,
1995
1995
  column: r.to,
1996
- onDelete: z(r.on_delete),
1997
- onUpdate: z(r.on_update)
1996
+ onDelete: R(r.on_delete),
1997
+ onUpdate: R(r.on_update)
1998
1998
  } : void 0, o = t.get(e.name);
1999
1999
  return {
2000
2000
  name: e.name,
@@ -2005,17 +2005,17 @@ BEGIN
2005
2005
  ...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
2006
2006
  ...a ? { references: a } : {},
2007
2007
  ...o ? { oneOf: o } : {},
2008
- ...Ln(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2008
+ ...Bn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
2009
2009
  };
2010
2010
  }), h = new Set(s.map((e) => e.from)), g = [];
2011
2011
  for (let e of c) {
2012
2012
  if (e.origin === "pk") continue;
2013
2013
  let t = f.get(e.name) ?? [];
2014
- t.length === 1 && qn(e.unique) || t.length === 1 && !qn(e.unique) && h.has(t[0]) && e.name !== `${i}_${t[0]}_idx` || g.push({
2014
+ t.length === 1 && Xn(e.unique) || t.length === 1 && !Xn(e.unique) && h.has(t[0]) && e.name !== `${i}_${t[0]}_idx` || g.push({
2015
2015
  name: e.name,
2016
2016
  table: i,
2017
2017
  columns: t,
2018
- unique: qn(e.unique)
2018
+ unique: Xn(e.unique)
2019
2019
  });
2020
2020
  }
2021
2021
  u.length > 0 && g.push({
@@ -2030,7 +2030,7 @@ BEGIN
2030
2030
  });
2031
2031
  }
2032
2032
  return { tables: r };
2033
- }), Yn = (e) => {
2033
+ }), Qn = (e) => {
2034
2034
  switch (e.toLowerCase()) {
2035
2035
  case "int":
2036
2036
  case "smallint":
@@ -2052,14 +2052,14 @@ BEGIN
2052
2052
  case "image": return "bytes";
2053
2053
  default: return "text";
2054
2054
  }
2055
- }, V = (e) => e === !0 || e === 1, Xn = (e) => S.gen(function* () {
2055
+ }, B = (e) => e === !0 || e === 1, $n = (e) => C.gen(function* () {
2056
2056
  let t = yield* e`
2057
2057
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2058
2058
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
2059
2059
  SELECT TABLE_NAME AS table_name, COLUMN_NAME AS column_name, DATA_TYPE AS data_type,
2060
2060
  IS_NULLABLE AS is_nullable, COLUMN_DEFAULT AS column_default,
2061
2061
  CHARACTER_MAXIMUM_LENGTH AS character_maximum_length
2062
- FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* S.orElseSucceed(e`
2062
+ FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* C.orElseSucceed(e`
2063
2063
  SELECT t.name AS table_name, c.name AS column_name, cc.definition AS definition,
2064
2064
  cc.is_persisted AS is_persisted
2065
2065
  FROM sys.computed_columns cc
@@ -2114,36 +2114,36 @@ BEGIN
2114
2114
  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();
2115
2115
  if (o) for (let [, e] of o) {
2116
2116
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2117
- if (V(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2118
- else V(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2117
+ if (B(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2118
+ else B(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2119
2119
  }
2120
2120
  let m = t.map((t) => {
2121
- let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : Yn(t.data_type), l = a ? {
2121
+ let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : Qn(t.data_type), l = a ? {
2122
2122
  table: a.target_table,
2123
2123
  column: a.target_column,
2124
- onDelete: Zn(a.delete_rule),
2125
- onUpdate: Zn(a.update_rule)
2126
- } : void 0, u = t.column_default === null ? null : Qn(t.column_default), d = c.get(`${e}.${t.column_name}`);
2124
+ onDelete: er(a.delete_rule),
2125
+ onUpdate: er(a.update_rule)
2126
+ } : void 0, u = t.column_default === null ? null : tr(t.column_default), d = c.get(`${e}.${t.column_name}`);
2127
2127
  return {
2128
2128
  name: t.column_name,
2129
2129
  type: o,
2130
2130
  nullable: t.is_nullable === "YES",
2131
- ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2131
+ ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2132
2132
  unique: p.has(t.column_name) || n && t.column_name === "id",
2133
2133
  hasDefault: u !== null,
2134
2134
  ...u === null ? {} : { defaultValue: u },
2135
2135
  ...l ? { references: l } : {},
2136
2136
  ...d ? { oneOf: d } : {},
2137
- ...Ln(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2137
+ ...Bn(i.get(`${e}.${t.column_name}`)?.definition ?? null, B(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2138
2138
  };
2139
2139
  }), h = [];
2140
2140
  if (o) for (let [t, n] of o) {
2141
2141
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2142
- V(r[0].is_primary) || r.length === 1 && V(r[0].is_unique) || r.length === 1 && !V(r[0].is_unique) && a.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || h.push({
2142
+ B(r[0].is_primary) || r.length === 1 && B(r[0].is_unique) || r.length === 1 && !B(r[0].is_unique) && a.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || h.push({
2143
2143
  name: t,
2144
2144
  table: e,
2145
2145
  columns: r.map((e) => e.column_name),
2146
- unique: V(r[0].is_unique)
2146
+ unique: B(r[0].is_unique)
2147
2147
  });
2148
2148
  }
2149
2149
  s.length > 0 && h.push({
@@ -2158,90 +2158,90 @@ BEGIN
2158
2158
  });
2159
2159
  }
2160
2160
  return { tables: f };
2161
- }), Zn = (e) => {
2161
+ }), er = (e) => {
2162
2162
  switch (e.toUpperCase().replace(/_/g, " ")) {
2163
2163
  case "CASCADE": return "cascade";
2164
2164
  case "SET NULL": return "setNull";
2165
2165
  case "SET DEFAULT": return "noAction";
2166
2166
  default: return "noAction";
2167
2167
  }
2168
- }, Qn = (e) => {
2168
+ }, tr = (e) => {
2169
2169
  let t = e.trim();
2170
2170
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2171
2171
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2172
- }, $n = /* @__PURE__ */ new Set([
2172
+ }, nr = /* @__PURE__ */ new Set([
2173
2173
  "character varying",
2174
2174
  "varchar",
2175
2175
  "nvarchar",
2176
2176
  "char",
2177
2177
  "character",
2178
2178
  "nchar"
2179
- ]), H = (e, t) => {
2180
- if (!$n.has(e.toLowerCase())) return;
2179
+ ]), V = (e, t) => {
2180
+ if (!nr.has(e.toLowerCase())) return;
2181
2181
  let n = Number(t);
2182
2182
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2183
- }, er = /* @__PURE__ */ new Set([k]), tr = (e) => e.onDialectOrElse({
2184
- mysql: () => Gn(e),
2185
- mssql: () => Xn(e),
2186
- sqlite: () => Jn(e),
2187
- orElse: () => Un(e)
2188
- }).pipe(S.map((e) => ({
2183
+ }, rr = /* @__PURE__ */ new Set([O]), ir = (e) => e.onDialectOrElse({
2184
+ mysql: () => Jn(e),
2185
+ mssql: () => $n(e),
2186
+ sqlite: () => Zn(e),
2187
+ orElse: () => Kn(e)
2188
+ }).pipe(C.map((e) => ({
2189
2189
  ...e,
2190
- tables: e.tables.filter((e) => !er.has(e.name))
2191
- }))), nr = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", rr = /* @__PURE__ */ new WeakMap(), ir = (e) => S.suspend(() => {
2192
- let t = rr.get(e);
2193
- return t === void 0 ? ar(e).pipe(S.tap((t) => S.sync(() => rr.set(e, t)))) : S.succeed(t);
2194
- }), ar = (e) => e.unsafe("SELECT VERSION() AS v").pipe(S.map((e) => {
2190
+ tables: e.tables.filter((e) => !rr.has(e.name))
2191
+ }))), ar = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", or = /* @__PURE__ */ new WeakMap(), H = (e) => C.suspend(() => {
2192
+ let t = or.get(e);
2193
+ return t === void 0 ? sr(e).pipe(C.tap((t) => C.sync(() => or.set(e, t)))) : C.succeed(t);
2194
+ }), sr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(C.map((e) => {
2195
2195
  let t = e[0]?.v;
2196
- return typeof t == "string" ? nr(t) : "mysql";
2197
- }), S.catchAll(() => S.succeed("mysql"))), or = (e) => {
2196
+ return typeof t == "string" ? ar(t) : "mysql";
2197
+ }), C.catchAll(() => C.succeed("mysql"))), cr = (e) => {
2198
2198
  let t = e;
2199
2199
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2200
2200
  let e = t;
2201
2201
  if (typeof e.errno == "number") return e.errno;
2202
2202
  t = e.cause;
2203
2203
  }
2204
- }, sr = (e) => {
2204
+ }, lr = (e) => {
2205
2205
  let t = [], n = e;
2206
2206
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2207
2207
  let e = n;
2208
2208
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2209
2209
  }
2210
2210
  return t.join(" | ");
2211
- }, cr = (e, t) => {
2211
+ }, ur = (e, t) => {
2212
2212
  if (t.length === 0) return !1;
2213
- let n = or(e), r = sr(e);
2213
+ let n = cr(e), r = lr(e);
2214
2214
  return t.some((e) => e.errno !== void 0 && n !== void 0 && e.errno.includes(n) || e.messageIncludes !== void 0 && e.messageIncludes.some((e) => r.includes(e)));
2215
- }, lr = {
2215
+ }, dr = {
2216
2216
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2217
2217
  errno: [1061]
2218
- }, ur = {
2218
+ }, fr = {
2219
2219
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2220
2220
  errno: [1091]
2221
- }, dr = {
2221
+ }, pr = {
2222
2222
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2223
2223
  messageIncludes: ["no such column"]
2224
- }, fr = {
2224
+ }, mr = {
2225
2225
  why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
2226
2226
  errno: [1091, 3940]
2227
2227
  }, U = (e, t) => e.onDialectOrElse({
2228
- mysql: () => S.succeed(t.replace("T", " ").replace("Z", "")),
2229
- orElse: () => S.succeed(t)
2230
- }), pr = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, mr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), hr = (e, t) => {
2231
- if ((e.type !== "text" || e.maxLength === void 0) && !mr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2228
+ mysql: () => C.succeed(t.replace("T", " ").replace("Z", "")),
2229
+ orElse: () => C.succeed(t)
2230
+ }), hr = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, gr = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), _r = (e, t) => {
2231
+ if ((e.type !== "text" || e.maxLength === void 0) && !gr(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2232
2232
  let n = e.type === "vector" && e.vectorDim === void 0 ? "vector dimension" : e.type === "array" && e.arrayElement === void 0 ? "array element type" : e.type === "enum" && e.enumName === void 0 && e.enumValues === void 0 ? "enum name/values" : void 0;
2233
2233
  if (n !== void 0) throw Error(`migration applier: cannot render '${e.name}' (${e.type}) — the schema snapshot carries no ${n}. Rendering it as 'text' would emit DDL that applies successfully and changes nothing, so this fails instead. This is a framework bug: declaredSchema.ts must carry the parameter into the ColumnSnapshot.`);
2234
- return M(e, t);
2235
- }, gr = (e) => {
2236
- let t = hr(e, "postgres");
2237
- return t === void 0 ? _r(e) : t;
2238
- }, _r = (e) => {
2234
+ return j(e, t);
2235
+ }, vr = (e) => {
2236
+ let t = _r(e, "postgres");
2237
+ return t === void 0 ? yr(e) : t;
2238
+ }, yr = (e) => {
2239
2239
  switch (e.type) {
2240
2240
  case "id": return "text";
2241
2241
  case "text": return "text";
2242
2242
  case "integer": return "integer";
2243
2243
  case "real": return "double precision";
2244
- case "decimal": return pr(e, "NUMERIC");
2244
+ case "decimal": return hr(e, "NUMERIC");
2245
2245
  case "bigint": return "bigint";
2246
2246
  case "boolean": return "boolean";
2247
2247
  case "timestamp": return "timestamptz";
@@ -2255,15 +2255,15 @@ BEGIN
2255
2255
  case "interval": return "interval";
2256
2256
  case "raw": return e.rawDdl ?? "text";
2257
2257
  }
2258
- }, vr = (e) => {
2259
- let t = hr(e, "mariadb");
2258
+ }, br = (e) => {
2259
+ let t = _r(e, "mariadb");
2260
2260
  if (t !== void 0) return t;
2261
2261
  switch (e.type) {
2262
2262
  case "id": return "VARCHAR(64)";
2263
2263
  case "text": return "LONGTEXT";
2264
2264
  case "integer": return "INT";
2265
2265
  case "real": return "DOUBLE";
2266
- case "decimal": return pr(e, "DECIMAL");
2266
+ case "decimal": return hr(e, "DECIMAL");
2267
2267
  case "bigint": return "BIGINT";
2268
2268
  case "boolean": return "TINYINT(1)";
2269
2269
  case "timestamp": return "DATETIME(6)";
@@ -2277,38 +2277,38 @@ BEGIN
2277
2277
  case "interval": return "BIGINT";
2278
2278
  case "raw": return e.rawDdl ?? "LONGTEXT";
2279
2279
  }
2280
- }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, yr = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", br = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, xr = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, Sr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Cr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Zr(t)}`)};`, wr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Er(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Tr = (e, t) => {
2280
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, xr = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", Sr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, Cr = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, wr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Tr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${$r(t)}`)};`, Er = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Or(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Dr = (e, t) => {
2281
2281
  let { defaultFactory: n, ...r } = e;
2282
- return M(e, t) !== M({
2282
+ return j(e, t) !== j({
2283
2283
  ...r,
2284
2284
  hasDefault: !1
2285
2285
  }, t);
2286
- }, Er = (e, t) => {
2286
+ }, Or = (e, t) => {
2287
2287
  let n = t(e.defaultValue);
2288
2288
  if (n === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${e.column}' (${JSON.stringify(e.defaultValue)}). Emitting 'DEFAULT NULL' would apply cleanly and drop the default silently, so this fails instead. This is a framework bug — report the column type + default.`);
2289
2289
  return n;
2290
- }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Dr = (e, t, n) => {
2290
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], kr = (e, t, n) => {
2291
2291
  let r = K(e, t, n);
2292
- return r ? qt(n, r) : void 0;
2293
- }, Or = (e, t, n) => {
2294
- let r = n ?? e.nullable, i = $e(e, "mariadb");
2292
+ return r ? Xt(n, r) : void 0;
2293
+ }, Ar = (e, t, n) => {
2294
+ let r = n ?? e.nullable, i = nt(e, "mariadb");
2295
2295
  return [
2296
2296
  G(t),
2297
- M(e, "mariadb"),
2297
+ j(e, "mariadb"),
2298
2298
  r ? null : "NOT NULL",
2299
2299
  i
2300
2300
  ].filter(Boolean).join(" ");
2301
- }, kr = (e, t) => e == null ? null : Array.isArray(e) ? Ar(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? N(e, "mariadb") : null, Ar = (e, t, n) => et(e, t ?? { type: "json" }, n), jr = (e, t) => e == null ? null : Array.isArray(e) ? Ar(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? N(e, "postgres") : null, q = (e, t) => {
2301
+ }, jr = (e, t) => e == null ? null : Array.isArray(e) ? Mr(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, Mr = (e, t, n) => rt(e, t ?? { type: "json" }, n), Nr = (e, t) => e == null ? null : Array.isArray(e) ? Mr(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, Pr = (e, t) => {
2302
2302
  if (!e.generatedAs) return null;
2303
2303
  let { expr: n, stored: r } = e.generatedAs;
2304
2304
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2305
- }, Mr = (e) => {
2306
- if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "postgres");
2307
- let t = q(e, "postgres");
2308
- if (t) return `${W(e.name)} ${gr(e)} ${t}`;
2309
- let n = [W(e.name), gr(e)];
2305
+ }, Fr = (e) => {
2306
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2307
+ let t = Pr(e, "postgres");
2308
+ if (t) return `${W(e.name)} ${vr(e)} ${t}`;
2309
+ let n = [W(e.name), vr(e)];
2310
2310
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2311
- let t = jr(e.defaultValue, e);
2311
+ let t = Nr(e.defaultValue, e);
2312
2312
  t && n.push(t);
2313
2313
  }
2314
2314
  return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
@@ -2317,24 +2317,24 @@ BEGIN
2317
2317
  setNull: "SET NULL",
2318
2318
  noAction: "NO ACTION"
2319
2319
  }[e.references.onDelete]}`)), n.join(" ");
2320
- }, Nr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Pr = (e) => {
2321
- let t = e.columns.map((e) => ` ${Mr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Nr(e, W)}\n)`];
2322
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(ni).join(", ")})`);
2320
+ }, Ir = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Lr = (e) => {
2321
+ let t = e.columns.map((e) => ` ${Fr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Ir(e, W)}\n)`];
2322
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(ii).join(", ")})`);
2323
2323
  return n;
2324
- }, Fr = 191, Ir = (e) => {
2325
- let t = vr(e).toUpperCase();
2324
+ }, Rr = 191, zr = (e) => {
2325
+ let t = br(e).toUpperCase();
2326
2326
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2327
- }, Lr = (e) => {
2328
- if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mariadb");
2329
- let t = q(e, "mariadb");
2330
- if (t) return `${G(e.name)} ${vr(e)} ${t}`;
2331
- let n = [G(e.name), vr(e)];
2332
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Ir(e) && n.push("UNIQUE"), e.hasDefault) {
2333
- let t = kr(e.defaultValue, e);
2327
+ }, Br = (e) => {
2328
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2329
+ let t = Pr(e, "mariadb");
2330
+ if (t) return `${G(e.name)} ${br(e)} ${t}`;
2331
+ let n = [G(e.name), br(e)];
2332
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !zr(e) && n.push("UNIQUE"), e.hasDefault) {
2333
+ let t = jr(e.defaultValue, e);
2334
2334
  t && n.push(t);
2335
2335
  }
2336
2336
  return n.join(" ");
2337
- }, Rr = (e) => e.columns.flatMap((t) => {
2337
+ }, Vr = (e) => e.columns.flatMap((t) => {
2338
2338
  if (!t.references) return [];
2339
2339
  let n = t.references.onDelete ? ` ON DELETE ${{
2340
2340
  cascade: "CASCADE",
@@ -2343,26 +2343,26 @@ BEGIN
2343
2343
  noAction: "NO ACTION"
2344
2344
  }[t.references.onDelete]}` : "";
2345
2345
  return [` CONSTRAINT ${G(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${G(t.name)}) REFERENCES ${G(t.references.table)} (${G(t.references.column)})${n}`];
2346
- }), zr = (e, t = "mariadb") => {
2346
+ }), Hr = (e, t = "mariadb") => {
2347
2347
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2348
- let t = ei(n.get(e));
2348
+ let t = ni(n.get(e));
2349
2349
  return t === void 0 ? G(e) : `${G(e)}(${t})`;
2350
- }, i = e.columns.map((e) => ` ${Lr(e)}`).join(",\n"), a = Rr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Nr(e, r)}\n)`];
2351
- for (let n of e.columns) n.unique && n.type !== "id" && Ir(n) && s.push(`CREATE UNIQUE INDEX ${yr(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2352
- for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${yr(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2350
+ }, i = e.columns.map((e) => ` ${Br(e)}`).join(",\n"), a = Vr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Ir(e, r)}\n)`];
2351
+ for (let n of e.columns) n.unique && n.type !== "id" && zr(n) && s.push(`CREATE UNIQUE INDEX ${xr(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
2352
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${xr(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
2353
2353
  return s;
2354
- }, Br = {
2354
+ }, Ur = {
2355
2355
  cascade: "CASCADE",
2356
2356
  restrict: "RESTRICT",
2357
2357
  setNull: "SET NULL",
2358
2358
  noAction: "NO ACTION"
2359
- }, Vr = {
2359
+ }, Wr = {
2360
2360
  cascade: "CASCADE",
2361
2361
  restrict: "NO ACTION",
2362
2362
  setNull: "SET NULL",
2363
2363
  noAction: "NO ACTION"
2364
- }, Hr = (e) => {
2365
- let t = hr(e, "sqlite");
2364
+ }, Gr = (e) => {
2365
+ let t = _r(e, "sqlite");
2366
2366
  if (t !== void 0) return t;
2367
2367
  switch (e.type) {
2368
2368
  case "integer":
@@ -2373,29 +2373,29 @@ BEGIN
2373
2373
  case "bytes": return "BLOB";
2374
2374
  default: return "TEXT";
2375
2375
  }
2376
- }, Ur = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? N(e, "sqlite") : null, Wr = (e) => {
2377
- if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "sqlite");
2378
- let t = q(e, "sqlite");
2379
- if (t) return `${W(e.name)} ${Hr(e)} ${t}`;
2380
- let n = [W(e.name), Hr(e)];
2376
+ }, q = (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, Kr = (e) => {
2377
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2378
+ let t = Pr(e, "sqlite");
2379
+ if (t) return `${W(e.name)} ${Gr(e)} ${t}`;
2380
+ let n = [W(e.name), Gr(e)];
2381
2381
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2382
- let t = Ur(e.defaultValue, "CURRENT_TIMESTAMP");
2382
+ let t = q(e.defaultValue, "CURRENT_TIMESTAMP");
2383
2383
  t && n.push(t);
2384
2384
  }
2385
- if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Br[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2385
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Ur[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2386
2386
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2387
2387
  n.push(`CHECK (${W(e.name)} IN (${t}))`);
2388
2388
  }
2389
2389
  return n.join(" ");
2390
- }, Gr = (e) => {
2391
- let t = e.columns.map((e) => ` ${Wr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Nr(e, W)}\n)`];
2390
+ }, qr = (e) => {
2391
+ let t = e.columns.map((e) => ` ${Kr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Ir(e, W)}\n)`];
2392
2392
  for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(W).join(", ")})`);
2393
2393
  return n;
2394
2394
  }, J = (e, t) => {
2395
2395
  let n = t.find((t) => t.tableName === e);
2396
2396
  if (!n) return [];
2397
- let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2398
- ...Gr({
2397
+ let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2398
+ ...qr({
2399
2399
  kind: "create-table",
2400
2400
  table: i,
2401
2401
  columns: r.columns,
@@ -2408,25 +2408,25 @@ BEGIN
2408
2408
  ];
2409
2409
  for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e)} (${t.columns.map(W).join(", ")})`);
2410
2410
  return o;
2411
- }, Kr = (e, t, n, r) => {
2411
+ }, Jr = (e, t, n, r) => {
2412
2412
  let i = r ?? e.nullable;
2413
- return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${M(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2414
- }, qr = (e, t) => {
2413
+ return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2414
+ }, Yr = (e, t) => {
2415
2415
  let n = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Y(e.table)} DROP CONSTRAINT [' + @dc + ']');` + (t ? ` ${t}` : "");
2416
2416
  if (!e.hasDefault) return n;
2417
- let r = Ur(e.defaultValue, "SYSUTCDATETIME()");
2417
+ let r = q(e.defaultValue, "SYSUTCDATETIME()");
2418
2418
  if (!r) return n;
2419
2419
  let i = r.replace(/^DEFAULT\s+/i, "");
2420
2420
  return `${n} ALTER TABLE ${Y(e.table)} ADD DEFAULT ${i} FOR ${Y(e.column)};`;
2421
- }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Jr = (e) => {
2422
- let t = hr(e, "mssql");
2421
+ }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Xr = (e) => {
2422
+ let t = _r(e, "mssql");
2423
2423
  if (t !== void 0) return t;
2424
2424
  switch (e.type) {
2425
2425
  case "id":
2426
2426
  case "reference": return "NVARCHAR(64)";
2427
2427
  case "integer": return "INT";
2428
2428
  case "real": return "FLOAT";
2429
- case "decimal": return pr(e, "DECIMAL");
2429
+ case "decimal": return hr(e, "DECIMAL");
2430
2430
  case "bigint": return "BIGINT";
2431
2431
  case "boolean": return "BIT";
2432
2432
  case "timestamp": return "DATETIME2(6)";
@@ -2434,44 +2434,44 @@ BEGIN
2434
2434
  case "bytes": return "VARBINARY(MAX)";
2435
2435
  default: return "NVARCHAR(MAX)";
2436
2436
  }
2437
- }, Yr = (e, t) => {
2438
- if (e.type === "id" && e.idScheme?.kind === "numeric") return P(e.name, "mssql");
2439
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Jr(e), r = q(e, "mssql");
2437
+ }, Zr = (e, t) => {
2438
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2439
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Xr(e), r = Pr(e, "mssql");
2440
2440
  if (r) return `${Y(e.name)} ${r}`;
2441
2441
  let i = [Y(e.name), n];
2442
2442
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2443
- let t = Ur(e.defaultValue, "SYSUTCDATETIME()");
2443
+ let t = q(e.defaultValue, "SYSUTCDATETIME()");
2444
2444
  t && i.push(t);
2445
2445
  }
2446
- return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Vr[e.references.onDelete]}`)), i.join(" ");
2447
- }, Xr = (e) => {
2448
- let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((e) => ` ${Yr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Nr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2446
+ return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Wr[e.references.onDelete]}`)), i.join(" ");
2447
+ }, Qr = (e) => {
2448
+ let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((e) => ` ${Zr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Ir(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2449
2449
  for (let n of e.indexes) {
2450
2450
  if (n.name === `${e.table}_pkey`) continue;
2451
2451
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Y(n.name)} ON ${Y(e.table)} (${n.columns.map(Y).join(", ")})`;
2452
2452
  a.push(`IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(n.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(r)}')`);
2453
2453
  }
2454
2454
  return a;
2455
- }, Zr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Qr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, $r = (e, t, n) => {
2456
- let r = `${e.table}${Zr(t)}`;
2455
+ }, $r = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, ei = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, ti = (e, t, n) => {
2456
+ let r = `${e.table}${$r(t)}`;
2457
2457
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2458
- }, ei = (e) => {
2459
- if (e === void 0 || !Ir(e)) return;
2458
+ }, ni = (e) => {
2459
+ if (e === void 0 || !zr(e)) return;
2460
2460
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2461
- return t === void 0 ? Fr : Math.min(Fr, t);
2462
- }, ti = (e, t, n) => {
2463
- let r = ei(Dr(e, t, n));
2461
+ return t === void 0 ? Rr : Math.min(Rr, t);
2462
+ }, ri = (e, t, n) => {
2463
+ let r = ni(kr(e, t, n));
2464
2464
  return r === void 0 ? G(n) : `${G(n)}(${r})`;
2465
- }, ni = (e) => e.startsWith("(") ? e : W(e), ri = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map(ni).join(", ")});`, ii = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${yr(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => ti(t, e.table, n)).join(", ")});`, ai = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, oi = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, si = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ci = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, li = (e) => {
2465
+ }, ii = (e) => e.startsWith("(") ? e : W(e), ai = (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(ii).join(", ")});`, oi = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${xr(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => ri(t, e.table, n)).join(", ")});`, si = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, ci = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, li = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ui = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, di = (e) => {
2466
2466
  let t = (e) => e.replace(/'/g, "''");
2467
2467
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2468
- }, ui = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, di = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, fi = (e) => {
2468
+ }, fi = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, pi = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, mi = (e) => {
2469
2469
  let t = (e) => e.replace(/'/g, "''");
2470
2470
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2471
- }, pi = (e) => {
2471
+ }, hi = (e) => {
2472
2472
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Y(e.index.name)} ON ${Y(e.table)} (${e.index.columns.map(Y).join(", ")})`;
2473
2473
  return `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(e.index.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(n)}');`;
2474
- }, mi = (e, t, n) => {
2474
+ }, gi = (e, t, n) => {
2475
2475
  let r = n.find((t) => t.tableName === e);
2476
2476
  if (!r) return [];
2477
2477
  let i = [];
@@ -2480,13 +2480,13 @@ BEGIN
2480
2480
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Y(e)} ALTER COLUMN ${Y(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2481
2481
  }
2482
2482
  return i;
2483
- }, hi = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, gi = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${ti(t, e.table, e.column)});`, _i = (e) => {
2483
+ }, _i = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, vi = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${ri(t, e.table, e.column)});`, yi = (e) => {
2484
2484
  let t = e.fields.map((e) => W(e)).join(", ");
2485
2485
  return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2486
- }, vi = (e, t) => {
2487
- let n = e.fields.map((n) => ti(t, e.table, n)).join(", ");
2486
+ }, bi = (e, t) => {
2487
+ let n = e.fields.map((n) => ri(t, e.table, n)).join(", ");
2488
2488
  return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2489
- }, yi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, bi = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, xi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, Si = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Ci = (e, t) => {
2489
+ }, xi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, Si = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, Ci = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, wi = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Ti = (e, t) => {
2490
2490
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2491
2491
  if (e.orphanPolicy) {
2492
2492
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2504,34 +2504,34 @@ BEGIN
2504
2504
  setNull: "SET NULL",
2505
2505
  noAction: "NO ACTION"
2506
2506
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2507
- }, wi = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Ti = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, Ei = (e, t) => {
2507
+ }, Ei = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, Di = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, Oi = (e, t) => {
2508
2508
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2509
2509
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2510
- }, Di = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Oi = (e, t) => S.gen(function* () {
2510
+ }, ki = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Ai = (e, t) => C.gen(function* () {
2511
2511
  let n = yield* e`
2512
2512
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2513
2513
  FROM information_schema.check_constraints cc
2514
- WHERE cc.constraint_schema = DATABASE() AND cc.table_name = ${t.table}`.pipe(S.orElse(() => e`
2514
+ WHERE cc.constraint_schema = DATABASE() AND cc.table_name = ${t.table}`.pipe(C.orElse(() => e`
2515
2515
  SELECT cc.constraint_name AS n, cc.check_clause AS c
2516
2516
  FROM information_schema.check_constraints cc
2517
2517
  JOIN information_schema.table_constraints tc
2518
2518
  ON tc.constraint_schema = cc.constraint_schema
2519
2519
  AND tc.constraint_name = cc.constraint_name
2520
- WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), S.orElseSucceed(() => []));
2520
+ WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), C.orElseSucceed(() => []));
2521
2521
  for (let e of n) {
2522
2522
  let n = String(e.n ?? "");
2523
- if (n !== "" && Fn(String(e.c ?? ""))?.column === t.column) return n;
2523
+ if (n !== "" && Rn(String(e.c ?? ""))?.column === t.column) return n;
2524
2524
  }
2525
- }), ki = (e, t, n) => S.gen(function* () {
2526
- let r = yield* Oi(e, t);
2527
- r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [fr]));
2528
- let i = yield* Oi(e, t);
2525
+ }), ji = (e, t, n) => C.gen(function* () {
2526
+ let r = yield* Ai(e, t);
2527
+ r !== void 0 && (yield* X(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [mr]));
2528
+ let i = yield* Ai(e, t);
2529
2529
  if (i === void 0) return;
2530
2530
  let a = K(n, t.table, t.column);
2531
- if (!a) return yield* S.die(/* @__PURE__ */ Error(`applier: cannot drop the CHECK on '${t.table}.${t.column}' — it is column-level (catalog name '${i}'), which this family removes only by redefining the column, and the declared column is not available to redefine it from.`));
2532
- yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Or(a, t.column)};`, t.kind);
2533
- }), Ai = (e, t, n, r) => {
2534
- let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Y : W, s = a ? vr(i) : r === "mssql" ? Jr(i) : r === "sqlite" ? Hr(i) : gr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? kr(e, i) : r === "mssql" ? Ur(e, "SYSUTCDATETIME()") : r === "sqlite" ? Ur(e, "CURRENT_TIMESTAMP") : jr(e, i), u = q(i, r);
2531
+ 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.`));
2532
+ yield* X(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Ar(a, t.column)};`, t.kind);
2533
+ }), Mi = (e, t, n, r) => {
2534
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Y : W, s = a ? br(i) : r === "mssql" ? Xr(i) : r === "sqlite" ? Gr(i) : vr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? jr(e, i) : r === "mssql" ? q(e, "SYSUTCDATETIME()") : r === "sqlite" ? q(e, "CURRENT_TIMESTAMP") : Nr(e, i), u = Pr(i, r);
2535
2535
  if (u) {
2536
2536
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2537
2537
  return {
@@ -2559,7 +2559,7 @@ BEGIN
2559
2559
  post: f ? [f] : []
2560
2560
  };
2561
2561
  return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
2562
- }, ji = (e) => {
2562
+ }, Ni = (e) => {
2563
2563
  let t = new Map(e.map((e) => [e.tableName, e]));
2564
2564
  return (e, n) => {
2565
2565
  let r = t.get(e);
@@ -2579,47 +2579,47 @@ BEGIN
2579
2579
  ...o
2580
2580
  };
2581
2581
  };
2582
- }, X = (e, t, n, r = []) => e.unsafe(t).pipe(S.catchIf((e) => cr(e, r), () => S.void), S.tapError((e) => S.sync(() => {
2583
- process.stderr.write(ie(`applier: statement failed (op=${n})`, t, e, 400));
2584
- })), S.mapError((e) => {
2585
- let r = ie(`applier: statement failed (op=${n})`, t, e, 400).trim();
2582
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(C.catchIf((e) => ur(e, r), () => C.void), C.tapError((e) => C.sync(() => {
2583
+ process.stderr.write(oe(`applier: statement failed (op=${n})`, t, e, 400));
2584
+ })), C.mapError((e) => {
2585
+ let r = oe(`applier: statement failed (op=${n})`, t, e, 400).trim();
2586
2586
  return Object.assign(e, { message: r });
2587
- }), S.map(() => void 0)), Z = (e, t, n) => S.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : _(r, t)} FROM ${_(n, t)} WHERE 1=0`).pipe(S.as(!0), S.catchAll(() => S.succeed(!1))), Mi = (e, t) => S.gen(function* () {
2588
- let n = I([Ie], t).tables[0];
2589
- if (!n) return yield* S.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2587
+ }), 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))), Pi = (e, t) => C.gen(function* () {
2588
+ let n = F([ze], t).tables[0];
2589
+ if (!n) return yield* C.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2590
2590
  let r = {
2591
2591
  kind: "create-table",
2592
- table: k,
2592
+ table: O,
2593
2593
  columns: n.columns,
2594
2594
  indexes: []
2595
2595
  }, i = yield* e.onDialectOrElse({
2596
- mysql: () => ir(e).pipe(S.map((e) => zr(r, e))),
2597
- mssql: () => S.succeed(Xr(r)),
2598
- sqlite: () => S.succeed(Gr(r)),
2599
- orElse: () => S.succeed(Pr(r))
2596
+ mysql: () => H(e).pipe(C.map((e) => Hr(r, e))),
2597
+ mssql: () => C.succeed(Qr(r)),
2598
+ sqlite: () => C.succeed(qr(r)),
2599
+ orElse: () => C.succeed(Lr(r))
2600
2600
  });
2601
- yield* S.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2602
- }), Ni = (e) => e`
2601
+ yield* C.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2602
+ }), Fi = (e) => e`
2603
2603
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2604
2604
  ${e("status")}, ${e("payload")}
2605
- FROM ${e(k)}
2606
- `, Pi = (e, t, n, r) => S.gen(function* () {
2605
+ FROM ${e(O)}
2606
+ `, Ii = (e, t, n, r) => C.gen(function* () {
2607
2607
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2608
- yield* S.forEach(r, ({ index: r, planned: a }) => e`
2609
- INSERT INTO ${e(k)}
2608
+ yield* C.forEach(r, ({ index: r, planned: a }) => e`
2609
+ INSERT INTO ${e(O)}
2610
2610
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2611
2611
  ${e("opKind")}, ${e("opTarget")}, ${e("status")}, ${e("payload")},
2612
2612
  ${e("createdAt")})
2613
2613
  VALUES
2614
2614
  (${`mop_${t}_${r}`}, ${t}, ${n}, ${r},
2615
- ${a.op.kind}, ${Re(a.op)}, ${"pending"},
2615
+ ${a.op.kind}, ${Ve(a.op)}, ${"pending"},
2616
2616
  ${JSON.stringify(a)}, ${i})
2617
2617
  `, { discard: !0 });
2618
- }), Fi = (e, t, n, r, i) => S.gen(function* () {
2618
+ }), Li = (e, t, n, r, i) => C.gen(function* () {
2619
2619
  let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2620
2620
  if (r === "applied") {
2621
2621
  yield* e`
2622
- UPDATE ${e(k)}
2622
+ UPDATE ${e(O)}
2623
2623
  SET ${e("status")} = ${r}, ${e("appliedAt")} = ${a},
2624
2624
  ${e("durationMs")} = ${i ?? null}
2625
2625
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
@@ -2627,50 +2627,50 @@ BEGIN
2627
2627
  return;
2628
2628
  }
2629
2629
  yield* e`
2630
- UPDATE ${e(k)}
2630
+ UPDATE ${e(O)}
2631
2631
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2632
2632
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2633
2633
  `;
2634
- }), Ii = (e, t, n, r) => S.gen(function* () {
2634
+ }), Ri = (e, t, n, r) => C.gen(function* () {
2635
2635
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2636
2636
  r.length > 0 && (yield* e`
2637
- UPDATE ${e(k)}
2637
+ UPDATE ${e(O)}
2638
2638
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
2639
2639
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(r)}
2640
2640
  `), n.length > 0 && (yield* e`
2641
- UPDATE ${e(k)}
2641
+ UPDATE ${e(O)}
2642
2642
  SET ${e("status")} = ${"pending"}
2643
2643
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2644
2644
  `);
2645
- }), Li = (e, t) => t === void 0 ? e`DELETE FROM ${e(k)}`.pipe(S.asVoid) : e`DELETE FROM ${e(k)} WHERE ${e("runId")} = ${t}`.pipe(S.asVoid), Ri = (e, t, n) => S.gen(function* () {
2646
- if (Ke(n.op, n.classification, t) !== "artefact-repair") return "clean";
2647
- let r = n.op, i = (e) => _(e, t);
2645
+ }), zi = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(C.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(C.asVoid), Bi = (e, t, n) => C.gen(function* () {
2646
+ if (Ye(n.op, n.classification, t) !== "artefact-repair") return "clean";
2647
+ let r = n.op, i = (e) => o(e, t);
2648
2648
  if (t === "sqlite" || t === "turso") {
2649
2649
  if (!("table" in r)) return "clean";
2650
- let n = `${r.table}${Ve}`;
2651
- 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* S.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
2650
+ let n = `${r.table}${We}`;
2651
+ 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";
2652
2652
  }
2653
2653
  if (r.kind !== "alter-column-type") return "clean";
2654
- let a = `${r.column}${He}`, o = `${r.column}${Ue}`, s = yield* $(e, t, r.table, r.column), c = yield* $(e, t, r.table, a), l = yield* $(e, t, r.table, o), u = (e) => S.logWarning(`migration resume: ${e}`).pipe(S.annotateLogs({ scope: "voltro:migrate" }));
2655
- return !c && !l ? "clean" : s && c && !l ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(a)}`, "resume-repair"), yield* u(`dropped a half-populated shadow column '${r.table}.${a}' — replaying the type change`), "outstanding") : !s && c && l ? (yield* X(e, `ALTER TABLE ${i(r.table)} RENAME COLUMN ${i(a)} TO ${i(r.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(o)}`, "resume-repair"), yield* u(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : s && !c && l ? (yield* X(e, `ALTER TABLE ${i(r.table)} DROP COLUMN ${i(o)}`, "resume-repair"), yield* u(`dropped the leftover pre-swap column '${r.table}.${o}'`), "applied") : yield* S.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${s}, ${a}=${c}, ${o}=${l}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2656
- }), zi = (e, t, n, r = "fresh") => S.gen(function* () {
2657
- let i = process.hrtime.bigint(), a = ji(n.declared), o = t.op;
2654
+ let a = `${r.column}${Ge}`, s = `${r.column}${Ke}`, 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" }));
2655
+ 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.`));
2656
+ }), Vi = (e, t, n, r = "fresh") => C.gen(function* () {
2657
+ let i = process.hrtime.bigint(), a = Ni(n.declared), o = t.op;
2658
2658
  switch (o.kind) {
2659
2659
  case "create-table": {
2660
2660
  let t = yield* e.onDialectOrElse({
2661
- mysql: () => ir(e).pipe(S.map((e) => zr(o, e))),
2662
- mssql: () => S.succeed(Xr(o)),
2663
- sqlite: () => S.succeed(Gr(o)),
2664
- orElse: () => S.succeed(Pr(o))
2661
+ mysql: () => H(e).pipe(C.map((e) => Hr(o, e))),
2662
+ mssql: () => C.succeed(Qr(o)),
2663
+ sqlite: () => C.succeed(qr(o)),
2664
+ orElse: () => C.succeed(Lr(o))
2665
2665
  }), n = yield* e.onDialectOrElse({
2666
- mysql: () => S.succeed([lr]),
2667
- orElse: () => S.succeed([])
2666
+ mysql: () => C.succeed([dr]),
2667
+ orElse: () => C.succeed([])
2668
2668
  });
2669
2669
  for (let r of t) yield* X(e, r, o.kind, n);
2670
2670
  break;
2671
2671
  }
2672
2672
  case "drop-table": {
2673
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? $r(o, n, e) : Qr(o, e);
2673
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? ti(o, n, e) : ei(o, e);
2674
2674
  yield* e.onDialectOrElse({
2675
2675
  mysql: () => X(e, r(G), o.kind),
2676
2676
  orElse: () => X(e, r(W), o.kind)
@@ -2680,92 +2680,92 @@ BEGIN
2680
2680
  case "drop-column": {
2681
2681
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2682
2682
  yield* e.onDialectOrElse({
2683
- mysql: () => ir(e).pipe(S.flatMap((r) => X(e, t ? Cr(o, n, G) : xr(o, r), o.kind, t ? [] : [ur]))),
2684
- sqlite: () => X(e, t ? Cr(o, n, W) : br(o, W, !1), o.kind, t ? [] : [dr]),
2685
- orElse: () => X(e, t ? Cr(o, n, W) : br(o, W), o.kind)
2683
+ mysql: () => H(e).pipe(C.flatMap((r) => X(e, t ? Tr(o, n, G) : Cr(o, r), o.kind, t ? [] : [fr]))),
2684
+ sqlite: () => X(e, t ? Tr(o, n, W) : Sr(o, W, !1), o.kind, t ? [] : [pr]),
2685
+ orElse: () => X(e, t ? Tr(o, n, W) : Sr(o, W), o.kind)
2686
2686
  });
2687
2687
  break;
2688
2688
  }
2689
2689
  case "rename-column":
2690
2690
  yield* e.onDialectOrElse({
2691
- mysql: () => X(e, Sr(o, G), o.kind),
2691
+ mysql: () => X(e, wr(o, G), o.kind),
2692
2692
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2693
- orElse: () => X(e, Sr(o, W), o.kind)
2693
+ orElse: () => X(e, wr(o, W), o.kind)
2694
2694
  });
2695
2695
  break;
2696
2696
  case "add-index":
2697
2697
  yield* e.onDialectOrElse({
2698
- mysql: () => ir(e).pipe(S.flatMap((t) => X(e, ii(o, n.declared, t), o.kind, [lr]))),
2699
- mssql: () => Z(e, [...mi(o.table, o.index.columns, n.declared), pi(o)], o.kind),
2700
- orElse: () => X(e, ri(o, t.classification === "online-required"), o.kind)
2698
+ mysql: () => H(e).pipe(C.flatMap((t) => X(e, oi(o, n.declared, t), o.kind, [dr]))),
2699
+ mssql: () => Z(e, [...gi(o.table, o.index.columns, n.declared), hi(o)], o.kind),
2700
+ orElse: () => X(e, ai(o, t.classification === "online-required"), o.kind)
2701
2701
  });
2702
2702
  break;
2703
2703
  case "drop-index":
2704
2704
  yield* e.onDialectOrElse({
2705
- mysql: () => X(e, oi(o), o.kind),
2706
- mssql: () => X(e, si(o), o.kind),
2707
- orElse: () => X(e, ai(o), o.kind)
2705
+ mysql: () => X(e, ci(o), o.kind),
2706
+ mssql: () => X(e, li(o), o.kind),
2707
+ orElse: () => X(e, si(o), o.kind)
2708
2708
  });
2709
2709
  break;
2710
2710
  case "rename-table":
2711
2711
  yield* e.onDialectOrElse({
2712
- mysql: () => X(e, ci(o, G), o.kind),
2713
- mssql: () => X(e, li(o), o.kind),
2714
- orElse: () => X(e, ci(o, W), o.kind)
2712
+ mysql: () => X(e, ui(o, G), o.kind),
2713
+ mssql: () => X(e, di(o), o.kind),
2714
+ orElse: () => X(e, ui(o, W), o.kind)
2715
2715
  });
2716
2716
  break;
2717
2717
  case "rename-index":
2718
2718
  yield* e.onDialectOrElse({
2719
- mysql: () => X(e, di(o), o.kind),
2720
- mssql: () => X(e, fi(o), o.kind),
2721
- orElse: () => X(e, ui(o), o.kind)
2719
+ mysql: () => X(e, pi(o), o.kind),
2720
+ mssql: () => X(e, mi(o), o.kind),
2721
+ orElse: () => X(e, fi(o), o.kind)
2722
2722
  });
2723
2723
  break;
2724
2724
  case "add-unique":
2725
2725
  yield* e.onDialectOrElse({
2726
- mysql: () => X(e, gi(o, n.declared), o.kind),
2726
+ mysql: () => X(e, vi(o, n.declared), o.kind),
2727
2727
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2728
- mssql: () => Z(e, [...mi(o.table, [o.column], n.declared), hi(o)], o.kind),
2729
- orElse: () => X(e, hi(o), o.kind)
2728
+ mssql: () => Z(e, [...gi(o.table, [o.column], n.declared), _i(o)], o.kind),
2729
+ orElse: () => X(e, _i(o), o.kind)
2730
2730
  });
2731
2731
  break;
2732
2732
  case "drop-unique":
2733
2733
  yield* e.onDialectOrElse({
2734
- mysql: () => X(e, Si(o), o.kind),
2734
+ mysql: () => X(e, wi(o), o.kind),
2735
2735
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2736
- orElse: () => X(e, xi(o), o.kind)
2736
+ orElse: () => X(e, Ci(o), o.kind)
2737
2737
  });
2738
2738
  break;
2739
2739
  case "add-unique-composite":
2740
2740
  yield* e.onDialectOrElse({
2741
- mysql: () => X(e, vi(o, n.declared), o.kind),
2741
+ mysql: () => X(e, bi(o, n.declared), o.kind),
2742
2742
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2743
- mssql: () => Z(e, [...mi(o.table, o.fields, n.declared), _i(o)], o.kind),
2744
- orElse: () => X(e, _i(o), o.kind)
2743
+ mssql: () => Z(e, [...gi(o.table, o.fields, n.declared), yi(o)], o.kind),
2744
+ orElse: () => X(e, yi(o), o.kind)
2745
2745
  });
2746
2746
  break;
2747
2747
  case "drop-unique-composite":
2748
2748
  yield* e.onDialectOrElse({
2749
- mysql: () => X(e, bi(o), o.kind),
2749
+ mysql: () => X(e, Si(o), o.kind),
2750
2750
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2751
- orElse: () => X(e, yi(o), o.kind)
2751
+ orElse: () => X(e, xi(o), o.kind)
2752
2752
  });
2753
2753
  break;
2754
2754
  case "add-foreign-key":
2755
2755
  yield* e.onDialectOrElse({
2756
- mysql: () => Z(e, Ci(o, G), o.kind),
2756
+ mysql: () => Z(e, Ti(o, G), o.kind),
2757
2757
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2758
- orElse: () => Z(e, Ci(o, W), o.kind)
2758
+ orElse: () => Z(e, Ti(o, W), o.kind)
2759
2759
  });
2760
2760
  break;
2761
2761
  case "add-column": {
2762
- let n = Ai(o, t, a, yield* e.onDialectOrElse({
2763
- mysql: () => S.succeed("mariadb"),
2764
- mssql: () => S.succeed("mssql"),
2765
- sqlite: () => S.succeed("sqlite"),
2766
- orElse: () => S.succeed("postgres")
2762
+ let n = Mi(o, t, a, yield* e.onDialectOrElse({
2763
+ mysql: () => C.succeed("mariadb"),
2764
+ mssql: () => C.succeed("mssql"),
2765
+ sqlite: () => C.succeed("sqlite"),
2766
+ orElse: () => C.succeed("postgres")
2767
2767
  }));
2768
- if (!(r === "resume" && (yield* $(e, Ne(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2768
+ if (!(r === "resume" && (yield* $(e, Ie(e), o.table, o.column.name)))) for (let t of n.pre) yield* X(e, t, o.kind);
2769
2769
  if (n.backfillKind === "sql" && n.backfillSql) {
2770
2770
  if (t.classification !== "online-required" && n.batchSize === void 0) yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql}`;
2771
2771
  else {
@@ -2774,10 +2774,10 @@ BEGIN
2774
2774
  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)}`;
2775
2775
  if (s.length === 0) break;
2776
2776
  let c = s.map((e) => e.id);
2777
- yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${n.backfillSql} WHERE ${e("id")} IN ${e.in(c)}`, a += s.length, yield* S.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows`).pipe(S.annotateLogs({
2777
+ 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({
2778
2778
  scope: "voltro:migrate",
2779
2779
  mode: "sql-batched"
2780
- })), i = s[s.length - 1].id, r > 0 && (yield* S.sleep(`${r} millis`));
2780
+ })), i = s[s.length - 1].id, r > 0 && (yield* C.sleep(`${r} millis`));
2781
2781
  }
2782
2782
  }
2783
2783
  } else if (n.backfillKind === "js" && n.backfillJs) {
@@ -2786,17 +2786,17 @@ BEGIN
2786
2786
  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)}`;
2787
2787
  if (s.length === 0) break;
2788
2788
  for (let t of s) {
2789
- let r = yield* S.tryPromise({
2789
+ let r = yield* C.tryPromise({
2790
2790
  try: () => Promise.resolve(n.backfillJs({ id: t.id })),
2791
2791
  catch: (e) => e
2792
- }).pipe(S.orDie);
2792
+ }).pipe(C.orDie);
2793
2793
  yield* e`UPDATE ${e(o.table)} SET ${e(o.column.name)} = ${r} WHERE ${e("id")} = ${t.id}`;
2794
2794
  }
2795
- a += s.length, yield* S.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(S.annotateLogs({
2795
+ a += s.length, yield* C.logInfo(`backfill ${o.table}.${o.column.name}: ${a} rows processed`).pipe(C.annotateLogs({
2796
2796
  scope: "voltro:migrate",
2797
2797
  table: o.table,
2798
2798
  column: o.column.name
2799
- })), i = s[s.length - 1].id, r > 0 && (yield* S.sleep(`${r} millis`));
2799
+ })), i = s[s.length - 1].id, r > 0 && (yield* C.sleep(`${r} millis`));
2800
2800
  }
2801
2801
  }
2802
2802
  for (let t of n.post) yield* X(e, t, o.kind);
@@ -2806,43 +2806,43 @@ BEGIN
2806
2806
  yield* e.onDialectOrElse({
2807
2807
  mysql: () => {
2808
2808
  let t = K(n.declared, o.table, o.column);
2809
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(t, o.column, o.toNullable)};`, o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2809
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Ar(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.`));
2810
2810
  },
2811
2811
  mssql: () => {
2812
2812
  let t = K(n.declared, o.table, o.column);
2813
- return t ? X(e, Kr(t, o.column, o.table, o.toNullable), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2813
+ return t ? X(e, Jr(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}'.`));
2814
2814
  },
2815
2815
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2816
2816
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2817
2817
  });
2818
2818
  break;
2819
2819
  case "alter-column-default": {
2820
- let t = Dr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Tr(r, e) ? r : void 0;
2820
+ let t = kr(n.declared, o.table, o.column), r = K(n.declared, o.table, o.column), i = (e) => o.hasDefault && r !== void 0 && Dr(r, e) ? r : void 0;
2821
2821
  yield* e.onDialectOrElse({
2822
2822
  mysql: () => {
2823
2823
  let n = i("mariadb");
2824
- return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(n, o.column)};` : wr(o, G, (e) => kr(e, t)), o.kind);
2824
+ return X(e, n ? `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Ar(n, o.column)};` : Er(o, G, (e) => jr(e, t)), o.kind);
2825
2825
  },
2826
2826
  mssql: () => {
2827
2827
  let t = i("mssql");
2828
- return X(e, qr(o, t ? Kr(t, o.column, o.table) : void 0), o.kind);
2828
+ return X(e, Yr(o, t ? Jr(t, o.column, o.table) : void 0), o.kind);
2829
2829
  },
2830
2830
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2831
- orElse: () => X(e, wr(o, W, (e) => jr(e, t)), o.kind)
2831
+ orElse: () => X(e, Er(o, W, (e) => Nr(e, t)), o.kind)
2832
2832
  });
2833
2833
  break;
2834
2834
  }
2835
2835
  case "alter-column-type": {
2836
- let r = gr(Dr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2836
+ let r = vr(kr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2837
2837
  if (t.classification !== "online-required") {
2838
2838
  yield* e.onDialectOrElse({
2839
2839
  mysql: () => {
2840
2840
  let t = K(n.declared, o.table, o.column);
2841
- return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Or(t, o.column)};`, o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2841
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${Ar(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.`));
2842
2842
  },
2843
2843
  mssql: () => {
2844
2844
  let t = K(n.declared, o.table, o.column);
2845
- return t ? X(e, Kr(t, o.column, o.table), o.kind) : S.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2845
+ return t ? X(e, Jr(t, o.column, o.table), o.kind) : C.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2846
2846
  },
2847
2847
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2848
2848
  orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
@@ -2850,8 +2850,8 @@ BEGIN
2850
2850
  break;
2851
2851
  }
2852
2852
  yield* e.onDialectOrElse({
2853
- mysql: () => S.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.`)),
2854
- orElse: () => S.void
2853
+ 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.`)),
2854
+ orElse: () => C.void
2855
2855
  });
2856
2856
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2857
2857
  yield* e.unsafe(`ALTER TABLE ${W(o.table)} ADD COLUMN ${W(a)} ${r}`);
@@ -2861,27 +2861,27 @@ BEGIN
2861
2861
  if (t.length === 0) break;
2862
2862
  yield* e.unsafe(`UPDATE ${W(o.table)} SET ${W(a)} = ${c} WHERE ${W(o.column)} IS NOT NULL AND ${W(a)} IS NULL AND ${W("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2863
2863
  }
2864
- yield* S.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(o.column)} TO ${W(s)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(a)} TO ${W(o.column)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} DROP COLUMN ${W(s)}`);
2864
+ 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)}`);
2865
2865
  break;
2866
2866
  }
2867
2867
  case "drop-foreign-key":
2868
2868
  yield* e.onDialectOrElse({
2869
- mysql: () => X(e, Ti(o), o.kind),
2869
+ mysql: () => X(e, Di(o), o.kind),
2870
2870
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2871
- orElse: () => X(e, wi(o), o.kind)
2871
+ orElse: () => X(e, Ei(o), o.kind)
2872
2872
  });
2873
2873
  break;
2874
2874
  case "add-check":
2875
2875
  yield* e.onDialectOrElse({
2876
- mysql: () => X(e, Ei(o, G), o.kind),
2876
+ mysql: () => X(e, Oi(o, G), o.kind),
2877
2877
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2878
- orElse: () => X(e, Ei(o, W), o.kind)
2878
+ orElse: () => X(e, Oi(o, W), o.kind)
2879
2879
  });
2880
2880
  break;
2881
2881
  case "drop-check": yield* e.onDialectOrElse({
2882
- mysql: () => ki(e, o, n.declared),
2882
+ mysql: () => ji(e, o, n.declared),
2883
2883
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2884
- orElse: () => X(e, Di(o), o.kind)
2884
+ orElse: () => X(e, ki(o), o.kind)
2885
2885
  });
2886
2886
  }
2887
2887
  return {
@@ -2889,32 +2889,32 @@ BEGIN
2889
2889
  status: "applied",
2890
2890
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2891
2891
  };
2892
- }), Bi = (e, t, n, r) => S.gen(function* () {
2892
+ }), Hi = (e, t, n, r) => C.gen(function* () {
2893
2893
  let i = [...new Set(r.map((e) => e.runId))];
2894
- if (i.length > 1) return yield* S.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${k}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2894
+ 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 \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2895
2895
  let a = i[0], o = [...r].map((e) => ({
2896
2896
  index: Number(e.opIndex),
2897
2897
  status: e.status,
2898
2898
  planned: JSON.parse(e.payload)
2899
2899
  })).sort((e, t) => e.index - t.index), s = o.find((e) => e.status === "started"), c = o.filter((e) => e.status === "started").length;
2900
- if (c > 1) return yield* S.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.`));
2901
- if (yield* S.logWarning(`migration resume: found an interrupted run (${a}) — ${o.filter((e) => e.status === "applied").length} of ${o.length} operation(s) completed${s ? `, in flight: ${s.planned.op.kind} ${Re(s.planned.op)}` : ""}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2900
+ 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 \`${O}\` by hand before re-running.`));
2901
+ 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} ${Ve(s.planned.op)}` : ""}`).pipe(C.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2902
2902
  kind: "discard",
2903
2903
  runId: a,
2904
2904
  why: "no operation had started — no DDL ran"
2905
2905
  };
2906
- let l = s ? yield* Ri(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2906
+ let l = s ? yield* Bi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2907
2907
  if (u !== n.toFingerprint) return {
2908
2908
  kind: "discard",
2909
2909
  runId: a,
2910
2910
  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`
2911
2911
  };
2912
- let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : Be(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2912
+ let d = (e) => e.status === "applied" ? !1 : s && e.index === s.index && l !== "clean" ? l === "outstanding" : Ue(n, e.planned.op), f = o.filter(d), p = o.filter((e) => e.status !== "applied" && !d(e));
2913
2913
  return f.length === 0 ? {
2914
2914
  kind: "discard",
2915
2915
  runId: a,
2916
2916
  why: "every recorded operation had already taken effect"
2917
- } : (yield* Ii(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* S.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), {
2917
+ } : (yield* Ri(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" })), {
2918
2918
  kind: "resume",
2919
2919
  runId: a,
2920
2920
  ops: f.map((e) => ({
@@ -2922,7 +2922,7 @@ BEGIN
2922
2922
  planned: e.planned
2923
2923
  }))
2924
2924
  });
2925
- }), Vi = (e) => {
2925
+ }), Ui = (e) => {
2926
2926
  let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
2927
2927
  return [
2928
2928
  t.kind,
@@ -2931,64 +2931,64 @@ BEGIN
2931
2931
  n("name"),
2932
2932
  n("to")
2933
2933
  ].join("\0");
2934
- }, Hi = (e, t, n) => S.gen(function* () {
2934
+ }, Wi = (e, t, n) => C.gen(function* () {
2935
2935
  let r = t.operations.filter((e) => e.blocked);
2936
- if (r.length > 0) return yield* S.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2937
- yield* je(e, { schema: n.lockSchema });
2938
- let i = Date.now(), a = [], o = Ne(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => Vi(e))), l = {
2936
+ 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.`));
2937
+ yield* Pe(e, { schema: n.lockSchema });
2938
+ let i = Date.now(), a = [], o = Ie(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => Ui(e))), l = {
2939
2939
  ...s,
2940
2940
  operations: s.operations.map((e) => {
2941
- if (!e.blocked || !c.has(Vi(e))) return e;
2941
+ if (!e.blocked || !c.has(Ui(e))) return e;
2942
2942
  let { blocked: t, ...n } = e;
2943
2943
  return n;
2944
2944
  })
2945
2945
  };
2946
- (l.operations.length !== t.operations.length || l.toFingerprint !== t.toFingerprint) && (yield* S.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(S.annotateLogs({ scope: "voltro:migrate" })));
2946
+ (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" })));
2947
2947
  let u = l.operations.filter((e) => e.blocked);
2948
- if (u.length > 0) return yield* O(e, { schema: n.lockSchema }).pipe(S.orDie), yield* S.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.`));
2949
- let d = Fe(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) => ({
2948
+ if (u.length > 0) return yield* D(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.`));
2949
+ let d = Re(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) => ({
2950
2950
  index: t,
2951
2951
  planned: e
2952
- })), g = "fresh";
2952
+ })), _ = "fresh";
2953
2953
  try {
2954
- yield* Mi(e, o);
2955
- let t = yield* Ni(e);
2954
+ yield* Pi(e, o);
2955
+ let t = yield* Fi(e);
2956
2956
  if (t.length > 0) {
2957
- let n = yield* Bi(e, o, l, t);
2958
- n.kind === "resume" ? (m = n.runId, h = n.ops, g = "resume") : (yield* S.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(S.annotateLogs({ scope: "voltro:migrate" })), yield* Li(e, n.runId));
2957
+ let n = yield* Hi(e, o, l, t);
2958
+ 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* zi(e, n.runId));
2959
2959
  }
2960
- g === "fresh" && h.length > 0 && (yield* Pi(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(S.gen(function* () {
2960
+ _ === "fresh" && h.length > 0 && (yield* Ii(e, m, l.toFingerprint, h)), f.length > 0 && (yield* e.withTransaction(C.gen(function* () {
2961
2961
  let e = yield* T.SqlClient;
2962
- for (let t of f) a.push(yield* zi(e, t, n));
2962
+ for (let t of f) a.push(yield* Vi(e, t, n));
2963
2963
  })));
2964
2964
  for (let { index: t, planned: r } of h) {
2965
- yield* Fi(e, m, t, "started");
2966
- let i = a.length, o = yield* zi(e, r, n, g).pipe(S.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${h.length + f.length} operation(s) applied before this one${f.length > 0 ? ` (${f.length} of them in a transaction)` : ""}.\n` + (d ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The next \`voltro db apply\` resumes from operation ${t} — the ledger records the sequence.\n`) })));
2967
- a.push(o), yield* Fi(e, m, t, "applied", o.durationMs);
2965
+ yield* Li(e, m, t, "started");
2966
+ let i = a.length, o = yield* Vi(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`) })));
2967
+ a.push(o), yield* Li(e, m, t, "applied", o.durationMs);
2968
2968
  }
2969
2969
  } finally {
2970
- yield* O(e, { schema: n.lockSchema }).pipe(S.orDie);
2970
+ yield* D(e, { schema: n.lockSchema }).pipe(C.orDie);
2971
2971
  }
2972
- let _ = yield* n.replan(e);
2973
- if (_.operations.length > 0) {
2974
- let e = _.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2975
- return yield* S.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${l.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${_.operations.length}:\n${e}${_.operations.length > 10 ? `\n … and ${_.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2972
+ let v = yield* n.replan(e);
2973
+ if (v.operations.length > 0) {
2974
+ 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");
2975
+ 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.`));
2976
2976
  }
2977
- let y = a.filter((e) => e.status === "applied").length, b = Date.now() - i, x = m, C = (/* @__PURE__ */ new Date()).toISOString(), ee = yield* U(e, C), w = [...f, ...h.map((e) => e.planned)];
2977
+ 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)];
2978
2978
  yield* e`
2979
2979
  INSERT INTO ${e("_voltro_migration_plans")}
2980
2980
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
2981
2981
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
2982
2982
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
2983
2983
  VALUES
2984
- (${x}, ${l.toFingerprint}, ${_.fromFingerprint}, ${JSON.stringify(w)},
2984
+ (${x}, ${l.toFingerprint}, ${v.fromFingerprint}, ${JSON.stringify(w)},
2985
2985
  ${n.appliedBy}, ${n.environment}, ${n.source},
2986
2986
  ${b}, ${ee}, ${n.notes ?? null})
2987
- `, yield* Li(e, m);
2987
+ `, yield* zi(e, m);
2988
2988
  let te = [...new Set(w.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2989
- return yield* S.promise(() => v({ changedTables: te }).catch(() => {})), {
2989
+ return yield* C.promise(() => g({ changedTables: te }).catch(() => {})), {
2990
2990
  id: x,
2991
- appliedAt: C,
2991
+ appliedAt: S,
2992
2992
  fingerprint: l.toFingerprint,
2993
2993
  operations: w,
2994
2994
  appliedBy: n.appliedBy,
@@ -2998,13 +2998,13 @@ BEGIN
2998
2998
  source: n.source,
2999
2999
  ...n.notes ? { notes: n.notes } : {}
3000
3000
  };
3001
- }), Ui = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Wi = (e) => e`
3001
+ }), Gi = (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"), Ki = (e) => e`
3002
3002
  SELECT fingerprint
3003
3003
  FROM _voltro_migration_plans
3004
3004
  ORDER BY ${e("appliedAt")} DESC
3005
3005
  LIMIT 1
3006
- `.pipe(S.map((e) => e.length > 0 ? e[0].fingerprint : void 0), S.catchAll(() => S.succeed(void 0))), Gi = (e, t, n) => S.gen(function* () {
3007
- if ((yield* Wi(e)) === t.toFingerprint) return "already-current";
3006
+ `.pipe(C.map((e) => e.length > 0 ? e[0].fingerprint : void 0), C.catchAll(() => C.succeed(void 0))), qi = (e, t, n) => C.gen(function* () {
3007
+ if ((yield* Ki(e)) === t.toFingerprint) return "already-current";
3008
3008
  let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3009
3009
  return yield* e`
3010
3010
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3016,8 +3016,8 @@ BEGIN
3016
3016
  ${n.appliedBy}, ${n.environment}, ${n.source},
3017
3017
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
3018
3018
  `, "recorded";
3019
- }).pipe(S.catchAll(() => S.succeed("already-current"))), Ki = (e, t) => S.gen(function* () {
3020
- let n = Gt(I(t, Ne(e))), r = yield* Wi(e);
3019
+ }).pipe(C.catchAll(() => C.succeed("already-current"))), Ji = (e, t) => C.gen(function* () {
3020
+ let n = Jt(F(t, Ie(e))), r = yield* Ki(e);
3021
3021
  return r === n ? {
3022
3022
  kind: "up-to-date",
3023
3023
  fingerprint: n
@@ -3026,23 +3026,23 @@ BEGIN
3026
3026
  expected: n,
3027
3027
  ...r === void 0 ? {} : { actual: r }
3028
3028
  };
3029
- }), qi = [
3029
+ }), Yi = [
3030
3030
  "pgeagertest_",
3031
3031
  "mig_e2e_",
3032
3032
  "mig_test_",
3033
3033
  "mysqleagertest_",
3034
3034
  "mssqleagertest_",
3035
3035
  "sqliteeagertest_"
3036
- ], Ji = (e) => qi.some((t) => e.startsWith(t)), Yi = (e, t) => S.gen(function* () {
3036
+ ], Xi = (e) => Yi.some((t) => e.startsWith(t)), Zi = (e, t) => C.gen(function* () {
3037
3037
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
3038
- let n = t.filter((e) => Ji(e.name)).map((e) => e.name);
3038
+ let n = t.filter((e) => Xi(e.name)).map((e) => e.name);
3039
3039
  if (n.length === 0) return [];
3040
- for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(S.catchAll(() => S.void));
3040
+ for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(C.catchAll(() => C.void));
3041
3041
  return n;
3042
- }), Xi = () => {
3042
+ }), Qi = () => {
3043
3043
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
3044
3044
  return e.length > 0 ? { ignoreTables: e } : {};
3045
- }, Zi = (e) => {
3045
+ }, $i = (e) => {
3046
3046
  if (e === void 0) return;
3047
3047
  let t = e.trim();
3048
3048
  if (t === "") return;
@@ -3052,87 +3052,94 @@ BEGIN
3052
3052
  kind: "tables",
3053
3053
  tables: new Set(n)
3054
3054
  } : void 0;
3055
- }, Qi = (e) => typeof e.table == "string" ? e.table : void 0, $i = (e, t = { kind: "all" }) => ({
3055
+ }, ea = (e) => typeof e.table == "string" ? e.table : void 0, ta = (e, t = { kind: "all" }) => ({
3056
3056
  ...e,
3057
3057
  operations: e.operations.map((e) => {
3058
3058
  if (!e.blocked || e.classification !== "lossy") return e;
3059
3059
  if (t?.kind === "tables") {
3060
- let n = Qi(e.op);
3060
+ let n = ea(e.op);
3061
3061
  if (n === void 0 || !t.tables.has(n)) return e;
3062
3062
  }
3063
3063
  let { blocked: n, ...r } = e;
3064
3064
  return r;
3065
3065
  })
3066
- }), ea = (e, t, n) => t === "postgres" ? Zt(e, n).pipe(S.flatMap((e) => {
3067
- let t = Qt(e);
3068
- return t === void 0 ? S.void : S.logWarning(`auto-migrate: ${t}`).pipe(S.annotateLogs({ scope: "voltro:migrate" }));
3069
- }), S.catchAll(() => S.void)) : S.void, ta = (e, t, n) => S.gen(function* () {
3070
- let r = Ne(e), i = t;
3066
+ }), na = (e, t, n) => t === "postgres" ? en(e, n).pipe(C.flatMap((e) => {
3067
+ let t = tn(e);
3068
+ return t === void 0 ? C.void : C.logWarning(`auto-migrate: ${t}`).pipe(C.annotateLogs({ scope: "voltro:migrate" }));
3069
+ }), C.catchAll(() => C.void)) : C.void, ra = (e, t, n) => C.gen(function* () {
3070
+ let r = Ie(e), a = t;
3071
3071
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
3072
- let t = Gt(I(i, r));
3073
- if ((yield* Wi(e)) === t) return yield* ea(e, r, i), {
3072
+ let t = Jt(F(a, r));
3073
+ if ((yield* Ki(e)) === t) return yield* na(e, r, a), {
3074
3074
  kind: "up-to-date",
3075
3075
  fingerprint: t
3076
3076
  };
3077
3077
  }
3078
- let a = yield* tr(e), o = yield* Yi(e, a.tables);
3079
- o.length > 0 && (yield* S.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(S.annotateLogs({
3078
+ let o = yield* ir(e), s = yield* Zi(e, o.tables);
3079
+ s.length > 0 && (yield* C.logInfo(`auto-migrate: reaped ${s.length} test-fixture leftover(s)`).pipe(C.annotateLogs({
3080
3080
  scope: "voltro:migrate",
3081
- count: o.length
3082
- })), a = yield* tr(e));
3083
- let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !h(e.name) || s.has(e.name)), l = Pn({
3084
- declared: i,
3085
- live: { tables: c(a.tables) },
3081
+ count: s.length
3082
+ })), o = yield* ir(e));
3083
+ {
3084
+ let e = n.softDropRetentionDays ?? 7, t = p(o, { retentionDays: e });
3085
+ t.length > 0 && (yield* C.logWarning(`auto-migrate: ${i(t, e)}`).pipe(C.annotateLogs({
3086
+ scope: "voltro:migrate",
3087
+ snapshots: t.map((e) => e.name)
3088
+ })));
3089
+ }
3090
+ let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !_(e.name) || c.has(e.name)), u = Ln({
3091
+ declared: a,
3092
+ live: { tables: l(o.tables) },
3086
3093
  dialect: r,
3087
- ...Xi()
3094
+ ...Qi()
3088
3095
  });
3089
- if (l.summary.blocked > 0) {
3090
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Zi(process.env.VOLTRO_DESTRUCTIVE_OK);
3091
- if (t === void 0 || !e || (l = $i(l, t), l.operations.some((e) => e.blocked))) return {
3096
+ if (u.summary.blocked > 0) {
3097
+ let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = $i(process.env.VOLTRO_DESTRUCTIVE_OK);
3098
+ if (t === void 0 || !e || (u = ta(u, t), u.operations.some((e) => e.blocked))) return {
3092
3099
  kind: "refused-blocked",
3093
- plan: l
3100
+ plan: u
3094
3101
  };
3095
3102
  }
3096
- return l.operations.length === 0 ? (yield* Gi(e, l, {
3103
+ return u.operations.length === 0 ? (yield* qi(e, u, {
3097
3104
  appliedBy: n.appliedBy,
3098
3105
  environment: n.environment === "prod" ? "dev" : n.environment,
3099
3106
  source: "auto-diff"
3100
3107
  }), {
3101
3108
  kind: "up-to-date",
3102
- fingerprint: l.toFingerprint
3109
+ fingerprint: u.toFingerprint
3103
3110
  }) : {
3104
3111
  kind: "applied",
3105
- applied: yield* Hi(e, l, {
3112
+ applied: yield* Wi(e, u, {
3106
3113
  declared: t,
3107
3114
  appliedBy: n.appliedBy,
3108
3115
  environment: n.environment === "prod" ? "dev" : n.environment,
3109
3116
  source: "auto-diff",
3110
- replan: (e) => S.gen(function* () {
3111
- let t = yield* tr(e);
3112
- return Pn({
3113
- declared: i,
3114
- live: { tables: c(t.tables) },
3117
+ replan: (e) => C.gen(function* () {
3118
+ let t = yield* ir(e);
3119
+ return Ln({
3120
+ declared: a,
3121
+ live: { tables: l(t.tables) },
3115
3122
  dialect: r,
3116
- ...Xi()
3123
+ ...Qi()
3117
3124
  });
3118
3125
  })
3119
3126
  }),
3120
- plan: l
3127
+ plan: u
3121
3128
  };
3122
- }), na = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? S.succeed({
3129
+ }), ia = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? C.succeed({
3123
3130
  kind: "skipped",
3124
3131
  reason: "VOLTRO_AUTO_MIGRATE=0"
3125
- }) : n.environment === "prod" ? Ki(e, t) : ta(e, t, n), ra = (e, t) => {
3132
+ }) : n.environment === "prod" ? Ji(e, t) : ra(e, t, n), aa = (e, t) => {
3126
3133
  switch (e.kind) {
3127
3134
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
3128
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${Kt(e.fingerprint)})`;
3135
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${Yt(e.fingerprint)})`;
3129
3136
  case "applied": {
3130
3137
  let t = e.plan.summary;
3131
- return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${Kt(e.applied.fingerprint)}`;
3138
+ 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=${Yt(e.applied.fingerprint)}`;
3132
3139
  }
3133
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${Kt(e.expected)}` + (e.actual ? ` live=${Kt(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3140
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${Yt(e.expected)}` + (e.actual ? ` live=${Yt(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3134
3141
  case "refused-blocked": {
3135
- let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + Ui(e.plan), c = [""];
3142
+ 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` + Gi(e.plan), c = [""];
3136
3143
  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) {
3137
3144
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3138
3145
  for (let r of e.plan.operations) {
@@ -3149,7 +3156,7 @@ BEGIN
3149
3156
  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");
3150
3157
  }
3151
3158
  }
3152
- }, ia = w({ scope: "voltro:migrate" }), aa = /* @__PURE__ */ new Set([
3159
+ }, oa = ne({ scope: "voltro:migrate" }), sa = /* @__PURE__ */ new Set([
3153
3160
  "node_modules",
3154
3161
  "dist",
3155
3162
  "build",
@@ -3158,25 +3165,25 @@ BEGIN
3158
3165
  ".next",
3159
3166
  ".git",
3160
3167
  ".framework"
3161
- ]), oa = async (e) => {
3168
+ ]), ca = async (e) => {
3162
3169
  let t = [], n = async (e) => {
3163
- let r = await te.readdir(e, { withFileTypes: !0 }).catch(() => []);
3170
+ let r = await re.readdir(e, { withFileTypes: !0 }).catch(() => []);
3164
3171
  for (let i of r) {
3165
- if (aa.has(i.name)) continue;
3166
- let r = ne(e, i.name);
3167
- i.isDirectory() ? await n(r) : i.isFile() && m.test(i.name) && t.push(r);
3172
+ if (sa.has(i.name)) continue;
3173
+ let r = ie(e, i.name);
3174
+ i.isDirectory() ? await n(r) : i.isFile() && S.test(i.name) && t.push(r);
3168
3175
  }
3169
3176
  };
3170
3177
  return await n(e), t.sort((e, t) => {
3171
3178
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3172
3179
  return n.localeCompare(r);
3173
3180
  });
3174
- }, sa = async (e) => {
3181
+ }, la = async (e) => {
3175
3182
  let t = [];
3176
3183
  for (let n of e) {
3177
- let e = (await import(re(n).href)).default;
3178
- if (!g(e)) {
3179
- ia.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3184
+ let e = (await import(ae(n).href)).default;
3185
+ if (!u(e)) {
3186
+ oa.warn("migration file has no default-exported `migration(...)` — skipped", { file: n });
3180
3187
  continue;
3181
3188
  }
3182
3189
  t.push({
@@ -3185,11 +3192,11 @@ BEGIN
3185
3192
  });
3186
3193
  }
3187
3194
  return t;
3188
- }, ca = (e) => e`
3195
+ }, ua = (e) => e`
3189
3196
  SELECT ${e("id")}
3190
3197
  FROM ${e("_voltro_migration_plans")}
3191
3198
  WHERE ${e("source")} = 'file'
3192
- `.pipe(S.map((e) => e.map((e) => e.id)), S.catchAll(() => S.succeed([]))), la = class extends Error {
3199
+ `.pipe(C.map((e) => e.map((e) => e.id)), C.catchAll(() => C.succeed([]))), da = class extends Error {
3193
3200
  migrationId;
3194
3201
  file;
3195
3202
  cause;
@@ -3197,27 +3204,27 @@ BEGIN
3197
3204
  constructor(e, t, n) {
3198
3205
  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";
3199
3206
  }
3200
- }, ua = (e, t, n, r) => S.gen(function* () {
3207
+ }, fa = (e, t, n, r) => C.gen(function* () {
3201
3208
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3202
3209
  sql: e,
3203
3210
  log: {
3204
- info: (e, n) => S.logInfo(e).pipe(S.annotateLogs({
3211
+ info: (e, n) => C.logInfo(e).pipe(C.annotateLogs({
3205
3212
  scope: `migrations:file:${t.migration.id}`,
3206
3213
  ...n ?? {}
3207
3214
  })),
3208
- warn: (e, n) => S.logWarning(e).pipe(S.annotateLogs({
3215
+ warn: (e, n) => C.logWarning(e).pipe(C.annotateLogs({
3209
3216
  scope: `migrations:file:${t.migration.id}`,
3210
3217
  ...n ?? {}
3211
3218
  }))
3212
3219
  },
3213
3220
  appliedAt: a
3214
3221
  }, s = t.migration.up(o);
3215
- S.isEffect(s) ? yield* s : yield* S.tryPromise({
3222
+ C.isEffect(s) ? yield* s : yield* C.tryPromise({
3216
3223
  try: () => s,
3217
3224
  catch: (e) => e
3218
3225
  });
3219
3226
  let c = Date.now() - i;
3220
- !S.isEffect(s) && c < 2 && (yield* S.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(S.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3227
+ !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}` })));
3221
3228
  let l = yield* U(e, a);
3222
3229
  return yield* e`
3223
3230
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3231,94 +3238,94 @@ BEGIN
3231
3238
  }])},
3232
3239
  ${r}, ${n}, ${"file"},
3233
3240
  ${c}, ${l}, ${t.migration.description})
3234
- `.pipe(S.mapError((e) => new la(t.migration.id, t.file, e))), { durationMs: c };
3235
- }), da = (e, t) => S.gen(function* () {
3236
- let n = yield* S.tryPromise({
3237
- try: () => oa(ne(t, "migrations")),
3241
+ `.pipe(C.mapError((e) => new da(t.migration.id, t.file, e))), { durationMs: c };
3242
+ }), pa = (e, t) => C.gen(function* () {
3243
+ let n = yield* C.tryPromise({
3244
+ try: () => ca(ie(t, "migrations")),
3238
3245
  catch: (e) => e
3239
3246
  });
3240
3247
  if (n.length === 0) return {
3241
3248
  pending: [],
3242
3249
  skipped: []
3243
3250
  };
3244
- let r = yield* S.tryPromise({
3245
- try: () => sa(n),
3251
+ let r = yield* C.tryPromise({
3252
+ try: () => la(n),
3246
3253
  catch: (e) => e
3247
3254
  });
3248
3255
  if (r.length === 0) return {
3249
3256
  pending: [],
3250
3257
  skipped: []
3251
3258
  };
3252
- let i = new Set(yield* ca(e));
3259
+ let i = new Set(yield* ua(e));
3253
3260
  return {
3254
3261
  pending: r.filter((e) => !i.has(e.migration.id)),
3255
3262
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3256
3263
  };
3257
- }), fa = (e, t) => da(e, t).pipe(S.map((e) => e.pending.map((e) => e.migration.id))), pa = (e, t) => S.gen(function* () {
3258
- let { pending: n, skipped: r } = yield* da(e, t.projectRoot);
3264
+ }), ma = (e, t) => pa(e, t).pipe(C.map((e) => e.pending.map((e) => e.migration.id))), ha = (e, t) => C.gen(function* () {
3265
+ let { pending: n, skipped: r } = yield* pa(e, t.projectRoot);
3259
3266
  if (n.length === 0) return {
3260
3267
  applied: [],
3261
3268
  skipped: r
3262
3269
  };
3263
- yield* je(e, { schema: t.lockSchema });
3270
+ yield* Pe(e, { schema: t.lockSchema });
3264
3271
  let i = [];
3265
3272
  try {
3266
3273
  for (let r of n) {
3267
- yield* S.logInfo("file-based migration applying").pipe(S.annotateLogs({
3274
+ yield* C.logInfo("file-based migration applying").pipe(C.annotateLogs({
3268
3275
  scope: "voltro:migrate",
3269
3276
  id: r.migration.id,
3270
3277
  file: r.file
3271
3278
  }));
3272
- let { durationMs: n } = yield* ua(e, r, t.env, t.appliedBy);
3279
+ let { durationMs: n } = yield* fa(e, r, t.env, t.appliedBy);
3273
3280
  i.push({
3274
3281
  id: r.migration.id,
3275
3282
  durationMs: n
3276
- }), yield* S.logInfo("file-based migration applied").pipe(S.annotateLogs({
3283
+ }), yield* C.logInfo("file-based migration applied").pipe(C.annotateLogs({
3277
3284
  scope: "voltro:migrate",
3278
3285
  id: r.migration.id,
3279
3286
  durationMs: n
3280
3287
  }));
3281
3288
  }
3282
3289
  } finally {
3283
- yield* O(e, { schema: t.lockSchema }).pipe(S.orDie);
3290
+ yield* D(e, { schema: t.lockSchema }).pipe(C.orDie);
3284
3291
  }
3285
3292
  return {
3286
3293
  applied: i,
3287
3294
  skipped: r
3288
3295
  };
3289
- }), ma = (e, t) => e`
3296
+ }), ga = (e, t) => e`
3290
3297
  SELECT ${e("id")}
3291
3298
  FROM ${e("_voltro_migration_plans")}
3292
3299
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3293
3300
  LIMIT 1
3294
- `, ha = (e, t) => S.gen(function* () {
3295
- if (!(yield* ma(e, t.id))[0]) return yield* S.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3296
- let n = yield* S.tryPromise({
3297
- try: () => oa(ne(t.projectRoot, "migrations")),
3301
+ `, _a = (e, t) => C.gen(function* () {
3302
+ if (!(yield* ga(e, t.id))[0]) return yield* C.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3303
+ let n = yield* C.tryPromise({
3304
+ try: () => ca(ie(t.projectRoot, "migrations")),
3298
3305
  catch: (e) => e
3299
- }), r = (yield* S.tryPromise({
3300
- try: () => sa(n),
3306
+ }), r = (yield* C.tryPromise({
3307
+ try: () => la(n),
3301
3308
  catch: (e) => e
3302
3309
  })).find((e) => e.migration.id === t.id);
3303
- if (!r) return yield* S.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3304
- yield* je(e, { schema: t.lockSchema });
3310
+ if (!r) return yield* C.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3311
+ yield* Pe(e, { schema: t.lockSchema });
3305
3312
  let i = Date.now();
3306
3313
  try {
3307
3314
  let n = {
3308
3315
  sql: e,
3309
3316
  log: {
3310
- info: (e, n) => S.logInfo(e).pipe(S.annotateLogs({
3317
+ info: (e, n) => C.logInfo(e).pipe(C.annotateLogs({
3311
3318
  scope: `migrations:file:${t.id}`,
3312
3319
  ...n ?? {}
3313
3320
  })),
3314
- warn: (e, n) => S.logWarning(e).pipe(S.annotateLogs({
3321
+ warn: (e, n) => C.logWarning(e).pipe(C.annotateLogs({
3315
3322
  scope: `migrations:file:${t.id}`,
3316
3323
  ...n ?? {}
3317
3324
  }))
3318
3325
  },
3319
3326
  appliedAt: (/* @__PURE__ */ new Date()).toISOString()
3320
3327
  }, a = r.migration.down(n);
3321
- S.isEffect(a) ? yield* a : yield* S.tryPromise({
3328
+ C.isEffect(a) ? yield* a : yield* C.tryPromise({
3322
3329
  try: () => a,
3323
3330
  catch: (e) => e
3324
3331
  });
@@ -3328,9 +3335,9 @@ BEGIN
3328
3335
  durationMs: o
3329
3336
  };
3330
3337
  } finally {
3331
- yield* O(e, { schema: t.lockSchema }).pipe(S.orDie);
3338
+ yield* D(e, { schema: t.lockSchema }).pipe(C.orDie);
3332
3339
  }
3333
- }), ga = (e) => S.gen(function* () {
3340
+ }), va = (e) => C.gen(function* () {
3334
3341
  let t = yield* T.SqlClient, n = yield* t`
3335
3342
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3336
3343
  WHERE source = 'auto-diff'
@@ -3338,9 +3345,9 @@ BEGIN
3338
3345
  AND appliedAt < ${e.before}
3339
3346
  ORDER BY appliedAt DESC
3340
3347
  `;
3341
- if (n.length === 0) return yield* S.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3348
+ if (n.length === 0) return yield* C.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
3342
3349
  let r = n[0];
3343
- if (r.fingerprint !== e.fingerprint) return yield* S.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.`));
3350
+ 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.`));
3344
3351
  yield* t`
3345
3352
  UPDATE _voltro_migration_plans
3346
3353
  SET squashedAt = CURRENT_TIMESTAMP
@@ -3375,7 +3382,7 @@ BEGIN
3375
3382
  snapshotFingerprint: e.fingerprint,
3376
3383
  snapshotId: i
3377
3384
  };
3378
- }), _a = { safe: !0 }, va = (e) => {
3385
+ }), ya = { safe: !0 }, ba = (e) => {
3379
3386
  switch (e.kind) {
3380
3387
  case "drop-column": return {
3381
3388
  safe: !1,
@@ -3402,7 +3409,7 @@ BEGIN
3402
3409
  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`,
3403
3410
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3404
3411
  };
3405
- case "alter-column-nullability": return e.toNullable ? _a : {
3412
+ case "alter-column-nullability": return e.toNullable ? ya : {
3406
3413
  safe: !1,
3407
3414
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3408
3415
  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)`
@@ -3432,12 +3439,12 @@ BEGIN
3432
3439
  case "drop-unique":
3433
3440
  case "drop-unique-composite":
3434
3441
  case "drop-foreign-key":
3435
- case "drop-check": return _a;
3442
+ case "drop-check": return ya;
3436
3443
  }
3437
- }, ya = (e) => {
3444
+ }, xa = (e) => {
3438
3445
  let t = [];
3439
3446
  for (let n of e) {
3440
- let e = va(n.op);
3447
+ let e = ba(n.op);
3441
3448
  e.safe || t.push({
3442
3449
  op: n,
3443
3450
  reason: e.reason,
@@ -3445,7 +3452,7 @@ BEGIN
3445
3452
  });
3446
3453
  }
3447
3454
  return t;
3448
- }, ba = (e) => {
3455
+ }, Sa = (e) => {
3449
3456
  if (!e.enabled || e.unsafeCount === 0) return {
3450
3457
  refuse: !1,
3451
3458
  warnForced: !1,
@@ -3461,18 +3468,18 @@ BEGIN
3461
3468
  warnForced: !1,
3462
3469
  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.`
3463
3470
  };
3464
- }, xa = (e) => {
3471
+ }, Ca = (e) => {
3465
3472
  let t = e.table;
3466
3473
  if (typeof t == "string") return t;
3467
3474
  let n = e.from;
3468
3475
  return typeof n == "string" ? n : void 0;
3469
- }, Sa = (e) => ({
3476
+ }, wa = (e) => ({
3470
3477
  kind: e.op.kind,
3471
- table: xa(e.op),
3478
+ table: Ca(e.op),
3472
3479
  classification: e.classification,
3473
3480
  reason: e.reason,
3474
3481
  blockedFix: e.blocked?.fix
3475
- }), Ca = (e) => e.operations.map(Sa), wa = async (e) => {
3482
+ }), Ta = (e) => e.operations.map(wa), Ea = async (e) => {
3476
3483
  let t = e.log ?? (() => {}), n = {
3477
3484
  branchId: e.branchId,
3478
3485
  mechanism: e.mechanism,
@@ -3491,10 +3498,10 @@ BEGIN
3491
3498
  applied: !1,
3492
3499
  converged: !1,
3493
3500
  residual: r,
3494
- infidelity: Ca(o)
3501
+ infidelity: Ta(o)
3495
3502
  };
3496
3503
  else {
3497
- let i = await e.plan(), o = Ca(i), s = o.filter((e) => e.classification === "lossy"), c = $i(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Sa);
3504
+ let i = await e.plan(), o = Ta(i), s = o.filter((e) => e.classification === "lossy"), c = ta(i), l = c.operations.filter((e) => e.blocked !== void 0).map(wa);
3498
3505
  if (l.length > 0) a = {
3499
3506
  ...n,
3500
3507
  outcome: "blocked",
@@ -3519,7 +3526,7 @@ BEGIN
3519
3526
  };
3520
3527
  else {
3521
3528
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3522
- let i = Ca(await e.replan());
3529
+ let i = Ta(await e.replan());
3523
3530
  a = {
3524
3531
  ...n,
3525
3532
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3557,7 +3564,7 @@ BEGIN
3557
3564
  ...a,
3558
3565
  tornDown: o
3559
3566
  };
3560
- }, Ta = (e) => {
3567
+ }, Da = (e) => {
3561
3568
  switch (e.outcome) {
3562
3569
  case "clean": return 0;
3563
3570
  case "lossy": return 2;
@@ -3566,22 +3573,22 @@ BEGIN
3566
3573
  case "infidelity": return 1;
3567
3574
  case "failed": return 1;
3568
3575
  }
3569
- }, Ea = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, Da = (e) => {
3576
+ }, Oa = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, ka = (e) => {
3570
3577
  let t = [];
3571
3578
  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"}`);
3572
3579
  else if (e.outcome === "infidelity") {
3573
3580
  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:");
3574
- for (let n of e.infidelity) t.push(Ea(n));
3581
+ for (let n of e.infidelity) t.push(Oa(n));
3575
3582
  } else {
3576
3583
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3577
- for (let n of e.operations) t.push(Ea(n));
3578
- if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(Ea(n));
3584
+ for (let n of e.operations) t.push(Oa(n));
3585
+ 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(Oa(n));
3579
3586
  }
3580
3587
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3581
- }, Oa = (e, ...t) => ({
3588
+ }, Aa = (e, ...t) => ({
3582
3589
  _tag: "RawSqlFragment",
3583
3590
  strings: [...e],
3584
3591
  values: [...t]
3585
- }), ka = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3592
+ }), ja = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3586
3593
  //#endregion
3587
- export { A as DEFAULT_CDC_CHANNEL, m as FILE_MIGRATION_PATTERN, la as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, fe as VOLTRO_MIGRATION_LOCK_KEY, je as acquireMigrationLock, U as appliedAtValue, Lt as applyNamespacedSchema, Hi as applyPlan, Dt as applySchema, ba as assessRollingDeployGate, Ta as branchRehearsalExitCode, Hn as chunkTables, va as classifyRollingDeploySafety, I as declaredSnapshot, et as defaultArrayClause, $e as defaultClause, N as defaultJsonClause, ra as describeOutcome, Zi as destructiveScope, Zt as detectReactiveTriggerDrift, ii as emitAddIndexMysql, zr as emitCreateTableMysql, br as emitDropColumnDdl, xr as emitDropColumnDdlMysql, Et as emitFrameworkBootstrapSql, wt as emitNamespaceProvisionDdl, Tt as emitNamespacedSchemaSql, Ct as emitSchemaSql, nr as engineFromVersion, Gt as fingerprintSchema, ve as fnv1a64, Da as formatBranchRehearsal, Qt as formatReactiveTriggerDrift, Xi as ignoreTablesFromEnv, tr as introspectSchema, cr as isAlreadySatisfied, g as isFileMigration, ka as isRawSqlFragment, kt as isReRunSafeDdl, In as mapPgType, o as migration, ye as migrationLockKeyForSchema, D as migrationLockNameForSchema, ei as mysqlIndexPrefixFor, Ye as notifyFunctionName, P as numericIdSql, Fn as parseEnumCheck, fa as pendingFileMigrationIds, Pn as planMigrations, Rt as provisionTenantNamespace, Je as reactiveTriggerName, mt as reactiveTriggerRepairSql, Gi as recordUpToDate, wa as rehearseMigrationOnBranch, Sa as rehearsedOperation, O as releaseMigrationLock, Lr as renderColumnMysql, Mr as renderColumnPg, me as resolveMigrationLockSchema, ir as resolveMysqlEngine, ha as rollbackFileBasedMigration, ya as rollingDeployUnsafeOps, pa as runFileBasedMigrations, zt as runFrameworkBootstrap, It as runMigrate, na as runPlannedMigrations, Kt as shortFingerprint, qt as snapshotColumn, Oa as sql, M as sqlType, ga as squashMigrationPlans, $i as unblockLossy, Me as withMigrationLock };
3594
+ export { k as DEFAULT_CDC_CHANNEL, S as FILE_MIGRATION_PATTERN, da as FileMigrationLedgerError, Xe as REACTIVE_TRIGGER_PREFIX, me as VOLTRO_MIGRATION_LOCK_KEY, Pe as acquireMigrationLock, U as appliedAtValue, Bt as applyNamespacedSchema, Wi as applyPlan, At as applySchema, Sa as assessRollingDeployGate, Da as branchRehearsalExitCode, Gn as chunkTables, ba as classifyRollingDeploySafety, F as declaredSnapshot, rt as defaultArrayClause, nt as defaultClause, M as defaultJsonClause, aa as describeOutcome, $i as destructiveScope, en as detectReactiveTriggerDrift, oi as emitAddIndexMysql, Hr as emitCreateTableMysql, Sr as emitDropColumnDdl, Cr as emitDropColumnDdlMysql, kt as emitFrameworkBootstrapSql, Dt as emitNamespaceProvisionDdl, Ot as emitNamespacedSchemaSql, Et as emitSchemaSql, ar as engineFromVersion, Jt as fingerprintSchema, be as fnv1a64, ka as formatBranchRehearsal, tn as formatReactiveTriggerDrift, Qi as ignoreTablesFromEnv, ir as introspectSchema, ur as isAlreadySatisfied, u as isFileMigration, ja as isRawSqlFragment, Mt as isReRunSafeDdl, zn as mapPgType, d as migration, xe as migrationLockKeyForSchema, Se as migrationLockNameForSchema, ni as mysqlIndexPrefixFor, Qe as notifyFunctionName, N as numericIdSql, Rn as parseEnumCheck, ma as pendingFileMigrationIds, Ln as planMigrations, Vt as provisionTenantNamespace, Ze as reactiveTriggerName, _t as reactiveTriggerRepairSql, qi as recordUpToDate, Ea as rehearseMigrationOnBranch, wa as rehearsedOperation, D as releaseMigrationLock, Br as renderColumnMysql, Fr as renderColumnPg, ge as resolveMigrationLockSchema, H as resolveMysqlEngine, _a as rollbackFileBasedMigration, xa as rollingDeployUnsafeOps, ha as runFileBasedMigrations, Ht as runFrameworkBootstrap, zt as runMigrate, ia as runPlannedMigrations, Yt as shortFingerprint, Xt as snapshotColumn, Aa as sql, j as sqlType, va as squashMigrationPlans, ta as unblockLossy, Fe as withMigrationLock };