@voltro/database 0.82.0 → 0.83.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,4 +1,4 @@
1
- import { A as e, An as t, Ar as n, B as r, Bt as i, D as a, Dn as o, Dr as s, Dt as c, E as l, En as u, Er as d, F as f, G as p, Gt as m, H as h, Ht as g, I as _, It as v, L as y, M as b, N as x, O as S, P as C, R as w, Rr as T, T as E, Tn as D, V as O, W as ee, Wn as te, X as ne, Xn as re, Yn as ie, _ as ae, at as oe, er as se, h as ce, j as le, jn as ue, k as de, nt as fe, p as pe, r as me, sr as he, t as ge, ut as _e, w as ve, yn as ye, z as be, zr as xe, zt as Se } from "./replaceInProgress-BbN7p1Q-.js";
1
+ import { A as e, B as t, Br as n, D as r, Dn as i, Dt as a, E as o, F as s, G as c, H as l, Ht as u, I as d, It as f, Kn as p, L as m, M as h, Mn as g, Mr as _, N as v, Nn as y, O as ee, On as b, Or as x, P as S, Qn as C, R as w, T as te, V as T, Vr as E, Vt as ne, W as re, Wt as D, X as ie, Zn as ae, _ as oe, at as se, h as ce, j as le, k as ue, kn as O, kr as de, lr as fe, nr as pe, nt as me, p as he, qt as ge, r as _e, t as ve, ut as ye, w as be, xn as xe, z as Se } from "./replaceInProgress-CncEA_Sx.js";
2
2
  import { Cause as Ce, Effect as k, Equal as we, Exit as Te, Schedule as Ee, Scope as De } from "effect";
3
3
  import { createHash as Oe, randomUUID as ke } from "node:crypto";
4
4
  import { createLogger as Ae } from "@voltro/logger";
@@ -14,7 +14,7 @@ var Fe = (e, t = "float32") => {
14
14
  m: r,
15
15
  efConstruction: i
16
16
  })) if (!Number.isSafeInteger(t) || t <= 0) throw Error(`HNSW ${e} must be a positive safe integer`);
17
- let a = n?.opclass ?? ue(n?.distance, t);
17
+ let a = n?.opclass ?? y(n?.distance, t);
18
18
  if (!/^[a-z_][a-z0-9_$]*(?:\.[a-z_][a-z0-9_$]*)?$/i.test(a)) throw Error("HNSW opclass must be an unquoted, optionally schema-qualified identifier");
19
19
  return {
20
20
  m: r,
@@ -196,19 +196,19 @@ var Fe = (e, t = "float32") => {
196
196
  mariadb: "per-operation",
197
197
  sqlite: "per-operation",
198
198
  turso: "per-operation"
199
- }, St = (e) => xt[e], N = "_voltro_migration_ops", Ct = t(N, {
200
- id: d({ prefix: "mop" }),
201
- runId: T(),
202
- planFingerprint: T(),
203
- opIndex: s(),
204
- opKind: T(),
205
- opTarget: T(),
206
- status: T(),
207
- payload: T(),
208
- startedAt: xe().nullable(),
209
- appliedAt: xe().nullable(),
210
- durationMs: s().nullable(),
211
- createdAt: xe().default("now")
199
+ }, St = (e) => xt[e], N = "_voltro_migration_ops", Ct = g(N, {
200
+ id: x({ prefix: "mop" }),
201
+ runId: n(),
202
+ planFingerprint: n(),
203
+ opIndex: de(),
204
+ opKind: n(),
205
+ opTarget: n(),
206
+ status: n(),
207
+ payload: n(),
208
+ startedAt: E().nullable(),
209
+ appliedAt: E().nullable(),
210
+ durationMs: de().nullable(),
211
+ createdAt: E().default("now")
212
212
  }), wt = (e) => {
213
213
  switch (e.kind) {
214
214
  case "create-table": return /* @__PURE__ */ new Set([
@@ -261,7 +261,7 @@ var Fe = (e, t = "float32") => {
261
261
  "alter-column-default"
262
262
  ]), Mt = /* @__PURE__ */ new Set(["alter-column-default", "alter-column-nullability"]), Nt = (e, t, n) => {
263
263
  let r = n === "sqlite" || n === "turso";
264
- return e.kind === "alter-column-type" && t === "online-required" || r && jt.has(e.kind) ? "artefact-repair" : Mt.has(e.kind) ? "idempotent" : "probe-then-replay";
264
+ return n === "postgres" && e.kind === "add-index" && t === "online-required" || e.kind === "alter-column-type" && t === "online-required" || r && jt.has(e.kind) ? "artefact-repair" : Mt.has(e.kind) ? "idempotent" : "probe-then-replay";
265
265
  };
266
266
  Object.keys(xt);
267
267
  //#endregion
@@ -332,7 +332,7 @@ var Pt = (e) => {
332
332
  }, t)}[]`;
333
333
  if (t === "mysql" || t === "mariadb") return "JSON";
334
334
  if (t === "mssql") return "NVARCHAR(MAX)";
335
- if (u(t)) return "TEXT";
335
+ if (b(t)) return "TEXT";
336
336
  }
337
337
  if (n === "vector") {
338
338
  let n = e.vectorDim;
@@ -341,27 +341,27 @@ var Pt = (e) => {
341
341
  if (t === "postgres") return r ? `HALFVEC(${n})` : `VECTOR(${n})`;
342
342
  if (t === "mysql" || t === "mariadb") return `VECTOR(${n})`;
343
343
  if (t === "mssql") return "VARBINARY(MAX)";
344
- if (u(t)) return "BLOB";
344
+ if (b(t)) return "BLOB";
345
345
  }
346
346
  if (n === "interval") {
347
347
  if (t === "postgres") return "INTERVAL";
348
348
  if (t === "mysql" || t === "mariadb" || t === "mssql") return "BIGINT";
349
- if (u(t)) return "INTEGER";
349
+ if (b(t)) return "INTEGER";
350
350
  }
351
351
  if (n === "decimal") {
352
352
  let n = e.precision, r = e.scale ?? 0;
353
353
  if (n === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
354
- return u(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
354
+ return b(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
355
355
  }
356
- if (n === "bigint") return u(t) ? "INTEGER" : "BIGINT";
356
+ if (n === "bigint") return b(t) ? "INTEGER" : "BIGINT";
357
357
  if (n === "enum") {
358
358
  if (t === "postgres") return e.enumName ?? "TEXT";
359
359
  if (t === "mysql" || t === "mariadb") return `ENUM(${(e.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
360
360
  if (t === "mssql") return "NVARCHAR(255)";
361
- if (u(t)) return "TEXT";
361
+ if (b(t)) return "TEXT";
362
362
  }
363
- if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : u(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
364
- if (u(t)) switch (n) {
363
+ if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : b(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
364
+ if (b(t)) switch (n) {
365
365
  case "id": return "TEXT";
366
366
  case "text": return "TEXT";
367
367
  case "integer": return "INTEGER";
@@ -431,7 +431,7 @@ var Pt = (e) => {
431
431
  }, Jt = (e, t) => {
432
432
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
433
433
  let n = e.defaultValue;
434
- return n === "now" ? u(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) ? Yt(n, e, t) : typeof n == "object" && n ? Xt(n, t) : null;
434
+ return n === "now" ? b(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) ? Yt(n, e, t) : typeof n == "object" && n ? Xt(n, t) : null;
435
435
  }, Yt = (e, t, n) => {
436
436
  if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return Xt(e, n);
437
437
  let r = F({
@@ -460,12 +460,12 @@ var Pt = (e) => {
460
460
  case "setNull": return "SET NULL";
461
461
  case "noAction": return "NO ACTION";
462
462
  }
463
- }, $t = (e, t, n) => n === null ? o(e, t) : `${o(n, t)}.${o(e, t)}`, en = 191, tn = (e, t) => {
463
+ }, $t = (e, t, n) => n === null ? O(e, t) : `${O(n, t)}.${O(e, t)}`, en = 191, tn = (e, t) => {
464
464
  if (!e || t !== "mysql" && t !== "mariadb") return !1;
465
465
  let n = F(e, t).toUpperCase();
466
466
  return n.endsWith("TEXT") || n.endsWith("BLOB");
467
467
  }, nn = (e, t, n) => {
468
- let r = o(e, n);
468
+ let r = O(e, n);
469
469
  if (n !== "mysql" && n !== "mariadb") return r;
470
470
  let i = t[e];
471
471
  if (!i) return r;
@@ -479,20 +479,20 @@ var Pt = (e) => {
479
479
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
480
480
  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.");
481
481
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
482
- }, an = (e, t, n, r, i = !1, a = !1) => {
482
+ }, an = (e, t, n, r, a = !1, o = !1) => {
483
483
  if (t.type === "id" && t.idScheme?.kind === "numeric") return Zt(e, n);
484
- let s = n === "mssql" ? Kt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? F(t, n) : `NVARCHAR(${s})`, l = [o(e, n), c];
485
- t.type === "id" && !a && l.push("PRIMARY KEY");
486
- let d = rn(t, n);
487
- if (d) l.push(d);
484
+ let s = n === "mssql" ? Kt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? F(t, n) : `NVARCHAR(${s})`, l = [O(e, n), c];
485
+ t.type === "id" && !o && l.push("PRIMARY KEY");
486
+ let u = rn(t, n);
487
+ if (u) l.push(u);
488
488
  else {
489
489
  t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !tn(t, n) && l.push("UNIQUE");
490
490
  let e = Jt(t, n);
491
491
  e && l.push(e);
492
492
  }
493
- if (t.type === "reference" && t.references && !i && !D(n)) {
493
+ if (t.type === "reference" && t.references && !a && !i(n)) {
494
494
  let e = t.references();
495
- l.push(`REFERENCES ${o(e.tableName, n)} (${o(t.referenceColumn ?? "id", n)})`);
495
+ l.push(`REFERENCES ${O(e.tableName, n)} (${O(t.referenceColumn ?? "id", n)})`);
496
496
  let r = Qt(t.onDelete ?? "restrict", n);
497
497
  l.push(`ON DELETE ${r}`);
498
498
  let i = Qt(t.refOnUpdate ?? "noAction", n);
@@ -500,37 +500,37 @@ var Pt = (e) => {
500
500
  }
501
501
  if (t.oneOf && t.oneOf.length > 0) {
502
502
  let r = t.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
503
- l.push(`CHECK (${o(e, n)} IN (${r}))`);
503
+ l.push(`CHECK (${O(e, n)} IN (${r}))`);
504
504
  }
505
505
  if (t.checks && t.checks.length > 0) for (let e of t.checks) l.push(`CHECK (${e})`);
506
- if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" || u(n))) {
506
+ if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" || b(n))) {
507
507
  let r = t.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
508
- l.push(`CHECK (${o(e, n)} IN (${r}))`);
508
+ l.push(`CHECK (${O(e, n)} IN (${r}))`);
509
509
  }
510
510
  if (t.type === "json" || t.type === "array") {
511
- let r = o(e, n);
512
- u(n) ? l.push(`CHECK (${r} IS NULL OR json_valid(${r}))`) : n === "mssql" && l.push(t.type === "json" ? `CHECK ${Pt(r)}` : `CHECK (${r} IS NULL OR ISJSON(${r}) = 1)`);
511
+ let r = O(e, n);
512
+ b(n) ? l.push(`CHECK (${r} IS NULL OR json_valid(${r}))`) : n === "mssql" && l.push(t.type === "json" ? `CHECK ${Pt(r)}` : `CHECK (${r} IS NULL OR ISJSON(${r}) = 1)`);
513
513
  }
514
514
  return l.join(" ");
515
515
  }, on = (e, t) => {
516
516
  if (t.charset !== void 0) {
517
- if (!D(e)) throw Error(`store charset '${t.charset}' is declared for a ${e} store — a character set is a MySQL / MariaDB setting. Remove \`charset\` from \`store\` in app.config.ts, or declare \`store: { dialect: 'mysql' | 'mariadb', charset }\`.`);
517
+ if (!i(e)) throw Error(`store charset '${t.charset}' is declared for a ${e} store — a character set is a MySQL / MariaDB setting. Remove \`charset\` from \`store\` in app.config.ts, or declare \`store: { dialect: 'mysql' | 'mariadb', charset }\`.`);
518
518
  return t.charset;
519
519
  }
520
- }, sn = (e, t, n = null, r, i) => {
521
- let a = /* @__PURE__ */ new Set();
522
- for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
523
- for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
524
- for (let [t, n] of Object.entries(e.fields)) n.unique && a.add(t);
520
+ }, sn = (e, t, n = null, r, a) => {
521
+ let o = /* @__PURE__ */ new Set();
522
+ for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
523
+ for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
524
+ for (let [t, n] of Object.entries(e.fields)) n.unique && o.add(t);
525
525
  let s = e.appliedPrimaryKey ?? [];
526
- for (let e of s) a.add(e);
527
- let c = s.length > 0, l = Object.entries(e.fields).map(([e, n]) => ` ${an(e, n, t, a, r?.has(e) ?? !1, c)}`).join(",\n"), u = (e.appliedUniques ?? []).map((n) => {
526
+ for (let e of s) o.add(e);
527
+ let c = s.length > 0, l = Object.entries(e.fields).map(([e, n]) => ` ${an(e, n, t, o, r?.has(e) ?? !1, c)}`).join(",\n"), u = (e.appliedUniques ?? []).map((n) => {
528
528
  let r = n.fields.map((n) => nn(n, e.fields, t)).join(", ");
529
- return ` CONSTRAINT ${o(n.name, t)} UNIQUE (${r})`;
530
- }), d = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${o(e.name, t)} CHECK (${e.expr})`), f = c ? [` PRIMARY KEY (${s.map((n) => nn(n, e.fields, t)).join(", ")})`] : [], p = D(t) ? Object.entries(e.fields).flatMap(([i, a]) => {
529
+ return ` CONSTRAINT ${O(n.name, t)} UNIQUE (${r})`;
530
+ }), d = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${O(e.name, t)} CHECK (${e.expr})`), f = c ? [` PRIMARY KEY (${s.map((n) => nn(n, e.fields, t)).join(", ")})`] : [], p = i(t) ? Object.entries(e.fields).flatMap(([i, a]) => {
531
531
  if (a.type !== "reference" || !a.references || (r?.has(i) ?? !1)) return [];
532
- let s = a.references(), c = Qt(a.onDelete ?? "restrict", t), l = Qt(a.refOnUpdate ?? "noAction", t);
533
- return [` CONSTRAINT ${o(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${o(i, t)}) REFERENCES ${$t(s.tableName, t, n)} (${o(a.referenceColumn ?? "id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
532
+ let o = a.references(), s = Qt(a.onDelete ?? "restrict", t), c = Qt(a.refOnUpdate ?? "noAction", t);
533
+ return [` CONSTRAINT ${O(`${e.tableName}_${i}_fkey`, t)} FOREIGN KEY (${O(i, t)}) REFERENCES ${$t(o.tableName, t, n)} (${O(a.referenceColumn ?? "id", t)}) ON DELETE ${s}${c === "NO ACTION" ? "" : ` ON UPDATE ${c}`}`];
534
534
  }) : [], m = [
535
535
  ...f,
536
536
  ...u,
@@ -544,26 +544,26 @@ var Pt = (e) => {
544
544
  return [
545
545
  `CREATE TABLE IF NOT EXISTS ${g} (`,
546
546
  h,
547
- `)${i !== void 0 && D(t) ? ` DEFAULT CHARACTER SET ${i}` : ""};`
547
+ `)${a !== void 0 && i(t) ? ` DEFAULT CHARACTER SET ${a}` : ""};`
548
548
  ].join("\n");
549
549
  }, cn = (e, t, n) => {
550
- 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 = [];
551
- 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;
550
+ let r = `${e}_${t.name}_fts`, i = (e) => O(e, n), a = t.columns.map(i).join(", "), o = t.columns.map((e) => `new.${i(e)}`).join(", "), s = [];
551
+ 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;
552
552
  }, ln = (e) => e.appliedFullText ?? [], un = (e, t) => {
553
553
  let n = [];
554
554
  for (let r of ln(e)) if (t === "postgres") {
555
- let i = r.config ?? "english", a = `${r.name}_tsv`, s = r.columns.map((e) => {
555
+ let i = r.config ?? "english", a = `${r.name}_tsv`, o = r.columns.map((e) => {
556
556
  let n = r.weights?.[e] ?? "A";
557
- return `setweight(to_tsvector('${i}', coalesce(${o(e, t)}, '')), '${n}')`;
557
+ return `setweight(to_tsvector('${i}', coalesce(${O(e, t)}, '')), '${n}')`;
558
558
  }).join(" || ");
559
- n.push(`ALTER TABLE ${o(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${o(a, t)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), n.push(`CREATE INDEX IF NOT EXISTS ${o(r.name, t)} ON ${o(e.tableName, t)} USING GIN (${o(a, t)});`);
559
+ n.push(`ALTER TABLE ${O(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${O(a, t)} tsvector GENERATED ALWAYS AS (${o}) STORED;`), n.push(`CREATE INDEX IF NOT EXISTS ${O(r.name, t)} ON ${O(e.tableName, t)} USING GIN (${O(a, t)});`);
560
560
  } else if (t === "mysql" || t === "mariadb") {
561
- let i = r.columns.map((e) => o(e, t)).join(", ");
562
- n.push(`CREATE FULLTEXT INDEX ${o(r.name, t)} ON ${o(e.tableName, t)} (${i});`);
561
+ let i = r.columns.map((e) => O(e, t)).join(", ");
562
+ n.push(`CREATE FULLTEXT INDEX ${O(r.name, t)} ON ${O(e.tableName, t)} (${i});`);
563
563
  } else t === "turso" || t === "sqlite" && n.push(...cn(e.tableName, r, t));
564
564
  return n;
565
565
  }, dn = (e, t, n = null) => {
566
- let r = [], i = /* @__PURE__ */ new Set(), a = (e) => e.join("\0"), s = (e, n, r, i, a) => {
566
+ let r = [], i = /* @__PURE__ */ new Set(), a = (e) => e.join("\0"), o = (e, n, r, i, a) => {
567
567
  if (t === "postgres") return Re(r, i, a);
568
568
  let o = {
569
569
  using: "",
@@ -579,25 +579,25 @@ var Pt = (e) => {
579
579
  withSuffix: "",
580
580
  skip: !0
581
581
  }) : o;
582
- }, c = (n, r) => {
582
+ }, s = (n, r) => {
583
583
  let i = n.map((n) => {
584
584
  if (typeof n == "string") return nn(n, e.fields, t);
585
585
  if ("jsonPath" in n) {
586
586
  let { column: e, path: r, numeric: i } = n.jsonPath;
587
- return `(${v(e, r, t, { numeric: i })})`;
587
+ return `(${f(e, r, t, { numeric: i })})`;
588
588
  }
589
589
  return `(${n.expr})`;
590
590
  });
591
591
  return r !== void 0 && i.length === 1 ? `${i[0]} ${r}` : i.join(", ");
592
- }, l = (r, i, a, l, d, f = "", p = !1) => {
593
- let m = a[0], h = typeof m == "string" ? e.fields[m]?.vectorPrecision : void 0, g = s(r, i, l, d, h);
594
- if (g.skip) return "";
595
- let _ = c(a, g.opclass), v = `${g.withSuffix}${f}`, y = $t(i, t, n), b = p ? "UNIQUE " : "";
596
- return u(t) && n !== null ? `CREATE ${b}INDEX IF NOT EXISTS ${$t(r, t, n)} ON ${o(i, t)} (${_})${v};` : t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${r}') CREATE ${b}INDEX ${o(r, t)} ON ${y}${g.using} (${_})${v};` : t === "mysql" ? `CREATE ${b}INDEX ${o(r, t)} ON ${y}${g.using} (${_})${v};` : `CREATE ${b}INDEX IF NOT EXISTS ${o(r, t)} ON ${y}${g.using} (${_})${v};`;
592
+ }, c = (r, i, a, c, l, u = "", d = !1) => {
593
+ let f = a[0], p = typeof f == "string" ? e.fields[f]?.vectorPrecision : void 0, m = o(r, i, c, l, p);
594
+ if (m.skip) return "";
595
+ let h = s(a, m.opclass), g = `${m.withSuffix}${u}`, _ = $t(i, t, n), v = d ? "UNIQUE " : "";
596
+ return b(t) && n !== null ? `CREATE ${v}INDEX IF NOT EXISTS ${$t(r, t, n)} ON ${O(i, t)} (${h})${g};` : t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${r}') CREATE ${v}INDEX ${O(r, t)} ON ${_}${m.using} (${h})${g};` : t === "mysql" ? `CREATE ${v}INDEX ${O(r, t)} ON ${_}${m.using} (${h})${g};` : `CREATE ${v}INDEX IF NOT EXISTS ${O(r, t)} ON ${_}${m.using} (${h})${g};`;
597
597
  };
598
598
  if (t === "mysql" || t === "mariadb") for (let [n, i] of Object.entries(e.fields)) {
599
599
  if (!i.unique || i.type === "id" || !tn(i, t)) continue;
600
- let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
600
+ let a = c(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
601
601
  a && r.push(a);
602
602
  }
603
603
  if (r.push(...un(e, t)), t === "mssql") for (let n of ln(e)) P(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
@@ -609,13 +609,13 @@ var Pt = (e) => {
609
609
  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.`);
610
610
  let o = "";
611
611
  n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? P(`[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}`);
612
- let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, o, n.unique === !0);
612
+ let s = c(n.name, e.tableName, n.fields, n.kind, n.kindOptions, o, n.unique === !0);
613
613
  s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && i.add(a(n.fields));
614
614
  }
615
615
  for (let [t, n] of Object.entries(e.fields)) {
616
616
  if (n.type !== "reference" || n.fkAutoIndex === !1 || i.has(a([t]))) continue;
617
617
  let o = `${e.tableName}_${t}_idx`;
618
- r.push(l(o, e.tableName, [t])), i.add(a([t]));
618
+ r.push(c(o, e.tableName, [t])), i.add(a([t]));
619
619
  }
620
620
  return r.join("\n");
621
621
  }, fn = (e, t, n = Rt) => {
@@ -739,23 +739,23 @@ $$ LANGUAGE plpgsql;
739
739
  cyclic: r
740
740
  };
741
741
  }, xn = (e, t, n = null) => {
742
- let r = (e) => n ? `${o(n, t)}.${o(e, t)}` : o(e, t), i = `${e.table}_${e.column}_fkey`, a = Qt(e.onDelete, t), s = Qt(e.onUpdate, t), c = ` ON DELETE ${a}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${o(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${o(e.column, t)}) REFERENCES ${r(e.targetTable)} (${o(e.targetColumn, t)})${c}`;
742
+ let r = (e) => n ? `${O(n, t)}.${O(e, t)}` : O(e, t), i = `${e.table}_${e.column}_fkey`, a = Qt(e.onDelete, t), o = Qt(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${O(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${O(e.column, t)}) REFERENCES ${r(e.targetTable)} (${O(e.targetColumn, t)})${s}`;
743
743
  switch (t) {
744
744
  case "postgres": return [
745
745
  "DO $$ BEGIN",
746
746
  " IF NOT EXISTS (SELECT 1 FROM pg_constraint",
747
747
  ` WHERE conname = '${i}' AND conrelid = '${n ? `${n}.` : ""}${e.table}'::regclass) THEN`,
748
- ` ALTER TABLE ${r(e.table)} ${l(!1)};`,
748
+ ` ALTER TABLE ${r(e.table)} ${c(!1)};`,
749
749
  " END IF;",
750
750
  "END $$;"
751
751
  ].join("\n");
752
- case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${i}') ALTER TABLE ${r(e.table)} ${l(!1)};`;
753
- case "mariadb": return `ALTER TABLE ${r(e.table)} ${l(!0)};`;
754
- default: return `ALTER TABLE ${r(e.table)} ${l(!1)};`;
752
+ case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${i}') ALTER TABLE ${r(e.table)} ${c(!1)};`;
753
+ case "mariadb": return `ALTER TABLE ${r(e.table)} ${c(!0)};`;
754
+ default: return `ALTER TABLE ${r(e.table)} ${c(!1)};`;
755
755
  }
756
756
  }, Sn = (e, t) => {
757
757
  let n = /* @__PURE__ */ new Map();
758
- if (u(t)) return n;
758
+ if (b(t)) return n;
759
759
  for (let t of e) {
760
760
  let e = n.get(t.table) ?? /* @__PURE__ */ new Set();
761
761
  e.add(t.column), n.set(t.table, e);
@@ -782,7 +782,7 @@ $$ LANGUAGE plpgsql;
782
782
  let n = /* @__PURE__ */ new Set();
783
783
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
784
784
  let r = [];
785
- for (let e of n) for (let { from: t, to: n } of he(e)) {
785
+ for (let e of n) for (let { from: t, to: n } of fe(e)) {
786
786
  let i = e.replace(/'/g, "''"), a = t.replace(/'/g, "''"), o = n.replace(/'/g, "''");
787
787
  r.push(`DO \$\$
788
788
  DECLARE
@@ -793,29 +793,29 @@ BEGIN
793
793
  return r.join("\n\n");
794
794
  }, Tn = (e) => {
795
795
  let t = [], n = [];
796
- for (let r of e) g(r) ? n.push(r) : t.push(r);
796
+ for (let r of e) D(r) ? n.push(r) : t.push(r);
797
797
  return {
798
798
  tables: t,
799
799
  views: n
800
800
  };
801
801
  }, En = (e, t, n = Rt, r = {}) => {
802
- let i = on(t, r), { tables: a, views: o } = Tn(e), { sorted: s, cyclic: c } = bn(a.map((e) => Ge(e, t))), l = Sn(c, t), d = [], f = _n(s, t);
803
- f && d.push(f);
804
- let p = wn(s, t);
805
- p && d.push(p);
806
- let h = Cn(s, t);
807
- h && d.push(h);
808
- for (let e of s) d.push(sn(e, t, null, l.get(e.tableName), i));
809
- if (!u(t)) for (let e of c) d.push(xn(e, t));
802
+ let i = on(t, r), { tables: a, views: o } = Tn(e), { sorted: s, cyclic: c } = bn(a.map((e) => Ge(e, t))), l = Sn(c, t), u = [], d = _n(s, t);
803
+ d && u.push(d);
804
+ let f = wn(s, t);
805
+ f && u.push(f);
806
+ let p = Cn(s, t);
807
+ p && u.push(p);
808
+ for (let e of s) u.push(sn(e, t, null, l.get(e.tableName), i));
809
+ if (!b(t)) for (let e of c) u.push(xn(e, t));
810
810
  for (let e of s) {
811
811
  let n = dn(e, t);
812
- n && d.push(n);
812
+ n && u.push(n);
813
813
  }
814
- d.push(...fn(s, t, n));
815
- for (let e of o) d.push(m(e, t));
816
- return d.join("\n\n") + "\n";
814
+ u.push(...fn(s, t, n));
815
+ for (let e of o) u.push(ge(e, t));
816
+ return u.join("\n\n") + "\n";
817
817
  }, Dn = (e, t, n, r) => {
818
- let i = o(e, t);
818
+ let i = O(e, t);
819
819
  switch (t) {
820
820
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${i};`;
821
821
  case "mysql":
@@ -825,16 +825,16 @@ BEGIN
825
825
  case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${i};`;
826
826
  }
827
827
  }, On = (e, t, n, r, i = {}) => {
828
- let a = on(t, i), s = Dn(n, t, r, a), c = o(n, t);
829
- if (t === "postgres") return `${s}\n\nSET search_path TO ${c};\n\n${En(e, t)}`;
830
- let { sorted: l, cyclic: d } = bn(e), f = Sn(d, t), p = [s];
831
- for (let e of l) p.push(sn(e, t, n, f.get(e.tableName), a));
832
- if (!u(t)) for (let e of d) p.push(xn(e, t, n));
833
- for (let e of l) {
828
+ let a = on(t, i), o = Dn(n, t, r, a), s = O(n, t);
829
+ if (t === "postgres") return `${o}\n\nSET search_path TO ${s};\n\n${En(e, t)}`;
830
+ let { sorted: c, cyclic: l } = bn(e), u = Sn(l, t), d = [o];
831
+ for (let e of c) d.push(sn(e, t, n, u.get(e.tableName), a));
832
+ if (!b(t)) for (let e of l) d.push(xn(e, t, n));
833
+ for (let e of c) {
834
834
  let r = dn(e, t, n);
835
- r && p.push(r);
835
+ r && d.push(r);
836
836
  }
837
- return p.join("\n\n") + "\n";
837
+ return d.join("\n\n") + "\n";
838
838
  }, kn = (e, t, n = Rt) => {
839
839
  let { sorted: r, cyclic: i } = bn(e), a = Sn(i, t), o = [], s = wn(r, t);
840
840
  s && o.push(s);
@@ -904,7 +904,7 @@ BEGIN
904
904
  let i = On(e, n, t, void 0, { charset: r.charset }), a = yield* A.SqlClient;
905
905
  yield* bt(a, Rn(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(k.orDie);
906
906
  }), Hn = async (e, t, n, r = "postgres", i = {}) => {
907
- await k.runPromise(Vn(e, t, r, i).pipe(k.provide(n))), await p({
907
+ await k.runPromise(Vn(e, t, r, i).pipe(k.provide(n))), await c({
908
908
  namespace: t,
909
909
  dialect: r
910
910
  });
@@ -1068,7 +1068,7 @@ BEGIN
1068
1068
  ...t.spatial === void 0 ? {} : { spatial: rr(t.spatial) },
1069
1069
  ...t.enumValues === void 0 ? {} : { enumValues: [...t.enumValues].sort() }
1070
1070
  };
1071
- }, hr = (e) => e.columns.filter((e) => !a(e.name)).map((t) => mr(er(t, qn(e, t)))).sort((e, t) => e.name.localeCompare(t.name)), gr = (e) => [...e].map(ar).sort((e, t) => e.name.localeCompare(t.name)), _r = (e) => [...e].filter((e) => !a(e.name)).map((e) => ({
1071
+ }, hr = (e) => e.columns.filter((e) => !r(e.name)).map((t) => mr(er(t, qn(e, t)))).sort((e, t) => e.name.localeCompare(t.name)), gr = (e) => [...e].map(ar).sort((e, t) => e.name.localeCompare(t.name)), _r = (e) => [...e].filter((e) => !r(e.name)).map((e) => ({
1072
1072
  name: e.name,
1073
1073
  columns: hr(e),
1074
1074
  indexes: gr(e.indexes)
@@ -1093,24 +1093,24 @@ BEGIN
1093
1093
  column: e.name,
1094
1094
  charset: e.charset
1095
1095
  }]), wr = "utf8mb4", Tr = (e) => e.columns.some((e) => e.type === "json" || e.type === "array" || e.storageType === "json"), Er = (e) => {
1096
- if (!D(e.dialect)) return [];
1096
+ if (!i(e.dialect)) return [];
1097
1097
  let t = [];
1098
1098
  for (let n of [...e.live.tables].sort((e, t) => e.name.localeCompare(t.name))) {
1099
- if (a(n.name)) continue;
1100
- let r = Cr(n);
1101
- if (r.length === 0) continue;
1099
+ if (r(n.name)) continue;
1100
+ let i = Cr(n);
1101
+ if (i.length === 0) continue;
1102
1102
  if (e.charset !== void 0) {
1103
- let i = r.filter((t) => t.charset !== e.charset);
1104
- i.length > 0 && t.push({
1103
+ let r = i.filter((t) => t.charset !== e.charset);
1104
+ r.length > 0 && t.push({
1105
1105
  table: n.name,
1106
1106
  kind: "disagrees-with-declaration",
1107
- columns: i,
1107
+ columns: r,
1108
1108
  expected: e.charset
1109
1109
  });
1110
1110
  continue;
1111
1111
  }
1112
1112
  if (Tr(n)) {
1113
- let e = r.filter((e) => e.charset !== wr);
1113
+ let e = i.filter((e) => e.charset !== wr);
1114
1114
  e.length > 0 && t.push({
1115
1115
  table: n.name,
1116
1116
  kind: "json-outruns-text",
@@ -1119,12 +1119,12 @@ BEGIN
1119
1119
  });
1120
1120
  continue;
1121
1121
  }
1122
- let i = new Set(r.map((e) => e.charset));
1123
- i.size > 1 && t.push({
1122
+ let a = new Set(i.map((e) => e.charset));
1123
+ a.size > 1 && t.push({
1124
1124
  table: n.name,
1125
1125
  kind: "mixed",
1126
- columns: r,
1127
- expected: [...i].sort().join(" / ")
1126
+ columns: i,
1127
+ expected: [...a].sort().join(" / ")
1128
1128
  });
1129
1129
  }
1130
1130
  return t;
@@ -1221,7 +1221,7 @@ BEGIN
1221
1221
  let r = n;
1222
1222
  if (r.dropped || !r.references || r.fkAutoIndex === !1 || c.has(t)) continue;
1223
1223
  let a = `${e.tableName}_${t}_idx`;
1224
- te(e.tableName, a, !0, [t]), i({
1224
+ p(e.tableName, a, !0, [t]), i({
1225
1225
  name: a,
1226
1226
  table: e.tableName,
1227
1227
  columns: [t],
@@ -1256,7 +1256,7 @@ BEGIN
1256
1256
  }
1257
1257
  }, Nr = (e, t, n = {}) => {
1258
1258
  if (n.charset !== void 0 && t !== "mysql" && t !== "mariadb") throw Error(`store charset '${n.charset}' is declared for a ${t ?? "dialect-less"} store — a character set is a MySQL / MariaDB setting. Remove \`charset\` from \`store\` in app.config.ts, or declare \`store: { dialect: 'mysql' | 'mariadb', charset }\`.`);
1259
- let r = e.filter((e) => !S(e.tableName)).map((e) => jr(Ge(e, t), t));
1259
+ let r = e.filter((e) => !ee(e.tableName)).map((e) => jr(Ge(e, t), t));
1260
1260
  if (t === "mysql" || t === "mariadb") {
1261
1261
  for (let e of r) for (let n of e.indexes) if (n.where !== void 0) throw Error(`Partial index '${n.name}' on '${e.name}' is not supported by ${t}. Use uniqueActive for portable conditional uniqueness.`);
1262
1262
  }
@@ -1271,7 +1271,7 @@ BEGIN
1271
1271
  if (t === "mssql" && !e.generatedAs && (e.type === "json" || e.type === "array") && (e = {
1272
1272
  ...e,
1273
1273
  jsonValidation: e.type === "json" ? "value" : "container"
1274
- }), u(t)) {
1274
+ }), b(t)) {
1275
1275
  if (e.maxLength === void 0) return e;
1276
1276
  let { maxLength: t, ...n } = e;
1277
1277
  return n;
@@ -1380,7 +1380,7 @@ BEGIN
1380
1380
  if (!n || !r || n.length !== r.length) return !1;
1381
1381
  let i = [...n].sort(), a = [...r].sort();
1382
1382
  return i.every((e, t) => e === a[t]);
1383
- }, Ur = (e, t, n, r) => n === void 0 || u(n) ? !0 : e.type !== "text" || !$n(t) || dr(e, n, r) === t.maxLength, Wr = (e, t, n, r, i = !1) => (!nr(e) || e.type === t.type || tr(e, t, i)) && er(e, i).idStorage === er(t, !1).idStorage && e.nullable === t.nullable && (e.unique === t.unique || tr(e, t, i)) && e.jsonValidation === t.jsonValidation && (t.enumValues === void 0 || e.enumValues === void 0 || e.enumValues.length === t.enumValues.length && e.enumValues.every((e) => t.enumValues.includes(e))) && (t.precision === void 0 || e.precision === t.precision && (e.scale ?? 0) === (t.scale ?? 0)) && ir(e.spatial, t.spatial) && (e.storageType !== void 0 || t.storageType !== void 0 || t.arrayElement === void 0 || e.arrayElement === void 0 || e.arrayElement === t.arrayElement) && (t.vectorDim === void 0 || e.vectorDim === t.vectorDim) && (e.vectorPrecision ?? "float32") === (t.vectorPrecision ?? "float32") && Vr(e, t) && Ur(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(ur(e.references)) === JSON.stringify(ur(t.references)) && Hr(e.oneOf, t.oneOf), Gr = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1383
+ }, Ur = (e, t, n, r) => n === void 0 || b(n) ? !0 : e.type !== "text" || !$n(t) || dr(e, n, r) === t.maxLength, Wr = (e, t, n, r, i = !1) => (!nr(e) || e.type === t.type || tr(e, t, i)) && er(e, i).idStorage === er(t, !1).idStorage && e.nullable === t.nullable && (e.unique === t.unique || tr(e, t, i)) && e.jsonValidation === t.jsonValidation && (t.enumValues === void 0 || e.enumValues === void 0 || e.enumValues.length === t.enumValues.length && e.enumValues.every((e) => t.enumValues.includes(e))) && (t.precision === void 0 || e.precision === t.precision && (e.scale ?? 0) === (t.scale ?? 0)) && ir(e.spatial, t.spatial) && (e.storageType !== void 0 || t.storageType !== void 0 || t.arrayElement === void 0 || e.arrayElement === void 0 || e.arrayElement === t.arrayElement) && (t.vectorDim === void 0 || e.vectorDim === t.vectorDim) && (e.vectorPrecision ?? "float32") === (t.vectorPrecision ?? "float32") && Vr(e, t) && Ur(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(ur(e.references)) === JSON.stringify(ur(t.references)) && Hr(e.oneOf, t.oneOf), Gr = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1384
1384
  kind: "add-check",
1385
1385
  table: e,
1386
1386
  column: t.name,
@@ -1475,7 +1475,7 @@ BEGIN
1475
1475
  let n = e.type;
1476
1476
  if (n === "id") return Qn(e) === "numeric" ? "bigint" : "text";
1477
1477
  if (n === "array") return t === void 0 || t === "postgres" ? "array" : t === "mysql" || t === "mariadb" ? "json" : "text";
1478
- if (n === "enum") return t === "mssql" || u(t ?? "postgres") ? "text" : "enum";
1478
+ if (n === "enum") return t === "mssql" || b(t ?? "postgres") ? "text" : "enum";
1479
1479
  if (n === "reference") return e.referenceStorage === "numeric" ? "bigint" : "text";
1480
1480
  switch (t) {
1481
1481
  case "sqlite":
@@ -1534,7 +1534,7 @@ BEGIN
1534
1534
  o.push(L(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: ri(n.type, t, r) }));
1535
1535
  }
1536
1536
  }
1537
- if (t.type === "text" && $n(n) && !u(r ?? "postgres") && t.maxLength !== n.maxLength) {
1537
+ if (t.type === "text" && $n(n) && !b(r ?? "postgres") && t.maxLength !== n.maxLength) {
1538
1538
  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})`;
1539
1539
  o.push(L({
1540
1540
  kind: "alter-column-type",
@@ -1806,18 +1806,18 @@ BEGIN
1806
1806
  return n === void 0 ? [] : [n.getTime()];
1807
1807
  }), i = new Date(Math.max(...r)), a = new Date(Date.UTC(i.getUTCFullYear(), i.getUTCMonth(), i.getUTCDate() + 1)).toISOString().slice(0, 10);
1808
1808
  return `${t.join("; ")}. Reclaim the snapshots first — \`voltro db gc-snapshots --before ${a}\` drops every snapshot older than that date, so run it with --dry-run to see the list — or, if a snapshot's data is still wanted, bring it back with \`voltro db restore-snapshot <plan-id>\` and declare it, so it converts in the same plan.`;
1809
- }, hi = (e, t, n, r) => {
1810
- let i = /* @__PURE__ */ new Map();
1811
- for (let a of e.tables) {
1812
- let e = t.get(a.name) ?? (n.has(a.name) ? t.get(n.get(a.name)) : void 0);
1809
+ }, hi = (e, t, n, i) => {
1810
+ let a = /* @__PURE__ */ new Map();
1811
+ for (let r of e.tables) {
1812
+ let e = t.get(r.name) ?? (n.has(r.name) ? t.get(n.get(r.name)) : void 0);
1813
1813
  if (e === void 0) continue;
1814
- let o = new Set(a.columns.filter(xr).map((e) => e.name));
1815
- Cr(e).filter((e) => o.has(e.column) && e.charset !== r).length > 0 && i.set(a.name, {
1816
- declared: a,
1814
+ let o = new Set(r.columns.filter(xr).map((e) => e.name));
1815
+ Cr(e).filter((e) => o.has(e.column) && e.charset !== i).length > 0 && a.set(r.name, {
1816
+ declared: r,
1817
1817
  live: e
1818
1818
  });
1819
1819
  }
1820
- if (i.size === 0) return [];
1820
+ if (a.size === 0) return [];
1821
1821
  let o = [];
1822
1822
  for (let e of t.values()) for (let n of e.columns) {
1823
1823
  if (n.references === void 0) continue;
@@ -1836,110 +1836,110 @@ BEGIN
1836
1836
  });
1837
1837
  }
1838
1838
  let s = [];
1839
- for (let [e, { declared: t, live: n }] of i) {
1839
+ for (let [e, { declared: t, live: n }] of a) {
1840
1840
  let c = t.columns.filter(xr).map((e) => e.name), l = new Map(n.columns.map((e) => [e.name, e])), u = [...new Set(c.flatMap((e) => {
1841
1841
  let t = l.get(e);
1842
1842
  return t?.charset === void 0 ? [] : [t.charset];
1843
1843
  }))].sort(), d = c.filter((e) => l.has(e)), f = o.filter((t) => t.table === e || t.targetTable === e), p = [], m = [], h = f.map((t) => {
1844
- let n = t.table === e ? t.targetTable : t.table, o = n === e || i.has(n), s = t.table === e ? t.targetCharset : t.sourceCharset;
1845
- if (!o && s !== void 0 && s !== r) {
1844
+ let n = t.table === e ? t.targetTable : t.table, o = n === e || a.has(n), s = t.table === e ? t.targetCharset : t.sourceCharset;
1845
+ if (!o && s !== void 0 && s !== i) {
1846
1846
  let e = `${t.name} (${t.table}.${t.column} → ${t.targetTable}.${t.targetColumn})`;
1847
- a(n) ? m.push(`${e}: "${n}" is a soft-drop snapshot, stored ${s}`) : p.push(`${e}: "${n}" stays ${s} — it is not a declared table, so the plan does not convert it`);
1847
+ r(n) ? m.push(`${e}: "${n}" is a soft-drop snapshot, stored ${s}`) : p.push(`${e}: "${n}" stays ${s} — it is not a declared table, so the plan does not convert it`);
1848
1848
  }
1849
1849
  let { sourceCharset: c, targetCharset: l, ...u } = t, d = o && n !== e && n.localeCompare(e) > 0 ? "peer" : "here";
1850
1850
  return {
1851
1851
  ...u,
1852
1852
  restore: d
1853
1853
  };
1854
- }), g = r === "utf8mb4", _ = `table rewrite: ${d.length} string column${d.length === 1 ? "" : "s"} ${u.join("/")} → ${r}` + (h.length > 0 ? `; ${h.length} foreign key${h.length === 1 ? "" : "s"} dropped and re-created around it` : ""), v = {
1854
+ }), g = i === "utf8mb4", _ = `table rewrite: ${d.length} string column${d.length === 1 ? "" : "s"} ${u.join("/")} → ${i}` + (h.length > 0 ? `; ${h.length} foreign key${h.length === 1 ? "" : "s"} dropped and re-created around it` : ""), v = {
1855
1855
  kind: "convert-charset",
1856
1856
  table: e,
1857
- charset: r,
1857
+ charset: i,
1858
1858
  columns: d,
1859
1859
  from: u,
1860
1860
  foreignKeys: h
1861
1861
  };
1862
1862
  if (p.length > 0 || m.length > 0) {
1863
1863
  let t = [...p.length > 0 ? [`${p.join("; ")}. Declare that table so it converts in the same plan, convert it by hand first, or leave the store charset undeclared.`] : [], ...m.length > 0 ? [mi(m, f)] : []];
1864
- s.push(L(v, "lossy", _, { fix: `converting "${e}" to ${r} would break a foreign key the plan cannot carry: ${t.join(" ")}` }));
1864
+ s.push(L(v, "lossy", _, { fix: `converting "${e}" to ${i} would break a foreign key the plan cannot carry: ${t.join(" ")}` }));
1865
1865
  continue;
1866
1866
  }
1867
- s.push(g ? L(v, "safe", _) : L(v, "lossy", _, { fix: `${e}: narrowing to ${r} can refuse or truncate 4-byte characters the columns already hold. Declare charset: 'utf8mb4' instead, or — after checking the data — allow it with the destructive opt-in (VOLTRO_DESTRUCTIVE_OK=1).` }));
1867
+ s.push(g ? L(v, "safe", _) : L(v, "lossy", _, { fix: `${e}: narrowing to ${i} can refuse or truncate 4-byte characters the columns already hold. Declare charset: 'utf8mb4' instead, or — after checking the data — allow it with the destructive opt-in (VOLTRO_DESTRUCTIVE_OK=1).` }));
1868
1868
  }
1869
1869
  return s;
1870
1870
  }, gi = (e) => {
1871
- let t = Nr(e.declared, e.dialect, { charset: e.charset }), n = Br(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? $r, o = [], s = di(t, r, n);
1872
- o.push(...s.ops);
1873
- for (let e of t.tables) if (!s.renamedInto.has(e.name) && !r.has(e.name)) {
1874
- o.push(Zr(e.name, e.columns, e.indexes, e.primaryKey, s.refusals.get(e.name)));
1871
+ let t = Nr(e.declared, e.dialect, { charset: e.charset }), n = Br(e.declared, t), i = new Map(e.live.tables.map((e) => [e.name, e])), a = e.onlineAfter ?? $r, s = [], c = di(t, i, n);
1872
+ s.push(...c.ops);
1873
+ for (let e of t.tables) if (!c.renamedInto.has(e.name) && !i.has(e.name)) {
1874
+ s.push(Zr(e.name, e.columns, e.indexes, e.primaryKey, c.refusals.get(e.name)));
1875
1875
  for (let t of e.columns) {
1876
1876
  let n = Gr(e.name, t);
1877
- n && o.push(n);
1877
+ n && s.push(n);
1878
1878
  }
1879
1879
  }
1880
- let c = new Set(e.ignoreTables ?? []), u = [];
1880
+ let l = new Set(e.ignoreTables ?? []), u = [];
1881
1881
  for (let t of e.live.tables) if (!n.has(t.name)) {
1882
- if (s.claimedOldNames.has(t.name)) {
1882
+ if (c.claimedOldNames.has(t.name)) {
1883
1883
  u.push(t.name);
1884
1884
  continue;
1885
1885
  }
1886
- if (l(t.name)) {
1886
+ if (o(t.name)) {
1887
1887
  u.push(t.name);
1888
1888
  continue;
1889
1889
  }
1890
- if (a(t.name)) {
1890
+ if (r(t.name)) {
1891
1891
  u.push(t.name);
1892
1892
  continue;
1893
1893
  }
1894
- if (c.has(t.name)) {
1894
+ if (l.has(t.name)) {
1895
1895
  u.push(t.name);
1896
1896
  continue;
1897
1897
  }
1898
- o.push(Qr(t.name));
1898
+ s.push(Qr(t.name));
1899
1899
  }
1900
- for (let c of t.tables) {
1901
- let t = s.renamedInto.get(c.name), l = r.get(c.name) ?? (t === void 0 ? void 0 : r.get(t));
1900
+ for (let o of t.tables) {
1901
+ let t = c.renamedInto.get(o.name), l = i.get(o.name) ?? (t === void 0 ? void 0 : i.get(t));
1902
1902
  if (!l) continue;
1903
- let u = fi(l, t, c.name, e.dialect);
1904
- o.push(...u.ops);
1905
- let d = u.live, f = n.get(c.name), p = qr(c, d, e.dialect), m = Jr(c, d, e.dialect), h = oi(f.table, f.columnDefs, p);
1906
- o.push(...h.ops);
1903
+ let u = fi(l, t, o.name, e.dialect);
1904
+ s.push(...u.ops);
1905
+ let d = u.live, f = n.get(o.name), p = qr(o, d, e.dialect), m = Jr(o, d, e.dialect), h = oi(f.table, f.columnDefs, p);
1906
+ s.push(...h.ops);
1907
1907
  for (let { op: t } of h.ops) {
1908
1908
  if (t.kind !== "rename-column") continue;
1909
- let n = c.columns.find((e) => e.name === t.to), r = d.columns.find((e) => e.name === t.from);
1910
- n && r && o.push(...ii(c.name, n, {
1909
+ let n = o.columns.find((e) => e.name === t.to), r = d.columns.find((e) => e.name === t.from);
1910
+ n && r && s.push(...ii(o.name, n, {
1911
1911
  ...r,
1912
1912
  name: t.to
1913
- }, e.dialect, d.rowCount, i));
1913
+ }, e.dialect, d.rowCount, a));
1914
1914
  }
1915
1915
  for (let e of p.removed) {
1916
- if (h.consumedRemovedNames.has(e.name) || a(e.name)) continue;
1917
- let t = f.columnDefs[e.name], n = Xr(c.name, e, t);
1918
- e.references !== void 0 && o.push({
1916
+ if (h.consumedRemovedNames.has(e.name) || r(e.name)) continue;
1917
+ let t = f.columnDefs[e.name], n = Xr(o.name, e, t);
1918
+ e.references !== void 0 && s.push({
1919
1919
  ...L({
1920
1920
  kind: "drop-foreign-key",
1921
- table: c.name,
1921
+ table: o.name,
1922
1922
  column: e.name,
1923
1923
  ...e.references.constraintName === void 0 ? {} : { name: e.references.constraintName }
1924
- }, n.blocked === void 0 ? "safe" : n.classification, `drop FK on ${c.name}.${e.name} (→ ${e.references.table}) before dropping the column`),
1924
+ }, n.blocked === void 0 ? "safe" : n.classification, `drop FK on ${o.name}.${e.name} (→ ${e.references.table}) before dropping the column`),
1925
1925
  ...n.blocked === void 0 ? {} : { blocked: n.blocked }
1926
- }), o.push(n);
1926
+ }), s.push(n);
1927
1927
  }
1928
1928
  for (let e of p.added) {
1929
1929
  if (h.consumedAddedNames.has(e.name)) continue;
1930
1930
  let t = f.columnDefs[e.name];
1931
- o.push(Yr(c.name, e, t));
1932
- let n = Gr(c.name, e);
1933
- n && o.push(n), o.push(...ai(c.name, e));
1931
+ s.push(Yr(o.name, e, t));
1932
+ let n = Gr(o.name, e);
1933
+ n && s.push(n), s.push(...ai(o.name, e));
1934
1934
  }
1935
- let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = ui(c.name, m, g, new Set(d.indexes.map((e) => e.name)), e.dialect);
1936
- o.push(..._.ops);
1937
- for (let e of m.added) _.consumedAddedNames.has(e.name) || o.push(ei(c.name, e, d.rowCount, i));
1938
- for (let e of m.removed) _.consumedRemovedNames.has(e.name) || o.push(ti(c.name, e));
1939
- for (let { declared: t, live: n } of p.changed) o.push(...ii(c.name, t, n, e.dialect, d.rowCount, i));
1940
- }
1941
- e.charset !== void 0 && o.push(...hi(t, r, s.renamedInto, e.charset));
1942
- let d = new Set(o.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), f = new Map(t.tables.map((e) => [e.name, e])), p = (e) => {
1935
+ let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = ui(o.name, m, g, new Set(d.indexes.map((e) => e.name)), e.dialect);
1936
+ s.push(..._.ops);
1937
+ for (let e of m.added) _.consumedAddedNames.has(e.name) || s.push(ei(o.name, e, d.rowCount, a));
1938
+ for (let e of m.removed) _.consumedRemovedNames.has(e.name) || s.push(ti(o.name, e));
1939
+ for (let { declared: t, live: n } of p.changed) s.push(...ii(o.name, t, n, e.dialect, d.rowCount, a));
1940
+ }
1941
+ e.charset !== void 0 && s.push(...hi(t, i, c.renamedInto, e.charset));
1942
+ let d = new Set(s.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), f = new Map(t.tables.map((e) => [e.name, e])), p = (e) => {
1943
1943
  let t = f.get(e);
1944
1944
  return t ? t.columns.flatMap((e) => e.references && d.has(e.references.table) ? [{
1945
1945
  column: e.name,
@@ -1957,13 +1957,13 @@ BEGIN
1957
1957
  }, "safe", `deferred FK ${e.name}.${t.name} → ${t.references.table} — breaks a create-time table cycle`));
1958
1958
  if (m.size > 0) {
1959
1959
  let e = (e) => e.references ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "references")) : e;
1960
- for (let t = 0; t < o.length; t += 1) {
1961
- let n = o[t];
1960
+ for (let t = 0; t < s.length; t += 1) {
1961
+ let n = s[t];
1962
1962
  if (n.op.kind !== "create-table") continue;
1963
1963
  let r = n.op;
1964
1964
  if (!r.columns.some((e) => m.has(j(r.table, e.name)))) continue;
1965
1965
  let i = r.columns.map((t) => m.has(j(r.table, t.name)) ? e(t) : t);
1966
- o[t] = {
1966
+ s[t] = {
1967
1967
  ...n,
1968
1968
  op: {
1969
1969
  ...r,
@@ -1971,7 +1971,7 @@ BEGIN
1971
1971
  }
1972
1972
  };
1973
1973
  }
1974
- o.push(...h);
1974
+ s.push(...h);
1975
1975
  }
1976
1976
  let g = new Map(t.tables.map((e) => [e.name, e])), _ = /* @__PURE__ */ new Map(), v = (e, t = /* @__PURE__ */ new Set()) => {
1977
1977
  let n = _.get(e);
@@ -1985,10 +1985,10 @@ BEGIN
1985
1985
  n && n !== e && !m.has(j(e, t.name)) && (a = Math.max(a, v(n, i) + 1));
1986
1986
  }
1987
1987
  return _.set(e, a), a;
1988
- }, y = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, b = (e) => {
1988
+ }, y = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, ee = (e) => {
1989
1989
  let t = "table" in e ? e.table : "";
1990
1990
  return e.kind === "create-table" ? v(t) : e.kind === "drop-table" ? -v(t) : 0;
1991
- }, x = {
1991
+ }, b = {
1992
1992
  "add-column": 0,
1993
1993
  "rename-column": 1,
1994
1994
  "rename-index": 1,
@@ -2008,41 +2008,41 @@ BEGIN
2008
2008
  "add-foreign-key": 6,
2009
2009
  "add-check": 6,
2010
2010
  "reconcile-json-check": 6
2011
- }, S = (e) => x[e] ?? 9, C = [...o].sort((e, t) => {
2011
+ }, x = (e) => b[e] ?? 9, S = [...s].sort((e, t) => {
2012
2012
  let n = y(e.op.kind), r = y(t.op.kind);
2013
2013
  if (n !== r) return n - r;
2014
- let i = b(e.op), a = b(t.op);
2014
+ let i = ee(e.op), a = ee(t.op);
2015
2015
  if (i !== a) return i - a;
2016
2016
  let o = "table" in e.op ? e.op.table : "", s = "table" in t.op ? t.op.table : "";
2017
2017
  if (o !== s) return o.localeCompare(s);
2018
- let c = S(e.op.kind), l = S(t.op.kind);
2018
+ let c = x(e.op.kind), l = x(t.op.kind);
2019
2019
  return c === l ? e.op.kind.localeCompare(t.op.kind) : c - l;
2020
- }), w = /* @__PURE__ */ new Set();
2021
- for (let e of C) "table" in e.op && w.add(e.op.table);
2022
- let T = [];
2020
+ }), C = /* @__PURE__ */ new Set();
2021
+ for (let e of S) "table" in e.op && C.add(e.op.table);
2022
+ let w = [];
2023
2023
  for (let e of t.tables) {
2024
- if (w.has(e.name) || s.renamedInto.has(e.name)) continue;
2025
- let t = r.get(e.name);
2026
- t !== void 0 && I({ tables: [t] }) !== I({ tables: [e] }) && T.push(e.name);
2024
+ if (C.has(e.name) || c.renamedInto.has(e.name)) continue;
2025
+ let t = i.get(e.name);
2026
+ t !== void 0 && I({ tables: [t] }) !== I({ tables: [e] }) && w.push(e.name);
2027
2027
  }
2028
2028
  return {
2029
- operations: C,
2029
+ operations: S,
2030
2030
  fromFingerprint: I(e.live),
2031
2031
  toFingerprint: I(t),
2032
- summary: pi(C),
2032
+ summary: pi(S),
2033
2033
  fingerprintDivergence: {
2034
2034
  outsideDiff: u,
2035
- diffEquivalent: T
2035
+ diffEquivalent: w
2036
2036
  }
2037
2037
  };
2038
- }, R = "_voltro_deploys", _i = t(R, {
2039
- id: d({ prefix: "dpl" }),
2040
- status: T(),
2041
- dialect: T(),
2042
- appliedBy: T(),
2043
- startedAt: T(),
2044
- baseline: T(),
2045
- report: T().nullable()
2038
+ }, R = "_voltro_deploys", _i = g(R, {
2039
+ id: x({ prefix: "dpl" }),
2040
+ status: n(),
2041
+ dialect: n(),
2042
+ appliedBy: n(),
2043
+ startedAt: n(),
2044
+ baseline: n(),
2045
+ report: n().nullable()
2046
2046
  }), vi = (e, t) => e`INSERT INTO ${e(R)} (${e("id")}, ${e("status")}, ${e("dialect")}, ${e("appliedBy")}, ${e("startedAt")}, ${e("baseline")}, ${e("report")})
2047
2047
  VALUES (${t.id}, ${"running"}, ${t.dialect}, ${t.appliedBy}, ${(/* @__PURE__ */ new Date()).toISOString()}, ${t.baseline}, ${null})`.pipe(k.asVoid), yi = (e, t) => e`DELETE FROM ${e(R)} WHERE ${e("id")} = ${t}`.pipe(k.asVoid), bi = (e, t, n) => e`UPDATE ${e(R)} SET ${e("status")} = ${"failed"}, ${e("report")} = ${n} WHERE ${e("id")} = ${t}`.pipe(k.asVoid), xi = (e) => e`SELECT ${e("id")}, ${e("status")}, ${e("dialect")}, ${e("appliedBy")}, ${e("startedAt")}, ${e("baseline")}, ${e("report")} FROM ${e(R)}`.pipe(k.map((e) => e.map((e) => ({
2048
2048
  ...e,
@@ -2219,7 +2219,7 @@ BEGIN
2219
2219
  let t = Ci(e.def, e.column_name);
2220
2220
  t !== null && y.set(`${e.table_name}.${e.column_name}`, t);
2221
2221
  }
2222
- let b = yield* a(l, (t) => e`
2222
+ let ee = yield* a(l, (t) => e`
2223
2223
  SELECT
2224
2224
  rel.relname AS source_table,
2225
2225
  att.attname AS source_column,
@@ -2245,7 +2245,7 @@ BEGIN
2245
2245
  WHERE con.contype = 'f' AND nsp.nspname = current_schema()
2246
2246
  AND rel.relname IN ${t}
2247
2247
  ORDER BY rel.relname, con.conname, ck.ord
2248
- `), x = yield* a(l, (t) => e`
2248
+ `), b = yield* a(l, (t) => e`
2249
2249
  WITH ix AS (
2250
2250
  SELECT
2251
2251
  c.relname AS table_name,
@@ -2286,34 +2286,34 @@ BEGIN
2286
2286
  AND c.relname IN ${t}
2287
2287
  )
2288
2288
  SELECT * FROM ix ORDER BY table_name, index_name, position
2289
- `), S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map(), E = /* @__PURE__ */ new Map(), D = /* @__PURE__ */ new Map();
2289
+ `), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map();
2290
2290
  for (let e of u) {
2291
- let t = S.get(e.table_name);
2292
- t || (t = [], S.set(e.table_name, t)), t.push(e);
2291
+ let t = x.get(e.table_name);
2292
+ t || (t = [], x.set(e.table_name, t)), t.push(e);
2293
2293
  }
2294
2294
  for (let e of d) {
2295
- let t = C.get(e.table_name);
2296
- t || (t = /* @__PURE__ */ new Set(), C.set(e.table_name, t)), t.add(e.column_name);
2295
+ let t = S.get(e.table_name);
2296
+ t || (t = /* @__PURE__ */ new Set(), S.set(e.table_name, t)), t.add(e.column_name);
2297
2297
  }
2298
- let O = /* @__PURE__ */ new Map();
2298
+ let E = /* @__PURE__ */ new Map();
2299
2299
  for (let e of f) {
2300
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = O.get(t);
2300
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = E.get(t);
2301
2301
  n || (n = {
2302
2302
  table: e.table_name,
2303
2303
  columns: []
2304
- }, O.set(t, n)), n.columns.push({
2304
+ }, E.set(t, n)), n.columns.push({
2305
2305
  name: e.column_name,
2306
2306
  position: e.position
2307
2307
  });
2308
2308
  }
2309
- for (let [e, t] of O) {
2309
+ for (let [e, t] of E) {
2310
2310
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
2311
2311
  if (n.length === 1) {
2312
- let e = w.get(t.table);
2313
- e || (e = /* @__PURE__ */ new Set(), w.set(t.table, e)), e.add(n[0]);
2312
+ let e = C.get(t.table);
2313
+ e || (e = /* @__PURE__ */ new Set(), C.set(t.table, e)), e.add(n[0]);
2314
2314
  } else {
2315
- let r = T.get(t.table);
2316
- r || (r = [], T.set(t.table, r)), r.push({
2315
+ let r = w.get(t.table);
2316
+ r || (r = [], w.set(t.table, r)), r.push({
2317
2317
  name: e.slice(e.indexOf("\0") + 1),
2318
2318
  table: t.table,
2319
2319
  columns: n,
@@ -2321,19 +2321,19 @@ BEGIN
2321
2321
  });
2322
2322
  }
2323
2323
  }
2324
- for (let e of b) {
2325
- let t = E.get(e.source_table);
2326
- t || (t = [], E.set(e.source_table, t)), t.push(e);
2324
+ for (let e of ee) {
2325
+ let t = te.get(e.source_table);
2326
+ t || (t = [], te.set(e.source_table, t)), t.push(e);
2327
2327
  }
2328
- for (let e of x) {
2329
- let t = D.get(e.table_name);
2330
- t || (t = /* @__PURE__ */ new Map(), D.set(e.table_name, t));
2328
+ for (let e of b) {
2329
+ let t = T.get(e.table_name);
2330
+ t || (t = /* @__PURE__ */ new Map(), T.set(e.table_name, t));
2331
2331
  let n = t.get(e.index_name);
2332
2332
  n || (n = [], t.set(e.index_name, n)), n.push(e);
2333
2333
  }
2334
- let ee = [];
2334
+ let ne = [];
2335
2335
  for (let e of c) {
2336
- let t = /* @__PURE__ */ new Set(), n = (S.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = C.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = w.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = E.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) => {
2336
+ let t = /* @__PURE__ */ new Set(), n = (x.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = S.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = C.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = te.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) => {
2337
2337
  let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = t.data_type === "USER-DEFINED" && t.udt_name !== void 0 && g.has(t.udt_name), c = s ? "enum" : Ti(t.data_type, t.udt_name), l = !a && n && t.column_name === "id", u = a ? "reference" : l ? "id" : c, d = a ? {
2338
2338
  table: a.target_table,
2339
2339
  column: a.target_column,
@@ -2355,7 +2355,7 @@ BEGIN
2355
2355
  vectorPrecision: t.udt_name === "halfvec" ? "half" : "float32",
2356
2356
  ...t.type_modifier !== void 0 && t.type_modifier > 0 ? { vectorDim: t.type_modifier } : {}
2357
2357
  } : {},
2358
- ...qi(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: qi(t.data_type, t.character_maximum_length) },
2358
+ ...Ji(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ji(t.data_type, t.character_maximum_length) },
2359
2359
  ...c === "decimal" && typeof t.numeric_precision == "number" ? {
2360
2360
  precision: t.numeric_precision,
2361
2361
  ...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
@@ -2369,7 +2369,7 @@ BEGIN
2369
2369
  ...f ? { oneOf: f } : {},
2370
2370
  ...Oi(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
2371
2371
  };
2372
- }), l = [], u = D.get(e.table_name);
2372
+ }), l = [], u = T.get(e.table_name);
2373
2373
  if (u) for (let [t, n] of u) {
2374
2374
  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) => {
2375
2375
  let t = e.position;
@@ -2396,7 +2396,7 @@ BEGIN
2396
2396
  ...a ? { expression: !0 } : {}
2397
2397
  });
2398
2398
  }
2399
- for (let t of T.get(e.table_name) ?? []) l.push(t);
2399
+ for (let t of w.get(e.table_name) ?? []) l.push(t);
2400
2400
  r.size > 0 && l.push({
2401
2401
  name: `${e.table_name}_pkey`,
2402
2402
  table: e.table_name,
@@ -2404,14 +2404,14 @@ BEGIN
2404
2404
  unique: !0
2405
2405
  });
2406
2406
  let d = Number(e.row_count ?? 0);
2407
- ee.push({
2407
+ ne.push({
2408
2408
  name: e.table_name,
2409
2409
  columns: c,
2410
2410
  indexes: l,
2411
2411
  ...d > 0 ? { rowCount: d } : {}
2412
2412
  });
2413
2413
  }
2414
- return { tables: ee };
2414
+ return { tables: ne };
2415
2415
  });
2416
2416
  return (t > 0 ? e.withTransaction(n) : n).pipe(k.catchAll((e) => {
2417
2417
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
@@ -2478,7 +2478,7 @@ BEGIN
2478
2478
  WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = Li(yield* e`
2479
2479
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
2480
2480
  FROM information_schema.statistics
2481
- WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
2481
+ WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY' AND index_type <> 'FULLTEXT'
2482
2482
  ORDER BY table_name, index_name, seq_in_index`), a = e`
2483
2483
  SELECT cc.table_name AS table_name, cc.check_clause AS check_clause
2484
2484
  FROM information_schema.check_constraints cc
@@ -2531,7 +2531,7 @@ BEGIN
2531
2531
  ...u ? { idStorage: Yn(s) } : {},
2532
2532
  ...d === "enum" && g !== void 0 ? { enumValues: g } : {},
2533
2533
  nullable: t.is_nullable === "YES",
2534
- ...qi(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: qi(t.data_type, t.character_maximum_length) },
2534
+ ...Ji(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ji(t.data_type, t.character_maximum_length) },
2535
2535
  ...s === "decimal" && typeof t.numeric_precision == "number" ? {
2536
2536
  precision: t.numeric_precision,
2537
2537
  ...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
@@ -2573,18 +2573,27 @@ BEGIN
2573
2573
  }), zi = (e) => {
2574
2574
  let t = e.toUpperCase();
2575
2575
  return t.includes("INT") ? "integer" : t.includes("CHAR") || t.includes("CLOB") || t.includes("TEXT") ? "text" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : /^(NUMERIC|DECIMAL)\b/.test(t.trim()) ? "decimal" : "text";
2576
- }, Bi = (e) => e === 1 || e === !0, Vi = (e) => k.gen(function* () {
2576
+ }, Bi = (e) => e === 1 || e === !0, Vi = [
2577
+ "content",
2578
+ "data",
2579
+ "idx",
2580
+ "config",
2581
+ "docsize",
2582
+ "segments",
2583
+ "segdir",
2584
+ "stat"
2585
+ ], Hi = (e) => k.gen(function* () {
2577
2586
  let t = yield* e`
2578
2587
  SELECT name, sql FROM sqlite_master
2579
2588
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
2580
- ORDER BY name`, n = (e) => `'${e.replace(/'/g, "''")}'`, r = [];
2581
- for (let { name: i, sql: a } of t) {
2589
+ ORDER BY name`, n = (e) => `'${e.replace(/'/g, "''")}'`, r = [], i = t.filter((e) => /^\s*CREATE\s+VIRTUAL\s+TABLE\b/i.test(e.sql ?? "")).map((e) => e.name), a = (e) => i.includes(e) || i.some((t) => Vi.some((n) => e === `${t}_${n}`));
2590
+ for (let { name: i, sql: o } of t.filter((e) => !a(e.name))) {
2582
2591
  let t = /* @__PURE__ */ new Map();
2583
- for (let e of (a ?? "").matchAll(/CHECK\s*\(\s*"([^"]+)"\s+IN\s*\(([^)]*)\)/gi)) {
2592
+ for (let e of (o ?? "").matchAll(/CHECK\s*\(\s*"([^"]+)"\s+IN\s*\(([^)]*)\)/gi)) {
2584
2593
  let n = [...e[2].matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
2585
2594
  n.length > 0 && t.set(e[1], n);
2586
2595
  }
2587
- let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = new Map(o.map((e) => [e.name.toLowerCase(), e.name])), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set();
2596
+ let a = 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 = a.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = new Map(a.map((e) => [e.name.toLowerCase(), e.name])), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set();
2588
2597
  for (let t of c) {
2589
2598
  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);
2590
2599
  if (f.set(t.name, r), t.partial !== void 0 && Bi(t.partial)) {
@@ -2593,7 +2602,7 @@ BEGIN
2593
2602
  }
2594
2603
  !p.has(t.name) && Bi(t.unique) && r.length === 1 && m.add(r[0]);
2595
2604
  }
2596
- let h = o.map((e) => {
2605
+ let h = a.map((e) => {
2597
2606
  let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = zi(e.type), a = !r && n && e.name === "id", o = r ? "reference" : a ? "id" : i, s = r ? {
2598
2607
  table: r.table,
2599
2608
  column: r.to,
@@ -2637,7 +2646,7 @@ BEGIN
2637
2646
  });
2638
2647
  }
2639
2648
  return { tables: r };
2640
- }), Hi = (e) => {
2649
+ }), Ui = (e) => {
2641
2650
  switch (e.toLowerCase()) {
2642
2651
  case "int":
2643
2652
  case "smallint":
@@ -2659,7 +2668,7 @@ BEGIN
2659
2668
  case "image": return "bytes";
2660
2669
  default: return "text";
2661
2670
  }
2662
- }, z = (e) => e === !0 || e === 1, Ui = (e) => k.gen(function* () {
2671
+ }, z = (e) => e === !0 || e === 1, Wi = (e) => k.gen(function* () {
2663
2672
  let t = yield* e`
2664
2673
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2665
2674
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -2728,13 +2737,13 @@ BEGIN
2728
2737
  else t[0].predicate == null && z(t[0].is_unique) && t.length === 1 && m.add(t[0].column_name);
2729
2738
  }
2730
2739
  let h = t.map((t) => {
2731
- let n = p.length === 1 && p[0] === t.column_name, a = r.get(t.column_name), o = Hi(t.data_type), l = !a && n && t.column_name === "id", u = a ? "reference" : l ? "id" : o, d = a ? {
2740
+ let n = p.length === 1 && p[0] === t.column_name, a = r.get(t.column_name), o = Ui(t.data_type), l = !a && n && t.column_name === "id", u = a ? "reference" : l ? "id" : o, d = a ? {
2732
2741
  table: a.target_table,
2733
2742
  column: a.target_column,
2734
- onDelete: Wi(a.delete_rule),
2735
- onUpdate: Wi(a.update_rule),
2743
+ onDelete: Gi(a.delete_rule),
2744
+ onUpdate: Gi(a.update_rule),
2736
2745
  constraintName: a.constraint_name
2737
- } : void 0, f = t.column_default === null ? null : Gi(t.column_default), h = c.get(`${e}.${t.column_name}`), g = s.flatMap((n) => {
2746
+ } : void 0, f = t.column_default === null ? null : Ki(t.column_default), h = c.get(`${e}.${t.column_name}`), g = s.flatMap((n) => {
2738
2747
  if (n.table_name !== e || n.column_name !== null && n.column_name !== t.column_name) return [];
2739
2748
  let r = It(t.column_name, n.def);
2740
2749
  return r ? [{
@@ -2749,7 +2758,7 @@ BEGIN
2749
2758
  type: u,
2750
2759
  ...l ? { idStorage: Yn(o) } : {},
2751
2760
  nullable: t.is_nullable === "YES",
2752
- ...qi(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: qi(t.data_type, t.character_maximum_length) },
2761
+ ...Ji(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ji(t.data_type, t.character_maximum_length) },
2753
2762
  ...o === "decimal" && typeof t.numeric_precision == "number" ? {
2754
2763
  precision: t.numeric_precision,
2755
2764
  ...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
@@ -2758,7 +2767,7 @@ BEGIN
2758
2767
  hasDefault: f !== null,
2759
2768
  ...f === null ? {} : { defaultValue: f },
2760
2769
  ...d ? { references: d } : {},
2761
- ...a ? { referenceStorage: ["integer", "bigint"].includes(Hi(t.data_type)) ? "numeric" : "text" } : {},
2770
+ ...a ? { referenceStorage: ["integer", "bigint"].includes(Ui(t.data_type)) ? "numeric" : "text" } : {},
2762
2771
  ...h ? { oneOf: h } : {},
2763
2772
  ...g.length > 0 ? { jsonChecks: g } : {},
2764
2773
  ..._ ? { jsonValidation: _ } : {},
@@ -2789,45 +2798,45 @@ BEGIN
2789
2798
  });
2790
2799
  }
2791
2800
  return { tables: f };
2792
- }), Wi = (e) => {
2801
+ }), Gi = (e) => {
2793
2802
  switch (e.toUpperCase().replace(/_/g, " ")) {
2794
2803
  case "CASCADE": return "cascade";
2795
2804
  case "SET NULL": return "setNull";
2796
2805
  case "SET DEFAULT": return "noAction";
2797
2806
  default: return "noAction";
2798
2807
  }
2799
- }, Gi = (e) => {
2808
+ }, Ki = (e) => {
2800
2809
  let t = e.trim();
2801
2810
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2802
2811
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2803
- }, Ki = /* @__PURE__ */ new Set([
2812
+ }, qi = /* @__PURE__ */ new Set([
2804
2813
  "character varying",
2805
2814
  "varchar",
2806
2815
  "nvarchar",
2807
2816
  "char",
2808
2817
  "character",
2809
2818
  "nchar"
2810
- ]), qi = (e, t) => {
2811
- if (!Ki.has(e.toLowerCase())) return;
2819
+ ]), Ji = (e, t) => {
2820
+ if (!qi.has(e.toLowerCase())) return;
2812
2821
  let n = Number(t);
2813
2822
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2814
- }, Ji = /* @__PURE__ */ new Set([
2823
+ }, Yi = /* @__PURE__ */ new Set([
2815
2824
  N,
2816
2825
  R,
2817
2826
  Si,
2818
2827
  "_voltro_plugin_migrations"
2819
2828
  ]), B = (e) => e.onDialectOrElse({
2820
2829
  mysql: () => Ri(e),
2821
- mssql: () => Ui(e),
2822
- sqlite: () => Vi(e),
2830
+ mssql: () => Wi(e),
2831
+ sqlite: () => Hi(e),
2823
2832
  orElse: () => Fi(e)
2824
2833
  }).pipe(k.map((e) => ({
2825
2834
  ...e,
2826
- tables: e.tables.filter((e) => !Ji.has(e.name))
2827
- }))), Yi = (e, t) => {
2835
+ tables: e.tables.filter((e) => !Yi.has(e.name))
2836
+ }))), Xi = (e, t) => {
2828
2837
  let n = M(e);
2829
2838
  return (n === "sqlite" ? e`SELECT COUNT(*) AS n FROM sqlite_master WHERE type = 'table' AND name = ${t}` : n === "mysql" ? e`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ${t}` : n === "mssql" ? e`SELECT COUNT(*) AS n FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ${t}` : e`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = ${t}`).pipe(k.map((e) => Number(e[0]?.n ?? 0) > 0));
2830
- }, Xi = (e, t) => {
2839
+ }, Zi = (e, t) => {
2831
2840
  let n = e.op;
2832
2841
  if (n.kind !== "drop-column" && n.kind !== "drop-table") return e;
2833
2842
  let r = n.kind === "drop-column" ? n.column : n.table, i = t.replace(/[-:T.Z]/g, "").slice(0, 14);
@@ -2836,7 +2845,7 @@ BEGIN
2836
2845
  ...e,
2837
2846
  softDropSnapshot: `${r}__dropped_${i}`
2838
2847
  };
2839
- }, Zi = (e) => {
2848
+ }, Qi = (e) => {
2840
2849
  if (e.softDropSnapshot === void 0) return;
2841
2850
  let t = e.op;
2842
2851
  if (t.kind !== "drop-column" && t.kind !== "drop-table") throw Error("Soft-drop snapshot belongs to a non-drop operation");
@@ -2846,51 +2855,51 @@ BEGIN
2846
2855
  }, V = (e, t) => {
2847
2856
  let n = Math.max(1, Math.floor(Number.isFinite(t) ? t : 1));
2848
2857
  return e.literal(M(e) === "mssql" ? `OFFSET 0 ROWS FETCH NEXT ${n} ROWS ONLY` : `LIMIT ${n}`);
2849
- }, Qi = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", $i = /* @__PURE__ */ new WeakMap(), H = (e) => k.suspend(() => {
2850
- let t = $i.get(e);
2851
- return t === void 0 ? ea(e).pipe(k.tap((t) => k.sync(() => $i.set(e, t)))) : k.succeed(t);
2852
- }), ea = (e) => e.unsafe("SELECT VERSION() AS v").pipe(k.map((e) => {
2858
+ }, $i = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", ea = /* @__PURE__ */ new WeakMap(), H = (e) => k.suspend(() => {
2859
+ let t = ea.get(e);
2860
+ return t === void 0 ? ta(e).pipe(k.tap((t) => k.sync(() => ea.set(e, t)))) : k.succeed(t);
2861
+ }), ta = (e) => e.unsafe("SELECT VERSION() AS v").pipe(k.map((e) => {
2853
2862
  let t = e[0]?.v;
2854
- return typeof t == "string" ? Qi(t) : "mysql";
2855
- }), k.catchAll(() => k.succeed("mysql"))), ta = (e) => {
2863
+ return typeof t == "string" ? $i(t) : "mysql";
2864
+ }), k.catchAll(() => k.succeed("mysql"))), na = (e) => {
2856
2865
  let t = e;
2857
2866
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2858
2867
  let e = t;
2859
2868
  if (typeof e.errno == "number") return e.errno;
2860
2869
  t = e.cause;
2861
2870
  }
2862
- }, na = (e) => {
2871
+ }, ra = (e) => {
2863
2872
  let t = [], n = e;
2864
2873
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2865
2874
  let e = n;
2866
2875
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2867
2876
  }
2868
2877
  return t.join(" | ");
2869
- }, ra = (e, t) => {
2878
+ }, ia = (e, t) => {
2870
2879
  if (t.length === 0) return !1;
2871
- let n = ta(e), r = na(e);
2880
+ let n = na(e), r = ra(e);
2872
2881
  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)));
2873
- }, ia = {
2882
+ }, aa = {
2874
2883
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2875
2884
  errno: [1061]
2876
- }, aa = {
2885
+ }, oa = {
2877
2886
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2878
2887
  errno: [1091]
2879
- }, oa = {
2888
+ }, sa = {
2880
2889
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2881
2890
  messageIncludes: ["no such column"]
2882
- }, sa = {
2891
+ }, ca = {
2883
2892
  why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
2884
2893
  errno: [1091, 3940]
2885
- }, ca = {
2894
+ }, la = {
2886
2895
  why: "mysql/mariadb ADD CONSTRAINT has no IF NOT EXISTS; 1826 is exactly \"already there\"",
2887
2896
  errno: [1826]
2888
- }, la = (e, t) => k.suspend(() => {
2897
+ }, ua = (e, t) => k.suspend(() => {
2889
2898
  let n;
2890
2899
  return e.withTransaction(t.pipe(k.tapErrorCause((e) => k.sync(() => {
2891
2900
  n = e;
2892
2901
  })))).pipe(k.catchAllCause((e) => k.failCause(n !== void 0 && !we.equals(n, e) ? Ce.sequential(n, e) : e)));
2893
- }), ua = (e, t, n) => {
2902
+ }), da = (e, t, n) => {
2894
2903
  let r = e.match(/'(?:''|[^'])*'|\[(?:\]\]|[^\]])*\]|\s+|[^'\[\s]+/g) ?? [];
2895
2904
  if (r.join("") !== e || r.some((e) => !e.startsWith("'") && !e.startsWith("[") && /"|\/\*|--/.test(e))) throw Error("Cannot safely rename CHECK: unsupported catalog SQL; use an explicit migration");
2896
2905
  let i = r.map((e, t) => ({
@@ -2898,32 +2907,32 @@ BEGIN
2898
2907
  index: t
2899
2908
  })).filter((e) => e.value.trim() !== ""), a = 0;
2900
2909
  for (let e = 0; e < i.length; e++) {
2901
- let s = i[e];
2902
- if (s.value !== o(t, "mssql")) continue;
2903
- let c = i[e - 1]?.value ?? "", l = i[e + 1]?.value ?? "";
2904
- if (c.endsWith(".") || l.startsWith(".") || l.startsWith("(")) throw Error(`Cannot safely rename CHECK reference '${t}': qualified or callable identifier; use an explicit migration`);
2905
- r[s.index] = o(n, "mssql"), a++;
2910
+ let o = i[e];
2911
+ if (o.value !== O(t, "mssql")) continue;
2912
+ let s = i[e - 1]?.value ?? "", c = i[e + 1]?.value ?? "";
2913
+ if (s.endsWith(".") || c.startsWith(".") || c.startsWith("(")) throw Error(`Cannot safely rename CHECK reference '${t}': qualified or callable identifier; use an explicit migration`);
2914
+ r[o.index] = O(n, "mssql"), a++;
2906
2915
  }
2907
2916
  if (a === 0 || r.join("").length === 0) throw Error(`Cannot safely rename CHECK reference '${t}': no exact catalog column token; use an explicit migration`);
2908
2917
  return r.join("");
2909
2918
  }, U = (e, t) => e.onDialectOrElse({
2910
2919
  mysql: () => k.succeed(t.replace("T", " ").replace("Z", "")),
2911
2920
  orElse: () => k.succeed(t)
2912
- }), da = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, fa = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), pa = (e, t) => {
2913
- if ((e.type !== "text" || e.maxLength === void 0) && !fa(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2921
+ }), fa = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, pa = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), ma = (e, t) => {
2922
+ if ((e.type !== "text" || e.maxLength === void 0) && !pa(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2914
2923
  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;
2915
2924
  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.`);
2916
2925
  return F(e, t);
2917
- }, ma = (e) => {
2918
- let t = pa(e, "postgres");
2919
- return t === void 0 ? ha(e) : t;
2920
2926
  }, ha = (e) => {
2927
+ let t = ma(e, "postgres");
2928
+ return t === void 0 ? ga(e) : t;
2929
+ }, ga = (e) => {
2921
2930
  switch (e.type) {
2922
2931
  case "id": return "text";
2923
2932
  case "text": return "text";
2924
2933
  case "integer": return "integer";
2925
2934
  case "real": return "double precision";
2926
- case "decimal": return da(e, "NUMERIC");
2935
+ case "decimal": return fa(e, "NUMERIC");
2927
2936
  case "bigint": return "bigint";
2928
2937
  case "boolean": return "boolean";
2929
2938
  case "timestamp": return "timestamptz";
@@ -2937,15 +2946,15 @@ BEGIN
2937
2946
  case "interval": return "interval";
2938
2947
  case "raw": return e.rawDdl ?? "text";
2939
2948
  }
2940
- }, ga = (e) => {
2941
- let t = pa(e, "mariadb");
2949
+ }, _a = (e) => {
2950
+ let t = ma(e, "mariadb");
2942
2951
  if (t !== void 0) return t;
2943
2952
  switch (e.type) {
2944
2953
  case "id": return "VARCHAR(64)";
2945
2954
  case "text": return "LONGTEXT";
2946
2955
  case "integer": return "INT";
2947
2956
  case "real": return "DOUBLE";
2948
- case "decimal": return da(e, "DECIMAL");
2957
+ case "decimal": return fa(e, "DECIMAL");
2949
2958
  case "bigint": return "BIGINT";
2950
2959
  case "boolean": return "TINYINT(1)";
2951
2960
  case "timestamp": return "DATETIME(6)";
@@ -2959,20 +2968,20 @@ BEGIN
2959
2968
  case "interval": return "BIGINT";
2960
2969
  case "raw": return e.rawDdl ?? "LONGTEXT";
2961
2970
  }
2962
- }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, _a = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", va = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, ya = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, ba = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, xa = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(t)};`, Sa = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${wa(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Ca = (e, t) => {
2971
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, va = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", ya = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, ba = (e, t = "mariadb") => `ALTER TABLE ${G(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${G(e.column)}, ALGORITHM=COPY;`, xa = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Sa = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(t)};`, Ca = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Ta(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, wa = (e, t) => {
2963
2972
  let { defaultFactory: n, ...r } = e;
2964
2973
  return F(e, t) !== F({
2965
2974
  ...r,
2966
2975
  hasDefault: !1
2967
2976
  }, t);
2968
- }, wa = (e, t) => {
2977
+ }, Ta = (e, t) => {
2969
2978
  let n = t(e.defaultValue);
2970
2979
  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.`);
2971
2980
  return n;
2972
- }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Ta = (e, t, n) => {
2981
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Ea = (e, t, n) => {
2973
2982
  let r = K(e, t, n);
2974
2983
  return r ? kr(n, r) : void 0;
2975
- }, Ea = (e, t, n, r) => {
2984
+ }, Da = (e, t, n, r) => {
2976
2985
  let i = n ?? e.nullable, a = Jt(e, "mariadb");
2977
2986
  return [
2978
2987
  G(t),
@@ -2981,20 +2990,20 @@ BEGIN
2981
2990
  a,
2982
2991
  r === void 0 ? null : `CHECK (${r})`
2983
2992
  ].filter(Boolean).join(" ");
2984
- }, Da = /^json_valid\(`[^`]+`\)$/i, Oa = (e, t) => H(e).pipe(k.flatMap((n) => n === "mariadb" ? e`
2993
+ }, Oa = /^json_valid\(`[^`]+`\)$/i, ka = (e, t) => H(e).pipe(k.flatMap((n) => n === "mariadb" ? e`
2985
2994
  SELECT constraint_name AS n, check_clause AS c
2986
2995
  FROM information_schema.check_constraints
2987
- WHERE constraint_schema = DATABASE() AND table_name = ${t} AND level = 'Column'`.pipe(k.map((e) => new Map(e.map((e) => [String(e.n ?? ""), String(e.c ?? "")]).filter(([e, t]) => e !== "" && t !== "" && !Da.test(t.trim()))))) : k.succeed(/* @__PURE__ */ new Map()))), ka = (e, t, n, r, i) => k.map(Oa(e, t), (e) => `ALTER TABLE ${G(t)} MODIFY COLUMN ${Ea(n, r, i, e.get(r))};`), Aa = (e, t) => e == null ? null : Array.isArray(e) ? ja(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" ? Xt(e, "mariadb") : null, ja = (e, t, n) => Yt(e, t ?? { type: "json" }, n), Ma = (e, t) => e == null ? null : Array.isArray(e) ? ja(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" ? Xt(e, "postgres") : null, Na = (e, t) => {
2996
+ WHERE constraint_schema = DATABASE() AND table_name = ${t} AND level = 'Column'`.pipe(k.map((e) => new Map(e.map((e) => [String(e.n ?? ""), String(e.c ?? "")]).filter(([e, t]) => e !== "" && t !== "" && !Oa.test(t.trim()))))) : k.succeed(/* @__PURE__ */ new Map()))), Aa = (e, t, n, r, i) => k.map(ka(e, t), (e) => `ALTER TABLE ${G(t)} MODIFY COLUMN ${Da(n, r, i, e.get(r))};`), ja = (e, t) => e == null ? null : Array.isArray(e) ? Ma(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" ? Xt(e, "mariadb") : null, Ma = (e, t, n) => Yt(e, t ?? { type: "json" }, n), Na = (e, t) => e == null ? null : Array.isArray(e) ? Ma(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" ? Xt(e, "postgres") : null, Pa = (e, t) => {
2988
2997
  if (!e.generatedAs) return null;
2989
2998
  let { expr: n, stored: r } = e.generatedAs;
2990
2999
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2991
- }, Pa = (e, t = !1) => {
3000
+ }, Fa = (e, t = !1) => {
2992
3001
  if (e.type === "id" && e.idScheme?.kind === "numeric") return Zt(e.name, "postgres");
2993
- let n = Na(e, "postgres");
2994
- if (n) return `${W(e.name)} ${ma(e)} ${n}`;
2995
- let r = [W(e.name), ma(e)];
3002
+ let n = Pa(e, "postgres");
3003
+ if (n) return `${W(e.name)} ${ha(e)} ${n}`;
3004
+ let r = [W(e.name), ha(e)];
2996
3005
  if (e.type === "id" && !t && r.push("PRIMARY KEY"), e.nullable || r.push("NOT NULL"), e.unique && e.type !== "id" && r.push("UNIQUE"), e.hasDefault) {
2997
- let t = Ma(e.defaultValue, e);
3006
+ let t = Na(e.defaultValue, e);
2998
3007
  t && r.push(t);
2999
3008
  }
3000
3009
  return e.references && (r.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && r.push(`ON DELETE ${{
@@ -3003,28 +3012,28 @@ BEGIN
3003
3012
  setNull: "SET NULL",
3004
3013
  noAction: "NO ACTION"
3005
3014
  }[e.references.onDelete]}`)), r.join(" ");
3006
- }, Fa = (e) => (e.primaryKey?.length ?? 0) > 0, Ia = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", La = (e) => {
3007
- let t = e.columns.map((t) => ` ${Pa(t, Fa(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Ia(e, W)}\n)`];
3008
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(uo({
3015
+ }, Ia = (e) => (e.primaryKey?.length ?? 0) > 0, La = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Ra = (e) => {
3016
+ let t = e.columns.map((t) => ` ${Fa(t, Ia(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${La(e, W)}\n)`];
3017
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(fo({
3009
3018
  kind: "add-index",
3010
3019
  table: e.table,
3011
3020
  index: t
3012
3021
  }, !1));
3013
3022
  return n;
3014
- }, Ra = 191, za = (e) => {
3015
- let t = ga(e).toUpperCase();
3023
+ }, za = 191, Ba = (e) => {
3024
+ let t = _a(e).toUpperCase();
3016
3025
  return t.endsWith("TEXT") || t.endsWith("BLOB");
3017
- }, Ba = (e, t = !1) => {
3026
+ }, Va = (e, t = !1) => {
3018
3027
  if (e.type === "id" && e.idScheme?.kind === "numeric") return Zt(e.name, "mariadb");
3019
- let n = e.charset === void 0 ? ga(e) : `${ga(e)} CHARACTER SET ${e.charset}`, r = Na(e, "mariadb");
3028
+ let n = e.charset === void 0 ? _a(e) : `${_a(e)} CHARACTER SET ${e.charset}`, r = Pa(e, "mariadb");
3020
3029
  if (r) return `${G(e.name)} ${n} ${r}`;
3021
3030
  let i = [G(e.name), n];
3022
- if (e.type === "id" && !t && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && !za(e) && i.push("UNIQUE"), e.hasDefault) {
3023
- let t = Aa(e.defaultValue, e);
3031
+ if (e.type === "id" && !t && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && !Ba(e) && i.push("UNIQUE"), e.hasDefault) {
3032
+ let t = ja(e.defaultValue, e);
3024
3033
  t && i.push(t);
3025
3034
  }
3026
3035
  return i.join(" ");
3027
- }, Va = (e) => e.columns.flatMap((t) => {
3036
+ }, Ha = (e) => e.columns.flatMap((t) => {
3028
3037
  if (!t.references) return [];
3029
3038
  let n = t.references.onDelete ? ` ON DELETE ${{
3030
3039
  cascade: "CASCADE",
@@ -3033,14 +3042,14 @@ BEGIN
3033
3042
  noAction: "NO ACTION"
3034
3043
  }[t.references.onDelete]}` : "";
3035
3044
  return [` CONSTRAINT ${G(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${G(t.name)}) REFERENCES ${G(t.references.table)} (${G(t.references.column)})${n}`];
3036
- }), Ha = (e) => {
3045
+ }), Ua = (e) => {
3037
3046
  let t = e.find((e) => e.charset !== void 0)?.charset;
3038
3047
  return t === void 0 ? "" : ` DEFAULT CHARACTER SET ${t}`;
3039
- }, Ua = (e, t, n = /* @__PURE__ */ new Map()) => {
3048
+ }, Wa = (e, t, n = /* @__PURE__ */ new Map()) => {
3040
3049
  let r = e.foreignKeys.map((e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(e.name)}`), i = e.columns.map((r) => {
3041
- let i = K(t, e.table, r), a = Ta(t, e.table, r);
3050
+ let i = K(t, e.table, r), a = Ea(t, e.table, r);
3042
3051
  if (i === void 0 || a === void 0) throw Error(`convert-charset: no declared column '${e.table}.${r}' to render MODIFY COLUMN from; it was not in ctx.declared.`);
3043
- let o = Na(a, "mariadb"), s = `${G(r)} ${F(i, "mariadb")} CHARACTER SET ${e.charset}`, c = n.get(r), l = c === void 0 ? null : `CHECK (${c})`;
3052
+ let o = Pa(a, "mariadb"), s = `${G(r)} ${F(i, "mariadb")} CHARACTER SET ${e.charset}`, c = n.get(r), l = c === void 0 ? null : `CHECK (${c})`;
3044
3053
  if (o) return `MODIFY COLUMN ${[
3045
3054
  s,
3046
3055
  o,
@@ -3057,29 +3066,29 @@ BEGIN
3057
3066
  return {
3058
3067
  drops: r,
3059
3068
  rewrite: `ALTER TABLE ${G(e.table)} ${[...i, `DEFAULT CHARACTER SET ${e.charset}`].join(", ")}`,
3060
- restores: e.foreignKeys.filter((e) => e.restore === "here").map((e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} FOREIGN KEY (${G(e.column)}) REFERENCES ${G(e.targetTable)} (${G(e.targetColumn)})` + (e.onDelete ? ` ON DELETE ${Ga[e.onDelete]}` : "") + (e.onUpdate && e.onUpdate !== "noAction" ? ` ON UPDATE ${Ga[e.onUpdate]}` : ""))
3069
+ restores: e.foreignKeys.filter((e) => e.restore === "here").map((e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} FOREIGN KEY (${G(e.column)}) REFERENCES ${G(e.targetTable)} (${G(e.targetColumn)})` + (e.onDelete ? ` ON DELETE ${Ka[e.onDelete]}` : "") + (e.onUpdate && e.onUpdate !== "noAction" ? ` ON UPDATE ${Ka[e.onUpdate]}` : ""))
3061
3070
  };
3062
- }, Wa = (e, t = "mariadb") => {
3063
- for (let n of e.indexes) po(n, t);
3071
+ }, Ga = (e, t = "mariadb") => {
3072
+ for (let n of e.indexes) mo(n, t);
3064
3073
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
3065
- let t = oo(n.get(e));
3074
+ let t = so(n.get(e));
3066
3075
  return t === void 0 ? G(e) : `${G(e)}(${t})`;
3067
- }, i = e.columns.map((t) => ` ${Ba(t, Fa(e))}`).join(",\n"), a = Va(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${Ia(e, r)}\n)${Ha(e.columns)}`];
3068
- for (let n of e.columns) n.unique && n.type !== "id" && za(n) && s.push(`CREATE UNIQUE INDEX ${_a(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
3069
- for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${_a(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
3076
+ }, i = e.columns.map((t) => ` ${Va(t, Ia(e))}`).join(",\n"), a = Ha(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${o}${La(e, r)}\n)${Ua(e.columns)}`];
3077
+ for (let n of e.columns) n.unique && n.type !== "id" && Ba(n) && s.push(`CREATE UNIQUE INDEX ${va(t)}${G(`${e.table}_${n.name}_key`)} ON ${G(e.table)} (${r(n.name)})`);
3078
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${va(t)}${G(n.name)} ON ${G(e.table)} (${n.columns.map(r).join(", ")})`);
3070
3079
  return s;
3071
- }, Ga = {
3080
+ }, Ka = {
3072
3081
  cascade: "CASCADE",
3073
3082
  restrict: "RESTRICT",
3074
3083
  setNull: "SET NULL",
3075
3084
  noAction: "NO ACTION"
3076
- }, Ka = {
3085
+ }, qa = {
3077
3086
  cascade: "CASCADE",
3078
3087
  restrict: "NO ACTION",
3079
3088
  setNull: "SET NULL",
3080
3089
  noAction: "NO ACTION"
3081
- }, qa = (e) => {
3082
- let t = pa(e, "sqlite");
3090
+ }, Ja = (e) => {
3091
+ let t = ma(e, "sqlite");
3083
3092
  if (t !== void 0) return t;
3084
3093
  switch (e.type) {
3085
3094
  case "integer":
@@ -3091,30 +3100,30 @@ BEGIN
3091
3100
  case "bytes": return "BLOB";
3092
3101
  default: return "TEXT";
3093
3102
  }
3094
- }, Ja = (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" ? Xt(e, "sqlite") : null, Ya = (e, t = !1) => {
3103
+ }, Ya = (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" ? Xt(e, "sqlite") : null, Xa = (e, t = !1) => {
3095
3104
  if (e.type === "id" && e.idScheme?.kind === "numeric") return Zt(e.name, "sqlite");
3096
- let n = Na(e, "sqlite");
3097
- if (n) return `${W(e.name)} ${qa(e)} ${n}`;
3098
- let r = [W(e.name), qa(e)];
3105
+ let n = Pa(e, "sqlite");
3106
+ if (n) return `${W(e.name)} ${Ja(e)} ${n}`;
3107
+ let r = [W(e.name), Ja(e)];
3099
3108
  if (e.type === "id" && !t && r.push("PRIMARY KEY"), e.nullable || r.push("NOT NULL"), e.unique && e.type !== "id" && r.push("UNIQUE"), e.hasDefault) {
3100
- let t = Ja(e.defaultValue, "CURRENT_TIMESTAMP");
3109
+ let t = Ya(e.defaultValue, "CURRENT_TIMESTAMP");
3101
3110
  t && r.push(t);
3102
3111
  }
3103
- if (e.references && (r.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && r.push(`ON DELETE ${Ga[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
3112
+ if (e.references && (r.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && r.push(`ON DELETE ${Ka[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
3104
3113
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
3105
3114
  r.push(`CHECK (${W(e.name)} IN (${t}))`);
3106
3115
  }
3107
3116
  return r.join(" ");
3108
- }, Xa = (e) => {
3109
- let t = e.columns.map((t) => ` ${Ya(t, Fa(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Ia(e, W)}\n)`];
3110
- 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(", ")})${lo(t)}`);
3117
+ }, Za = (e) => {
3118
+ let t = e.columns.map((t) => ` ${Xa(t, Ia(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${La(e, W)}\n)`];
3119
+ 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(", ")})${uo(t)}`);
3111
3120
  return n;
3112
- }, Za = (e, t) => {
3121
+ }, Qa = (e, t) => {
3113
3122
  let n = t.find((t) => t.tableName === e);
3114
- return n ? Qa(Nr([n], "sqlite").tables[0]) : [];
3115
- }, Qa = (e) => {
3123
+ return n ? $a(Nr([n], "sqlite").tables[0]) : [];
3124
+ }, $a = (e) => {
3116
3125
  let t = e.name, n = `${t}__voltro_rebuild`, r = e.columns.map((e) => W(e.name)).join(", "), i = [
3117
- ...Xa({
3126
+ ...Za({
3118
3127
  kind: "create-table",
3119
3128
  table: n,
3120
3129
  columns: e.columns,
@@ -3125,27 +3134,27 @@ BEGIN
3125
3134
  `DROP TABLE ${W(t)}`,
3126
3135
  `ALTER TABLE ${W(n)} RENAME TO ${W(t)}`
3127
3136
  ];
3128
- for (let n of e.indexes) n.name !== `${t}_pkey` && i.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(n.name)} ON ${W(t)} (${n.columns.map(W).join(", ")})${lo(n)}`);
3137
+ for (let n of e.indexes) n.name !== `${t}_pkey` && i.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(n.name)} ON ${W(t)} (${n.columns.map(W).join(", ")})${uo(n)}`);
3129
3138
  return i;
3130
- }, $a = (e, t, n, r) => {
3139
+ }, eo = (e, t, n, r) => {
3131
3140
  let i = r ?? e.nullable;
3132
3141
  return `ALTER TABLE ${q(n)} ALTER COLUMN ${q(t)} ${F(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
3133
- }, eo = (e, t) => {
3142
+ }, to = (e, t) => {
3134
3143
  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 ${q(e.table)} DROP CONSTRAINT [' + @dc + ']');` + (t ? ` ${t}` : "");
3135
3144
  if (!e.hasDefault) return n;
3136
- let r = Ja(e.defaultValue, "SYSUTCDATETIME()");
3145
+ let r = Ya(e.defaultValue, "SYSUTCDATETIME()");
3137
3146
  if (!r) return n;
3138
3147
  let i = r.replace(/^DEFAULT\s+/i, "");
3139
3148
  return `${n} ALTER TABLE ${q(e.table)} ADD DEFAULT ${i} FOR ${q(e.column)};`;
3140
- }, q = (e) => `[${e.replace(/]/g, "]]")}]`, to = (e) => {
3141
- let t = pa(e, "mssql");
3149
+ }, q = (e) => `[${e.replace(/]/g, "]]")}]`, no = (e) => {
3150
+ let t = ma(e, "mssql");
3142
3151
  if (t !== void 0) return t;
3143
3152
  switch (e.type) {
3144
3153
  case "id": return "NVARCHAR(64)";
3145
3154
  case "reference": return e.referenceStorage === "numeric" ? "BIGINT" : "NVARCHAR(64)";
3146
3155
  case "integer": return "INT";
3147
3156
  case "real": return "FLOAT";
3148
- case "decimal": return da(e, "DECIMAL");
3157
+ case "decimal": return fa(e, "DECIMAL");
3149
3158
  case "bigint": return "BIGINT";
3150
3159
  case "boolean": return "BIT";
3151
3160
  case "timestamp": return "DATETIME2(6)";
@@ -3153,50 +3162,50 @@ BEGIN
3153
3162
  case "bytes": return "VARBINARY(MAX)";
3154
3163
  default: return "NVARCHAR(MAX)";
3155
3164
  }
3156
- }, no = (e, t, n = !1) => {
3165
+ }, ro = (e, t, n = !1) => {
3157
3166
  if (e.type === "id" && e.idScheme?.kind === "numeric") return Zt(e.name, "mssql");
3158
- let r = e.type === "text" && t?.has(e.name) ? `NVARCHAR(${Math.min(e.maxLength ?? 450, 450)})` : to(e), i = Na(e, "mssql");
3167
+ let r = e.type === "text" && t?.has(e.name) ? `NVARCHAR(${Math.min(e.maxLength ?? 450, 450)})` : no(e), i = Pa(e, "mssql");
3159
3168
  if (i) return `${q(e.name)} ${i}`;
3160
3169
  let a = [q(e.name), r];
3161
3170
  if (e.type === "json" && a.push(`CHECK ${Pt(q(e.name))}`), e.type === "array" && a.push(`CHECK (${q(e.name)} IS NULL OR ISJSON(${q(e.name)}) = 1)`), e.type === "id" && !n && a.push("PRIMARY KEY"), e.nullable || a.push("NOT NULL"), e.unique && e.type !== "id" && a.push("UNIQUE"), e.hasDefault) {
3162
- let t = Ja(e.defaultValue, "SYSUTCDATETIME()");
3171
+ let t = Ya(e.defaultValue, "SYSUTCDATETIME()");
3163
3172
  t && a.push(t);
3164
3173
  }
3165
- return e.references && (a.push(`REFERENCES ${q(e.references.table)} (${q(e.references.column)})`), e.references.onDelete && a.push(`ON DELETE ${Ka[e.references.onDelete]}`)), a.join(" ");
3166
- }, ro = (e) => {
3167
- 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((t) => ` ${no(t, n, Fa(e))}`).join(",\n"), i = `CREATE TABLE ${q(e.table)} (\n${r}${Ia(e, q)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
3174
+ return e.references && (a.push(`REFERENCES ${q(e.references.table)} (${q(e.references.column)})`), e.references.onDelete && a.push(`ON DELETE ${qa[e.references.onDelete]}`)), a.join(" ");
3175
+ }, io = (e) => {
3176
+ 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((t) => ` ${ro(t, n, Ia(e))}`).join(",\n"), i = `CREATE TABLE ${q(e.table)} (\n${r}${La(e, q)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
3168
3177
  for (let n of e.indexes) {
3169
3178
  if (n.name === `${e.table}_pkey`) continue;
3170
- let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${q(n.name)} ON ${q(e.table)} (${n.columns.map(q).join(", ")})${lo(n)}`;
3179
+ let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${q(n.name)} ON ${q(e.table)} (${n.columns.map(q).join(", ")})${uo(n)}`;
3171
3180
  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)}')`);
3172
3181
  }
3173
3182
  return a;
3174
- }, io = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, ao = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME TO ${n(t)};`, oo = (e) => {
3175
- if (e === void 0 || !za(e)) return;
3183
+ }, ao = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, oo = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME TO ${n(t)};`, so = (e) => {
3184
+ if (e === void 0 || !Ba(e)) return;
3176
3185
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
3177
- return t === void 0 ? Ra : Math.min(Ra, t);
3178
- }, so = (e, t, n) => {
3179
- let r = oo(Ta(e, t, n));
3186
+ return t === void 0 ? za : Math.min(za, t);
3187
+ }, co = (e, t, n) => {
3188
+ let r = so(Ea(e, t, n));
3180
3189
  return r === void 0 ? G(n) : `${G(n)}(${r})`;
3181
- }, co = (e) => e.startsWith("(") ? e : W(e), lo = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, uo = (e, t) => {
3182
- let n = Re(e.index.kind, e.index.kindOptions), r = e.index.columns.map(co);
3190
+ }, lo = (e) => e.startsWith("(") ? e : W(e), uo = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, fo = (e, t) => {
3191
+ let n = Re(e.index.kind, e.index.kindOptions), r = e.index.columns.map(lo);
3183
3192
  if (n.opclass !== void 0) {
3184
3193
  if (r.length !== 1) throw Error("HNSW index requires exactly one column");
3185
3194
  r[0] = `${r[0]} ${n.opclass}`;
3186
3195
  }
3187
- return `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)}${n.using} (${r.join(", ")})${n.withSuffix}${lo(e.index)};`;
3188
- }, fo = (e, t, n = "mariadb") => (po(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${_a(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => so(t, e.table, n)).join(", ")});`), po = (e, t) => {
3196
+ return `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)}${n.using} (${r.join(", ")})${n.withSuffix}${uo(e.index)};`;
3197
+ }, po = (e, t, n = "mariadb") => (mo(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${va(n)}${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => co(t, e.table, n)).join(", ")});`), mo = (e, t) => {
3189
3198
  if (e.where !== void 0) throw Error(`Partial index '${e.name}' is not supported by ${t}; uniqueActive must be lowered before applying the plan.`);
3190
- }, mo = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, ho = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, go = (e) => `DROP INDEX IF EXISTS ${q(e.index)} ON ${q(e.table)};`, _o = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, vo = (e) => {
3199
+ }, ho = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, go = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, _o = (e) => `DROP INDEX IF EXISTS ${q(e.index)} ON ${q(e.table)};`, vo = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, yo = (e) => {
3191
3200
  let t = (e) => e.replace(/'/g, "''");
3192
3201
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
3193
- }, yo = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, bo = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, xo = (e) => {
3202
+ }, bo = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, xo = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, So = (e) => {
3194
3203
  let t = (e) => e.replace(/'/g, "''");
3195
3204
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
3196
- }, So = (e) => {
3197
- let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${q(e.index.name)} ON ${q(e.table)} (${e.index.columns.map(q).join(", ")})${lo(e.index)}`;
3205
+ }, Co = (e) => {
3206
+ let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${q(e.index.name)} ON ${q(e.table)} (${e.index.columns.map(q).join(", ")})${uo(e.index)}`;
3198
3207
  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)}');`;
3199
- }, Co = (e, t, n) => {
3208
+ }, wo = (e, t, n) => {
3200
3209
  let r = n.find((t) => t.tableName === e);
3201
3210
  if (!r) return [];
3202
3211
  let i = [];
@@ -3208,13 +3217,13 @@ BEGIN
3208
3217
  }
3209
3218
  }
3210
3219
  return i;
3211
- }, wo = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, To = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${so(t, e.table, e.column)});`, Eo = (e) => {
3220
+ }, To = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, Eo = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${co(t, e.table, e.column)});`, Do = (e) => {
3212
3221
  let t = e.fields.map((e) => W(e)).join(", ");
3213
3222
  return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
3214
- }, Do = (e, t) => {
3215
- let n = e.fields.map((n) => so(t, e.table, n)).join(", ");
3223
+ }, Oo = (e, t) => {
3224
+ let n = e.fields.map((n) => co(t, e.table, n)).join(", ");
3216
3225
  return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
3217
- }, Oo = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, ko = (e) => [Oo(e), `DROP INDEX IF EXISTS ${W(e.name)};`], Ao = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, jo = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, Mo = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, No = (e, t, n = Ga) => {
3226
+ }, ko = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, Ao = (e) => [ko(e), `DROP INDEX IF EXISTS ${W(e.name)};`], jo = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, Mo = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, No = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, Po = (e, t, n = Ka) => {
3218
3227
  let r = [], i = t(e.table), a = t(e.column), o = t(e.targetTable), s = t(e.targetColumn);
3219
3228
  if (e.orphanPolicy) {
3220
3229
  let t = `${a} IS NOT NULL AND ${a} NOT IN (SELECT ${s} FROM ${o})`;
@@ -3227,10 +3236,10 @@ BEGIN
3227
3236
  `REFERENCES ${o} (${s})`
3228
3237
  ];
3229
3238
  return e.onDelete && c.push(`ON DELETE ${n[e.onDelete]}`), r.push(c.join(" ") + ";"), r;
3230
- }, Po = (e) => e.name ?? `${e.table}_${e.column}_fkey`, Fo = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(Po(e))};`, Io = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(Po(e))};`, Lo = (e, t) => {
3239
+ }, Fo = (e) => e.name ?? `${e.table}_${e.column}_fkey`, Io = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(Fo(e))};`, Lo = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(Fo(e))};`, Ro = (e, t) => {
3231
3240
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
3232
3241
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
3233
- }, Ro = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, zo = (e, t) => k.gen(function* () {
3242
+ }, zo = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, Bo = (e, t) => k.gen(function* () {
3234
3243
  let n = yield* e`
3235
3244
  SELECT cc.constraint_name AS n, cc.check_clause AS c
3236
3245
  FROM information_schema.check_constraints cc
@@ -3245,16 +3254,16 @@ BEGIN
3245
3254
  let n = String(e.n ?? "");
3246
3255
  if (n !== "" && wi(String(e.c ?? ""))?.column === t.column) return n;
3247
3256
  }
3248
- }), Bo = (e, t, n) => k.gen(function* () {
3249
- let r = yield* zo(e, t);
3250
- r !== void 0 && (yield* J(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [sa]));
3251
- let i = yield* zo(e, t);
3257
+ }), Vo = (e, t, n) => k.gen(function* () {
3258
+ let r = yield* Bo(e, t);
3259
+ r !== void 0 && (yield* J(e, `ALTER TABLE ${G(t.table)} DROP CONSTRAINT ${G(r)};`, t.kind, [ca]));
3260
+ let i = yield* Bo(e, t);
3252
3261
  if (i === void 0) return;
3253
3262
  let a = K(n, t.table, t.column);
3254
3263
  if (!a) return yield* k.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.`));
3255
- yield* J(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Ea(a, t.column)};`, t.kind);
3256
- }), Vo = (e, t, n, r) => {
3257
- let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? q : W, s = a ? ga(i) : r === "mssql" ? to(i) : r === "sqlite" ? qa(i) : ma(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = r === "mssql" ? i.type === "json" ? ` CHECK ${Pt(o(i.name))}` : i.type === "array" ? ` CHECK (${o(i.name)} IS NULL OR ISJSON(${o(i.name)}) = 1)` : "" : "", u = (e) => a ? Aa(e, i) : r === "mssql" ? Ja(e, "SYSUTCDATETIME()") : r === "sqlite" ? Ja(e, "CURRENT_TIMESTAMP") : Ma(e, i), d = Na(i, r);
3264
+ yield* J(e, `ALTER TABLE ${G(t.table)} MODIFY COLUMN ${Da(a, t.column)};`, t.kind);
3265
+ }), Ho = (e, t, n, r) => {
3266
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? q : W, s = a ? _a(i) : r === "mssql" ? no(i) : r === "sqlite" ? Ja(i) : ha(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = r === "mssql" ? i.type === "json" ? ` CHECK ${Pt(o(i.name))}` : i.type === "array" ? ` CHECK (${o(i.name)} IS NULL OR ISJSON(${o(i.name)}) = 1)` : "" : "", u = (e) => a ? ja(e, i) : r === "mssql" ? Ya(e, "SYSUTCDATETIME()") : r === "sqlite" ? Ya(e, "CURRENT_TIMESTAMP") : Na(e, i), d = Pa(i, r);
3258
3267
  if (d) {
3259
3268
  let t = r === "mssql" ? `${o(i.name)} ${d}` : `${o(i.name)} ${s} ${d}`;
3260
3269
  return {
@@ -3283,7 +3292,7 @@ BEGIN
3283
3292
  post: p ? [p] : []
3284
3293
  };
3285
3294
  return i.unique && i.type !== "id" && (m.uniquePending = !0), f?.sql && (m.backfillKind = "sql", m.backfillSql = f.sql), f?.js && (m.backfillKind = "js", m.backfillJs = f.js), f?.batchSize !== void 0 && (m.batchSize = f.batchSize), f?.sleepMs !== void 0 && (m.sleepMs = f.sleepMs), m;
3286
- }, Ho = /* @__PURE__ */ new Set([
3295
+ }, Uo = /* @__PURE__ */ new Set([
3287
3296
  "drop-index",
3288
3297
  "drop-check",
3289
3298
  "drop-unique",
@@ -3291,7 +3300,7 @@ BEGIN
3291
3300
  "drop-foreign-key",
3292
3301
  "drop-column",
3293
3302
  "drop-table"
3294
- ]), Uo = (e) => {
3303
+ ]), Wo = (e) => {
3295
3304
  let t = new Map(e.map((e) => [e.tableName, e]));
3296
3305
  return (e, n) => {
3297
3306
  let r = t.get(e);
@@ -3311,12 +3320,12 @@ BEGIN
3311
3320
  ...o
3312
3321
  };
3313
3322
  };
3314
- }, J = (e, t, n, r = []) => e.unsafe(t).pipe(k.catchIf((e) => ra(e, r), () => k.void), k.tapError((e) => k.sync(() => {
3323
+ }, J = (e, t, n, r = []) => e.unsafe(t).pipe(k.catchIf((e) => ia(e, r), () => k.void), k.tapError((e) => k.sync(() => {
3315
3324
  process.stderr.write(ze(`applier: statement failed (op=${n})`, t, e, 400));
3316
3325
  })), k.mapError((e) => {
3317
3326
  let r = ze(`applier: statement failed (op=${n})`, t, e, 400).trim();
3318
3327
  return Object.assign(e, { message: r });
3319
- }), k.map(() => void 0)), Y = (e, t, n, r) => Wo(e, t, Za(t, n), r), Wo = (e, t, n, r) => {
3328
+ }), k.map(() => void 0)), Y = (e, t, n, r) => Go(e, t, Qa(t, n), r), Go = (e, t, n, r) => {
3320
3329
  if (n.length === 0) return k.void;
3321
3330
  let i = (e) => (n) => {
3322
3331
  let i = ze(`applier: statement failed (op=${r}, sqlite rebuild of ${t})`, e, n, 400).trim();
@@ -3333,7 +3342,7 @@ BEGIN
3333
3342
  }
3334
3343
  }), k.ignore(a("PRAGMA foreign_keys = ON")));
3335
3344
  }));
3336
- }, Go = (e, t) => k.gen(function* () {
3345
+ }, Ko = (e, t) => k.gen(function* () {
3337
3346
  let n = (yield* e`
3338
3347
  SELECT ck.name, ck.definition, ck.is_disabled AS disabled,
3339
3348
  ck.is_not_trusted AS untrusted, ck.is_not_for_replication AS notForReplication
@@ -3345,33 +3354,33 @@ BEGIN
3345
3354
  ) ORDER BY ck.name
3346
3355
  `).map((e) => ({
3347
3356
  ...e,
3348
- definition: ua(e.definition, t.from, t.to)
3349
- })), r = (e) => o(e, "mssql"), i = (e) => e.replace(/'/g, "''");
3357
+ definition: da(e.definition, t.from, t.to)
3358
+ })), r = (e) => O(e, "mssql"), i = (e) => e.replace(/'/g, "''");
3350
3359
  return yield* X(e, [
3351
3360
  ...n.map((e) => `ALTER TABLE ${r(t.table)} DROP CONSTRAINT ${r(e.name)}`),
3352
3361
  `EXEC sp_rename N'${i(`${r(t.table)}.${r(t.from)}`)}', N'${i(t.to)}', 'COLUMN';`,
3353
3362
  ...n.flatMap((e) => [`ALTER TABLE ${r(t.table)} WITH ${e.untrusted ? "NOCHECK" : "CHECK"} ADD CONSTRAINT ${r(e.name)} CHECK ${e.notForReplication ? "NOT FOR REPLICATION " : ""}${e.definition}`, ...e.disabled ? [`ALTER TABLE ${r(t.table)} NOCHECK CONSTRAINT ${r(e.name)}`] : []])
3354
3363
  ], t.kind);
3355
- }), Ko = (e, t, n) => e == null ? e : t.type === "json" ? JSON.stringify(e) : (t.type === "array" || t.type === "vector") && n !== "postgres" ? typeof e == "string" ? e : JSON.stringify(e) : e, X = (e, t, n) => k.forEach(t, (t) => J(e, t, n), { discard: !0 }), qo = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : o(r, t)} FROM ${o(n, t)} WHERE 1=0`).pipe(k.as(!0), k.catchAll(() => k.succeed(!1))), Jo = (e, t, n) => es(e, t, Ct, N, n), Yo = (e, t, n) => es(e, t, pe, "_voltro_migration_plans", n), Xo = (e, t, n) => es(e, t, ae, "_voltro_schema_owner", n), Zo = (e, t, n) => es(e, t, ce, "_voltro_plugin_migrations", n), Qo = (e, t, n) => es(e, t, _i, R, n), $o = (e, t, n) => es(e, t, me, ge, n), es = (e, t, n, r, i) => k.gen(function* () {
3356
- let a = Nr([n], t, i !== void 0 && D(t) ? { charset: i } : {}).tables[0];
3357
- if (!a) return yield* k.die(/* @__PURE__ */ Error(`migration applier: the ${r} table descriptor produced no snapshot. This is a framework bug.`));
3358
- let o = {
3364
+ }), qo = (e, t, n) => e == null ? e : t.type === "json" ? JSON.stringify(e) : (t.type === "array" || t.type === "vector") && n !== "postgres" ? typeof e == "string" ? e : JSON.stringify(e) : e, X = (e, t, n) => k.forEach(t, (t) => J(e, t, n), { discard: !0 }), Jo = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : O(r, t)} FROM ${O(n, t)} WHERE 1=0`).pipe(k.as(!0), k.catchAll(() => k.succeed(!1))), Yo = (e, t, n) => ts(e, t, Ct, N, n), Xo = (e, t, n) => ts(e, t, he, "_voltro_migration_plans", n), Zo = (e, t, n) => ts(e, t, oe, "_voltro_schema_owner", n), Qo = (e, t, n) => ts(e, t, ce, "_voltro_plugin_migrations", n), $o = (e, t, n) => ts(e, t, _i, R, n), es = (e, t, n) => ts(e, t, _e, ve, n), ts = (e, t, n, r, a) => k.gen(function* () {
3365
+ let o = Nr([n], t, a !== void 0 && i(t) ? { charset: a } : {}).tables[0];
3366
+ if (!o) return yield* k.die(/* @__PURE__ */ Error(`migration applier: the ${r} table descriptor produced no snapshot. This is a framework bug.`));
3367
+ let s = {
3359
3368
  kind: "create-table",
3360
3369
  table: r,
3361
- columns: a.columns,
3370
+ columns: o.columns,
3362
3371
  indexes: []
3363
- }, s = yield* e.onDialectOrElse({
3364
- mysql: () => H(e).pipe(k.map((e) => Wa(o, e))),
3365
- mssql: () => k.succeed(ro(o)),
3366
- sqlite: () => k.succeed(Xa(o)),
3367
- orElse: () => k.succeed(La(o))
3372
+ }, c = yield* e.onDialectOrElse({
3373
+ mysql: () => H(e).pipe(k.map((e) => Ga(s, e))),
3374
+ mssql: () => k.succeed(io(s)),
3375
+ sqlite: () => k.succeed(Za(s)),
3376
+ orElse: () => k.succeed(Ra(s))
3368
3377
  });
3369
- yield* k.forEach(s, (t) => J(e, t, "resume-ledger-bootstrap"), { discard: !0 });
3370
- }), ts = (e) => e`
3378
+ yield* k.forEach(c, (t) => J(e, t, "resume-ledger-bootstrap"), { discard: !0 });
3379
+ }), ns = (e) => e`
3371
3380
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
3372
3381
  ${e("status")}, ${e("payload")}
3373
3382
  FROM ${e(N)}
3374
- `, ns = (e) => Yi(e, N).pipe(k.flatMap((t) => t ? ts(e).pipe(k.map((e) => e.length > 0)) : k.succeed(!1))), rs = (e, t, n, r) => k.gen(function* () {
3383
+ `, rs = (e) => Xi(e, N).pipe(k.flatMap((t) => t ? ns(e).pipe(k.map((e) => e.length > 0)) : k.succeed(!1))), is = (e, t, n, r) => k.gen(function* () {
3375
3384
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3376
3385
  yield* k.forEach(r, ({ index: r, planned: a }) => e`
3377
3386
  INSERT INTO ${e(N)}
@@ -3383,7 +3392,7 @@ BEGIN
3383
3392
  ${a.op.kind}, ${Tt(a.op)}, ${"pending"},
3384
3393
  ${JSON.stringify(a)}, ${i})
3385
3394
  `, { discard: !0 });
3386
- }), is = (e, t, n, r, i) => k.gen(function* () {
3395
+ }), as = (e, t, n, r, i) => k.gen(function* () {
3387
3396
  let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3388
3397
  if (r === "applied") {
3389
3398
  yield* e`
@@ -3399,7 +3408,7 @@ BEGIN
3399
3408
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
3400
3409
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
3401
3410
  `;
3402
- }), as = (e, t, n, r) => k.gen(function* () {
3411
+ }), os = (e, t, n, r) => k.gen(function* () {
3403
3412
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3404
3413
  r.length > 0 && (yield* e`
3405
3414
  UPDATE ${e(N)}
@@ -3410,346 +3419,360 @@ BEGIN
3410
3419
  SET ${e("status")} = ${"pending"}
3411
3420
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
3412
3421
  `);
3413
- }), os = (e, t) => t === void 0 ? e`DELETE FROM ${e(N)}`.pipe(k.asVoid) : e`DELETE FROM ${e(N)} WHERE ${e("runId")} = ${t}`.pipe(k.asVoid), ss = (e) => ts(e).pipe(k.map((e) => e.filter((e) => e.status === "started" || e.status === "added" || e.status === "applied").map((e) => JSON.parse(e.payload))), k.catchAll(() => k.succeed([]))), cs = (e) => os(e).pipe(k.catchAll(() => k.void)), ls = (e, t, n) => k.gen(function* () {
3422
+ }), ss = (e, t) => t === void 0 ? e`DELETE FROM ${e(N)}`.pipe(k.asVoid) : e`DELETE FROM ${e(N)} WHERE ${e("runId")} = ${t}`.pipe(k.asVoid), cs = (e) => ns(e).pipe(k.map((e) => e.filter((e) => e.status === "started" || e.status === "added" || e.status === "applied").map((e) => JSON.parse(e.payload))), k.catchAll(() => k.succeed([]))), ls = (e) => ss(e).pipe(k.catchAll(() => k.void)), us = (e, t, n) => k.gen(function* () {
3414
3423
  if (Nt(n.op, n.classification, t) !== "artefact-repair") return "clean";
3415
- let r = n.op, i = (e) => o(e, t);
3424
+ let r = n.op, i = (e) => O(e, t);
3425
+ if (t === "postgres" && r.kind === "add-index") {
3426
+ let t = yield* e`
3427
+ SELECT ns.nspname AS schema_name
3428
+ FROM pg_index ix
3429
+ JOIN pg_class idx ON idx.oid = ix.indexrelid
3430
+ JOIN pg_namespace ns ON ns.oid = idx.relnamespace
3431
+ WHERE ix.indrelid = to_regclass(${i(r.table)})
3432
+ AND idx.relname = ${r.index.name}
3433
+ AND NOT ix.indisvalid
3434
+ `;
3435
+ return t.length === 0 ? "clean" : (yield* J(e, `DROP INDEX CONCURRENTLY ${i(t[0].schema_name)}.${i(r.index.name)}`, "resume-repair"), "outstanding");
3436
+ }
3416
3437
  if (t === "sqlite" || t === "turso") {
3417
3438
  if (!("table" in r)) return "clean";
3418
3439
  let n = `${r.table}${Ot}`;
3419
- return (yield* qo(e, t, n)) ? ((yield* qo(e, t, r.table)) ? yield* J(e, `DROP TABLE ${i(n)}`, "resume-repair") : yield* J(e, `ALTER TABLE ${i(n)} RENAME TO ${i(r.table)}`, "resume-repair"), yield* k.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
3440
+ return (yield* Jo(e, t, n)) ? ((yield* Jo(e, t, r.table)) ? yield* J(e, `DROP TABLE ${i(n)}`, "resume-repair") : yield* J(e, `ALTER TABLE ${i(n)} RENAME TO ${i(r.table)}`, "resume-repair"), yield* k.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
3420
3441
  }
3421
3442
  if (r.kind !== "alter-column-type") return "clean";
3422
- let a = `${r.column}${kt}`, s = `${r.column}${At}`, c = yield* qo(e, t, r.table, r.column), l = yield* qo(e, t, r.table, a), u = yield* qo(e, t, r.table, s), d = (e) => k.logWarning(`migration resume: ${e}`).pipe(k.annotateLogs({ scope: "voltro:migrate" }));
3423
- return !l && !u ? "clean" : c && l && !u ? (yield* J(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* J(e, `ALTER TABLE ${i(r.table)} RENAME COLUMN ${i(a)} TO ${i(r.column)}`, "resume-repair"), yield* J(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* J(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* k.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.`));
3424
- }), us = (e, t, n, r = "fresh", i) => k.gen(function* () {
3425
- let a = process.hrtime.bigint(), s = Uo(n.declared), c = t.op, l = M(e);
3426
- switch (c.kind) {
3443
+ let a = `${r.column}${kt}`, o = `${r.column}${At}`, s = yield* Jo(e, t, r.table, r.column), c = yield* Jo(e, t, r.table, a), l = yield* Jo(e, t, r.table, o), u = (e) => k.logWarning(`migration resume: ${e}`).pipe(k.annotateLogs({ scope: "voltro:migrate" }));
3444
+ return !c && !l ? "clean" : s && c && !l ? (yield* J(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* J(e, `ALTER TABLE ${i(r.table)} RENAME COLUMN ${i(a)} TO ${i(r.column)}`, "resume-repair"), yield* J(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* J(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* k.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.`));
3445
+ }), ds = (e, t, n, r = "fresh", i) => k.gen(function* () {
3446
+ let a = process.hrtime.bigint(), o = Wo(n.declared), s = t.op, c = M(e);
3447
+ switch (s.kind) {
3427
3448
  case "create-table": {
3428
3449
  let t = yield* e.onDialectOrElse({
3429
- mysql: () => H(e).pipe(k.map((e) => Wa(c, e))),
3430
- mssql: () => k.succeed(ro(c)),
3431
- sqlite: () => k.succeed(Xa(c)),
3432
- orElse: () => k.succeed(La(c))
3450
+ mysql: () => H(e).pipe(k.map((e) => Ga(s, e))),
3451
+ mssql: () => k.succeed(io(s)),
3452
+ sqlite: () => k.succeed(Za(s)),
3453
+ orElse: () => k.succeed(Ra(s))
3433
3454
  }), n = yield* e.onDialectOrElse({
3434
- mysql: () => k.succeed([ia]),
3455
+ mysql: () => k.succeed([aa]),
3435
3456
  orElse: () => k.succeed([])
3436
3457
  });
3437
- for (let r of t) yield* J(e, r, c.kind, n);
3458
+ for (let r of t) yield* J(e, r, s.kind, n);
3438
3459
  break;
3439
3460
  }
3440
3461
  case "drop-table": {
3441
- let n = Zi(t), r = n !== void 0 || process.env.VOLTRO_SOFT_DROP === "1", i = n ?? Xi(t, (/* @__PURE__ */ new Date()).toISOString()).softDropSnapshot, a = (e) => r ? ao(c, i, e) : io(c, e);
3462
+ let n = Qi(t), r = n !== void 0 || process.env.VOLTRO_SOFT_DROP === "1", i = n ?? Zi(t, (/* @__PURE__ */ new Date()).toISOString()).softDropSnapshot, a = (e) => r ? oo(s, i, e) : ao(s, e);
3442
3463
  yield* e.onDialectOrElse({
3443
- mysql: () => J(e, a(G), c.kind),
3444
- orElse: () => J(e, a(W), c.kind)
3464
+ mysql: () => J(e, a(G), s.kind),
3465
+ orElse: () => J(e, a(W), s.kind)
3445
3466
  });
3446
3467
  break;
3447
3468
  }
3448
3469
  case "drop-column": {
3449
- let n = Zi(t), r = n !== void 0 || process.env.VOLTRO_SOFT_DROP === "1", i = n ?? Xi(t, (/* @__PURE__ */ new Date()).toISOString()).softDropSnapshot;
3470
+ let n = Qi(t), r = n !== void 0 || process.env.VOLTRO_SOFT_DROP === "1", i = n ?? Zi(t, (/* @__PURE__ */ new Date()).toISOString()).softDropSnapshot;
3450
3471
  yield* e.onDialectOrElse({
3451
- mysql: () => H(e).pipe(k.flatMap((t) => J(e, r ? xa(c, i, G) : ya(c, t), c.kind, r ? [] : [aa]))),
3452
- sqlite: () => J(e, r ? xa(c, i, W) : va(c, W, !1), c.kind, r ? [] : [oa]),
3453
- orElse: () => J(e, r ? xa(c, i, W) : va(c, W), c.kind)
3472
+ mysql: () => H(e).pipe(k.flatMap((t) => J(e, r ? Sa(s, i, G) : ba(s, t), s.kind, r ? [] : [oa]))),
3473
+ sqlite: () => J(e, r ? Sa(s, i, W) : ya(s, W, !1), s.kind, r ? [] : [sa]),
3474
+ orElse: () => J(e, r ? Sa(s, i, W) : ya(s, W), s.kind)
3454
3475
  });
3455
3476
  break;
3456
3477
  }
3457
3478
  case "rename-column":
3458
3479
  yield* e.onDialectOrElse({
3459
- mysql: () => J(e, ba(c, G), c.kind),
3460
- mssql: () => Go(e, c),
3461
- orElse: () => J(e, ba(c, W), c.kind)
3480
+ mysql: () => J(e, xa(s, G), s.kind),
3481
+ mssql: () => Ko(e, s),
3482
+ orElse: () => J(e, xa(s, W), s.kind)
3462
3483
  });
3463
3484
  break;
3464
3485
  case "add-index":
3465
3486
  yield* e.onDialectOrElse({
3466
- sqlite: () => J(e, uo(c, !1), c.kind),
3467
- mysql: () => H(e).pipe(k.flatMap((t) => J(e, fo(c, n.declared, t), c.kind, [ia]))),
3468
- mssql: () => X(e, [...Co(c.table, c.index.columns, n.declared), So(c)], c.kind),
3469
- orElse: () => J(e, uo(c, t.classification === "online-required"), c.kind)
3487
+ sqlite: () => J(e, fo(s, !1), s.kind),
3488
+ mysql: () => H(e).pipe(k.flatMap((t) => J(e, po(s, n.declared, t), s.kind, [aa]))),
3489
+ mssql: () => X(e, [...wo(s.table, s.index.columns, n.declared), Co(s)], s.kind),
3490
+ orElse: () => J(e, fo(s, t.classification === "online-required"), s.kind)
3470
3491
  });
3471
3492
  break;
3472
3493
  case "drop-index":
3473
3494
  yield* e.onDialectOrElse({
3474
- mysql: () => J(e, ho(c), c.kind),
3475
- mssql: () => J(e, go(c), c.kind),
3476
- orElse: () => J(e, mo(c), c.kind)
3495
+ mysql: () => J(e, go(s), s.kind),
3496
+ mssql: () => J(e, _o(s), s.kind),
3497
+ orElse: () => J(e, ho(s), s.kind)
3477
3498
  });
3478
3499
  break;
3479
3500
  case "rename-table":
3480
3501
  yield* e.onDialectOrElse({
3481
- mysql: () => J(e, _o(c, G), c.kind),
3482
- mssql: () => J(e, vo(c), c.kind),
3483
- orElse: () => J(e, _o(c, W), c.kind)
3502
+ mysql: () => J(e, vo(s, G), s.kind),
3503
+ mssql: () => J(e, yo(s), s.kind),
3504
+ orElse: () => J(e, vo(s, W), s.kind)
3484
3505
  });
3485
3506
  break;
3486
3507
  case "rename-index":
3487
3508
  yield* e.onDialectOrElse({
3488
- mysql: () => J(e, bo(c), c.kind),
3489
- mssql: () => J(e, xo(c), c.kind),
3490
- orElse: () => J(e, yo(c), c.kind)
3509
+ mysql: () => J(e, xo(s), s.kind),
3510
+ mssql: () => J(e, So(s), s.kind),
3511
+ orElse: () => J(e, bo(s), s.kind)
3491
3512
  });
3492
3513
  break;
3493
3514
  case "add-unique":
3494
3515
  yield* e.onDialectOrElse({
3495
- mysql: () => J(e, To(c, n.declared), c.kind),
3496
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3497
- mssql: () => X(e, [...Co(c.table, [c.column], n.declared), wo(c)], c.kind),
3498
- orElse: () => J(e, wo(c), c.kind)
3516
+ mysql: () => J(e, Eo(s, n.declared), s.kind),
3517
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3518
+ mssql: () => X(e, [...wo(s.table, [s.column], n.declared), To(s)], s.kind),
3519
+ orElse: () => J(e, To(s), s.kind)
3499
3520
  });
3500
3521
  break;
3501
3522
  case "drop-unique":
3502
3523
  yield* e.onDialectOrElse({
3503
- mysql: () => J(e, Mo(c), c.kind),
3504
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3505
- orElse: () => J(e, jo(c), c.kind)
3524
+ mysql: () => J(e, No(s), s.kind),
3525
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3526
+ orElse: () => J(e, Mo(s), s.kind)
3506
3527
  });
3507
3528
  break;
3508
3529
  case "add-enum-value":
3509
3530
  yield* e.onDialectOrElse({
3510
- pg: () => c.enumName === void 0 ? k.die(/* @__PURE__ */ Error(`add-enum-value on postgres needs the type name for ${c.table}.${c.column}; the plan carries none.`)) : J(e, `ALTER TYPE ${o(c.enumName, "postgres")} ADD VALUE IF NOT EXISTS '${c.value.replace(/'/g, "''")}'`, c.kind),
3531
+ pg: () => s.enumName === void 0 ? k.die(/* @__PURE__ */ Error(`add-enum-value on postgres needs the type name for ${s.table}.${s.column}; the plan carries none.`)) : J(e, `ALTER TYPE ${O(s.enumName, "postgres")} ADD VALUE IF NOT EXISTS '${s.value.replace(/'/g, "''")}'`, s.kind),
3511
3532
  mysql: () => {
3512
- let t = K(n.declared, c.table, c.column);
3513
- return t === void 0 || t.enumValues === void 0 || t.enumValues.length === 0 ? k.die(/* @__PURE__ */ Error(`add-enum-value on the mysql family needs the declared column ${c.table}.${c.column} and its labels; the declaration carries none.`)) : k.flatMap(ka(e, c.table, t, c.column), (t) => J(e, t, c.kind));
3533
+ let t = K(n.declared, s.table, s.column);
3534
+ return t === void 0 || t.enumValues === void 0 || t.enumValues.length === 0 ? k.die(/* @__PURE__ */ Error(`add-enum-value on the mysql family needs the declared column ${s.table}.${s.column} and its labels; the declaration carries none.`)) : k.flatMap(Aa(e, s.table, t, s.column), (t) => J(e, t, s.kind));
3514
3535
  },
3515
3536
  orElse: () => k.void
3516
3537
  });
3517
3538
  break;
3518
3539
  case "add-unique-composite":
3519
3540
  yield* e.onDialectOrElse({
3520
- mysql: () => J(e, Do(c, n.declared), c.kind),
3521
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3522
- mssql: () => X(e, [...Co(c.table, c.fields, n.declared), Eo(c)], c.kind),
3523
- orElse: () => J(e, Eo(c), c.kind)
3541
+ mysql: () => J(e, Oo(s, n.declared), s.kind),
3542
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3543
+ mssql: () => X(e, [...wo(s.table, s.fields, n.declared), Do(s)], s.kind),
3544
+ orElse: () => J(e, Do(s), s.kind)
3524
3545
  });
3525
3546
  break;
3526
3547
  case "drop-unique-composite":
3527
3548
  yield* e.onDialectOrElse({
3528
- mysql: () => J(e, Ao(c), c.kind),
3529
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3530
- mssql: () => J(e, Oo(c), c.kind),
3531
- orElse: () => X(e, ko(c), c.kind)
3549
+ mysql: () => J(e, jo(s), s.kind),
3550
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3551
+ mssql: () => J(e, ko(s), s.kind),
3552
+ orElse: () => X(e, Ao(s), s.kind)
3532
3553
  });
3533
3554
  break;
3534
3555
  case "add-foreign-key":
3535
3556
  yield* e.onDialectOrElse({
3536
- mysql: () => X(e, No(c, G), c.kind),
3537
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3538
- mssql: () => X(e, No(c, q, Ka), c.kind),
3539
- orElse: () => X(e, No(c, W), c.kind)
3557
+ mysql: () => X(e, Po(s, G), s.kind),
3558
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3559
+ mssql: () => X(e, Po(s, q, qa), s.kind),
3560
+ orElse: () => X(e, Po(s, W), s.kind)
3540
3561
  });
3541
3562
  break;
3542
3563
  case "add-column": {
3543
- let o = Vo(c, t, s, yield* e.onDialectOrElse({
3564
+ let l = Ho(s, t, o, yield* e.onDialectOrElse({
3544
3565
  mysql: () => k.succeed("mariadb"),
3545
3566
  mssql: () => k.succeed("mssql"),
3546
3567
  sqlite: () => k.succeed("sqlite"),
3547
3568
  orElse: () => k.succeed("postgres")
3548
3569
  }));
3549
- if (!(r === "resume" && (yield* qo(e, M(e), c.table, c.column.name)))) for (let t of o.pre) yield* J(e, t, c.kind);
3550
- let d = t.classification === "online-required" || o.batchSize !== void 0 || o.sleepMs !== void 0, f = k.gen(function* () {
3551
- if (o.backfillKind === "sql" && o.backfillSql) {
3552
- if (t.classification !== "online-required" && o.batchSize === void 0) yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${o.backfillSql}`;
3570
+ if (!(r === "resume" && (yield* Jo(e, M(e), s.table, s.column.name)))) for (let t of l.pre) yield* J(e, t, s.kind);
3571
+ let u = t.classification === "online-required" || l.batchSize !== void 0 || l.sleepMs !== void 0, d = k.gen(function* () {
3572
+ if (l.backfillKind === "sql" && l.backfillSql) {
3573
+ if (t.classification !== "online-required" && l.batchSize === void 0) yield* e`UPDATE ${e(s.table)} SET ${e(s.column.name)} = ${l.backfillSql}`;
3553
3574
  else {
3554
- let t = o.batchSize ?? 5e3, n = o.sleepMs ?? 0, r, i = 0;
3575
+ let t = l.batchSize ?? 5e3, n = l.sleepMs ?? 0, r, i = 0;
3555
3576
  for (;;) {
3556
- let a = r === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${V(e, t)}` : yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL AND ${e("id")} > ${r} ORDER BY ${e("id")} ${V(e, t)}`;
3577
+ let a = r === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(s.table)} WHERE ${e(s.column.name)} IS NULL ORDER BY ${e("id")} ${V(e, t)}` : yield* e`SELECT ${e("id")} FROM ${e(s.table)} WHERE ${e(s.column.name)} IS NULL AND ${e("id")} > ${r} ORDER BY ${e("id")} ${V(e, t)}`;
3557
3578
  if (a.length === 0) break;
3558
- let s = a.map((e) => e.id);
3559
- yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${o.backfillSql} WHERE ${e("id")} IN ${e.in(s)}`, i += a.length, yield* k.logInfo(`backfill ${c.table}.${c.column.name}: ${i} rows`).pipe(k.annotateLogs({
3579
+ let o = a.map((e) => e.id);
3580
+ yield* e`UPDATE ${e(s.table)} SET ${e(s.column.name)} = ${l.backfillSql} WHERE ${e("id")} IN ${e.in(o)}`, i += a.length, yield* k.logInfo(`backfill ${s.table}.${s.column.name}: ${i} rows`).pipe(k.annotateLogs({
3560
3581
  scope: "voltro:migrate",
3561
3582
  mode: "sql-batched"
3562
3583
  })), r = a[a.length - 1].id, n > 0 && (yield* k.sleep(`${n} millis`));
3563
3584
  }
3564
3585
  }
3565
- } else if (o.backfillKind === "js" && o.backfillJs) {
3566
- let t = o.batchSize ?? 1e3, r = o.sleepMs ?? 0, i = n.declared.find((e) => e.tableName === c.table), a, s = 0;
3586
+ } else if (l.backfillKind === "js" && l.backfillJs) {
3587
+ let t = l.batchSize ?? 1e3, r = l.sleepMs ?? 0, i = n.declared.find((e) => e.tableName === s.table), a, o = 0;
3567
3588
  for (;;) {
3568
- let n = a === void 0 ? yield* e`SELECT * FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${V(e, t)}` : yield* e`SELECT * FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL AND ${e("id")} > ${a} ORDER BY ${e("id")} ${V(e, t)}`;
3589
+ let n = a === void 0 ? yield* e`SELECT * FROM ${e(s.table)} WHERE ${e(s.column.name)} IS NULL ORDER BY ${e("id")} ${V(e, t)}` : yield* e`SELECT * FROM ${e(s.table)} WHERE ${e(s.column.name)} IS NULL AND ${e("id")} > ${a} ORDER BY ${e("id")} ${V(e, t)}`;
3569
3590
  if (n.length === 0) break;
3570
- let u = i === void 0 ? n : Se(n, i, l);
3591
+ let u = i === void 0 ? n : ne(n, i, c);
3571
3592
  for (let t of u) {
3572
3593
  let n = yield* k.tryPromise({
3573
- try: () => Promise.resolve(o.backfillJs(t)),
3594
+ try: () => Promise.resolve(l.backfillJs(t)),
3574
3595
  catch: (e) => e
3575
3596
  }).pipe(k.orDie);
3576
- yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${Ko(n, c.column, l)} WHERE ${e("id")} = ${t.id}`;
3597
+ yield* e`UPDATE ${e(s.table)} SET ${e(s.column.name)} = ${qo(n, s.column, c)} WHERE ${e("id")} = ${t.id}`;
3577
3598
  }
3578
- s += u.length, yield* k.logInfo(`backfill ${c.table}.${c.column.name}: ${s} rows processed`).pipe(k.annotateLogs({
3599
+ o += u.length, yield* k.logInfo(`backfill ${s.table}.${s.column.name}: ${o} rows processed`).pipe(k.annotateLogs({
3579
3600
  scope: "voltro:migrate",
3580
- table: c.table,
3581
- column: c.column.name
3601
+ table: s.table,
3602
+ column: s.column.name
3582
3603
  })), a = u[u.length - 1].id, r > 0 && (yield* k.sleep(`${r} millis`));
3583
3604
  }
3584
3605
  }
3585
- }), p = k.gen(function* () {
3586
- for (let t of o.post) yield* J(e, t, c.kind);
3587
- if (u(l) && (o.uniquePending === !0 || o.backfillKind !== void 0 && !c.column.nullable)) yield* Y(e, c.table, n.declared, c.kind);
3588
- else if (o.uniquePending === !0) {
3606
+ }), f = k.gen(function* () {
3607
+ for (let t of l.post) yield* J(e, t, s.kind);
3608
+ if (b(c) && (l.uniquePending === !0 || l.backfillKind !== void 0 && !s.column.nullable)) yield* Y(e, s.table, n.declared, s.kind);
3609
+ else if (l.uniquePending === !0) {
3589
3610
  let t = {
3590
3611
  kind: "add-unique",
3591
- table: c.table,
3592
- column: c.column.name
3612
+ table: s.table,
3613
+ column: s.column.name
3593
3614
  };
3594
3615
  yield* e.onDialectOrElse({
3595
- mysql: () => J(e, To(t, n.declared), c.kind),
3596
- mssql: () => X(e, [...Co(c.table, [c.column.name], n.declared), wo(t)], c.kind),
3597
- orElse: () => J(e, wo(t), c.kind)
3616
+ mysql: () => J(e, Eo(t, n.declared), s.kind),
3617
+ mssql: () => X(e, [...wo(s.table, [s.column.name], n.declared), To(t)], s.kind),
3618
+ orElse: () => J(e, To(t), s.kind)
3598
3619
  });
3599
3620
  }
3600
3621
  });
3601
- if (i !== void 0 && o.backfillKind !== void 0 && !d) return i({
3602
- table: c.table,
3603
- op: c,
3604
- data: f,
3605
- after: p
3622
+ if (i !== void 0 && l.backfillKind !== void 0 && !u) return i({
3623
+ table: s.table,
3624
+ op: s,
3625
+ data: d,
3626
+ after: f
3606
3627
  }), {
3607
- op: c,
3628
+ op: s,
3608
3629
  status: "applied",
3609
3630
  deferred: !0,
3610
3631
  durationMs: Number(process.hrtime.bigint() - a) / 1e6
3611
3632
  };
3612
- yield* f, yield* p;
3633
+ yield* d, yield* f;
3613
3634
  break;
3614
3635
  }
3615
3636
  case "alter-column-nullability":
3616
3637
  yield* e.onDialectOrElse({
3617
3638
  mysql: () => {
3618
- let t = K(n.declared, c.table, c.column);
3619
- return t ? k.flatMap(ka(e, c.table, t, c.column, c.toNullable), (t) => J(e, t, c.kind)) : k.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${c.table}.${c.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
3639
+ let t = K(n.declared, s.table, s.column);
3640
+ return t ? k.flatMap(Aa(e, s.table, t, s.column, s.toNullable), (t) => J(e, t, s.kind)) : k.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${s.table}.${s.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
3620
3641
  },
3621
3642
  mssql: () => {
3622
- let t = K(n.declared, c.table, c.column);
3623
- return t ? J(e, $a(t, c.column, c.table, c.toNullable), c.kind) : k.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${c.table}.${c.column}'.`));
3643
+ let t = K(n.declared, s.table, s.column);
3644
+ return t ? J(e, eo(t, s.column, s.table, s.toNullable), s.kind) : k.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${s.table}.${s.column}'.`));
3624
3645
  },
3625
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3626
- orElse: () => J(e, `ALTER TABLE ${W(c.table)} ALTER COLUMN ${W(c.column)} ${c.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, c.kind)
3646
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3647
+ orElse: () => J(e, `ALTER TABLE ${W(s.table)} ALTER COLUMN ${W(s.column)} ${s.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, s.kind)
3627
3648
  });
3628
3649
  break;
3629
3650
  case "alter-column-default": {
3630
- let t = Ta(n.declared, c.table, c.column), r = K(n.declared, c.table, c.column), i = (e) => c.hasDefault && r !== void 0 && Ca(r, e) ? r : void 0;
3651
+ let t = Ea(n.declared, s.table, s.column), r = K(n.declared, s.table, s.column), i = (e) => s.hasDefault && r !== void 0 && wa(r, e) ? r : void 0;
3631
3652
  yield* e.onDialectOrElse({
3632
3653
  mysql: () => {
3633
3654
  let n = i("mariadb");
3634
- return k.flatMap(n ? ka(e, c.table, n, c.column) : k.succeed(Sa(c, G, (e) => Aa(e, t))), (t) => J(e, t, c.kind));
3655
+ return k.flatMap(n ? Aa(e, s.table, n, s.column) : k.succeed(Ca(s, G, (e) => ja(e, t))), (t) => J(e, t, s.kind));
3635
3656
  },
3636
3657
  mssql: () => {
3637
3658
  let t = i("mssql");
3638
- return J(e, eo(c, t ? $a(t, c.column, c.table) : void 0), c.kind);
3659
+ return J(e, to(s, t ? eo(t, s.column, s.table) : void 0), s.kind);
3639
3660
  },
3640
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3641
- orElse: () => J(e, Sa(c, W, (e) => Ma(e, t)), c.kind)
3661
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3662
+ orElse: () => J(e, Ca(s, W, (e) => Na(e, t)), s.kind)
3642
3663
  });
3643
3664
  break;
3644
3665
  }
3645
3666
  case "alter-column-type": {
3646
- let r = ma(Ta(n.declared, c.table, c.column) ?? { type: c.to }), i = c.using ? ` USING ${c.using}` : "";
3667
+ let r = ha(Ea(n.declared, s.table, s.column) ?? { type: s.to }), i = s.using ? ` USING ${s.using}` : "";
3647
3668
  if (t.classification !== "online-required") {
3648
3669
  yield* e.onDialectOrElse({
3649
3670
  mysql: () => {
3650
- let t = K(n.declared, c.table, c.column);
3651
- return t ? k.flatMap(ka(e, c.table, t, c.column), (t) => J(e, t, c.kind)) : k.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${c.table}.${c.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
3671
+ let t = K(n.declared, s.table, s.column);
3672
+ return t ? k.flatMap(Aa(e, s.table, t, s.column), (t) => J(e, t, s.kind)) : k.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${s.table}.${s.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
3652
3673
  },
3653
3674
  mssql: () => {
3654
- let t = K(n.declared, c.table, c.column);
3655
- return t ? J(e, $a(t, c.column, c.table), c.kind) : k.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${c.table}.${c.column}'.`));
3675
+ let t = K(n.declared, s.table, s.column);
3676
+ return t ? J(e, eo(t, s.column, s.table), s.kind) : k.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${s.table}.${s.column}'.`));
3656
3677
  },
3657
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3658
- orElse: () => J(e, `ALTER TABLE ${W(c.table)} ALTER COLUMN ${W(c.column)} TYPE ${r}${i};`, c.kind)
3678
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3679
+ orElse: () => J(e, `ALTER TABLE ${W(s.table)} ALTER COLUMN ${W(s.column)} TYPE ${r}${i};`, s.kind)
3659
3680
  });
3660
3681
  break;
3661
3682
  }
3662
3683
  yield* e.onDialectOrElse({
3663
- mysql: () => k.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${c.table}.${c.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
3684
+ mysql: () => k.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${s.table}.${s.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
3664
3685
  orElse: () => k.void
3665
3686
  });
3666
- let a = `${c.column}__shadow`, o = `${c.column}__old`;
3667
- yield* e.unsafe(`ALTER TABLE ${W(c.table)} ADD COLUMN ${W(a)} ${r}`);
3668
- let s = c.using ?? W(c.column), l;
3687
+ let a = `${s.column}__shadow`, o = `${s.column}__old`;
3688
+ yield* e.unsafe(`ALTER TABLE ${W(s.table)} ADD COLUMN ${W(a)} ${r}`);
3689
+ let c = s.using ?? W(s.column), l;
3669
3690
  for (;;) {
3670
- let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${V(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${V(e, 5e3)}`;
3691
+ let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(s.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${V(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(s.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${V(e, 5e3)}`;
3671
3692
  if (t.length === 0) break;
3672
- yield* e.unsafe(`UPDATE ${W(c.table)} SET ${W(a)} = ${s} WHERE ${W(c.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;
3693
+ yield* e.unsafe(`UPDATE ${W(s.table)} SET ${W(a)} = ${c} WHERE ${W(s.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;
3673
3694
  }
3674
- yield* k.logInfo(`alter-column-type shadow ${c.table}.${c.column}: shadow populated`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(c.table)} RENAME COLUMN ${W(c.column)} TO ${W(o)}`), yield* e.unsafe(`ALTER TABLE ${W(c.table)} RENAME COLUMN ${W(a)} TO ${W(c.column)}`), yield* e.unsafe(`ALTER TABLE ${W(c.table)} DROP COLUMN ${W(o)}`);
3695
+ yield* k.logInfo(`alter-column-type shadow ${s.table}.${s.column}: shadow populated`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(s.table)} RENAME COLUMN ${W(s.column)} TO ${W(o)}`), yield* e.unsafe(`ALTER TABLE ${W(s.table)} RENAME COLUMN ${W(a)} TO ${W(s.column)}`), yield* e.unsafe(`ALTER TABLE ${W(s.table)} DROP COLUMN ${W(o)}`);
3675
3696
  break;
3676
3697
  }
3677
3698
  case "drop-foreign-key":
3678
3699
  yield* e.onDialectOrElse({
3679
- mysql: () => J(e, Io(c), c.kind),
3680
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3681
- orElse: () => J(e, Fo(c), c.kind)
3700
+ mysql: () => J(e, Lo(s), s.kind),
3701
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3702
+ orElse: () => J(e, Io(s), s.kind)
3682
3703
  });
3683
3704
  break;
3684
3705
  case "add-check":
3685
3706
  yield* e.onDialectOrElse({
3686
- mysql: () => J(e, Lo(c, G), c.kind),
3687
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3688
- orElse: () => J(e, Lo(c, W), c.kind)
3707
+ mysql: () => J(e, Ro(s, G), s.kind),
3708
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3709
+ orElse: () => J(e, Ro(s, W), s.kind)
3689
3710
  });
3690
3711
  break;
3691
3712
  case "convert-charset":
3692
3713
  yield* e.onDialectOrElse({
3693
3714
  mysql: () => k.gen(function* () {
3694
- let { drops: t, rewrite: r, restores: i } = Ua(c, n.declared, yield* Oa(e, c.table));
3695
- for (let n of t) yield* J(e, n, c.kind, [sa]);
3696
- yield* J(e, r, c.kind);
3697
- for (let t of i) yield* J(e, t, c.kind, [ca]);
3715
+ let { drops: t, rewrite: r, restores: i } = Wa(s, n.declared, yield* ka(e, s.table));
3716
+ for (let n of t) yield* J(e, n, s.kind, [ca]);
3717
+ yield* J(e, r, s.kind);
3718
+ for (let t of i) yield* J(e, t, s.kind, [la]);
3698
3719
  }),
3699
3720
  orElse: () => k.dieMessage("convert-charset requires MySQL or MariaDB")
3700
3721
  });
3701
3722
  break;
3702
3723
  case "reconcile-json-check": {
3703
- let t = q(c.column), n = c.validation === "value" ? Pt(t) : `(${t} IS NULL OR ISJSON(${t}) = 1)`;
3724
+ let t = q(s.column), n = s.validation === "value" ? Pt(t) : `(${t} IS NULL OR ISJSON(${t}) = 1)`;
3704
3725
  yield* e.onDialectOrElse({
3705
- mssql: () => X(e, [...c.dropConstraints.map((e) => `ALTER TABLE ${q(c.table)} DROP CONSTRAINT ${q(e)}`), `ALTER TABLE ${q(c.table)} WITH CHECK ADD CHECK ${n}`], c.kind),
3726
+ mssql: () => X(e, [...s.dropConstraints.map((e) => `ALTER TABLE ${q(s.table)} DROP CONSTRAINT ${q(e)}`), `ALTER TABLE ${q(s.table)} WITH CHECK ADD CHECK ${n}`], s.kind),
3706
3727
  orElse: () => k.dieMessage("reconcile-json-check requires SQL Server")
3707
3728
  });
3708
3729
  break;
3709
3730
  }
3710
3731
  case "drop-check": yield* e.onDialectOrElse({
3711
- mysql: () => Bo(e, c, n.declared),
3712
- sqlite: () => Y(e, c.table, n.declared, c.kind),
3713
- orElse: () => J(e, Ro(c), c.kind)
3732
+ mysql: () => Vo(e, s, n.declared),
3733
+ sqlite: () => Y(e, s.table, n.declared, s.kind),
3734
+ orElse: () => J(e, zo(s), s.kind)
3714
3735
  });
3715
3736
  }
3716
3737
  return {
3717
- op: c,
3738
+ op: s,
3718
3739
  status: "applied",
3719
3740
  durationMs: Number((process.hrtime.bigint() - a) / 1000000n)
3720
3741
  };
3721
- }), ds = (e, t, n, r) => k.gen(function* () {
3722
- let i = [...new Set(r.map((e) => e.runId))];
3723
- if (i.length > 1) return yield* k.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 \`${N}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
3724
- let a = i[0], o = [...r].map((e) => ({
3742
+ }), fs = (e, t, n, r, i) => k.gen(function* () {
3743
+ let a = [...new Set(r.map((e) => e.runId))];
3744
+ if (a.length > 1) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${a.length} unfinished runs (${a.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 \`${N}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
3745
+ let o = a[0], s = [...r].map((e) => ({
3725
3746
  index: Number(e.opIndex),
3726
3747
  status: e.status,
3727
3748
  planned: JSON.parse(e.payload)
3728
- })).sort((e, t) => e.index - t.index), s = o.find((e) => e.status === "started"), c = o.filter((e) => e.status === "started").length;
3729
- if (c > 1) return yield* k.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 \`${N}\` by hand before re-running.`));
3730
- let l = o.filter((e) => e.status === "added");
3731
- if (yield* k.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} ${Tt(s.planned.op)}` : ""}${l.length > 0 ? `, ${l.length} column(s) added with the backfill still owed` : ""}`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
3749
+ })).sort((e, t) => e.index - t.index), c = s.find((e) => e.status === "started"), l = s.filter((e) => e.status === "started").length;
3750
+ if (l > 1) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${l} operations as in-flight for run ${o}. 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 \`${N}\` by hand before re-running.`));
3751
+ let u = s.filter((e) => e.status === "added");
3752
+ if (yield* k.logWarning(`migration resume: found an interrupted run (${o}) — ${s.filter((e) => e.status === "applied").length} of ${s.length} operation(s) completed${c ? `, in flight: ${c.planned.op.kind} ${Tt(c.planned.op)}` : ""}${u.length > 0 ? `, ${u.length} column(s) added with the backfill still owed` : ""}`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), s.every((e) => e.status === "pending")) return {
3732
3753
  kind: "discard",
3733
- runId: a,
3754
+ runId: o,
3734
3755
  why: "no operation had started — no DDL ran"
3735
3756
  };
3736
- let u = s ? yield* ls(e, t, s.planned) : "clean", d = r[0].planFingerprint;
3737
- if (d !== n.toFingerprint) return {
3757
+ let d = c ? yield* us(e, t, c.planned) : "clean";
3758
+ d !== "clean" && (n = yield* i());
3759
+ let f = r[0].planFingerprint;
3760
+ if (f !== n.toFingerprint) return {
3738
3761
  kind: "discard",
3739
- runId: a,
3740
- why: `the declared schema changed since the interruption (recorded target ${d.slice(0, 12)}…, current ${n.toFingerprint.slice(0, 12)}…) — applying the freshly-diffed plan instead`
3762
+ runId: o,
3763
+ why: `the declared schema changed since the interruption (recorded target ${f.slice(0, 12)}…, current ${n.toFingerprint.slice(0, 12)}…) — applying the freshly-diffed plan instead`
3741
3764
  };
3742
- let f = (e) => e.status === "applied" ? !1 : s && e.index === s.index && u !== "clean" ? u === "outstanding" : Dt(n, e.planned.op), p = o.filter(f), m = o.filter((e) => e.status !== "applied" && !f(e));
3743
- return yield* as(e, a, p.map((e) => e.index), m.map((e) => e.index)), yield* k.logWarning(`migration resume: continuing run ${a} — replaying ${p.length} operation(s), ${o.length - p.length} already applied`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), {
3765
+ let p = (e) => e.status === "applied" ? !1 : c && e.index === c.index && d !== "clean" ? d === "outstanding" : Dt(n, e.planned.op), m = s.filter(p), h = s.filter((e) => e.status !== "applied" && !p(e));
3766
+ return yield* os(e, o, m.map((e) => e.index), h.map((e) => e.index)), yield* k.logWarning(`migration resume: continuing run ${o} — replaying ${m.length} operation(s), ${s.length - m.length} already applied`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), {
3744
3767
  kind: "resume",
3745
- runId: a,
3746
- ops: p.map((e) => ({
3768
+ runId: o,
3769
+ ops: m.map((e) => ({
3747
3770
  index: e.index,
3748
3771
  planned: e.planned
3749
3772
  })),
3750
- history: o.filter((e) => e.status !== "pending" || f(e)).map((e) => e.planned)
3773
+ history: s.filter((e) => e.status !== "pending" || p(e)).map((e) => e.planned)
3751
3774
  };
3752
- }), fs = (e, t, n) => k.gen(function* () {
3775
+ }), ps = (e, t, n) => k.gen(function* () {
3753
3776
  for (let r of t.operations) {
3754
3777
  let i = r.op;
3755
3778
  if (i.kind !== "add-index" || !i.index.unique || i.index.where === void 0 || t.operations.some((e) => e.op.kind === "rename-table" ? e.op.to === i.table : e.op.table === i.table && [
@@ -3757,10 +3780,10 @@ BEGIN
3757
3780
  "add-column",
3758
3781
  "rename-column"
3759
3782
  ].includes(e.op.kind))) continue;
3760
- let a = i.index.columns.map((e) => e.startsWith("(") ? e : o(e, n)), s = n === "mssql" ? "" : a.map((e) => ` AND ${e} IS NOT NULL`).join(""), c = n === "mssql" ? "SELECT TOP (1) 1" : "SELECT 1", l = n === "mssql" ? "" : " LIMIT 1";
3761
- if ((yield* e.unsafe(`${c} FROM ${o(i.table, n)} WHERE (${i.index.where})${s} GROUP BY ${a.join(", ")} HAVING COUNT(*) > 1${l}`)).length > 0) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: partial unique index '${i.index.name}' on '${i.table}' conflicts with existing qualifying rows. No schema or row changes were applied. Resolve the conflicting data explicitly before retrying.`));
3783
+ let a = i.index.columns.map((e) => e.startsWith("(") ? e : O(e, n)), o = n === "mssql" ? "" : a.map((e) => ` AND ${e} IS NOT NULL`).join(""), s = n === "mssql" ? "SELECT TOP (1) 1" : "SELECT 1", c = n === "mssql" ? "" : " LIMIT 1";
3784
+ if ((yield* e.unsafe(`${s} FROM ${O(i.table, n)} WHERE (${i.index.where})${o} GROUP BY ${a.join(", ")} HAVING COUNT(*) > 1${c}`)).length > 0) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: partial unique index '${i.index.name}' on '${i.table}' conflicts with existing qualifying rows. No schema or row changes were applied. Resolve the conflicting data explicitly before retrying.`));
3762
3785
  }
3763
- }), ps = (e) => {
3786
+ }), ms = (e) => {
3764
3787
  let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
3765
3788
  return [
3766
3789
  t.kind,
@@ -3769,13 +3792,13 @@ BEGIN
3769
3792
  n("name"),
3770
3793
  n("to")
3771
3794
  ].join("\0");
3772
- }, ms = (e, t, n) => k.acquireUseRelease(_t(e, { schema: n.lockSchema }), () => hs(e, t, n), (e) => e.release.pipe(k.orDie)), hs = (e, t, n) => k.gen(function* () {
3795
+ }, hs = (e, t, n) => k.acquireUseRelease(_t(e, { schema: n.lockSchema }), () => gs(e, t, n), (e) => e.release.pipe(k.orDie)), gs = (e, t, n) => k.gen(function* () {
3773
3796
  let r = t.operations.filter((e) => e.blocked);
3774
3797
  if (r.length > 0) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
3775
- let i = Date.now(), a = [], o = M(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => ps(e))), l = {
3798
+ let i = Date.now(), a = [], o = M(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => ms(e))), l = {
3776
3799
  ...s,
3777
3800
  operations: s.operations.map((e) => {
3778
- if (!e.blocked || !c.has(ps(e))) return e;
3801
+ if (!e.blocked || !c.has(ms(e))) return e;
3779
3802
  let { blocked: t, ...n } = e;
3780
3803
  return n;
3781
3804
  })
@@ -3789,93 +3812,99 @@ BEGIN
3789
3812
  f && (yield* J(e, f, "enum-types"));
3790
3813
  let p = Cn(n.declared, o);
3791
3814
  p && (yield* J(e, p, "enum-types"));
3792
- let m = St(o) === "plan-transactional", h = (/* @__PURE__ */ new Date()).toISOString(), g = process.env.VOLTRO_SOFT_DROP === "1" ? l.operations.map((e) => Xi(e, h)) : l.operations, _ = m ? g.filter((e) => e.classification !== "online-required") : [], v = m ? g.filter((e) => e.classification === "online-required") : g, y = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, b = v.map((e, t) => ({
3793
- index: _.length + t,
3815
+ let m = St(o) === "plan-transactional";
3816
+ yield* ps(e, l, o), yield* Yo(e, o, n.charset);
3817
+ let h = yield* ns(e), g = h.length > 0 ? yield* fs(e, o, l, h, () => n.replan(e).pipe(k.map((e) => (l = {
3818
+ ...e,
3819
+ operations: e.operations.map((e) => {
3820
+ if (!e.blocked || !c.has(ms(e))) return e;
3821
+ let { blocked: t, ...n } = e;
3822
+ return n;
3823
+ })
3824
+ }, l)))) : void 0;
3825
+ if (l.operations.some((e) => e.blocked)) return yield* k.die(/* @__PURE__ */ Error("applyPlan: refusing blocked operations after interrupted-run repair. Run `voltro db plan` to inspect the remaining work."));
3826
+ g?.kind === "discard" && (yield* k.logWarning(`migration resume: discarding ledger of run ${g.runId} — ${g.why}`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), yield* ss(e, g.runId));
3827
+ let _ = (/* @__PURE__ */ new Date()).toISOString(), v = process.env.VOLTRO_SOFT_DROP === "1" ? l.operations.map((e) => Zi(e, _)) : l.operations, y = m ? v.filter((e) => e.classification !== "online-required") : [], ee = m ? v.filter((e) => e.classification === "online-required") : v, b = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, x = ee.map((e, t) => ({
3828
+ index: y.length + t,
3794
3829
  planned: e
3795
- })), x = "fresh", S;
3796
- yield* fs(e, l, o), yield* Jo(e, o, n.charset);
3797
- let C = yield* ts(e);
3798
- if (C.length > 0) {
3799
- let t = yield* ds(e, o, l, C);
3800
- t.kind === "resume" ? (y = t.runId, b = t.ops, S = t.history, x = "resume") : (yield* k.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(k.annotateLogs({ scope: "voltro:migrate" })), yield* os(e, t.runId));
3801
- }
3802
- (_.length > 0 || b.length > 0) && n.beforeExecute !== void 0 && (yield* n.beforeExecute), x === "fresh" && b.length > 0 && (yield* rs(e, y, l.toFingerprint, b)), _.length > 0 && (yield* la(e, k.gen(function* () {
3830
+ })), S = "fresh", C;
3831
+ g?.kind === "resume" && (b = g.runId, x = g.ops, C = g.history, S = "resume"), (y.length > 0 || x.length > 0) && n.beforeExecute !== void 0 && (yield* n.beforeExecute), S === "fresh" && x.length > 0 && (yield* is(e, b, l.toFingerprint, x)), y.length > 0 && (yield* ua(e, k.gen(function* () {
3803
3832
  let e = yield* A.SqlClient;
3804
- if (x === "resume") return yield* k.die(/* @__PURE__ */ Error("applyPlan: transactional work appeared while resuming an interrupted run with the same target. Inspect the live schema and operation ledger before retrying."));
3805
- let t = _.map((e, t) => ({
3833
+ if (S === "resume") return yield* k.die(/* @__PURE__ */ Error("applyPlan: transactional work appeared while resuming an interrupted run with the same target. Inspect the live schema and operation ledger before retrying."));
3834
+ let t = y.map((e, t) => ({
3806
3835
  index: t,
3807
3836
  planned: e
3808
3837
  }));
3809
- yield* rs(e, y, l.toFingerprint, t);
3838
+ yield* is(e, b, l.toFingerprint, t);
3810
3839
  let r = [], i = () => k.gen(function* () {
3811
3840
  for (let e of r.splice(0)) yield* e.data, yield* e.after;
3812
3841
  });
3813
- for (let t of _) Ho.has(t.op.kind) && r.length > 0 && (yield* i()), a.push(yield* us(e, t, n, "fresh", (e) => r.push(e)));
3842
+ for (let t of y) Uo.has(t.op.kind) && r.length > 0 && (yield* i()), a.push(yield* ds(e, t, n, "fresh", (e) => r.push(e)));
3814
3843
  yield* i();
3815
- for (let { index: n } of t) yield* is(e, y, n, "applied");
3844
+ for (let { index: n } of t) yield* as(e, b, n, "applied");
3816
3845
  })));
3817
- let w = [], T = () => k.gen(function* () {
3846
+ let w = [], te = () => k.gen(function* () {
3818
3847
  let t = w.splice(0);
3819
3848
  if (t.length !== 0) {
3820
- yield* la(e, k.gen(function* () {
3849
+ yield* ua(e, k.gen(function* () {
3821
3850
  for (let e of t) yield* e.data;
3822
3851
  }));
3823
3852
  for (let n of t) yield* n.after, a.push({
3824
3853
  op: n.op,
3825
3854
  status: "applied",
3826
3855
  durationMs: Number(process.hrtime.bigint() - n.startedAt) / 1e6
3827
- }), yield* is(e, y, n.index, "applied", Number(process.hrtime.bigint() - n.startedAt) / 1e6);
3856
+ }), yield* as(e, b, n.index, "applied", Number(process.hrtime.bigint() - n.startedAt) / 1e6);
3828
3857
  }
3829
3858
  });
3830
- for (let { index: t, planned: r } of b) {
3831
- Ho.has(r.op.kind) && w.length > 0 && (yield* T()), yield* is(e, y, t, "started");
3832
- let i = a.length, o = process.hrtime.bigint(), s = yield* us(e, r, n, x, (e) => w.push({
3859
+ for (let { index: t, planned: r } of x) {
3860
+ Uo.has(r.op.kind) && w.length > 0 && (yield* te()), yield* as(e, b, t, "started");
3861
+ let i = a.length, o = process.hrtime.bigint(), s = yield* ds(e, r, n, S, (e) => w.push({
3833
3862
  ...e,
3834
3863
  index: t,
3835
3864
  startedAt: o
3836
- })).pipe(k.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${b.length + _.length} operation(s) applied before this one${_.length > 0 ? ` (${_.length} of them in a transaction)` : ""}.\n` + (m ? " 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 ledger records how far it got (operation ${t} was in flight).\n`) })));
3865
+ })).pipe(k.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${x.length + y.length} operation(s) applied before this one${y.length > 0 ? ` (${y.length} of them in a transaction)` : ""}.\n` + (m ? (y.length > 0 ? "The transactional batch completed before this phase; this failure does not roll it back.\n" : "This phase runs outside a transactional batch; completed operations are not rolled back by this failure.\n") + "An enclosing deployment transaction may still undo its own changes. Inspect the live schema and operation ledger before retrying.\nThe failing operation may also have made partial progress.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The ledger records how far it got (operation ${t} was in flight).\n`) })));
3837
3866
  if (s.deferred === !0) {
3838
- yield* is(e, y, t, "added");
3867
+ yield* as(e, b, t, "added");
3839
3868
  continue;
3840
3869
  }
3841
- a.push(s), yield* is(e, y, t, "applied", s.durationMs);
3870
+ a.push(s), yield* as(e, b, t, "applied", s.durationMs);
3842
3871
  }
3843
- yield* T();
3844
- let E = yield* n.replan(e);
3845
- if (E.operations.length > 0) {
3846
- let e = (e) => "column" in e ? typeof e.column == "string" ? `.${e.column}` : `.${String(e.column.name ?? "")}` : "", t = E.operations.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n"), n = a.filter((e) => e.status === "applied"), r = n.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n") + (n.length > 10 ? `\n … and ${n.length - 10} more` : "");
3847
- return yield* k.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 ${E.operations.length}:\n${t}${E.operations.length > 10 ? `\n … and ${E.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.\n` + (m ? " This dialect applies a plan atomically, so the run is rolled back and the schema IS unchanged.\n" : ` This dialect does NOT apply a plan atomically. The ${n.length} operation(s) below are COMMITTED\n and there is no rollback — the schema is PART-APPLIED, not unchanged:\n${r}\n Re-running plans from where the database now is, which is a different plan from the one that failed.\n`) + "Two 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."));
3872
+ yield* te();
3873
+ let T = yield* n.replan(e);
3874
+ if (T.operations.length > 0) {
3875
+ let e = (e) => "column" in e ? typeof e.column == "string" ? `.${e.column}` : `.${String(e.column.name ?? "")}` : "", t = T.operations.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n"), n = a.filter((e) => e.status === "applied"), r = n.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n") + (n.length > 10 ? `\n … and ${n.length - 10} more` : "");
3876
+ return yield* k.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 ${T.operations.length}:\n${t}${T.operations.length > 10 ? `\n … and ${T.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.\n` + (m ? (y.length > 0 ? "The transactional batch completed before this convergence check; this check does not roll it back.\n" : "This convergence check does not roll back completed operations; this plan had no transactional batch.\n") + `An enclosing deployment transaction may still undo its own changes. Inspect the live schema and operation ledger before retrying.\nOperations reported applied before this check:\n${r}\n` : ` This dialect does NOT apply a plan atomically. The ${n.length} operation(s) below are COMMITTED\n and there is no rollback — the schema is PART-APPLIED, not unchanged:\n${r}\n Re-running plans from where the database now is, which is a different plan from the one that failed.\n`) + "Two 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."));
3848
3877
  }
3849
- let D = a.filter((e) => e.status === "applied").length, O = Date.now() - i, te = y, ne = (/* @__PURE__ */ new Date()).toISOString(), re = yield* U(e, ne), ie = [..._, ...S ?? b.map((e) => e.planned)], ae = x === "resume" ? yield* e`SELECT ${e("fingerprint")}, ${e("operations")}
3850
- FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${te}` : [];
3851
- if (ae.length > 0) {
3852
- let e = ae[0], t = typeof e.operations == "string" ? JSON.parse(e.operations) : e.operations;
3853
- if (e.fingerprint !== l.toFingerprint || !Array.isArray(t) || !ie.every((e) => t.some((t) => je(t, e)))) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: history for resumed run ${te} does not match its recorded operations; the resume ledger was retained.`));
3878
+ let E = a.filter((e) => e.status === "applied").length, ne = Date.now() - i, D = b, ie = (/* @__PURE__ */ new Date()).toISOString(), ae = yield* U(e, ie), oe = [...y, ...C ?? x.map((e) => e.planned)], se = S === "resume" ? yield* e`SELECT ${e("fingerprint")}, ${e("operations")}
3879
+ FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${D}` : [];
3880
+ if (se.length > 0) {
3881
+ let e = se[0], t = typeof e.operations == "string" ? JSON.parse(e.operations) : e.operations;
3882
+ if (e.fingerprint !== l.toFingerprint || !Array.isArray(t) || !oe.every((e) => t.some((t) => je(t, e)))) return yield* k.die(/* @__PURE__ */ Error(`applyPlan: history for resumed run ${D} does not match its recorded operations; the resume ledger was retained.`));
3854
3883
  }
3855
- ae.length === 0 && (yield* e`
3884
+ se.length === 0 && (yield* e`
3856
3885
  INSERT INTO ${e("_voltro_migration_plans")}
3857
3886
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
3858
3887
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
3859
3888
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
3860
3889
  VALUES
3861
- (${te}, ${l.toFingerprint}, ${E.fromFingerprint}, ${JSON.stringify(ie)},
3890
+ (${D}, ${l.toFingerprint}, ${T.fromFingerprint}, ${JSON.stringify(oe)},
3862
3891
  ${n.appliedBy}, ${n.environment}, ${n.source},
3863
- ${O}, ${re}, ${n.notes ?? null})
3864
- `), yield* os(e, y);
3865
- let oe = [...new Set(ie.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
3866
- return yield* k.promise(() => ee({ changedTables: oe }).catch(() => {})), {
3867
- id: te,
3868
- appliedAt: ne,
3892
+ ${ne}, ${ae}, ${n.notes ?? null})
3893
+ `.pipe(k.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\nMigration ${D}: schema work completed, but writing its history failed.\nThe operation ledger is retained for recovery. This error does not establish whole-plan rollback; inspect the live schema before retrying.` })))), yield* ss(e, b).pipe(k.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\nMigration ${D}: the history row was written, but operation-ledger cleanup failed.\nAn enclosing transaction may still roll back its own changes. Inspect the recorded history and any remaining operation ledger before retrying; do not assume the schema is unchanged.` })));
3894
+ let ce = [...new Set(oe.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
3895
+ return yield* k.promise(() => re({ changedTables: ce }).catch(() => {})), {
3896
+ id: D,
3897
+ appliedAt: ie,
3869
3898
  fingerprint: l.toFingerprint,
3870
- operations: ie,
3899
+ operations: oe,
3871
3900
  appliedBy: n.appliedBy,
3872
3901
  environment: n.environment,
3873
- durationMs: O,
3874
- appliedOps: D,
3902
+ durationMs: ne,
3903
+ appliedOps: E,
3875
3904
  source: n.source,
3876
3905
  ...n.notes ? { notes: n.notes } : {}
3877
3906
  };
3878
- }), gs = (e, t) => {
3907
+ }), _s = (e, t) => {
3879
3908
  switch (t.kind) {
3880
3909
  case "drop-foreign-key": return {
3881
3910
  ...e,
@@ -3908,36 +3937,36 @@ BEGIN
3908
3937
  };
3909
3938
  }
3910
3939
  }, Z = (e, t, n) => {
3911
- let r = n.tables.find((e) => e.name === t.table), i = () => r === void 0 ? k.void : Wo(e, t.table, Qa(gs(r, t)), t.kind);
3940
+ let r = n.tables.find((e) => e.name === t.table), i = () => r === void 0 ? k.void : Go(e, t.table, $a(_s(r, t)), t.kind);
3912
3941
  switch (t.kind) {
3913
3942
  case "drop-foreign-key": return e.onDialectOrElse({
3914
- mysql: () => J(e, Io(t), t.kind),
3943
+ mysql: () => J(e, Lo(t), t.kind),
3915
3944
  sqlite: i,
3916
- orElse: () => J(e, Fo(t), t.kind)
3945
+ orElse: () => J(e, Io(t), t.kind)
3917
3946
  });
3918
3947
  case "drop-index": return e.onDialectOrElse({
3919
- mysql: () => J(e, ho(t), t.kind),
3920
- mssql: () => J(e, go(t), t.kind),
3921
- orElse: () => J(e, mo(t), t.kind)
3948
+ mysql: () => J(e, go(t), t.kind),
3949
+ mssql: () => J(e, _o(t), t.kind),
3950
+ orElse: () => J(e, ho(t), t.kind)
3922
3951
  });
3923
3952
  case "drop-column": return e.onDialectOrElse({
3924
- mysql: () => H(e).pipe(k.flatMap((n) => J(e, ya(t, n), t.kind, [aa]))),
3953
+ mysql: () => H(e).pipe(k.flatMap((n) => J(e, ba(t, n), t.kind, [oa]))),
3925
3954
  sqlite: i,
3926
- orElse: () => J(e, va(t, W), t.kind)
3955
+ orElse: () => J(e, ya(t, W), t.kind)
3927
3956
  });
3928
3957
  case "rename-column": return e.onDialectOrElse({
3929
- mysql: () => J(e, ba(t, G), t.kind),
3930
- mssql: () => Go(e, t),
3931
- orElse: () => J(e, ba(t, W), t.kind)
3958
+ mysql: () => J(e, xa(t, G), t.kind),
3959
+ mssql: () => Ko(e, t),
3960
+ orElse: () => J(e, xa(t, W), t.kind)
3932
3961
  });
3933
3962
  }
3934
- }, _s = (e, t, n) => us(e, t, { declared: n }), vs = "utf8mb4", ys = (e, t) => l(e) && !t.has(e) && !e.startsWith("_cloud_") && !e.startsWith("__turso_internal_") && !a(e) && !S(e), bs = (e) => e.columnDefault !== null && e.columnDefault.toUpperCase() !== "NULL", xs = (e, t, n, r) => {
3935
- if (n !== vs) return {
3963
+ }, vs = (e, t, n) => ds(e, t, { declared: n }), ys = (e) => e.literal("(source = 'file' AND id NOT LIKE 'plan!_%' ESCAPE '!')"), bs = (e) => e.literal("(source IS NULL OR source <> 'file' OR id LIKE 'plan!_%' ESCAPE '!')"), xs = "utf8mb4", Ss = (e, t) => o(e) && !t.has(e) && !e.startsWith("_cloud_") && !e.startsWith("__turso_internal_") && !r(e) && !ee(e), Cs = (e) => e.columnDefault !== null && e.columnDefault.toUpperCase() !== "NULL", ws = (e, t, n, r) => {
3964
+ if (n !== xs) return {
3936
3965
  tables: [],
3937
3966
  left: []
3938
3967
  };
3939
- let i = e.filter((e) => ys(e.table, t) && (r === void 0 || r.has(e.table)) && e.charset !== vs), a = i.filter((e) => bs(e) || e.generated), o = /* @__PURE__ */ new Map();
3940
- for (let e of i) bs(e) || e.generated || o.set(e.table, [...o.get(e.table) ?? [], e]);
3968
+ let i = e.filter((e) => Ss(e.table, t) && (r === void 0 || r.has(e.table)) && e.charset !== xs), a = i.filter((e) => Cs(e) || e.generated), o = /* @__PURE__ */ new Map();
3969
+ for (let e of i) Cs(e) || e.generated || o.set(e.table, [...o.get(e.table) ?? [], e]);
3941
3970
  return {
3942
3971
  tables: [...o.entries()].sort(([e], [t]) => e.localeCompare(t)).map(([e, t]) => ({
3943
3972
  table: e,
@@ -3945,7 +3974,7 @@ BEGIN
3945
3974
  })),
3946
3975
  left: a
3947
3976
  };
3948
- }, Ss = (e) => e.tables.length === 0 && e.left.length === 0, Cs = (e) => [...e.tables.map((e) => `${e.table}: ${e.columns.length} string column${e.columns.length === 1 ? "" : "s"} ${[...new Set(e.columns.map((e) => e.charset))].sort().join("/")} → ${vs}`), ...e.left.map((e) => `${e.table}.${e.column} stays ${e.charset}: it has a ${e.generated ? "generation expression" : "default"}, which this step does not rewrite — convert it by hand`)], ws = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), Ts = (e) => k.map(e.unsafe("SELECT c.table_name, c.column_name, c.character_set_name, c.column_type, c.is_nullable, c.column_default, c.extra\n FROM information_schema.columns c\n JOIN information_schema.tables t ON t.table_schema = c.table_schema AND t.table_name = c.table_name\n WHERE c.table_schema = DATABASE() AND t.table_type = 'BASE TABLE' AND c.character_set_name IS NOT NULL\n ORDER BY c.table_name, c.ordinal_position"), (e) => ws(e).map((e) => ({
3977
+ }, Ts = (e) => e.tables.length === 0 && e.left.length === 0, Es = (e) => [...e.tables.map((e) => `${e.table}: ${e.columns.length} string column${e.columns.length === 1 ? "" : "s"} ${[...new Set(e.columns.map((e) => e.charset))].sort().join("/")} → ${xs}`), ...e.left.map((e) => `${e.table}.${e.column} stays ${e.charset}: it has a ${e.generated ? "generation expression" : "default"}, which this step does not rewrite — convert it by hand`)], Ds = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), Os = (e) => k.map(e.unsafe("SELECT c.table_name, c.column_name, c.character_set_name, c.column_type, c.is_nullable, c.column_default, c.extra\n FROM information_schema.columns c\n JOIN information_schema.tables t ON t.table_schema = c.table_schema AND t.table_name = c.table_name\n WHERE c.table_schema = DATABASE() AND t.table_type = 'BASE TABLE' AND c.character_set_name IS NOT NULL\n ORDER BY c.table_name, c.ordinal_position"), (e) => Ds(e).map((e) => ({
3949
3978
  table: String(e.table_name),
3950
3979
  column: String(e.column_name),
3951
3980
  charset: String(e.character_set_name),
@@ -3953,26 +3982,27 @@ BEGIN
3953
3982
  nullable: String(e.is_nullable).toUpperCase() === "YES",
3954
3983
  columnDefault: e.column_default === null || e.column_default === void 0 ? null : String(e.column_default),
3955
3984
  generated: /GENERATED/i.test(String(e.extra ?? "")) && !/DEFAULT_GENERATED/i.test(String(e.extra ?? ""))
3956
- }))), Es = (e) => `\`${e.replace(/`/g, "``")}\``, Ds = (e, t = /* @__PURE__ */ new Map()) => e.tables.map((e) => `ALTER TABLE ${Es(e.table)} ${e.columns.map((n) => {
3985
+ }))), ks = (e) => `\`${e.replace(/`/g, "``")}\``, As = (e, t = /* @__PURE__ */ new Map()) => e.tables.map((e) => `ALTER TABLE ${ks(e.table)} ${e.columns.map((n) => {
3957
3986
  let r = t.get(e.table)?.get(n.column);
3958
- return `MODIFY COLUMN ${Es(n.column)} ${n.columnType} CHARACTER SET ${vs}${n.nullable ? "" : " NOT NULL"}${r === void 0 ? "" : ` CHECK (${r})`}`;
3959
- }).join(", ")}`), Os = (e, t) => k.gen(function* () {
3987
+ return `MODIFY COLUMN ${ks(n.column)} ${n.columnType} CHARACTER SET ${xs}${n.nullable ? "" : " NOT NULL"}${r === void 0 ? "" : ` CHECK (${r})`}`;
3988
+ }).join(", ")}`), js = (e, t) => k.gen(function* () {
3960
3989
  let n = /* @__PURE__ */ new Map();
3961
- for (let r of t.tables) n.set(r.table, yield* Oa(e, r.table));
3962
- for (let r of Ds(t, n)) yield* e.unsafe(r).unprepared;
3963
- }), ks = (e, t) => bt(e, k.gen(function* () {
3964
- let n = xs(yield* Ts(e), t.declaredNames, t.charset);
3965
- return yield* Os(e, n), n;
3966
- }), { schema: t.lockSchema }), As = (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"), js = (e) => e`
3990
+ for (let r of t.tables) n.set(r.table, yield* ka(e, r.table));
3991
+ for (let r of As(t, n)) yield* e.unsafe(r).unprepared;
3992
+ }), Ms = (e, t) => bt(e, k.gen(function* () {
3993
+ let n = ws(yield* Os(e), t.declaredNames, t.charset);
3994
+ return yield* js(e, n), n;
3995
+ }), { schema: t.lockSchema }), Ns = (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"), Ps = (e) => e`
3967
3996
  SELECT fingerprint
3968
3997
  FROM _voltro_migration_plans
3998
+ WHERE ${bs(e)}
3969
3999
  ORDER BY ${e("appliedAt")} DESC
3970
4000
  ${V(e, 1)}
3971
4001
  `.pipe(k.map((e) => e.length > 0 ? e[0].fingerprint : void 0), k.catchAll((t) => e`SELECT COUNT(*) AS n FROM _voltro_migration_plans`.pipe(k.matchEffect({
3972
4002
  onFailure: () => k.succeed(void 0),
3973
4003
  onSuccess: () => k.die(/* @__PURE__ */ Error(`reading the newest applied plan from _voltro_migration_plans failed while the table exists — this is a query defect, not a missing ledger: ${String(t)}`))
3974
- })))), Ms = (e, t, n) => k.gen(function* () {
3975
- if ((yield* js(e)) === t.toFingerprint) return "already-current";
4004
+ })))), Fs = (e, t, n) => k.gen(function* () {
4005
+ if ((yield* Ps(e)) === t.toFingerprint) return "already-current";
3976
4006
  let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
3977
4007
  return yield* e`
3978
4008
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -3984,8 +4014,8 @@ BEGIN
3984
4014
  ${n.appliedBy}, ${n.environment}, ${n.source},
3985
4015
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
3986
4016
  `, "recorded";
3987
- }).pipe(k.catchAll(() => k.succeed("already-current"))), Ns = (e, t, n) => k.gen(function* () {
3988
- let r = I(Nr(t, M(e), { charset: n.charset })), i = yield* js(e);
4017
+ }).pipe(k.catchAll(() => k.succeed("already-current"))), Is = (e, t, n) => k.gen(function* () {
4018
+ let r = I(Nr(t, M(e), { charset: n.charset })), i = yield* Ps(e);
3989
4019
  return i === r ? {
3990
4020
  kind: "up-to-date",
3991
4021
  fingerprint: r
@@ -3994,23 +4024,23 @@ BEGIN
3994
4024
  expected: r,
3995
4025
  ...i === void 0 ? {} : { actual: i }
3996
4026
  };
3997
- }), Ps = [
4027
+ }), Ls = [
3998
4028
  "pgeagertest_",
3999
4029
  "mig_e2e_",
4000
4030
  "mig_test_",
4001
4031
  "mysqleagertest_",
4002
4032
  "mssqleagertest_",
4003
4033
  "sqliteeagertest_"
4004
- ], Fs = (e) => Ps.some((t) => e.startsWith(t)), Is = (e, t) => k.gen(function* () {
4034
+ ], Rs = (e) => Ls.some((t) => e.startsWith(t)), zs = (e, t) => k.gen(function* () {
4005
4035
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
4006
- let n = t.filter((e) => Fs(e.name)).map((e) => e.name);
4036
+ let n = t.filter((e) => Rs(e.name)).map((e) => e.name);
4007
4037
  if (n.length === 0) return [];
4008
4038
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(k.catchAll(() => k.void));
4009
4039
  return n;
4010
- }), Ls = () => {
4040
+ }), Bs = () => {
4011
4041
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
4012
4042
  return e.length > 0 ? { ignoreTables: e } : {};
4013
- }, Rs = (e) => {
4043
+ }, Vs = (e) => {
4014
4044
  if (e === void 0) return;
4015
4045
  let t = e.trim();
4016
4046
  if (t === "") return;
@@ -4020,67 +4050,67 @@ BEGIN
4020
4050
  kind: "tables",
4021
4051
  tables: new Set(n)
4022
4052
  } : void 0;
4023
- }, zs = (e) => typeof e.table == "string" ? e.table : void 0, Bs = (e, t = { kind: "all" }) => ({
4053
+ }, Hs = (e) => typeof e.table == "string" ? e.table : void 0, Us = (e, t = { kind: "all" }) => ({
4024
4054
  ...e,
4025
4055
  operations: e.operations.map((e) => {
4026
4056
  if (!e.blocked || e.classification !== "lossy") return e;
4027
4057
  if (t?.kind === "tables") {
4028
- let n = zs(e.op);
4058
+ let n = Hs(e.op);
4029
4059
  if (n === void 0 || !t.tables.has(n)) return e;
4030
4060
  }
4031
4061
  let { blocked: n, ...r } = e;
4032
4062
  return r;
4033
4063
  })
4034
- }), Vs = (e, t, n) => t === "postgres" ? Fr(e, n).pipe(k.flatMap((e) => {
4064
+ }), Ws = (e, t, n) => t === "postgres" ? Fr(e, n).pipe(k.flatMap((e) => {
4035
4065
  let t = Ir(e);
4036
4066
  return t === void 0 ? k.void : k.logWarning(`auto-migrate: ${t}`).pipe(k.annotateLogs({ scope: "voltro:migrate" }));
4037
- }), k.catchAll(() => k.void)) : k.void, Hs = (e, t, n) => k.gen(function* () {
4067
+ }), k.catchAll(() => k.void)) : k.void, Gs = (e, t, n) => k.gen(function* () {
4038
4068
  let r = M(e), i = t;
4039
4069
  if (n.charset === "utf8mb4") {
4040
4070
  let r = new Set(t.map((e) => e.tableName));
4041
- if (!Ss(xs(yield* Ts(e), r, n.charset))) {
4042
- let t = yield* ks(e, {
4071
+ if (!Ts(ws(yield* Os(e), r, n.charset))) {
4072
+ let t = yield* Ms(e, {
4043
4073
  declaredNames: r,
4044
4074
  charset: n.charset
4045
4075
  });
4046
- for (let e of Cs(t)) yield* k.logInfo(`auto-migrate: store charset — ${e}`).pipe(k.annotateLogs({ scope: "voltro:migrate" }));
4076
+ for (let e of Es(t)) yield* k.logInfo(`auto-migrate: store charset — ${e}`).pipe(k.annotateLogs({ scope: "voltro:migrate" }));
4047
4077
  }
4048
4078
  }
4049
- let a = yield* ns(e);
4079
+ let a = yield* rs(e);
4050
4080
  if (!a && process.env.VOLTRO_MIGRATE_FORCE !== "1") {
4051
4081
  let t = I(Nr(i, r, { charset: n.charset }));
4052
- if ((yield* js(e)) === t) return yield* Vs(e, r, i), {
4082
+ if ((yield* Ps(e)) === t) return yield* Ws(e, r, i), {
4053
4083
  kind: "up-to-date",
4054
4084
  fingerprint: t
4055
4085
  };
4056
4086
  }
4057
- let o = yield* B(e), s = yield* Is(e, o.tables);
4087
+ let o = yield* B(e), s = yield* zs(e, o.tables);
4058
4088
  s.length > 0 && (yield* k.logInfo(`auto-migrate: reaped ${s.length} test-fixture leftover(s)`).pipe(k.annotateLogs({
4059
4089
  scope: "voltro:migrate",
4060
4090
  count: s.length
4061
4091
  })), o = yield* B(e));
4062
4092
  {
4063
- let e = n.softDropRetentionDays ?? 7, t = ve(o, { retentionDays: e });
4064
- t.length > 0 && (yield* k.logWarning(`auto-migrate: ${E(t, e)}`).pipe(k.annotateLogs({
4093
+ let e = n.softDropRetentionDays ?? 7, t = be(o, { retentionDays: e });
4094
+ t.length > 0 && (yield* k.logWarning(`auto-migrate: ${te(t, e)}`).pipe(k.annotateLogs({
4065
4095
  scope: "voltro:migrate",
4066
4096
  snapshots: t.map((e) => e.name)
4067
4097
  })));
4068
4098
  }
4069
- let c = new Set(t.map((e) => e.tableName)), l = (e) => de(e, c), u = gi({
4099
+ let c = new Set(t.map((e) => e.tableName)), l = (e) => ue(e, c), u = gi({
4070
4100
  declared: i,
4071
4101
  live: { tables: l(o.tables) },
4072
4102
  dialect: r,
4073
4103
  charset: n.charset,
4074
- ...Ls()
4104
+ ...Bs()
4075
4105
  });
4076
4106
  if (u.summary.blocked > 0) {
4077
- let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Rs(process.env.VOLTRO_DESTRUCTIVE_OK);
4078
- if (t === void 0 || !e || (u = Bs(u, t), u.operations.some((e) => e.blocked))) return {
4107
+ let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Vs(process.env.VOLTRO_DESTRUCTIVE_OK);
4108
+ if (t === void 0 || !e || (u = Us(u, t), u.operations.some((e) => e.blocked))) return {
4079
4109
  kind: "refused-blocked",
4080
4110
  plan: u
4081
4111
  };
4082
4112
  }
4083
- return u.operations.length === 0 && !a ? (yield* Ms(e, u, {
4113
+ return u.operations.length === 0 && !a ? (yield* Fs(e, u, {
4084
4114
  appliedBy: n.appliedBy,
4085
4115
  environment: n.environment === "prod" ? "dev" : n.environment,
4086
4116
  source: "auto-diff"
@@ -4089,7 +4119,7 @@ BEGIN
4089
4119
  fingerprint: u.toFingerprint
4090
4120
  }) : {
4091
4121
  kind: "applied",
4092
- applied: yield* ms(e, u, {
4122
+ applied: yield* hs(e, u, {
4093
4123
  ...n.beforeExecute === void 0 ? {} : { beforeExecute: n.beforeExecute },
4094
4124
  declared: t,
4095
4125
  charset: n.charset,
@@ -4103,16 +4133,16 @@ BEGIN
4103
4133
  live: { tables: l(t.tables) },
4104
4134
  dialect: r,
4105
4135
  charset: n.charset,
4106
- ...Ls()
4136
+ ...Bs()
4107
4137
  });
4108
4138
  })
4109
4139
  }),
4110
4140
  plan: u
4111
4141
  };
4112
- }), Us = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? k.succeed({
4142
+ }), Ks = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? k.succeed({
4113
4143
  kind: "skipped",
4114
4144
  reason: "VOLTRO_AUTO_MIGRATE=0"
4115
- }) : n.environment === "prod" ? Ns(e, t, n) : Hs(e, t, n).pipe(k.tap((n) => n.kind === "applied" || n.kind === "up-to-date" ? Mn(t, M(e)) : k.void)), Ws = (e, t) => {
4145
+ }) : n.environment === "prod" ? Is(e, t, n) : Gs(e, t, n).pipe(k.tap((n) => n.kind === "applied" || n.kind === "up-to-date" ? Mn(t, M(e)) : k.void)), qs = (e, t) => {
4116
4146
  switch (e.kind) {
4117
4147
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
4118
4148
  case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${vr(e.fingerprint)})`;
@@ -4122,7 +4152,7 @@ BEGIN
4122
4152
  }
4123
4153
  case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${vr(e.expected)}` + (e.actual ? ` live=${vr(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
4124
4154
  case "refused-blocked": {
4125
- 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` + As(e.plan), c = [""];
4155
+ 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` + Ns(e.plan), c = [""];
4126
4156
  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) {
4127
4157
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
4128
4158
  for (let r of e.plan.operations) {
@@ -4139,7 +4169,7 @@ BEGIN
4139
4169
  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");
4140
4170
  }
4141
4171
  }
4142
- }, Gs = (e) => typeof e.__definition == "function" ? n({ c: e }).c : e, Ks = (e) => {
4172
+ }, Js = (e) => typeof e.__definition == "function" ? _({ c: e }).c : e, Ys = (e) => {
4143
4173
  if (typeof e != "string") return e;
4144
4174
  let t = e.trim().replace(/::[a-zA-Z0-9_ "]+$/, "").trim();
4145
4175
  if (/^current_timestamp(\(\d*\))?$/i.test(t) || /^now\(\)$/i.test(t)) return "now";
@@ -4151,10 +4181,11 @@ BEGIN
4151
4181
  let e = r.references, i = e === void 0 ? void 0 : t.get(e.table);
4152
4182
  n[r.name] = {
4153
4183
  type: r.type,
4184
+ ...r.type === "id" && Zn(r) === "numeric" ? { idScheme: { kind: "numeric" } } : {},
4154
4185
  nullable: r.nullable,
4155
4186
  unique: r.unique,
4156
4187
  hasDefault: r.hasDefault,
4157
- ...r.hasDefault ? { defaultValue: Ks(r.defaultValue) } : {},
4188
+ ...r.hasDefault ? { defaultValue: Ys(r.defaultValue) } : {},
4158
4189
  ...r.maxLength === void 0 ? {} : { maxLength: r.maxLength },
4159
4190
  ...r.precision === void 0 ? {} : { precision: r.precision },
4160
4191
  ...r.scale === void 0 ? {} : { scale: r.scale },
@@ -4164,6 +4195,8 @@ BEGIN
4164
4195
  ...r.oneOf === void 0 ? {} : { oneOf: r.oneOf },
4165
4196
  ...r.referenceStorage === void 0 ? {} : { referenceStorage: r.referenceStorage },
4166
4197
  ...r.vectorDim === void 0 ? {} : { vectorDim: r.vectorDim },
4198
+ ...r.vectorPrecision === void 0 ? {} : { vectorPrecision: r.vectorPrecision },
4199
+ ...r.generatedAs === void 0 ? {} : { generatedAs: r.generatedAs },
4167
4200
  ...r.spatial === void 0 ? {} : { spatial: r.spatial },
4168
4201
  ...e === void 0 ? {} : {
4169
4202
  references: () => i === void 0 ? {
@@ -4196,14 +4229,14 @@ BEGIN
4196
4229
  })),
4197
4230
  ...e.primaryKey === void 0 ? {} : { appliedPrimaryKey: e.primaryKey }
4198
4231
  };
4199
- }, qs = (e) => {
4232
+ }, Xs = (e) => {
4200
4233
  let t = new Map(e.tables.map((e) => [e.name, e]));
4201
4234
  return e.tables.map((e) => Q(e, t));
4202
- }, Js = (e, t = "safe") => ({
4235
+ }, Zs = (e, t = "safe") => ({
4203
4236
  op: e,
4204
4237
  classification: t,
4205
4238
  reason: "file migration schema operation"
4206
- }), $ = "this context was built over an in-memory store without a `sql` client, and this needs a live connection. Run the migration against a database (the runner supplies the client), or keep a database-free test to `each`, `rewrite`, `expect`, `skipUnless`, `store`, `log`, `schema.tableExists`, `schema.columnExists` and a Promise body under `transactional`.", Ys = {
4239
+ }), $ = "this context was built over an in-memory store without a `sql` client, and this needs a live connection. Run the migration against a database (the runner supplies the client), or keep a database-free test to `each`, `rewrite`, `expect`, `skipUnless`, `store`, `log`, `schema.tableExists`, `schema.columnExists` and a Promise body under `transactional`.", Qs = {
4207
4240
  snapshot: "the in-memory store holds rows, not a catalog — it has no column types, defaults, indexes or constraints to report. `schema.tableExists` and `schema.columnExists` answer from the rows it holds; a body that needs the whole shape needs a database.",
4208
4241
  indexExists: "the in-memory store has no indexes — every read of it is a scan — so there is no honest answer to give, and `false` would claim an index is absent from a store that could never have had one. Run this migration against a database, or guard on `schema.tableExists` / `schema.columnExists`, which the store can answer.",
4209
4242
  foreignKeyExists: "the in-memory store has no constraints, so there is no honest answer to give, and `false` would claim a foreign key is absent from a store that could never have had one. Run this migration against a database, or guard on `schema.tableExists` / `schema.columnExists`, which the store can answer.",
@@ -4220,31 +4253,31 @@ BEGIN
4220
4253
  dropColumn: $,
4221
4254
  renameColumn: $,
4222
4255
  truncate: $
4223
- }, Xs = "this context was built over a store that cannot report the tables it holds (`DataStore.storedTables` is not implemented), so the question has no honest answer here. Use the in-memory store `@voltro/runtime` ships, or run the migration against a database.", Zs = (e, t) => {
4256
+ }, $s = "this context was built over a store that cannot report the tables it holds (`DataStore.storedTables` is not implemented), so the question has no honest answer here. Use the in-memory store `@voltro/runtime` ships, or run the migration against a database.", ec = (e, t) => {
4224
4257
  let n = () => {
4225
4258
  let e = t.storedTables;
4226
4259
  if (e !== void 0) return new Map(e.call(t).map((e) => [e.table, e]));
4227
- }, r = (t, n) => k.fail(new f(e, t, n));
4260
+ }, r = (t, n) => k.fail(new s(e, t, n));
4228
4261
  return {
4229
4262
  tableExists: (e) => k.suspend(() => {
4230
4263
  let t = n();
4231
- return t === void 0 ? r("schema.tableExists()", Xs) : k.succeed(t.has(e));
4264
+ return t === void 0 ? r("schema.tableExists()", $s) : k.succeed(t.has(e));
4232
4265
  }),
4233
4266
  columnExists: (e, t) => k.suspend(() => {
4234
4267
  let i = n();
4235
- if (i === void 0) return r("schema.columnExists()", Xs);
4268
+ if (i === void 0) return r("schema.columnExists()", $s);
4236
4269
  let a = i.get(e);
4237
4270
  return a === void 0 ? k.succeed(!1) : a.rowCount === 0 ? r(`schema.columnExists(${JSON.stringify(e)}, ${JSON.stringify(t)})`, `${e} is in this store and holds no rows, and a column exists in a store without a catalog only as a key on a row — so "no such column" and "no row has said yet" are the same observation, and answering either would be a guess. Seed ${e} with a row carrying the columns this migration guards on, or run the migration against a database.`) : k.succeed(a.columns.includes(t));
4238
4271
  })
4239
4272
  };
4240
- }, Qs = (e, t) => {
4241
- let n = { ...Zs(e, t) };
4242
- for (let [t, r] of Object.entries(Ys)) n[t] = () => k.fail(new f(e, `schema.${t}()`, r));
4273
+ }, tc = (e, t) => {
4274
+ let n = { ...ec(e, t) };
4275
+ for (let [t, r] of Object.entries(Qs)) n[t] = () => k.fail(new s(e, `schema.${t}()`, r));
4243
4276
  return n;
4244
- }, $s = (e) => typeof e == "function" && typeof e.onDialectOrElse == "function", ec = (e) => k.isEffect(e) ? e : k.tryPromise({
4277
+ }, nc = (e) => typeof e == "function" && typeof e.onDialectOrElse == "function", rc = (e) => k.isEffect(e) ? e : k.tryPromise({
4245
4278
  try: () => e,
4246
4279
  catch: (e) => e
4247
- }), tc = (e, t, n) => t.run === void 0 ? Promise.reject(new f(e, "transactional() with an Effect body", "an Effect returned from `transactional` runs ON the transaction's connection, and this store has none. Return a Promise body that uses the transaction's `store`, or run the migration against a database.")) : t.run(n), nc = (e, t) => {
4280
+ }), ic = (e, t, n) => t.run === void 0 ? Promise.reject(new s(e, "transactional() with an Effect body", "an Effect returned from `transactional` runs ON the transaction's connection, and this store has none. Return a Promise body that uses the transaction's `store`, or run the migration against a database.")) : t.run(n), ac = (e, t) => {
4248
4281
  let n = e.run;
4249
4282
  if (n === void 0) return t;
4250
4283
  let r = {};
@@ -4256,19 +4289,19 @@ BEGIN
4256
4289
  });
4257
4290
  }
4258
4291
  return r;
4259
- }, rc = (e, t, n) => {
4292
+ }, oc = (e, t, n) => {
4260
4293
  let r = () => B(e), i = (e, t) => e.tables.find((e) => e.name === t), a = (e, t, n) => i(e, t)?.columns.find((e) => e.name === n), o = (e) => k.succeed(e), s = (e) => new Map(e.tables.map((e) => [e.name, e])), c = (e, t) => {
4261
4294
  let n = i(e, t);
4262
4295
  if (n === void 0) throw Error(`schema: table ${t} does not exist`);
4263
4296
  return n;
4264
4297
  }, l = (n) => k.gen(function* () {
4265
- let i = () => r().pipe(k.map((e) => ({ tables: e.tables.filter((e) => e.name === n.tableName) }))), a = Bs(gi({
4298
+ let i = () => r().pipe(k.map((e) => ({ tables: e.tables.filter((e) => e.name === n.tableName) }))), a = Us(gi({
4266
4299
  declared: [n],
4267
4300
  live: yield* i(),
4268
4301
  dialect: t
4269
4302
  })), o = a.operations.filter((e) => e.blocked !== void 0);
4270
4303
  if (o.length > 0) return yield* k.fail(/* @__PURE__ */ Error(`evolve(${n.tableName}): ${o.length} operation(s) cannot be planned:\n` + o.map((e) => ` - ${e.op.kind}: ${e.blocked?.fix ?? e.reason}`).join("\n")));
4271
- for (let t of a.operations) yield* _s(e, t, [n]);
4304
+ for (let t of a.operations) yield* vs(e, t, [n]);
4272
4305
  let s = gi({
4273
4306
  declared: [n],
4274
4307
  live: yield* i(),
@@ -4283,14 +4316,14 @@ BEGIN
4283
4316
  return (yield* r()).tables.some((t) => t.name === e.tableName) ? yield* o("already-present") : (yield* l(e), "applied");
4284
4317
  }),
4285
4318
  dropTable: (t) => k.gen(function* () {
4286
- return (yield* r()).tables.some((e) => e.name === t) ? (yield* _s(e, Js({
4319
+ return (yield* r()).tables.some((e) => e.name === t) ? (yield* vs(e, Zs({
4287
4320
  kind: "drop-table",
4288
4321
  table: t
4289
4322
  }, "lossy"), []), "applied") : yield* o("already-absent");
4290
4323
  }),
4291
4324
  renameTable: (t, n) => k.gen(function* () {
4292
4325
  let a = yield* r(), s = i(a, t) !== void 0, l = i(a, n) !== void 0;
4293
- return !s && l ? yield* o("already-present") : s ? l ? yield* k.fail(/* @__PURE__ */ Error(`renameTable: ${n} already exists beside ${t}`)) : (yield* _s(e, Js({
4326
+ return !s && l ? yield* o("already-present") : s ? l ? yield* k.fail(/* @__PURE__ */ Error(`renameTable: ${n} already exists beside ${t}`)) : (yield* vs(e, Zs({
4294
4327
  kind: "rename-table",
4295
4328
  from: t,
4296
4329
  to: n
@@ -4299,7 +4332,7 @@ BEGIN
4299
4332
  addColumn: (t, n, i) => k.gen(function* () {
4300
4333
  let a = yield* r(), u = c(a, t);
4301
4334
  if (u.columns.some((e) => e.name === n)) return yield* o("already-present");
4302
- let d = Gs(i);
4335
+ let d = Js(i);
4303
4336
  if (!d.nullable && !d.hasDefault && d.backfill === void 0) {
4304
4337
  let r = yield* e`SELECT COUNT(*) AS n FROM ${e(t)}`;
4305
4338
  if (Number(r[0]?.n ?? 0) > 0) return yield* k.fail(/* @__PURE__ */ Error(`addColumn(${t}.${n}): a NOT NULL column without a default cannot be added to a table with rows on any dialect. Add it nullable or with a default, fill it (rewrite), then alterColumn(${JSON.stringify(t)}, ${JSON.stringify(n)}, { nullable: false }).`));
@@ -4435,13 +4468,13 @@ BEGIN
4435
4468
  }, s), "applied") : yield* k.fail(/* @__PURE__ */ Error(`renameColumn: ${t}.${n} does not exist`));
4436
4469
  })
4437
4470
  };
4438
- }, ic = (e, t, n, r) => {
4471
+ }, sc = (e, t, n, r) => {
4439
4472
  let i;
4440
4473
  return (async function* () {
4441
4474
  for (;;) {
4442
- let a = [i === void 0 ? void 0 : oe("id", i), r].filter((e) => e !== void 0), o = await e.query({
4475
+ let a = [i === void 0 ? void 0 : se("id", i), r].filter((e) => e !== void 0), o = await e.query({
4443
4476
  table: t,
4444
- predicate: a.length === 0 ? void 0 : a.length === 1 ? a[0] : ne(...a),
4477
+ predicate: a.length === 0 ? void 0 : a.length === 1 ? a[0] : ie(...a),
4445
4478
  order: [{
4446
4479
  column: "id",
4447
4480
  direction: "asc"
@@ -4457,8 +4490,8 @@ BEGIN
4457
4490
  if (i = s, yield o, o.length < n) return;
4458
4491
  }
4459
4492
  })();
4460
- }, ac = (e) => e > 0 ? k.sleep(`${e} millis`) : k.void, oc = (e) => (t, n, r = {}) => k.gen(function* () {
4461
- let i = r.batchSize ?? 1e3, a = 0, o = 0, s = ic(e, t, i);
4493
+ }, cc = (e) => e > 0 ? k.sleep(`${e} millis`) : k.void, lc = (e) => (t, n, r = {}) => k.gen(function* () {
4494
+ let i = r.batchSize ?? 1e3, a = 0, o = 0, s = sc(e, t, i);
4462
4495
  for (;;) {
4463
4496
  let e = yield* k.tryPromise({
4464
4497
  try: () => s.next(),
@@ -4466,16 +4499,16 @@ BEGIN
4466
4499
  });
4467
4500
  if (e.done) break;
4468
4501
  o++;
4469
- for (let t of e.value) yield* ec(n(t)), a++;
4470
- yield* ac(r.sleepMs ?? 0);
4502
+ for (let t of e.value) yield* rc(n(t)), a++;
4503
+ yield* cc(r.sleepMs ?? 0);
4471
4504
  }
4472
4505
  return {
4473
4506
  scanned: a,
4474
4507
  pages: o
4475
4508
  };
4476
- }), sc = (e, t) => t == null ? _e(e) : fe(e, t), cc = (e) => typeof e != "object" || !e || e instanceof Date, lc = (e, t) => k.gen(function* () {
4509
+ }), uc = (e, t) => t == null ? ye(e) : me(e, t), dc = (e) => typeof e != "object" || !e || e instanceof Date, fc = (e, t) => k.gen(function* () {
4477
4510
  if (e === void 0) return [];
4478
- let n = (yield* B(e)).tables.find((e) => e.name === t)?.columns ?? [], r = new Set(n.map((e) => e.name)), i = ye(t)?.fields;
4511
+ let n = (yield* B(e)).tables.find((e) => e.name === t)?.columns ?? [], r = new Set(n.map((e) => e.name)), i = xe(t)?.fields;
4479
4512
  return n.filter((e) => e.type === "timestamp" || e.type === "date" || i?.[e.name]?.type === "timestamp" || i?.[e.name]?.type === "date").map((e, t) => {
4480
4513
  let n = `__voltro_rewrite_guard_${t}`;
4481
4514
  for (; r.has(n);) n += "_";
@@ -4484,30 +4517,30 @@ BEGIN
4484
4517
  alias: n
4485
4518
  };
4486
4519
  });
4487
- }), uc = (e, t, n, r) => (a, o, s = {}) => k.gen(function* () {
4488
- let l = s.batchSize ?? 1e3, u = s.maxPasses ?? 10, d = s.guard ?? [], f = yield* lc(n, a), p = /* @__PURE__ */ new WeakMap(), m = f.length === 0 || n === void 0 ? t : { query: async (o) => {
4489
- let s = c(o, n), l = f.map(({ column: e, alias: t }) => n`${n.onDialectOrElse({
4520
+ }), pc = (e, t, n, r) => (i, o, s = {}) => k.gen(function* () {
4521
+ let c = s.batchSize ?? 1e3, l = s.maxPasses ?? 10, d = s.guard ?? [], f = yield* fc(n, i), p = /* @__PURE__ */ new WeakMap(), h = f.length === 0 || n === void 0 ? t : { query: async (o) => {
4522
+ let s = a(o, n), c = f.map(({ column: e, alias: t }) => n`${n.onDialectOrElse({
4490
4523
  mysql: () => n`CAST(${n(e)} AS CHAR)`,
4491
4524
  mssql: () => n`CONVERT(VARCHAR(40), ${n(e)}, 127)`,
4492
4525
  orElse: () => n`CAST(${n(e)} AS TEXT)`
4493
4526
  })} AS ${n(t)}`);
4494
- return (await tc(e, t, n`SELECT *, ${n.csv(l)} FROM (${s}) AS ${n("__voltro_rewrite_rows")} ORDER BY ${n("id")} ASC`)).map((e) => {
4527
+ return (await ic(e, t, n`SELECT *, ${n.csv(c)} FROM (${s}) AS ${n("__voltro_rewrite_rows")} ORDER BY ${n("id")} ASC`)).map((e) => {
4495
4528
  let t = { ...e }, n = /* @__PURE__ */ new Map();
4496
4529
  for (let { column: e, alias: r } of f) n.set(e, t[r]), delete t[r];
4497
- let o = i([t], a, r)[0];
4498
- return p.set(o, n), o;
4530
+ let a = u([t], i, r)[0];
4531
+ return p.set(a, n), a;
4499
4532
  });
4500
- } }, h = {
4533
+ } }, g = {
4501
4534
  passes: 0,
4502
4535
  scanned: 0,
4503
4536
  rewritten: 0,
4504
4537
  contended: 0
4505
- }, g = h;
4506
- for (let e = 1; e <= u; e++) {
4507
- let n = 0, r = 0, i = 0, c = ic(m, a, l);
4538
+ }, _ = g;
4539
+ for (let e = 1; e <= l; e++) {
4540
+ let n = 0, r = 0, a = 0, l = sc(h, i, c);
4508
4541
  for (;;) {
4509
4542
  let e = yield* k.tryPromise({
4510
- try: () => c.next(),
4543
+ try: () => l.next(),
4511
4544
  catch: (e) => e
4512
4545
  });
4513
4546
  if (e.done) break;
@@ -4520,36 +4553,36 @@ BEGIN
4520
4553
  if (e === void 0) continue;
4521
4554
  let c = Object.entries(e).filter(([e, t]) => !Object.is(s[e], t));
4522
4555
  if (c.length === 0) continue;
4523
- let l = [fe("id", s.id)], u = (e) => p.get(s)?.has(e) ? p.get(s).get(e) : s[e];
4524
- for (let [e] of c) cc(s[e]) && l.push(sc(e, u(e)));
4525
- for (let e of d) l.push(sc(e, u(e)));
4556
+ let l = [me("id", s.id)], u = (e) => p.get(s)?.has(e) ? p.get(s).get(e) : s[e];
4557
+ for (let [e] of c) dc(s[e]) && l.push(uc(e, u(e)));
4558
+ for (let e of d) l.push(uc(e, u(e)));
4526
4559
  (yield* k.tryPromise({
4527
- try: () => t.updateMany(a, Object.fromEntries(c), { where: ne(...l) }),
4560
+ try: () => t.updateMany(i, Object.fromEntries(c), { where: ie(...l) }),
4528
4561
  catch: (e) => e
4529
- })) === 1 ? r++ : i++;
4562
+ })) === 1 ? r++ : a++;
4530
4563
  }
4531
- yield* ac(s.sleepMs ?? 0);
4564
+ yield* cc(s.sleepMs ?? 0);
4532
4565
  }
4533
- if (g = {
4566
+ if (_ = {
4534
4567
  passes: e,
4535
4568
  scanned: n,
4536
4569
  rewritten: r,
4537
- contended: i
4538
- }, h = {
4570
+ contended: a
4571
+ }, g = {
4539
4572
  passes: e,
4540
- scanned: h.scanned + n,
4541
- rewritten: h.rewritten + r,
4542
- contended: h.contended + i
4543
- }, r === 0 && i === 0) return h;
4573
+ scanned: g.scanned + n,
4574
+ rewritten: g.rewritten + r,
4575
+ contended: g.contended + a
4576
+ }, r === 0 && a === 0) return g;
4544
4577
  }
4545
- return yield* k.fail(new y(a, g));
4546
- }), dc = (e) => {
4578
+ return yield* k.fail(new m(i, _));
4579
+ }), mc = (e) => {
4547
4580
  let { migrationId: t } = e, n = `migrations:file:${t}`;
4548
- if (e.sql !== void 0 && !$s(e.sql)) throw new f(t, "makeFileMigrationContext()", `\`sql\` is not an @effect/sql client (got ${typeof e.sql}). Pass the client the store executes on, or omit \`sql\` to drive the body over an in-memory store.`);
4549
- if (e.sql === void 0 && e.store.run !== void 0) throw new f(t, "makeFileMigrationContext()", "a SQL-backed store was given without `sql`. Its migration context runs `raw()`, `schema` and the guarded rewrite on the client the store executes on; pass that client, or use an in-memory store for a database-free test.");
4581
+ if (e.sql !== void 0 && !nc(e.sql)) throw new s(t, "makeFileMigrationContext()", `\`sql\` is not an @effect/sql client (got ${typeof e.sql}). Pass the client the store executes on, or omit \`sql\` to drive the body over an in-memory store.`);
4582
+ if (e.sql === void 0 && e.store.run !== void 0) throw new s(t, "makeFileMigrationContext()", "a SQL-backed store was given without `sql`. Its migration context runs `raw()`, `schema` and the guarded rewrite on the client the store executes on; pass that client, or use an in-memory store for a database-free test.");
4550
4583
  let r = e.sql, i = [], a = (e) => {
4551
4584
  if (typeof e != "string" || e.trim().length < 12) throw Error(`raw(reason): say why this migration needs raw SQL — the reason is what a reviewer and \`voltro doctor\` read (got ${JSON.stringify(e)})`);
4552
- if (r === void 0) throw new f(t, `raw(${JSON.stringify(e)})`, $);
4585
+ if (r === void 0) throw new s(t, `raw(${JSON.stringify(e)})`, $);
4553
4586
  return r;
4554
4587
  };
4555
4588
  return {
@@ -4569,9 +4602,9 @@ BEGIN
4569
4602
  ...t ?? {}
4570
4603
  }))
4571
4604
  },
4572
- schema: r === void 0 ? Qs(t, o) : nc(o, rc(r, e.dialect, o)),
4573
- each: oc(o),
4574
- rewrite: uc(t, o, r, e.dialect),
4605
+ schema: r === void 0 ? tc(t, o) : ac(o, oc(r, e.dialect, o)),
4606
+ each: lc(o),
4607
+ rewrite: pc(t, o, r, e.dialect),
4575
4608
  expect: (e, t) => {
4576
4609
  i.push({
4577
4610
  description: e,
@@ -4579,7 +4612,7 @@ BEGIN
4579
4612
  });
4580
4613
  },
4581
4614
  skipUnless: (e, t) => k.gen(function* () {
4582
- if (!(typeof e == "boolean" ? e : yield* ec(e))) return yield* k.fail(new _(t));
4615
+ if (!(typeof e == "boolean" ? e : yield* rc(e))) return yield* k.fail(new d(t));
4583
4616
  })
4584
4617
  }))(e.store),
4585
4618
  transactional: (n) => k.tryPromise({
@@ -4588,19 +4621,19 @@ BEGIN
4588
4621
  store: e,
4589
4622
  raw: a
4590
4623
  });
4591
- return k.isEffect(r) ? tc(t, e, r) : r;
4624
+ return k.isEffect(r) ? ic(t, e, r) : r;
4592
4625
  }),
4593
4626
  catch: (e) => e
4594
4627
  })
4595
4628
  },
4596
4629
  expectations: i
4597
4630
  };
4598
- }, fc = (e) => k.gen(function* () {
4631
+ }, hc = (e) => k.gen(function* () {
4599
4632
  let t = [];
4600
- for (let { description: n, check: r } of e) (yield* ec(r())) || t.push(n);
4633
+ for (let { description: n, check: r } of e) (yield* rc(r())) || t.push(n);
4601
4634
  return t;
4602
- }), pc = (e) => e.kind === "table" ? e.table : `${e.table}.${e.name}`, mc = (e, t) => e.kind === t.kind && e.table === t.table && pc(e) === pc(t), hc = (e) => {
4603
- let t = [], n = (e) => (n) => (!n && !t.some((t) => mc(t, e)) && t.push(e), n), r = (e, t) => (...r) => e(...r).pipe(k.map(n(t(...r)))), i = {
4635
+ }), gc = (e) => e.kind === "table" ? e.table : `${e.table}.${e.name}`, _c = (e, t) => e.kind === t.kind && e.table === t.table && gc(e) === gc(t), vc = (e) => {
4636
+ let t = [], n = (e) => (n) => (!n && !t.some((t) => _c(t, e)) && t.push(e), n), r = (e, t) => (...r) => e(...r).pipe(k.map(n(t(...r)))), i = {
4604
4637
  tableExists: r(e.schema.tableExists, (e) => ({
4605
4638
  kind: "table",
4606
4639
  table: e
@@ -4631,9 +4664,9 @@ BEGIN
4631
4664
  },
4632
4665
  absent: () => t.slice()
4633
4666
  };
4634
- }, gc = (e) => {
4667
+ }, yc = (e) => {
4635
4668
  let t = [], n = (e) => {
4636
- t.some((t) => mc(t, e)) || t.push(e);
4669
+ t.some((t) => _c(t, e)) || t.push(e);
4637
4670
  };
4638
4671
  for (let t of e.operations) {
4639
4672
  let e = t.op;
@@ -4676,17 +4709,17 @@ BEGIN
4676
4709
  }
4677
4710
  }
4678
4711
  return t;
4679
- }, _c = (e, t) => {
4680
- let n = gc(t);
4712
+ }, bc = (e, t) => {
4713
+ let n = yc(t);
4681
4714
  return n.length === 0 ? [] : e.flatMap((e) => {
4682
- let t = e.absent.filter((e) => n.some((t) => mc(t, e)));
4715
+ let t = e.absent.filter((e) => n.some((t) => _c(t, e)));
4683
4716
  return t.length === 0 ? [] : [{
4684
4717
  id: e.id,
4685
4718
  reason: e.reason,
4686
4719
  created: t
4687
4720
  }];
4688
4721
  });
4689
- }, vc = Ae({ scope: "voltro:migrate" }), yc = (e) => Oe("sha256").update(e).digest("hex").slice(0, 16), bc = [{
4722
+ }, xc = Ae({ scope: "voltro:migrate" }), Sc = (e) => Oe("sha256").update(e).digest("hex").slice(0, 16), Cc = [{
4690
4723
  codemod: "0.78.0/01_file-migration-phase",
4691
4724
  inverse: (e) => {
4692
4725
  let t = /\n {2}phase: 'before-schema',\n {2}/g, n = /\n {2}phase: 'before-schema'(?=\r?\n[ \t]*\})/g, r = e.includes("\r\n") ? "\r\n" : "\n", i = (t) => {
@@ -4695,7 +4728,7 @@ BEGIN
4695
4728
  };
4696
4729
  return [e.replace(t, (e, t) => r + i(t)).replace(n, ""), e.replace(t, " ").replace(n, "")];
4697
4730
  }
4698
- }], xc = (e) => new Set([e, ...bc.flatMap((t) => t.inverse(e))].map(yc)), Sc = /* @__PURE__ */ new Set([
4731
+ }], wc = (e) => new Set([e, ...Cc.flatMap((t) => t.inverse(e))].map(Sc)), Tc = /* @__PURE__ */ new Set([
4699
4732
  "node_modules",
4700
4733
  "dist",
4701
4734
  "build",
@@ -4704,11 +4737,11 @@ BEGIN
4704
4737
  ".next",
4705
4738
  ".git",
4706
4739
  ".framework"
4707
- ]), Cc = async (e) => {
4740
+ ]), Ec = async (e) => {
4708
4741
  let t = [], n = async (e) => {
4709
4742
  let r = await Me.readdir(e, { withFileTypes: !0 }).catch(() => []);
4710
4743
  for (let i of r) {
4711
- if (Sc.has(i.name)) continue;
4744
+ if (Tc.has(i.name)) continue;
4712
4745
  let r = Ne(e, i.name);
4713
4746
  i.isDirectory() ? await n(r) : i.isFile() && le.test(i.name) && t.push(r);
4714
4747
  }
@@ -4717,42 +4750,42 @@ BEGIN
4717
4750
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
4718
4751
  return n.localeCompare(r);
4719
4752
  });
4720
- }, wc = async (e) => await import(Pe(e).href), Tc = async (e, t = wc) => {
4753
+ }, Dc = async (e) => await import(Pe(e).href), Oc = async (e, t = Dc) => {
4721
4754
  let n = [];
4722
4755
  for (let r of e) {
4723
4756
  let e = (await t(r)).default;
4724
- if (!O(e)) {
4725
- vc.warn("migration file has no default-exported `migration(...)` — skipped", { file: r });
4757
+ if (!T(e)) {
4758
+ xc.warn("migration file has no default-exported `migration(...)` — skipped", { file: r });
4726
4759
  continue;
4727
4760
  }
4728
4761
  let i = await Me.readFile(r, "utf8").catch(() => "");
4729
4762
  n.push({
4730
4763
  file: r,
4731
4764
  migration: e,
4732
- hash: yc(i),
4733
- accepted: xc(i)
4765
+ hash: Sc(i),
4766
+ accepted: wc(i)
4734
4767
  });
4735
4768
  }
4736
4769
  return n;
4737
- }, Ec = "_voltro_migration_plans", Dc = (e) => Oc(e).pipe(k.map((e) => e.map((e) => e.id))), Oc = (e) => Yi(e, Ec).pipe(k.flatMap((t) => t ? e`
4770
+ }, kc = "_voltro_migration_plans", Ac = (e) => jc(e).pipe(k.map((e) => e.map((e) => e.id))), jc = (e) => Xi(e, kc).pipe(k.flatMap((t) => t ? e`
4738
4771
  SELECT ${e("id")}, ${e("fingerprint")}
4739
- FROM ${e(Ec)}
4740
- WHERE ${e("source")} = 'file'
4772
+ FROM ${e(kc)}
4773
+ WHERE ${ys(e)}
4741
4774
  `.pipe(k.map((e) => e.map((e) => ({
4742
4775
  id: e.id,
4743
4776
  hash: e.fingerprint ?? ""
4744
- })))) : k.succeed([]))), kc = (e, t) => t.filter((t) => {
4777
+ })))) : k.succeed([]))), Mc = (e, t) => t.filter((t) => {
4745
4778
  let n = e.get(t.migration.id);
4746
4779
  return n !== void 0 && n !== "" && !t.accepted.has(n);
4747
- }).map((e) => e.migration.id), Ac = /* @__PURE__ */ new Set(), jc = (e) => re(se(e))?.kind === "unique", Mc = class extends Error {
4780
+ }).map((e) => e.migration.id), Nc = /* @__PURE__ */ new Set(), Pc = (e) => C(pe(e))?.kind === "unique", Fc = class extends Error {
4748
4781
  migrationId;
4749
4782
  file;
4750
4783
  cause;
4751
4784
  _tag = "FileMigrationLedgerError";
4752
4785
  constructor(e, t, n) {
4753
- super(jc(n) ? `migration ${e}: up() SUCCEEDED here, and ANOTHER process had already recorded the same migration.\n The body has run TWICE. The ledger row is correct — do not delete it; the next run will not apply ${t} again.\n Two processes applied it without being serialised by the migration lock: check that both reach the same database and lock schema.\n Cause: ${n instanceof Error ? n.message : String(n)}` : `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";
4786
+ super(Pc(n) ? `migration ${e}: up() SUCCEEDED here, and ANOTHER process had already recorded the same migration.\n The body has run TWICE. The ledger row is correct — do not delete it; the next run will not apply ${t} again.\n Two processes applied it without being serialised by the migration lock: check that both reach the same database and lock schema.\n Cause: ${n instanceof Error ? n.message : String(n)}` : `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";
4754
4787
  }
4755
- }, Nc = (e, t, n) => k.gen(function* () {
4788
+ }, Ic = (e, t, n) => k.gen(function* () {
4756
4789
  let r = yield* U(e, n.appliedAtIso);
4757
4790
  yield* e`
4758
4791
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -4767,27 +4800,27 @@ BEGIN
4767
4800
  }])},
4768
4801
  ${n.appliedBy}, ${n.env}, ${"file"},
4769
4802
  ${n.durationMs}, ${r}, ${n.notes})
4770
- `.pipe(k.mapError((e) => new Mc(t.migration.id, t.file, e)));
4771
- }), Pc = (e) => {
4772
- for (let t of ie(e)) if (t instanceof _) return t.reason;
4773
- }, Fc = (e, t, n) => k.gen(function* () {
4774
- let r = hc(t), i = r.ctx, a = e.migration.up(i), o = !k.isEffect(a), s = yield* (k.isEffect(a) ? a : k.tryPromise({
4803
+ `.pipe(k.mapError((e) => new Fc(t.migration.id, t.file, e)));
4804
+ }), Lc = (e) => {
4805
+ for (let t of ae(e)) if (t instanceof d) return t.reason;
4806
+ }, Rc = (e, t, n) => k.gen(function* () {
4807
+ let r = vc(t), i = r.ctx, a = e.migration.up(i), o = !k.isEffect(a), s = yield* (k.isEffect(a) ? a : k.tryPromise({
4775
4808
  try: () => a,
4776
4809
  catch: (e) => e
4777
4810
  })).pipe(k.as(void 0), k.catchAll((e) => {
4778
- let t = Pc(e);
4811
+ let t = Lc(e);
4779
4812
  return t === void 0 ? k.fail(e) : k.succeed(t);
4780
4813
  }));
4781
4814
  if (s === void 0) {
4782
- let t = yield* fc(n);
4783
- if (t.length > 0) return yield* k.fail(new C(e.migration.id, t));
4815
+ let t = yield* hc(n);
4816
+ if (t.length > 0) return yield* k.fail(new S(e.migration.id, t));
4784
4817
  }
4785
4818
  return {
4786
4819
  skipped: s,
4787
4820
  promiseForm: o,
4788
4821
  absent: r.absent()
4789
4822
  };
4790
- }), Ic = (e, t, n, r, i, a, o) => k.gen(function* () {
4823
+ }), zc = (e, t, n, r, i, a, o) => k.gen(function* () {
4791
4824
  let s = Date.now(), c = (/* @__PURE__ */ new Date()).toISOString(), l = M(e), u = `migrations:file:${n.migration.id}`, d = (e) => ({
4792
4825
  durationMs: Date.now() - s,
4793
4826
  notes: e.skipped === void 0 ? n.migration.description : `skipped: ${e.skipped}`
@@ -4795,19 +4828,19 @@ BEGIN
4795
4828
  if (n.migration.transactional !== !1 && !a) {
4796
4829
  if (t.run === void 0) return yield* k.fail(/* @__PURE__ */ Error(`migration ${n.migration.id}: transactional: true needs a SQL-backed store`));
4797
4830
  let a = l === "mysql" || l === "mariadb", s = `probe_${n.migration.id}_${Date.now().toString(36)}`;
4798
- a && (yield* Jo(e, l, o));
4831
+ a && (yield* Yo(e, l, o));
4799
4832
  let f = () => e`SELECT COUNT(*) AS n FROM ${e(N)} WHERE ${e("runId")} = ${s}`.pipe(k.map((e) => Number(e[0]?.n ?? 0) > 0)), p = yield* k.tryPromise({
4800
4833
  try: () => t.transactional(async (t) => {
4801
4834
  a && await t.run(e`INSERT INTO ${e(N)} (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")}, ${e("status")}, ${e("opKind")}, ${e("opTarget")}, ${e("payload")})
4802
4835
  VALUES (${`mop_${s}`}, ${s}, ${""}, ${0}, ${"pending"}, ${"probe"}, ${""}, ${"{}"})`);
4803
- let { ctx: o, expectations: u } = dc({
4836
+ let { ctx: o, expectations: u } = mc({
4804
4837
  sql: e,
4805
4838
  store: t,
4806
4839
  dialect: l,
4807
4840
  migrationId: n.migration.id,
4808
4841
  appliedAt: c
4809
- }), p = await t.run(Fc(n, o, u)), m = a && await k.runPromise(f().pipe(k.provideService(A.SqlClient, e))), { durationMs: h, notes: g } = d(p);
4810
- return await t.run(Nc(e, n, {
4842
+ }), p = await t.run(Rc(n, o, u)), m = a && await k.runPromise(f().pipe(k.provideService(A.SqlClient, e))), { durationMs: h, notes: g } = d(p);
4843
+ return await t.run(Ic(e, n, {
4811
4844
  env: r,
4812
4845
  appliedBy: i,
4813
4846
  durationMs: h,
@@ -4830,14 +4863,14 @@ BEGIN
4830
4863
  }
4831
4864
  });
4832
4865
  }
4833
- let { ctx: f, expectations: p } = dc({
4866
+ let { ctx: f, expectations: p } = mc({
4834
4867
  sql: e,
4835
4868
  store: t,
4836
4869
  dialect: l,
4837
4870
  migrationId: n.migration.id,
4838
4871
  appliedAt: c
4839
- }), m = yield* Fc(n, f, p), { durationMs: h, notes: g } = d(m);
4840
- return m.promiseForm && m.skipped === void 0 && h < 2 && (yield* k.logWarning(`migration ${n.migration.id}: up() resolved in ${h}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(k.annotateLogs({ scope: u }))), m.skipped !== void 0 && (yield* k.logInfo(`migration ${n.migration.id} skipped: ${m.skipped}`).pipe(k.annotateLogs({ scope: u }))), yield* Nc(e, n, {
4872
+ }), m = yield* Rc(n, f, p), { durationMs: h, notes: g } = d(m);
4873
+ return m.promiseForm && m.skipped === void 0 && h < 2 && (yield* k.logWarning(`migration ${n.migration.id}: up() resolved in ${h}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(k.annotateLogs({ scope: u }))), m.skipped !== void 0 && (yield* k.logInfo(`migration ${n.migration.id} skipped: ${m.skipped}`).pipe(k.annotateLogs({ scope: u }))), yield* Ic(e, n, {
4841
4874
  env: r,
4842
4875
  appliedBy: i,
4843
4876
  durationMs: h,
@@ -4851,9 +4884,9 @@ BEGIN
4851
4884
  absent: m.absent
4852
4885
  }
4853
4886
  };
4854
- }), Lc = (e, t, n, r) => k.gen(function* () {
4887
+ }), Bc = (e, t, n, r) => k.gen(function* () {
4855
4888
  let i = yield* k.tryPromise({
4856
- try: () => Cc(Ne(t, "migrations")),
4889
+ try: () => Ec(Ne(t, "migrations")),
4857
4890
  catch: (e) => e
4858
4891
  });
4859
4892
  if (i.length === 0) return {
@@ -4862,7 +4895,7 @@ BEGIN
4862
4895
  drifted: []
4863
4896
  };
4864
4897
  let a = yield* k.tryPromise({
4865
- try: () => Tc(i, r),
4898
+ try: () => Oc(i, r),
4866
4899
  catch: (e) => e
4867
4900
  });
4868
4901
  if (a.length === 0) return {
@@ -4870,10 +4903,10 @@ BEGIN
4870
4903
  alreadyApplied: [],
4871
4904
  drifted: []
4872
4905
  };
4873
- let o = new Map((yield* Oc(e)).map((e) => [e.id, e.hash])), s = kc(o, a);
4906
+ let o = new Map((yield* jc(e)).map((e) => [e.id, e.hash])), s = Mc(o, a);
4874
4907
  for (let e of s) {
4875
4908
  let t = a.find((t) => t.migration.id === e), n = `${t?.file ?? e}:${t?.hash ?? ""}`;
4876
- Ac.has(n) || (Ac.add(n), vc.warn("file migration: the body on disk is not the one that was applied — the file no longer describes this database", {
4909
+ Nc.has(n) || (Nc.add(n), xc.warn("file migration: the body on disk is not the one that was applied — the file no longer describes this database", {
4877
4910
  id: e,
4878
4911
  file: t?.file
4879
4912
  }));
@@ -4884,11 +4917,11 @@ BEGIN
4884
4917
  alreadyApplied: c.filter((e) => o.has(e.migration.id)),
4885
4918
  drifted: s
4886
4919
  };
4887
- }), Rc = (e, t, n, r) => Lc(e, t, n, r).pipe(k.map((e) => e.pending.map((e) => e.migration.id))), zc = (e, t, n) => Lc(e, t, n).pipe(k.map((e) => e.pending.map((e) => ({
4920
+ }), Vc = (e, t, n, r) => Bc(e, t, n, r).pipe(k.map((e) => e.pending.map((e) => e.migration.id))), Hc = (e, n, r) => Bc(e, n, r).pipe(k.map((e) => e.pending.map((e) => ({
4888
4921
  id: e.migration.id,
4889
4922
  phase: e.migration.phase,
4890
- irreversible: r(e.migration.down)
4891
- })))), Bc = (e, t) => Lc(e, t).pipe(k.map((e) => {
4923
+ irreversible: t(e.migration.down)
4924
+ })))), Uc = (e, t) => Bc(e, t).pipe(k.map((e) => {
4892
4925
  let t = new Set(e.drifted);
4893
4926
  return [...e.alreadyApplied.map((e) => ({
4894
4927
  id: e.migration.id,
@@ -4901,16 +4934,16 @@ BEGIN
4901
4934
  applied: !1,
4902
4935
  bodyChanged: !1
4903
4936
  }))].sort((e, t) => e.id < t.id ? -1 : 1);
4904
- })), Vc = (e, t) => k.gen(function* () {
4905
- let { pending: n, alreadyApplied: r } = yield* Lc(e, t.projectRoot, t.phase), i = r.map((e) => e.migration.id);
4937
+ })), Wc = (e, t) => k.gen(function* () {
4938
+ let { pending: n, alreadyApplied: r } = yield* Bc(e, t.projectRoot, t.phase), i = r.map((e) => e.migration.id);
4906
4939
  if (n.length === 0) return {
4907
4940
  applied: [],
4908
4941
  skipped: i,
4909
4942
  skips: []
4910
4943
  };
4911
- yield* Yo(e, M(e), t.charset);
4944
+ yield* Xo(e, M(e), t.charset);
4912
4945
  let a = yield* k.acquireUseRelease(_t(e, { schema: t.lockSchema }), () => k.gen(function* () {
4913
- let r = new Set((yield* Oc(e)).map((e) => e.id)), i = n.filter((e) => !r.has(e.migration.id));
4946
+ let r = new Set((yield* jc(e)).map((e) => e.id)), i = n.filter((e) => !r.has(e.migration.id));
4914
4947
  i.length < n.length && (yield* k.logInfo("file-based migrations applied by another process while this one waited for the migration lock").pipe(k.annotateLogs({
4915
4948
  scope: "voltro:migrate",
4916
4949
  ids: n.filter((e) => r.has(e.migration.id)).map((e) => e.migration.id).join(",")
@@ -4925,7 +4958,7 @@ BEGIN
4925
4958
  file: n.file,
4926
4959
  phase: n.migration.phase
4927
4960
  }));
4928
- let { durationMs: r, skip: i } = yield* Ic(e, t.store, n, t.env, t.appliedBy, t.enclosed === !0, t.charset);
4961
+ let { durationMs: r, skip: i } = yield* zc(e, t.store, n, t.env, t.appliedBy, t.enclosed === !0, t.charset);
4929
4962
  a.push({
4930
4963
  id: n.migration.id,
4931
4964
  durationMs: r
@@ -4946,43 +4979,43 @@ BEGIN
4946
4979
  skipped: i,
4947
4980
  skips: a.skips
4948
4981
  };
4949
- }), Hc = (e, t) => e`
4982
+ }), Gc = (e, t) => e`
4950
4983
  SELECT ${e("id")}
4951
4984
  FROM ${e("_voltro_migration_plans")}
4952
4985
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
4953
- `, Uc = (e, t) => k.gen(function* () {
4954
- if (!(yield* Hc(e, t.id))[0]) return yield* k.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
4955
- let n = yield* k.tryPromise({
4956
- try: () => Cc(Ne(t.projectRoot, "migrations")),
4986
+ `, Kc = (e, n) => k.gen(function* () {
4987
+ if (!(yield* Gc(e, n.id))[0]) return yield* k.fail(/* @__PURE__ */ Error(`rollback: ${n.id} not found in _voltro_migration_plans (file source)`));
4988
+ let r = yield* k.tryPromise({
4989
+ try: () => Ec(Ne(n.projectRoot, "migrations")),
4957
4990
  catch: (e) => e
4958
4991
  }), i = (yield* k.tryPromise({
4959
- try: () => Tc(n),
4992
+ try: () => Oc(r),
4960
4993
  catch: (e) => e
4961
- })).find((e) => e.migration.id === t.id);
4962
- if (!i) return yield* k.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
4963
- let a = r(i.migration.down);
4964
- return a === void 0 ? yield* k.acquireUseRelease(_t(e, { schema: t.lockSchema }), () => k.gen(function* () {
4965
- if ((yield* Hc(e, t.id))[0] === void 0) return yield* k.fail(/* @__PURE__ */ Error(`rollback: ${t.id} was rolled back by another process while this one waited for the migration lock — nothing to do`));
4966
- let n = Date.now(), { ctx: r } = dc({
4994
+ })).find((e) => e.migration.id === n.id);
4995
+ if (!i) return yield* k.fail(/* @__PURE__ */ Error(`rollback: file for migration ${n.id} not found on disk under ${n.projectRoot}/migrations/`));
4996
+ let a = t(i.migration.down);
4997
+ return a === void 0 ? yield* k.acquireUseRelease(_t(e, { schema: n.lockSchema }), () => k.gen(function* () {
4998
+ if ((yield* Gc(e, n.id))[0] === void 0) return yield* k.fail(/* @__PURE__ */ Error(`rollback: ${n.id} was rolled back by another process while this one waited for the migration lock — nothing to do`));
4999
+ let t = Date.now(), { ctx: r } = mc({
4967
5000
  sql: e,
4968
- store: t.store,
5001
+ store: n.store,
4969
5002
  dialect: M(e),
4970
- migrationId: t.id,
5003
+ migrationId: n.id,
4971
5004
  appliedAt: (/* @__PURE__ */ new Date()).toISOString()
4972
5005
  });
4973
- t.beforeExecute !== void 0 && (yield* t.beforeExecute);
5006
+ n.beforeExecute !== void 0 && (yield* n.beforeExecute);
4974
5007
  let a = i.migration.down(r);
4975
5008
  k.isEffect(a) ? yield* a : yield* k.tryPromise({
4976
5009
  try: () => a,
4977
5010
  catch: (e) => e
4978
5011
  });
4979
- let o = Date.now() - n;
4980
- return yield* e`DELETE FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t.id} AND ${e("source")} = 'file'`, {
4981
- id: t.id,
5012
+ let o = Date.now() - t;
5013
+ return yield* e`DELETE FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${n.id} AND ${e("source")} = 'file'`, {
5014
+ id: n.id,
4982
5015
  durationMs: o
4983
5016
  };
4984
- }), (e) => e.release.pipe(k.orDie)) : yield* k.fail(new b(t.id, a));
4985
- }), Wc = (e) => k.gen(function* () {
5017
+ }), (e) => e.release.pipe(k.orDie)) : yield* k.fail(new h(n.id, a));
5018
+ }), qc = (e) => k.gen(function* () {
4986
5019
  let t = yield* A.SqlClient;
4987
5020
  if (!Number.isFinite(Date.parse(e.before))) return yield* k.fail(/* @__PURE__ */ Error("squash: cut-off must be a valid date"));
4988
5021
  let n = yield* t`
@@ -5014,10 +5047,10 @@ BEGIN
5014
5047
  token: i
5015
5048
  }
5016
5049
  };
5017
- }), Gc = (e) => Wc(e).pipe(k.map((e) => e.preview)), Kc = (e) => k.gen(function* () {
5050
+ }), Jc = (e) => qc(e).pipe(k.map((e) => e.preview)), Yc = (e) => k.gen(function* () {
5018
5051
  let t = yield* A.SqlClient;
5019
- return yield* bt(t, la(t, k.gen(function* () {
5020
- let { eligible: n, preview: r } = yield* Wc(e);
5052
+ return yield* bt(t, ua(t, k.gen(function* () {
5053
+ let { eligible: n, preview: r } = yield* qc(e);
5021
5054
  if (e.expectedPreview !== void 0 && e.expectedPreview !== r.token) return yield* k.fail(/* @__PURE__ */ Error("squash: selected history changed after preview; review a new preview before confirming"));
5022
5055
  yield* t`
5023
5056
  UPDATE _voltro_migration_plans
@@ -5054,8 +5087,8 @@ BEGIN
5054
5087
  snapshotId: i
5055
5088
  };
5056
5089
  })));
5057
- }), qc = (e) => new Set(e.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), Jc = (e, t) => t !== void 0 && "table" in e && t.createdTables.has(e.table), Yc = { safe: !0 }, Xc = (e, t) => {
5058
- if (Jc(e, t)) return Yc;
5090
+ }), Xc = (e) => new Set(e.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), Zc = (e, t) => t !== void 0 && "table" in e && t.createdTables.has(e.table), Qc = { safe: !0 }, $c = (e, t) => {
5091
+ if (Zc(e, t)) return Qc;
5059
5092
  switch (e.kind) {
5060
5093
  case "add-enum-value": return { safe: !0 };
5061
5094
  case "drop-column": return {
@@ -5087,7 +5120,7 @@ BEGIN
5087
5120
  reason: `instances on the previous release read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
5088
5121
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
5089
5122
  };
5090
- case "alter-column-nullability": return e.toNullable ? Yc : {
5123
+ case "alter-column-nullability": return e.toNullable ? Qc : {
5091
5124
  safe: !1,
5092
5125
  reason: `instances on the previous release may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
5093
5126
  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)`
@@ -5098,12 +5131,12 @@ BEGIN
5098
5131
  reason: `instances on the previous release still write "${e.table}" without honouring the new uniqueness; a colliding insert now fails mid-rollout`,
5099
5132
  remedy: "make code enforce uniqueness first and deploy that; add the constraint in a LATER deploy once no old writer remains"
5100
5133
  };
5101
- case "reconcile-json-check": return e.previousValidation === "container" && e.validation === "value" ? Yc : {
5134
+ case "reconcile-json-check": return e.previousValidation === "container" && e.validation === "value" ? Qc : {
5102
5135
  safe: !1,
5103
5136
  reason: `instances on the previous release write "${e.table}"."${e.column}" without the new JSON validation, which now rejects them`,
5104
5137
  remedy: "ensure all writers supply valid JSON in the required domain before enabling this check"
5105
5138
  };
5106
- case "add-check": return e.table.startsWith("_voltro_") ? Yc : {
5139
+ case "add-check": return e.table.startsWith("_voltro_") ? Qc : {
5107
5140
  safe: !1,
5108
5141
  reason: `instances on the previous release may write values to "${e.table}" the new CHECK rejects`,
5109
5142
  remedy: "make code satisfy the constraint first and deploy that; add the CHECK in a LATER deploy"
@@ -5113,7 +5146,7 @@ BEGIN
5113
5146
  reason: `instances on the previous release may write "${e.table}"."${e.column}" values with no matching parent row, which the new FK rejects`,
5114
5147
  remedy: "make code guarantee the referent first and deploy that; add the FK in a LATER deploy"
5115
5148
  };
5116
- case "convert-charset": return e.charset === "utf8mb4" ? Yc : {
5149
+ case "convert-charset": return e.charset === "utf8mb4" ? Qc : {
5117
5150
  safe: !1,
5118
5151
  reason: `instances on the previous release may write 4-byte characters into "${e.table}", which utf8mb3 rejects with errno 1366`,
5119
5152
  remedy: "keep utf8mb4 while any writer on the previous release remains; narrow in a LATER deploy, after every writer refuses such input itself"
@@ -5127,12 +5160,12 @@ BEGIN
5127
5160
  case "drop-unique":
5128
5161
  case "drop-unique-composite":
5129
5162
  case "drop-foreign-key":
5130
- case "drop-check": return Yc;
5163
+ case "drop-check": return Qc;
5131
5164
  }
5132
- }, Zc = (e) => {
5133
- let t = [], n = { createdTables: qc(e) };
5165
+ }, el = (e) => {
5166
+ let t = [], n = { createdTables: Xc(e) };
5134
5167
  for (let r of e) {
5135
- let e = Xc(r.op, n);
5168
+ let e = $c(r.op, n);
5136
5169
  e.safe || t.push({
5137
5170
  op: r,
5138
5171
  reason: e.reason,
@@ -5140,7 +5173,7 @@ BEGIN
5140
5173
  });
5141
5174
  }
5142
5175
  return t;
5143
- }, Qc = (e) => {
5176
+ }, tl = (e) => {
5144
5177
  if (!e.enabled || e.unsafeCount === 0) return {
5145
5178
  refuse: !1,
5146
5179
  warnForced: !1,
@@ -5156,18 +5189,18 @@ BEGIN
5156
5189
  warnForced: !1,
5157
5190
  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.`
5158
5191
  };
5159
- }, $c = (e) => {
5192
+ }, nl = (e) => {
5160
5193
  let t = e.table;
5161
5194
  if (typeof t == "string") return t;
5162
5195
  let n = e.from;
5163
5196
  return typeof n == "string" ? n : void 0;
5164
- }, el = (e) => ({
5197
+ }, rl = (e) => ({
5165
5198
  kind: e.op.kind,
5166
- table: $c(e.op),
5199
+ table: nl(e.op),
5167
5200
  classification: e.classification,
5168
5201
  reason: e.reason,
5169
5202
  blockedFix: e.blocked?.fix
5170
- }), tl = (e) => e.operations.map(el), nl = async (e) => {
5203
+ }), il = (e) => e.operations.map(rl), al = async (e) => {
5171
5204
  let t = e.log ?? (() => {}), n = {
5172
5205
  branchId: e.branchId,
5173
5206
  mechanism: e.mechanism,
@@ -5186,10 +5219,10 @@ BEGIN
5186
5219
  applied: !1,
5187
5220
  converged: !1,
5188
5221
  residual: r,
5189
- infidelity: tl(o)
5222
+ infidelity: il(o)
5190
5223
  };
5191
5224
  else {
5192
- let i = await e.plan(), o = tl(i), s = o.filter((e) => e.classification === "lossy"), c = Bs(i), l = c.operations.filter((e) => e.blocked !== void 0).map(el);
5225
+ let i = await e.plan(), o = il(i), s = o.filter((e) => e.classification === "lossy"), c = Us(i), l = c.operations.filter((e) => e.blocked !== void 0).map(rl);
5193
5226
  if (l.length > 0) a = {
5194
5227
  ...n,
5195
5228
  outcome: "blocked",
@@ -5214,7 +5247,7 @@ BEGIN
5214
5247
  };
5215
5248
  else {
5216
5249
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
5217
- let i = tl(await e.replan());
5250
+ let i = il(await e.replan());
5218
5251
  a = {
5219
5252
  ...n,
5220
5253
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -5252,7 +5285,7 @@ BEGIN
5252
5285
  ...a,
5253
5286
  tornDown: o
5254
5287
  };
5255
- }, rl = (e) => {
5288
+ }, ol = (e) => {
5256
5289
  switch (e.outcome) {
5257
5290
  case "clean": return 0;
5258
5291
  case "lossy": return 2;
@@ -5261,28 +5294,28 @@ BEGIN
5261
5294
  case "infidelity": return 1;
5262
5295
  case "failed": return 1;
5263
5296
  }
5264
- }, il = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, al = (e) => {
5297
+ }, sl = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, cl = (e) => {
5265
5298
  let t = [];
5266
5299
  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"}`);
5267
5300
  else if (e.outcome === "infidelity") {
5268
5301
  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:");
5269
- for (let n of e.infidelity) t.push(il(n));
5302
+ for (let n of e.infidelity) t.push(sl(n));
5270
5303
  } else {
5271
5304
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
5272
- for (let n of e.operations) t.push(il(n));
5273
- 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(il(n));
5305
+ for (let n of e.operations) t.push(sl(n));
5306
+ 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(sl(n));
5274
5307
  }
5275
5308
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
5276
- }, ol = "tenant_", sl = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), cl = async (e, t) => e(k.gen(function* () {
5277
- let e = yield* A.SqlClient, n = sl(yield* e`
5309
+ }, ll = "tenant_", ul = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), dl = async (e, t) => e(k.gen(function* () {
5310
+ let e = yield* A.SqlClient, n = ul(yield* e`
5278
5311
  SELECT schema_name FROM information_schema.schemata
5279
- WHERE schema_name LIKE ${`${ol}%`} ORDER BY schema_name`), r = [];
5312
+ WHERE schema_name LIKE ${`${ll}%`} ORDER BY schema_name`), r = [];
5280
5313
  for (let { schema_name: i } of n) {
5281
- let n = sl(yield* e`
5314
+ let n = ul(yield* e`
5282
5315
  SELECT table_name, column_name, data_type, character_set_name
5283
5316
  FROM information_schema.columns
5284
5317
  WHERE table_schema = ${i}
5285
- ORDER BY table_name, ordinal_position`), a = sl(yield* e`
5318
+ ORDER BY table_name, ordinal_position`), a = ul(yield* e`
5286
5319
  SELECT cc.table_name AS table_name, cc.check_clause AS check_clause
5287
5320
  FROM information_schema.check_constraints cc
5288
5321
  WHERE cc.constraint_schema = ${i}`.pipe(k.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set();
@@ -5317,33 +5350,33 @@ BEGIN
5317
5350
  });
5318
5351
  }
5319
5352
  return r;
5320
- })), ll = "owner", ul = (e) => k.map(e`SELECT ${e("appName")}, ${e("claimedAt")} FROM ${e(Si)} WHERE ${e("id")} = ${ll}`, (e) => e[0]), dl = (e, t) => e.appName === t ? { kind: "owned" } : {
5353
+ })), fl = "owner", pl = (e) => k.map(e`SELECT ${e("appName")}, ${e("claimedAt")} FROM ${e(Si)} WHERE ${e("id")} = ${fl}`, (e) => e[0]), ml = (e, t) => e.appName === t ? { kind: "owned" } : {
5321
5354
  kind: "foreign",
5322
5355
  owner: e.appName,
5323
5356
  claimedAt: e.claimedAt === void 0 || e.claimedAt === null ? void 0 : String(e.claimedAt)
5324
- }, fl = (e, t) => Xo(e, M(e), t).pipe(k.catchAll(() => Xo(e, M(e), t))), pl = (e, t, n) => k.gen(function* () {
5357
+ }, hl = (e, t) => Zo(e, M(e), t).pipe(k.catchAll(() => Zo(e, M(e), t))), gl = (e, t, n) => k.gen(function* () {
5325
5358
  if (!n.mayWrite) {
5326
- let n = yield* ul(e).pipe(k.catchAll(() => k.succeed(void 0)));
5327
- return n === void 0 ? { kind: "unclaimed" } : dl(n, t.appName);
5359
+ let n = yield* pl(e).pipe(k.catchAll(() => k.succeed(void 0)));
5360
+ return n === void 0 ? { kind: "unclaimed" } : ml(n, t.appName);
5328
5361
  }
5329
- yield* fl(e, n.charset);
5330
- let r = yield* ul(e);
5331
- if (r !== void 0) return dl(r, t.appName);
5362
+ yield* hl(e, n.charset);
5363
+ let r = yield* pl(e);
5364
+ if (r !== void 0) return ml(r, t.appName);
5332
5365
  let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
5333
5366
  if (yield* e`INSERT INTO ${e("_voltro_schema_owner")} ${e.insert({
5334
- id: ll,
5367
+ id: fl,
5335
5368
  appName: t.appName,
5336
5369
  projectName: t.projectName ?? null,
5337
5370
  frameworkVersion: t.frameworkVersion ?? null,
5338
5371
  claimedAt: i
5339
5372
  })}`.pipe(k.as(!0), k.catchAll(() => k.succeed(!1)))) return { kind: "claimed" };
5340
- let a = yield* ul(e);
5341
- return a === void 0 ? { kind: "unclaimed" } : dl(a, t.appName);
5342
- }), ml = (e, t, n) => k.gen(function* () {
5343
- yield* fl(e, n);
5344
- let r = yield* ul(e), i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
5373
+ let a = yield* pl(e);
5374
+ return a === void 0 ? { kind: "unclaimed" } : ml(a, t.appName);
5375
+ }), _l = (e, t, n) => k.gen(function* () {
5376
+ yield* hl(e, n);
5377
+ let r = yield* pl(e), i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
5345
5378
  return r === void 0 ? yield* e`INSERT INTO ${e(Si)} ${e.insert({
5346
- id: ll,
5379
+ id: fl,
5347
5380
  appName: t.appName,
5348
5381
  projectName: t.projectName ?? null,
5349
5382
  frameworkVersion: t.frameworkVersion ?? null,
@@ -5353,27 +5386,36 @@ BEGIN
5353
5386
  projectName: t.projectName ?? null,
5354
5387
  frameworkVersion: t.frameworkVersion ?? null,
5355
5388
  claimedAt: i
5356
- })} WHERE ${e("id")} = ${ll}`, { previous: r?.appName };
5357
- }), hl = (e, t, n) => `this database belongs to the app '${t}'${n === void 0 ? "" : ` (claimed ${n})`}, and '${e}' is a different app. Two apps on one schema each plan to drop the other's tables, and their data is shared with no contract between them. Give this app its own database (DB_URL) or its own schema (DB_SCHEMA); if it needs the other app's data, call it — \`apis:\` on this app, \`service:\` procedures on the other. If this app was RENAMED from '${t}', run \`voltro db claim\` once to hand the schema over.`, gl = (e, ...t) => ({
5389
+ })} WHERE ${e("id")} = ${fl}`, { previous: r?.appName };
5390
+ }), vl = (e, t, n) => `this database belongs to the app '${t}'${n === void 0 ? "" : ` (claimed ${n})`}, and '${e}' is a different app. Two apps on one schema each plan to drop the other's tables, and their data is shared with no contract between them. Give this app its own database (DB_URL) or its own schema (DB_SCHEMA); if it needs the other app's data, call it — \`apis:\` on this app, \`service:\` procedures on the other. If this app was RENAMED from '${t}', run \`voltro db claim\` once to hand the schema over.`, yl = (e, ...t) => ({
5358
5391
  _tag: "RawSqlFragment",
5359
5392
  strings: [...e],
5360
5393
  values: [...t]
5361
- }), _l = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment", vl = (e) => k.gen(function* () {
5362
- let t = [], n;
5394
+ }), bl = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment", xl = (e) => k.gen(function* () {
5395
+ let t = e.onDialectOrElse({
5396
+ mysql: () => e`CAST(${e("operations")} AS CHAR)`,
5397
+ mssql: () => e`CAST(${e("operations")} AS NVARCHAR(MAX))`,
5398
+ orElse: () => e`CAST(${e("operations")} AS TEXT)`
5399
+ }), n = e`(${t} LIKE ${"%softDropSnapshot%"} OR ${t} LIKE ${"%\\%"} ESCAPE '!')`, r = e.onDialectOrElse({
5400
+ pg: () => e`CASE WHEN pg_typeof(${e("operations")})::text IN ('json', 'jsonb')
5401
+ THEN jsonb_path_exists(${e("operations")}::jsonb, '$[*].softDropSnapshot')
5402
+ ELSE ${n} END`,
5403
+ orElse: () => n
5404
+ }), i = [], a;
5363
5405
  for (;;) {
5364
- let r = yield* e`
5406
+ let t = yield* e`
5365
5407
  SELECT ${e("id")}, ${e("operations")} FROM ${e("_voltro_migration_plans")}
5366
- ${n === void 0 ? e`` : e`WHERE ${e("id")} > ${n}`}
5408
+ WHERE ${r} ${a === void 0 ? e`` : e`AND ${e("id")} > ${a}`}
5367
5409
  ORDER BY ${e("id")}
5368
5410
  ${e.onDialectOrElse({
5369
5411
  mssql: () => e`OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY`,
5370
5412
  orElse: () => e`LIMIT 100`
5371
5413
  })}
5372
5414
  `;
5373
- if (t.push(...r), r.length < 100) return t;
5374
- n = r[r.length - 1].id;
5415
+ if (i.push(...t), t.length < 100) return i;
5416
+ a = t[t.length - 1].id;
5375
5417
  }
5376
- }), yl = (e, t) => {
5418
+ }), Sl = (e, t) => {
5377
5419
  let n = [], r = /* @__PURE__ */ new Map(), i = (e, t) => JSON.stringify(e.kind === "table" ? ["table", e.snapshotName] : [
5378
5420
  "column",
5379
5421
  t.find((t) => t.kind === "table" && t.originalName === e.table)?.snapshotName ?? e.table,
@@ -5388,7 +5430,7 @@ BEGIN
5388
5430
  }
5389
5431
  if (!Array.isArray(e)) continue;
5390
5432
  let o = [];
5391
- for (let t of e) xl(t) && xl(t.op) && typeof t.softDropSnapshot == "string" && typeof t.op.table == "string" && (t.op.kind === "drop-table" && o.push({
5433
+ for (let t of e) wl(t) && wl(t.op) && typeof t.softDropSnapshot == "string" && typeof t.op.table == "string" && (t.op.kind === "drop-table" && o.push({
5392
5434
  kind: "table",
5393
5435
  table: t.op.table,
5394
5436
  originalName: t.op.table,
@@ -5404,7 +5446,7 @@ BEGIN
5404
5446
  n.add(a.id), r.set(t, n);
5405
5447
  }
5406
5448
  try {
5407
- let r = Cl(e, t);
5449
+ let r = El(e, t);
5408
5450
  r.length > 0 && n.push({
5409
5451
  planId: a.id,
5410
5452
  objects: r
@@ -5412,18 +5454,18 @@ BEGIN
5412
5454
  } catch {}
5413
5455
  }
5414
5456
  return n.filter((e) => e.objects.every((t) => r.get(i(t, e.objects))?.size === 1));
5415
- }, bl = (e, t) => vl(e).pipe(k.map((e) => yl(e, t))), xl = (e) => typeof e == "object" && !!e && !Array.isArray(e), Sl = {
5457
+ }, Cl = (e, t) => xl(e).pipe(k.map((e) => Sl(e, t))), wl = (e) => typeof e == "object" && !!e && !Array.isArray(e), Tl = {
5416
5458
  postgres: !0,
5417
5459
  mysql: !1,
5418
5460
  mariadb: !1,
5419
5461
  mssql: !0,
5420
5462
  sqlite: !0
5421
- }, Cl = (e, t) => {
5463
+ }, El = (e, t) => {
5422
5464
  let n = typeof e == "string" ? JSON.parse(e) : e;
5423
5465
  if (!Array.isArray(n)) throw Error("Snapshot restoration requires an operation array");
5424
5466
  let r = [], i = /* @__PURE__ */ new Set();
5425
5467
  for (let e of n) {
5426
- if (!xl(e) || !xl(e.op) || typeof e.op.kind != "string") throw Error("Invalid migration operation history");
5468
+ if (!wl(e) || !wl(e.op) || typeof e.op.kind != "string") throw Error("Invalid migration operation history");
5427
5469
  let t = e.op;
5428
5470
  if (t.kind !== "drop-column" && t.kind !== "drop-table") {
5429
5471
  if (e.softDropSnapshot !== void 0) throw Error("Snapshot metadata belongs to a non-drop operation");
@@ -5431,7 +5473,7 @@ BEGIN
5431
5473
  }
5432
5474
  if (typeof t.table != "string" || !t.table || t.kind === "drop-column" && (typeof t.column != "string" || !t.column)) throw Error("Invalid drop operation identity");
5433
5475
  if (typeof e.softDropSnapshot != "string") throw Error("Snapshot ownership is unavailable for this plan. Its history has no exact soft-drop identity; automatic restoration is refused.");
5434
- let n = Zi({
5476
+ let n = Qi({
5435
5477
  op: t.kind === "drop-table" ? {
5436
5478
  kind: "drop-table",
5437
5479
  table: t.table
@@ -5441,7 +5483,7 @@ BEGIN
5441
5483
  column: String(t.column)
5442
5484
  },
5443
5485
  classification: "lossy",
5444
- atomicByDialect: Sl,
5486
+ atomicByDialect: Tl,
5445
5487
  softDropSnapshot: e.softDropSnapshot
5446
5488
  }), a = {
5447
5489
  kind: t.kind === "drop-table" ? "table" : "column",
@@ -5467,17 +5509,17 @@ BEGIN
5467
5509
  if (!i.columns.some((t) => t.name === e.snapshotName)) throw Error(`Recorded snapshot is missing: ${e.table}.${e.snapshotName}`);
5468
5510
  }
5469
5511
  return r;
5470
- }, wl = (e, t, n = {}) => k.acquireUseRelease(_t(e), () => {
5512
+ }, Dl = (e, t, n = {}) => k.acquireUseRelease(_t(e), () => {
5471
5513
  let r = k.gen(function* () {
5472
5514
  let e = yield* A.SqlClient, r = yield* e`SELECT ${e("operations")} FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t}`;
5473
5515
  if (r.length !== 1) return yield* k.fail(/* @__PURE__ */ Error(`Snapshot plan not found: ${t}`));
5474
5516
  let i = yield* B(e), a = yield* k.try({
5475
- try: () => Cl(r[0].operations, i),
5517
+ try: () => El(r[0].operations, i),
5476
5518
  catch: (e) => e instanceof Error ? e : Error(String(e))
5477
5519
  });
5478
- if (a.length > 0 && !(yield* bl(e, i)).some((e) => e.planId === t)) return yield* k.fail(/* @__PURE__ */ Error("Snapshot ownership is ambiguous across migration history; automatic restoration is refused."));
5520
+ if (a.length > 0 && !(yield* Cl(e, i)).some((e) => e.planId === t)) return yield* k.fail(/* @__PURE__ */ Error("Snapshot ownership is ambiguous across migration history; automatic restoration is refused."));
5479
5521
  a.length > 0 && n.beforeExecute && (yield* n.beforeExecute(e));
5480
- for (let t of a) yield* _s(e, {
5522
+ for (let t of a) yield* vs(e, {
5481
5523
  op: t.kind === "table" ? {
5482
5524
  kind: "rename-table",
5483
5525
  from: t.snapshotName,
@@ -5489,7 +5531,7 @@ BEGIN
5489
5531
  to: t.originalName
5490
5532
  },
5491
5533
  classification: "safe",
5492
- atomicByDialect: Sl
5534
+ atomicByDialect: Tl
5493
5535
  }, []);
5494
5536
  return {
5495
5537
  restoredColumns: a.filter((e) => e.kind === "column").length,
@@ -5497,7 +5539,7 @@ BEGIN
5497
5539
  objects: a
5498
5540
  };
5499
5541
  });
5500
- return St(M(e)) === "plan-transactional" ? la(e, r) : r;
5542
+ return St(M(e)) === "plan-transactional" ? ua(e, r) : r;
5501
5543
  }, (e) => e.release.pipe(k.orDie));
5502
5544
  //#endregion
5503
- export { Rt as DEFAULT_CDC_CHANNEL, R as DEPLOY_LEDGER_TABLE, le as FILE_MIGRATION_PATTERN, bc as FRAMEWORK_MIGRATION_EDITS, Mc as FileMigrationLedgerError, b as IrreversibleMigrationError, xt as MIGRATION_ATOMICITY, vt as MIGRATION_NEEDS_TWO_CONNECTIONS, x as MIGRATION_PHASES, yr as MYSQL_CHARSETS, C as MigrationExpectationFailed, f as MigrationNeedsSqlClient, _ as MigrationSkipped, zt as REACTIVE_TRIGGER_PREFIX, y as RewriteUnstableError, Si as SCHEMA_OWNER_TABLE, Or as STORE_CHARSET_REMEDY, w as TransactionBrokenByBodyError, Ze as VOLTRO_MIGRATION_LOCK_KEY, _i as _voltroDeploysTable, xc as acceptedBodyHashes, _t as acquireMigrationLock, Vo as addColumnDdl, U as appliedAtValue, Dc as appliedFileMigrationIds, Oc as appliedFileMigrations, ss as appliedLedgerOperations, Vn as applyNamespacedSchema, ms as applyPlan, An as applySchema, Os as applyUndeclaredCharsetWork, Qc as assessRollingDeployGate, rl as branchRehearsalExitCode, Cr as charsetColumnsOf, pl as checkSchemaOwner, Pi as chunkTables, Xc as classifyRollingDeploySafety, cs as clearResumeLedger, yi as closeDeploy, Oa as columnLevelChecksMysql, xr as columnTakesCharset, ks as convergeUndeclaredCharset, qc as createdTablesOf, Nr as declaredSnapshot, Yt as defaultArrayClause, Jt as defaultClause, Xt as defaultJsonClause, Ws as describeOutcome, pc as describeProbe, Dr as describeStoreCharsetFinding, Cs as describeUndeclaredCharsetWork, Rs as destructiveScope, Fr as detectReactiveTriggerDrift, M as dialectOf, fo as emitAddIndexMysql, Ua as emitConvertCharsetMysql, ro as emitCreateTableMssql, Wa as emitCreateTableMysql, La as emitCreateTablePg, Xa as emitCreateTableSqlite, va as emitDropColumnDdl, ya as emitDropColumnDdlMysql, kn as emitFrameworkBootstrapSql, Dn as emitNamespaceProvisionDdl, On as emitNamespacedSchemaSql, En as emitSchemaSql, Qi as engineFromVersion, Qo as ensureDeployLedgerTable, Mn as ensureFullTextIndexes, Jo as ensureLedgerTable, Yo as ensurePlanLedgerTable, Zo as ensurePluginMigrationsLedgerTable, $o as ensureReplaceMarkerTable, Xo as ensureSchemaOwnerTable, wn as enumRenameBlocks, Cn as enumTypeBlocks, _n as extensionBlocks, bi as failDeploy, fc as failedExpectations, js as fetchLastFingerprint, Bc as fileMigrationStatus, I as fingerprintSchema, rt as fnv1a64, hl as foreignOwnerMessage, al as formatBranchRehearsal, Ir as formatReactiveTriggerDrift, un as fullTextIndexSql, ns as hasInterruptedMigration, Ls as ignoreTablesFromEnv, B as introspectSchema, be as irreversible, r as irreversibleReason, ra as isAlreadySatisfied, O as isFileMigration, br as isMysqlCharset, _l as isRawSqlFragment, Nn as isReRunSafeDdl, ys as isUndeclaredCharsetTable, Ss as isUndeclaredCharsetWorkEmpty, V as limitClause, dc as makeFileMigrationContext, Ti as mapPgType, qs as materialiseSnapshot, h as migration, St as migrationAtomicityFor, yc as migrationBodyHash, it as migrationLockKeyForSchema, at as migrationLockNameForSchema, oo as mysqlIndexPrefixFor, Wt as notifyFunctionName, Zt as numericIdSql, vi as openDeploy, wi as parseEnumCheck, Rc as pendingFileMigrationIds, zc as pendingFileMigrationSummary, _c as permanentSkips, gi as planMigrations, de as plannableLiveTables, gc as plannedCreations, Gc as previewMigrationSquash, Hn as provisionTenantNamespace, Bt as reactiveTriggerName, gn as reactiveTriggerRepairSql, bl as readMigrationSnapshotCandidates, Ts as readUndeclaredCharsetColumns, Ms as recordUpToDate, Je as registerSqlPoolCapacity, nl as rehearseMigrationOnBranch, el as rehearsedOperation, Ba as renderColumnMysql, Pa as renderColumnPg, $e as resolveMigrationLockSchema, H as resolveMysqlEngine, wl as restoreMigrationSnapshots, Uc as rollbackFileBasedMigration, Zc as rollingDeployUnsafeOps, Vc as runFileBasedMigrations, Un as runFrameworkBootstrap, Bn as runMigrate, _s as runMigrationOp, Us as runPlannedMigrations, Z as runSchemaOp, vr as shortFingerprint, kr as snapshotColumn, gl as sql, Ye as sqlPoolCapacity, F as sqlType, Kc as squashMigrationPlans, Sr as stampDeclaredCharset, Er as storeCharsetFindings, cl as tenantNamespaceCharsetFindings, ml as transferSchemaOwner, Bs as unblockLossy, Ds as undeclaredCharsetStatements, xs as undeclaredCharsetWork, xi as unfinishedDeploys, Cc as walkMigrationFiles, bt as withMigrationLock, hc as withSchemaProbeRecorder };
5545
+ export { Rt as DEFAULT_CDC_CHANNEL, R as DEPLOY_LEDGER_TABLE, le as FILE_MIGRATION_PATTERN, Cc as FRAMEWORK_MIGRATION_EDITS, Fc as FileMigrationLedgerError, h as IrreversibleMigrationError, xt as MIGRATION_ATOMICITY, vt as MIGRATION_NEEDS_TWO_CONNECTIONS, v as MIGRATION_PHASES, yr as MYSQL_CHARSETS, S as MigrationExpectationFailed, s as MigrationNeedsSqlClient, d as MigrationSkipped, zt as REACTIVE_TRIGGER_PREFIX, m as RewriteUnstableError, Si as SCHEMA_OWNER_TABLE, Or as STORE_CHARSET_REMEDY, w as TransactionBrokenByBodyError, Ze as VOLTRO_MIGRATION_LOCK_KEY, _i as _voltroDeploysTable, wc as acceptedBodyHashes, _t as acquireMigrationLock, Ho as addColumnDdl, U as appliedAtValue, Ac as appliedFileMigrationIds, jc as appliedFileMigrations, cs as appliedLedgerOperations, Vn as applyNamespacedSchema, hs as applyPlan, An as applySchema, js as applyUndeclaredCharsetWork, tl as assessRollingDeployGate, ol as branchRehearsalExitCode, Cr as charsetColumnsOf, gl as checkSchemaOwner, Pi as chunkTables, $c as classifyRollingDeploySafety, ls as clearResumeLedger, yi as closeDeploy, ka as columnLevelChecksMysql, xr as columnTakesCharset, Ms as convergeUndeclaredCharset, Xc as createdTablesOf, Nr as declaredSnapshot, Yt as defaultArrayClause, Jt as defaultClause, Xt as defaultJsonClause, qs as describeOutcome, gc as describeProbe, Dr as describeStoreCharsetFinding, Es as describeUndeclaredCharsetWork, bs as describesSchema, Vs as destructiveScope, Fr as detectReactiveTriggerDrift, M as dialectOf, po as emitAddIndexMysql, Wa as emitConvertCharsetMysql, io as emitCreateTableMssql, Ga as emitCreateTableMysql, Ra as emitCreateTablePg, Za as emitCreateTableSqlite, ya as emitDropColumnDdl, ba as emitDropColumnDdlMysql, kn as emitFrameworkBootstrapSql, Dn as emitNamespaceProvisionDdl, On as emitNamespacedSchemaSql, En as emitSchemaSql, $i as engineFromVersion, $o as ensureDeployLedgerTable, Mn as ensureFullTextIndexes, Yo as ensureLedgerTable, Xo as ensurePlanLedgerTable, Qo as ensurePluginMigrationsLedgerTable, es as ensureReplaceMarkerTable, Zo as ensureSchemaOwnerTable, wn as enumRenameBlocks, Cn as enumTypeBlocks, _n as extensionBlocks, bi as failDeploy, hc as failedExpectations, Ps as fetchLastFingerprint, Uc as fileMigrationStatus, I as fingerprintSchema, rt as fnv1a64, vl as foreignOwnerMessage, cl as formatBranchRehearsal, Ir as formatReactiveTriggerDrift, un as fullTextIndexSql, rs as hasInterruptedMigration, Bs as ignoreTablesFromEnv, B as introspectSchema, Se as irreversible, t as irreversibleReason, ia as isAlreadySatisfied, T as isFileMigration, ys as isFileMigrationRow, br as isMysqlCharset, bl as isRawSqlFragment, Nn as isReRunSafeDdl, Ss as isUndeclaredCharsetTable, Ts as isUndeclaredCharsetWorkEmpty, V as limitClause, mc as makeFileMigrationContext, Ti as mapPgType, Xs as materialiseSnapshot, l as migration, St as migrationAtomicityFor, Sc as migrationBodyHash, it as migrationLockKeyForSchema, at as migrationLockNameForSchema, so as mysqlIndexPrefixFor, Wt as notifyFunctionName, Zt as numericIdSql, vi as openDeploy, wi as parseEnumCheck, Vc as pendingFileMigrationIds, Hc as pendingFileMigrationSummary, bc as permanentSkips, gi as planMigrations, ue as plannableLiveTables, yc as plannedCreations, Jc as previewMigrationSquash, Hn as provisionTenantNamespace, Bt as reactiveTriggerName, gn as reactiveTriggerRepairSql, Cl as readMigrationSnapshotCandidates, Os as readUndeclaredCharsetColumns, Fs as recordUpToDate, Je as registerSqlPoolCapacity, al as rehearseMigrationOnBranch, rl as rehearsedOperation, Va as renderColumnMysql, Fa as renderColumnPg, $e as resolveMigrationLockSchema, H as resolveMysqlEngine, Dl as restoreMigrationSnapshots, Kc as rollbackFileBasedMigration, el as rollingDeployUnsafeOps, Wc as runFileBasedMigrations, Un as runFrameworkBootstrap, Bn as runMigrate, vs as runMigrationOp, Ks as runPlannedMigrations, Z as runSchemaOp, vr as shortFingerprint, kr as snapshotColumn, yl as sql, Ye as sqlPoolCapacity, F as sqlType, Yc as squashMigrationPlans, Sr as stampDeclaredCharset, Er as storeCharsetFindings, dl as tenantNamespaceCharsetFindings, _l as transferSchemaOwner, Us as unblockLossy, As as undeclaredCharsetStatements, ws as undeclaredCharsetWork, xi as unfinishedDeploys, Ec as walkMigrationFiles, bt as withMigrationLock, vc as withSchemaProbeRecorder };