@voltro/database 0.36.0 → 0.38.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/dist/sql.js +371 -370
  3. package/package.json +2 -2
package/dist/sql.js CHANGED
@@ -38,20 +38,21 @@ var ie = (e, t, n, r = 400) => {
38
38
  let t = o(e);
39
39
  t !== void 0 && s.push(`db.${e}: ${t}`);
40
40
  }
41
- return s.push(""), s.join("\n");
42
- }, ae = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, oe = (e) => e.replace(/"/g, "`"), se = (e) => typeof e == "string" ? e : e.name ?? String(e), ce = (e, t) => `_ua_${t}_${e}`.slice(0, 64), le = (e, t) => {
43
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(ae)) return e;
41
+ let c = ae(o("code"));
42
+ return c !== void 0 && s.push("", c), s.push(""), s.join("\n");
43
+ }, ae = (e) => e === "3F000" ? "remedy: the connection's search_path names a schema that does not exist. Voltro sets it from DB_SCHEMA — create the schema (`CREATE SCHEMA \"<name>\"`) or unset DB_SCHEMA to use the connection default. Voltro creates TABLES, never the schema itself: that is a namespace decision, and inventing one from a typo is how a migration lands somewhere nobody is looking." : void 0, oe = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, se = (e) => e.replace(/"/g, "`"), ce = (e) => typeof e == "string" ? e : e.name ?? String(e), le = (e, t) => `_ua_${t}_${e}`.slice(0, 64), ue = (e, t) => {
44
+ if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(oe)) return e;
44
45
  let n = { ...e.fields }, r = [], i = [];
45
46
  for (let t of e.appliedIndexes) {
46
- if (!ae(t)) {
47
+ if (!oe(t)) {
47
48
  r.push(t);
48
49
  continue;
49
50
  }
50
- let a = oe(t.where), o = [];
51
+ let a = se(t.where), o = [];
51
52
  for (let r of t.fields) {
52
- let i = se(r);
53
+ let i = ce(r);
53
54
  if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
54
- let s = ce(t.name, i);
55
+ let s = le(t.name, i);
55
56
  o.push(s), n[s] = {
56
57
  type: "text",
57
58
  nullable: !0,
@@ -74,7 +75,7 @@ var ie = (e, t, n, r = 400) => {
74
75
  appliedIndexes: r,
75
76
  appliedUniques: [...e.appliedUniques ?? [], ...i]
76
77
  };
77
- }, w = (e, t) => `${e}::${t}`, ue = (e, t) => {
78
+ }, w = (e, t) => `${e}::${t}`, de = (e, t) => {
78
79
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
79
80
  n.add(e);
80
81
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
@@ -83,21 +84,21 @@ var ie = (e, t, n, r = 400) => {
83
84
  };
84
85
  for (let t of [...e].sort()) r.has(t) || a(t);
85
86
  return i;
86
- }, de = 6322741009312437n, fe = (e) => {
87
+ }, fe = 6322741009312437n, pe = (e) => {
87
88
  let t = e?.trim();
88
89
  return t === void 0 || t === "" || t === "public" ? void 0 : t;
89
- }, pe = (e) => e?.schema === void 0 ? fe(process.env.DB_SCHEMA) : fe(e.schema), me = 14695981039346656037n, he = 1099511628211n, ge = 18446744073709551615n, _e = (e) => {
90
- let t = me;
91
- for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * he & ge;
90
+ }, me = (e) => e?.schema === void 0 ? pe(process.env.DB_SCHEMA) : pe(e.schema), he = 14695981039346656037n, ge = 1099511628211n, _e = 18446744073709551615n, ve = (e) => {
91
+ let t = he;
92
+ for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * ge & _e;
92
93
  return t;
93
- }, ve = (e) => {
94
- let t = fe(e);
95
- return t === void 0 ? de : _e(`voltro_migration_lock:${t}`) & 9223372036854775807n;
96
94
  }, ye = (e) => {
97
- let t = `voltro_migration_${de.toString(36)}`, n = fe(e);
95
+ let t = pe(e);
96
+ return t === void 0 ? fe : ve(`voltro_migration_lock:${t}`) & 9223372036854775807n;
97
+ }, T = (e) => {
98
+ let t = `voltro_migration_${fe.toString(36)}`, n = pe(e);
98
99
  if (n === void 0) return t;
99
100
  let r = `${t}_${n}`;
100
- return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(_e(`voltro_migration_lock:${n}`) & ge).toString(16)}`;
101
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(ve(`voltro_migration_lock:${n}`) & _e).toString(16)}`;
101
102
  }, be = 250, xe = () => {
102
103
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
103
104
  return Number.isFinite(e) && e > 0 ? e : 3e4;
@@ -124,23 +125,23 @@ var ie = (e, t, n, r = 400) => {
124
125
  (n[0]?.res ?? -999) < 0 && (yield* b.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${t}' (sp_getapplock returned ${n[0]?.res ?? "no row"}; another migration is in progress).`)));
125
126
  }), ke = (e, t) => b.gen(function* () {
126
127
  yield* e`EXEC sp_releaseapplock @Resource = ${t}, @LockOwner = 'Session'`;
127
- }), Ae = b.void, T = (e, t) => {
128
- let n = pe(t);
128
+ }), Ae = b.void, E = (e, t) => {
129
+ let n = me(t);
129
130
  return e.onDialectOrElse({
130
- mysql: () => Te(e, ye(n)),
131
- mssql: () => Oe(e, ye(n)),
131
+ mysql: () => Te(e, T(n)),
132
+ mssql: () => Oe(e, T(n)),
132
133
  sqlite: () => Ae,
133
- orElse: () => Se(e, ve(n))
134
+ orElse: () => Se(e, ye(n))
134
135
  });
135
- }, E = (e, t) => {
136
- let n = pe(t);
136
+ }, D = (e, t) => {
137
+ let n = me(t);
137
138
  return e.onDialectOrElse({
138
- mysql: () => Ee(e, ye(n)),
139
- mssql: () => ke(e, ye(n)),
139
+ mysql: () => Ee(e, T(n)),
140
+ mssql: () => ke(e, T(n)),
140
141
  sqlite: () => Ae,
141
- orElse: () => Ce(e, ve(n))
142
+ orElse: () => Ce(e, ye(n))
142
143
  });
143
- }, je = (e, t, n) => b.acquireUseRelease(T(e, n), () => t, () => E(e, n).pipe(b.orDie)), Me = (e) => e.onDialectOrElse({
144
+ }, je = (e, t, n) => b.acquireUseRelease(E(e, n), () => t, () => D(e, n).pipe(b.orDie)), Me = (e) => e.onDialectOrElse({
144
145
  pg: () => "postgres",
145
146
  mysql: () => "mysql",
146
147
  mssql: () => "mssql",
@@ -153,7 +154,7 @@ var ie = (e, t, n, r = 400) => {
153
154
  mariadb: "per-operation",
154
155
  sqlite: "per-operation",
155
156
  turso: "per-operation"
156
- }, Pe = (e) => Ne[e], D = "_voltro_migration_ops", Fe = l(D, {
157
+ }, Pe = (e) => Ne[e], O = "_voltro_migration_ops", Fe = l(O, {
157
158
  id: e({ prefix: "mop" }),
158
159
  runId: _(),
159
160
  planFingerprint: _(),
@@ -216,9 +217,9 @@ var ie = (e, t, n, r = 400) => {
216
217
  Object.keys(Ne);
217
218
  //#endregion
218
219
  //#region src/migrations/reactiveTriggerName.ts
219
- var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "framework_changes" ? `${Ke}${e}` : `${Ke}${t}_${e}`, Je = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Ye = "voltro:notify:v2", Xe = S({ scope: "voltro:migrate" }), k = (e) => {
220
+ var k = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "framework_changes" ? `${Ke}${e}` : `${Ke}${t}_${e}`, Je = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Ye = "voltro:notify:v2", Xe = S({ scope: "voltro:migrate" }), A = (e) => {
220
221
  Xe.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
221
- }, A = (e, t) => {
222
+ }, j = (e, t) => {
222
223
  let n = e.type;
223
224
  if (e.spatial) {
224
225
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -229,7 +230,7 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
229
230
  return e.rawDdl;
230
231
  }
231
232
  if (n === "array" && e.arrayElement) {
232
- if (t === "postgres") return `${A({
233
+ if (t === "postgres") return `${j({
233
234
  ...e,
234
235
  type: e.arrayElement,
235
236
  arrayElement: void 0
@@ -332,19 +333,19 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
332
333
  }, Ze = (e, t) => {
333
334
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
334
335
  let n = e.defaultValue;
335
- return n === "now" ? r(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) ? Qe(n, e, t) : typeof n == "object" && n ? j(n, t) : null;
336
+ return n === "now" ? r(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) ? Qe(n, e, t) : typeof n == "object" && n ? M(n, t) : null;
336
337
  }, Qe = (e, t, n) => {
337
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return j(e, n);
338
- let r = A({
338
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return M(e, n);
339
+ let r = j({
339
340
  ...t,
340
341
  type: t.arrayElement,
341
342
  arrayElement: void 0
342
343
  }, n);
343
344
  return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
344
- }, j = (e, t) => {
345
+ }, M = (e, t) => {
345
346
  let n = JSON.stringify(e).replace(/'/g, "''");
346
347
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CONVERT('${n}' USING utf8mb4))` : `DEFAULT '${n}'`;
347
- }, M = (e, t) => {
348
+ }, N = (e, t) => {
348
349
  switch (t) {
349
350
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
350
351
  case "mysql":
@@ -366,19 +367,19 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
366
367
  if (n !== "mysql" && n !== "mariadb") return r;
367
368
  let a = t[e];
368
369
  if (!a) return r;
369
- let o = A(a, n).toUpperCase();
370
+ let o = j(a, n).toUpperCase();
370
371
  return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${r}(${tt})` : r;
371
372
  }, rt = (e, t) => {
372
373
  if (!e.generatedAs) return null;
373
374
  let { expr: n, stored: r } = e.generatedAs;
374
- if (t === "postgres") return r || k("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
375
+ if (t === "postgres") return r || A("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
375
376
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
376
377
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
377
378
  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.");
378
379
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
379
380
  }, it = (e, t, n, a, o = !1, s = !1) => {
380
- if (t.type === "id" && t.idScheme?.kind === "numeric") return M(e, n);
381
- let c = n === "mssql" && t.type === "text" && !t.generatedAs && t.maxLength === void 0 && a?.has(e) ? "NVARCHAR(450)" : A(t, n), l = [i(e, n), c];
381
+ if (t.type === "id" && t.idScheme?.kind === "numeric") return N(e, n);
382
+ let c = n === "mssql" && t.type === "text" && !t.generatedAs && t.maxLength === void 0 && a?.has(e) ? "NVARCHAR(450)" : j(t, n), l = [i(e, n), c];
382
383
  t.type === "id" && !s && l.push("PRIMARY KEY");
383
384
  let u = rt(t, n);
384
385
  if (u) l.push(u);
@@ -445,21 +446,21 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
445
446
  using: " USING GIST",
446
447
  withSuffix: "",
447
448
  skip: !1
448
- } : (k(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
449
+ } : (A(`[voltro:migrate] index '${e}' on '${n}': ${t} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
449
450
  if (r === "gin") return t === "postgres" ? {
450
451
  using: " USING GIN",
451
452
  withSuffix: "",
452
453
  skip: !1
453
- } : t === "mysql" || t === "mariadb" ? (k(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
454
+ } : t === "mysql" || t === "mariadb" ? (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
454
455
  using: "",
455
456
  withSuffix: "",
456
457
  skip: !0
457
- }) : (k(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
458
+ }) : (A(`[voltro:migrate] gin index '${e}' on '${n}': ${t} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
458
459
  if (r === "brin") return t === "postgres" ? {
459
460
  using: " USING BRIN",
460
461
  withSuffix: "",
461
462
  skip: !1
462
- } : (k(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
463
+ } : (A(`[voltro:migrate] brin index '${e}' on '${n}': ${t} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
463
464
  if (r === "hnsw") {
464
465
  if (t === "postgres") {
465
466
  let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? y(i?.hnsw?.distance);
@@ -470,7 +471,7 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
470
471
  skip: !1
471
472
  };
472
473
  }
473
- return k(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
474
+ return A(`[voltro:migrate] hnsw index '${e}' on '${n}': ${t} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
474
475
  using: "",
475
476
  withSuffix: "",
476
477
  skip: !0
@@ -503,15 +504,15 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
503
504
  let a = n.columns.map((e) => i(e, t)).join(", ");
504
505
  r.push(`CREATE FULLTEXT INDEX ${i(n.name, t)} ON ${i(e.tableName, t)} (${a});`);
505
506
  } else if (t === "turso") throw Error(`@voltro/sql-turso: full-text index '${n.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
506
- else t === "sqlite" ? r.push(...ot(e.tableName, n, t)) : k(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
507
+ else t === "sqlite" ? r.push(...ot(e.tableName, n, t)) : A(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
507
508
  for (let n of e.appliedIndexes) {
508
509
  if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
509
- k(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
510
+ A(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
510
511
  continue;
511
512
  }
512
513
  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.`);
513
514
  let i = "";
514
- n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? k(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : i = ` WHERE ${n.where}`);
515
+ n.where !== void 0 && n.where.length > 0 && (t === "mysql" || t === "mariadb" ? A(`[voltro:migrate] partial index '${n.name}' on '${e.tableName}': ${t} does not support WHERE clauses on indexes — emitting a full index`) : i = ` WHERE ${n.where}`);
515
516
  let s = l(n.name, e.tableName, n.fields, n.kind, n.kindOptions, i, n.unique === !0);
516
517
  s !== "" && r.push(s), n.fields.every((e) => typeof e == "string") && a.add(o(n.fields));
517
518
  }
@@ -521,7 +522,7 @@ var O = "framework_changes", Ke = "framework_changes_", qe = (e, t) => t === "fr
521
522
  r.push(l(i, e.tableName, [t])), a.add(o([t]));
522
523
  }
523
524
  return r.join("\n");
524
- }, ct = (e, t, n = O) => {
525
+ }, ct = (e, t, n = k) => {
525
526
  if (t !== "postgres") return [];
526
527
  let r = e.filter((e) => e.isReactive !== !1);
527
528
  return r.length === 0 ? [] : [lt(n), ...r.map((e) => dt(e, n))];
@@ -600,7 +601,7 @@ $$ LANGUAGE plpgsql;
600
601
  for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${qe(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
601
602
  return r;
602
603
  }, pt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), mt = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), ht = (e) => {
603
- let t = new Map(e.map((e) => [e.tableName, e])), n = ue(e.map((e) => e.tableName), (e) => {
604
+ let t = new Map(e.map((e) => [e.tableName, e])), n = de(e.map((e) => e.tableName), (e) => {
604
605
  let n = t.get(e);
605
606
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
606
607
  if (n.type !== "reference" || !n.references) return [];
@@ -696,8 +697,8 @@ BEGIN
696
697
  tables: t,
697
698
  views: n
698
699
  };
699
- }, xt = (e, t, n = O) => {
700
- let { tables: i, views: o } = bt(e), { sorted: s, cyclic: c } = ht(i.map((e) => le(e, t))), l = _t(c, t), u = [];
700
+ }, xt = (e, t, n = k) => {
701
+ let { tables: i, views: o } = bt(e), { sorted: s, cyclic: c } = ht(i.map((e) => ue(e, t))), l = _t(c, t), u = [];
701
702
  t === "postgres" && pt(s) && u.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && mt(s) && u.push("CREATE EXTENSION IF NOT EXISTS postgis;");
702
703
  let d = yt(s, t);
703
704
  d && u.push(d);
@@ -734,7 +735,7 @@ BEGIN
734
735
  r && d.push(r);
735
736
  }
736
737
  return d.join("\n\n") + "\n";
737
- }, wt = (e, t, n = O) => {
738
+ }, wt = (e, t, n = k) => {
738
739
  let { sorted: r, cyclic: i } = ht(e), a = _t(i, t), o = [], s = yt(r, t);
739
740
  s && o.push(s);
740
741
  let c = vt(r, t);
@@ -742,7 +743,7 @@ BEGIN
742
743
  for (let e of r) o.push(at(e, t, null, a.get(e.tableName)));
743
744
  for (let e of i) o.push(gt(e, t));
744
745
  return o.push(...ct(r, t, n)), o.join("\n\n") + "\n";
745
- }, Tt = (e, t = "postgres", n = O, r = {}) => b.gen(function* () {
746
+ }, Tt = (e, t = "postgres", n = k, r = {}) => b.gen(function* () {
746
747
  let i = yield* C.SqlClient;
747
748
  yield* je(i, Mt(i, xt(e, t, n), t, r.retryFilter), { schema: r.lockSchema }).pipe(b.orDie);
748
749
  }), Et = (e, t) => {
@@ -825,10 +826,10 @@ BEGIN
825
826
  name: e.name,
826
827
  columns: Bt(e.columns),
827
828
  indexes: Vt(e.indexes)
828
- })).sort((e, t) => e.name.localeCompare(t.name)), N = (e) => {
829
+ })).sort((e, t) => e.name.localeCompare(t.name)), P = (e) => {
829
830
  let t = { tables: Ht(e.tables) }, n = JSON.stringify(Rt(t));
830
831
  return ee("sha256").update(n).digest("hex");
831
- }, P = (e) => e.slice(0, 16), Ut = (e, t) => {
832
+ }, F = (e) => e.slice(0, 16), Ut = (e, t) => {
832
833
  let n = t.references ? {
833
834
  table: t.references().tableName,
834
835
  column: "id",
@@ -940,10 +941,10 @@ BEGIN
940
941
  if (r !== void 0 && r !== n.name) throw Error(`duplicate index name '${e.name}' across tables '${r}' and '${n.name}'. Index names must be unique per SCHEMA, not just per table — the DB creates only one, so the other never applies and 'db plan' re-emits it forever. Give each an explicit, table-prefixed name (e.g. '${n.name}_${e.name}').`);
941
942
  t.set(e.name, n.name);
942
943
  }
943
- }, F = (e, t) => {
944
- let n = e.map((e) => Gt(le(e, t)));
944
+ }, I = (e, t) => {
945
+ let n = e.map((e) => Gt(ue(e, t)));
945
946
  return Kt(n), { tables: n };
946
- }, qt = (e, t, n = O) => b.gen(function* () {
947
+ }, qt = (e, t, n = k) => b.gen(function* () {
947
948
  let r = (yield* e`
948
949
  SELECT p.prosrc
949
950
  FROM pg_proc p
@@ -1017,29 +1018,29 @@ BEGIN
1017
1018
  snapshot: n.get(e.tableName),
1018
1019
  columnDefs: e.fields
1019
1020
  }]));
1020
- }, I = (e) => {
1021
+ }, L = (e) => {
1021
1022
  if (typeof e != "object" || !e) return JSON.stringify(e);
1022
- if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
1023
+ if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1023
1024
  let t = e;
1024
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
1025
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1025
1026
  }, $t = (e) => {
1026
1027
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1027
1028
  let t = e.defaultValue;
1028
1029
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1029
1030
  if (typeof t == "number") return String(t);
1030
- if (typeof t != "string") return I(t);
1031
+ if (typeof t != "string") return L(t);
1031
1032
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1032
1033
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1033
1034
  let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
1034
1035
  if (o) try {
1035
- return I(JSON.parse(o[1]));
1036
+ return L(JSON.parse(o[1]));
1036
1037
  } catch {}
1037
1038
  let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1038
1039
  if (s) try {
1039
- return I(JSON.parse(s[1]));
1040
+ return L(JSON.parse(s[1]));
1040
1041
  } catch {}
1041
1042
  if (a.startsWith("{") || a.startsWith("[")) try {
1042
- return I(JSON.parse(a));
1043
+ return L(JSON.parse(a));
1043
1044
  } catch {}
1044
1045
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1045
1046
  }, en = (e, t) => {
@@ -1064,12 +1065,12 @@ BEGIN
1064
1065
  return i.every((e, t) => e === a[t]);
1065
1066
  }, rn = (e, t) => {
1066
1067
  try {
1067
- let n = /\((\d+)\)/.exec(A(e, t));
1068
+ let n = /\((\d+)\)/.exec(j(e, t));
1068
1069
  return n ? Number(n[1]) : void 0;
1069
1070
  } catch {
1070
1071
  return;
1071
1072
  }
1072
- }, an = (e, t, n) => n === void 0 || r(n) ? !0 : e.type !== "text" || t.type !== "text" || rn(e, n) === t.maxLength, on = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && en(e, t) && an(e, t, n) && JSON.stringify(tn(e.references)) === JSON.stringify(tn(t.references)) && nn(e.oneOf, t.oneOf), sn = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
1073
+ }, an = (e, t, n) => n === void 0 || r(n) ? !0 : e.type !== "text" || t.type !== "text" || rn(e, n) === t.maxLength, on = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && en(e, t) && an(e, t, n) && JSON.stringify(tn(e.references)) === JSON.stringify(tn(t.references)) && nn(e.oneOf, t.oneOf), sn = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1073
1074
  kind: "add-check",
1074
1075
  table: e,
1075
1076
  column: t.name,
@@ -1104,7 +1105,7 @@ BEGIN
1104
1105
  added: i,
1105
1106
  removed: a
1106
1107
  };
1107
- }, L = (e, t, n, r) => ({
1108
+ }, R = (e, t, n, r) => ({
1108
1109
  op: e,
1109
1110
  classification: t,
1110
1111
  atomicByDialect: Zt(e.kind),
@@ -1116,21 +1117,21 @@ BEGIN
1116
1117
  table: e,
1117
1118
  column: t
1118
1119
  };
1119
- return t.nullable ? L(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? L(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? L(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : L(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1120
+ return t.nullable ? R(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? R(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? R(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : R(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1120
1121
  }, fn = (e, t, n) => {
1121
1122
  let r = {
1122
1123
  kind: "drop-column",
1123
1124
  table: e,
1124
1125
  column: t.name
1125
1126
  };
1126
- return n?.dropped ? L(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : L(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1127
- }, pn = (e, t, n, r, i) => L({
1127
+ return n?.dropped ? R(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : R(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1128
+ }, pn = (e, t, n, r, i) => R({
1128
1129
  kind: "create-table",
1129
1130
  table: e,
1130
1131
  columns: t,
1131
1132
  indexes: n,
1132
1133
  ...r && r.length > 0 ? { primaryKey: r } : {}
1133
- }, "safe", i ?? "new table — no data to preserve"), mn = (e) => L({
1134
+ }, "safe", i ?? "new table — no data to preserve"), mn = (e) => R({
1134
1135
  kind: "drop-table",
1135
1136
  table: e
1136
1137
  }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), hn = 5e4, gn = (e, t, n, r) => {
@@ -1148,12 +1149,12 @@ BEGIN
1148
1149
  kind: "add-index",
1149
1150
  table: e,
1150
1151
  index: t
1151
- }, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1152
- }, _n = (e, t) => t.unique && t.columns.length > 1 ? L({
1152
+ }, i ? R(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1153
+ }, _n = (e, t) => t.unique && t.columns.length > 1 ? R({
1153
1154
  kind: "drop-unique-composite",
1154
1155
  table: e,
1155
1156
  name: t.name
1156
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
1157
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
1157
1158
  kind: "drop-index",
1158
1159
  table: e,
1159
1160
  index: t.name
@@ -1174,7 +1175,7 @@ BEGIN
1174
1175
  column: t.name,
1175
1176
  toNullable: t.nullable
1176
1177
  };
1177
- s.push(t.nullable ? L(n, "safe", `loosen ${e}.${t.name} to nullable`) : L(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1178
+ s.push(t.nullable ? R(n, "safe", `loosen ${e}.${t.name} to nullable`) : R(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1178
1179
  }
1179
1180
  if (t.unique !== n.unique) if (t.unique) {
1180
1181
  let n = {
@@ -1182,8 +1183,8 @@ BEGIN
1182
1183
  table: e,
1183
1184
  column: t.name
1184
1185
  }, r = (a ?? 0) >= o;
1185
- s.push(r ? L(n, "online-required", `online unique build on ${a} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1186
- } else s.push(L({
1186
+ s.push(r ? R(n, "online-required", `online unique build on ${a} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1187
+ } else s.push(R({
1187
1188
  kind: "drop-unique",
1188
1189
  table: e,
1189
1190
  column: t.name
@@ -1199,7 +1200,7 @@ BEGIN
1199
1200
  to: t.type,
1200
1201
  ...r.using === void 0 ? {} : { using: r.using }
1201
1202
  };
1202
- s.push(L(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1203
+ s.push(R(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1203
1204
  } else {
1204
1205
  let r = {
1205
1206
  kind: "alter-column-type",
@@ -1208,12 +1209,12 @@ BEGIN
1208
1209
  from: n.type,
1209
1210
  to: t.type
1210
1211
  };
1211
- s.push(L(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1212
+ s.push(R(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1212
1213
  }
1213
1214
  }
1214
1215
  if (t.type === "text" && n.type === "text" && !r(i ?? "postgres") && t.maxLength !== n.maxLength) {
1215
1216
  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})`;
1216
- s.push(L({
1217
+ s.push(R({
1217
1218
  kind: "alter-column-type",
1218
1219
  table: e,
1219
1220
  column: t.name,
@@ -1229,10 +1230,10 @@ BEGIN
1229
1230
  hasDefault: t.hasDefault,
1230
1231
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1231
1232
  };
1232
- s.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1233
+ s.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1233
1234
  }
1234
1235
  if (!nn(t.oneOf, n.oneOf)) {
1235
- n.oneOf && n.oneOf.length > 0 && s.push(L({
1236
+ n.oneOf && n.oneOf.length > 0 && s.push(R({
1236
1237
  kind: "drop-check",
1237
1238
  table: e,
1238
1239
  column: t.name
@@ -1240,7 +1241,7 @@ BEGIN
1240
1241
  let r = sn(e, t);
1241
1242
  r && s.push(r);
1242
1243
  }
1243
- return JSON.stringify(tn(t.references)) !== JSON.stringify(tn(n.references)) && (n.references && s.push(L({
1244
+ return JSON.stringify(tn(t.references)) !== JSON.stringify(tn(n.references)) && (n.references && s.push(R({
1244
1245
  kind: "drop-foreign-key",
1245
1246
  table: e,
1246
1247
  column: t.name
@@ -1257,15 +1258,15 @@ BEGIN
1257
1258
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1258
1259
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1259
1260
  };
1260
- return i === "null" && !t.nullable ? n.push(L(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(L({
1261
+ return i === "null" && !t.nullable ? n.push(R(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(R({
1261
1262
  ...a,
1262
1263
  orphanPolicy: i
1263
- }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(L(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1264
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(R(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1264
1265
  }, xn = (e, t, n) => {
1265
1266
  let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = new Set(n.removed.map((e) => e.name)), s = new Set(n.added.map((e) => e.name));
1266
1267
  for (let [n, c] of Object.entries(t)) {
1267
1268
  let t = c.renamedFrom;
1268
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1269
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1269
1270
  kind: "rename-column",
1270
1271
  table: e.tableName,
1271
1272
  from: t,
@@ -1296,7 +1297,7 @@ BEGIN
1296
1297
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1297
1298
  if (r.length !== 1) continue;
1298
1299
  let i = r[0];
1299
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(L({
1300
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1300
1301
  kind: "rename-index",
1301
1302
  table: e,
1302
1303
  from: n.name,
@@ -1319,7 +1320,7 @@ BEGIN
1319
1320
  continue;
1320
1321
  }
1321
1322
  if (t.has(c.name)) {
1322
- r.push(L({
1323
+ r.push(R({
1323
1324
  kind: "rename-table",
1324
1325
  from: e,
1325
1326
  to: c.name
@@ -1327,14 +1328,14 @@ BEGIN
1327
1328
  continue;
1328
1329
  }
1329
1330
  if ((s.get(e) ?? 0) !== 1) {
1330
- r.push(L({
1331
+ r.push(R({
1331
1332
  kind: "rename-table",
1332
1333
  from: e,
1333
1334
  to: c.name
1334
1335
  }, "needs-rename-annotation", `.renamedFrom('${e}') is claimed by ${s.get(e)} tables — nothing says which receives its rows`, { fix: `remove the \`.renamedFrom('${e}')\` marker from all but one of them.` }));
1335
1336
  continue;
1336
1337
  }
1337
- i.set(c.name, e), a.add(e), r.push(L({
1338
+ i.set(c.name, e), a.add(e), r.push(R({
1338
1339
  kind: "rename-table",
1339
1340
  from: e,
1340
1341
  to: c.name
@@ -1360,7 +1361,7 @@ BEGIN
1360
1361
  ...e,
1361
1362
  name: r,
1362
1363
  table: n
1363
- } : i ? (a.push(L({
1364
+ } : i ? (a.push(R({
1364
1365
  kind: "rename-index",
1365
1366
  table: n,
1366
1367
  from: e.name,
@@ -1415,7 +1416,7 @@ BEGIN
1415
1416
  }
1416
1417
  return t;
1417
1418
  }, kn = (e) => {
1418
- let t = F(e.declared, e.dialect), n = Qt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? hn, a = [], o = En(t, r, n);
1419
+ let t = I(e.declared, e.dialect), n = Qt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? hn, a = [], o = En(t, r, n);
1419
1420
  a.push(...o.ops);
1420
1421
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1421
1422
  a.push(pn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
@@ -1457,8 +1458,8 @@ BEGIN
1457
1458
  column: e.name,
1458
1459
  target: e.references.table
1459
1460
  }] : []) : [];
1460
- }, d = ue([...c], u), f = [];
1461
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(L({
1461
+ }, d = de([...c], u), f = [];
1462
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(R({
1462
1463
  kind: "add-foreign-key",
1463
1464
  table: e.name,
1464
1465
  column: t.name,
@@ -1530,8 +1531,8 @@ BEGIN
1530
1531
  });
1531
1532
  return {
1532
1533
  operations: S,
1533
- fromFingerprint: N(e.live),
1534
- toFingerprint: N(t),
1534
+ fromFingerprint: P(e.live),
1535
+ toFingerprint: P(t),
1535
1536
  summary: On(S)
1536
1537
  };
1537
1538
  }, An = (e) => {
@@ -1569,7 +1570,7 @@ BEGIN
1569
1570
  case "USER-DEFINED": return "text";
1570
1571
  default: return "text";
1571
1572
  }
1572
- }, R = (e) => {
1573
+ }, z = (e) => {
1573
1574
  switch (e.toUpperCase()) {
1574
1575
  case "CASCADE": return "cascade";
1575
1576
  case "RESTRICT": return "restrict";
@@ -1742,13 +1743,13 @@ BEGIN
1742
1743
  let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : jn(t.data_type, t.udt_name), c = a ? {
1743
1744
  table: a.target_table,
1744
1745
  column: a.target_column,
1745
- onDelete: R(a.delete_rule),
1746
- onUpdate: R(a.update_rule)
1746
+ onDelete: z(a.delete_rule),
1747
+ onUpdate: z(a.update_rule)
1747
1748
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1748
1749
  return {
1749
1750
  name: t.column_name,
1750
1751
  type: s,
1751
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1752
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1752
1753
  nullable: t.is_nullable === "YES",
1753
1754
  unique: i.has(t.column_name) || n && t.column_name === "id",
1754
1755
  hasDefault: t.column_default !== null,
@@ -1825,21 +1826,21 @@ BEGIN
1825
1826
  case "json": return "json";
1826
1827
  default: return "text";
1827
1828
  }
1828
- }, z = (e) => e.map((e) => {
1829
+ }, B = (e) => e.map((e) => {
1829
1830
  let t = e, n = {};
1830
1831
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1831
1832
  return n;
1832
1833
  }), zn = (e) => b.gen(function* () {
1833
- let t = z(yield* e`
1834
+ let t = B(yield* e`
1834
1835
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1835
1836
  FROM information_schema.tables
1836
1837
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1837
- ORDER BY table_name`), n = z(yield* e`
1838
+ ORDER BY table_name`), n = B(yield* e`
1838
1839
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1839
1840
  character_maximum_length
1840
1841
  FROM information_schema.columns
1841
1842
  WHERE table_schema = DATABASE()
1842
- ORDER BY table_name, ordinal_position`), r = z(yield* e`
1843
+ ORDER BY table_name, ordinal_position`), r = B(yield* e`
1843
1844
  SELECT k.table_name AS source_table,
1844
1845
  k.column_name AS source_column,
1845
1846
  k.referenced_table_name AS target_table,
@@ -1849,11 +1850,11 @@ BEGIN
1849
1850
  JOIN information_schema.referential_constraints r
1850
1851
  ON k.constraint_name = r.constraint_name
1851
1852
  AND k.table_schema = r.constraint_schema
1852
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
1853
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = B(yield* e`
1853
1854
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1854
1855
  FROM information_schema.statistics
1855
1856
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1856
- ORDER BY table_name, index_name, seq_in_index`), a = z(yield* e`
1857
+ ORDER BY table_name, index_name, seq_in_index`), a = B(yield* e`
1857
1858
  SELECT table_name, check_clause
1858
1859
  FROM information_schema.check_constraints
1859
1860
  WHERE constraint_schema = DATABASE()`.unprepared.pipe(b.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
@@ -1889,14 +1890,14 @@ BEGIN
1889
1890
  let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Rn(t.data_type, t.column_type), u = c ? {
1890
1891
  table: c.target_table,
1891
1892
  column: c.target_column,
1892
- onDelete: R(c.delete_rule),
1893
- onUpdate: R(c.update_rule)
1893
+ onDelete: z(c.delete_rule),
1894
+ onUpdate: z(c.update_rule)
1894
1895
  } : void 0, d = a.has(t.column_name) || n && t.column_name === "id", f = t.column_default === "NULL" ? null : t.column_default, p = s.get(`${e.table_name}.${t.column_name}`);
1895
1896
  return {
1896
1897
  name: t.column_name,
1897
1898
  type: l,
1898
1899
  nullable: t.is_nullable === "YES",
1899
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
1900
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1900
1901
  unique: d,
1901
1902
  hasDefault: f !== null,
1902
1903
  ...f === null ? {} : { defaultValue: f },
@@ -1951,8 +1952,8 @@ BEGIN
1951
1952
  let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Bn(e.type), a = r ? {
1952
1953
  table: r.table,
1953
1954
  column: r.to,
1954
- onDelete: R(r.on_delete),
1955
- onUpdate: R(r.on_update)
1955
+ onDelete: z(r.on_delete),
1956
+ onUpdate: z(r.on_update)
1956
1957
  } : void 0, o = t.get(e.name);
1957
1958
  return {
1958
1959
  name: e.name,
@@ -2009,7 +2010,7 @@ BEGIN
2009
2010
  case "image": return "bytes";
2010
2011
  default: return "text";
2011
2012
  }
2012
- }, B = (e) => e === !0 || e === 1, Un = (e) => b.gen(function* () {
2013
+ }, V = (e) => e === !0 || e === 1, Un = (e) => b.gen(function* () {
2013
2014
  let t = yield* e`
2014
2015
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2015
2016
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -2066,8 +2067,8 @@ BEGIN
2066
2067
  let t = s.get(e) ?? [], n = c.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = new Set(n.map((e) => e.source_column)), a = l.get(e), d = [], f = /* @__PURE__ */ new Set();
2067
2068
  if (a) for (let [, e] of a) {
2068
2069
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2069
- if (B(t[0].is_primary)) for (let e of t) d.push(e.column_name);
2070
- else B(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
2070
+ if (V(t[0].is_primary)) for (let e of t) d.push(e.column_name);
2071
+ else V(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
2071
2072
  }
2072
2073
  let p = t.map((t) => {
2073
2074
  let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Hn(t.data_type), s = i ? {
@@ -2080,7 +2081,7 @@ BEGIN
2080
2081
  name: t.column_name,
2081
2082
  type: a,
2082
2083
  nullable: t.is_nullable === "YES",
2083
- ...V(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: V(t.data_type, t.character_maximum_length) },
2084
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2084
2085
  unique: f.has(t.column_name) || n && t.column_name === "id",
2085
2086
  hasDefault: c !== null,
2086
2087
  ...c === null ? {} : { defaultValue: c },
@@ -2090,11 +2091,11 @@ BEGIN
2090
2091
  }), m = [];
2091
2092
  if (a) for (let [t, n] of a) {
2092
2093
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2093
- B(r[0].is_primary) || r.length === 1 && B(r[0].is_unique) || r.length === 1 && !B(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
2094
+ V(r[0].is_primary) || r.length === 1 && V(r[0].is_unique) || r.length === 1 && !V(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
2094
2095
  name: t,
2095
2096
  table: e,
2096
2097
  columns: r.map((e) => e.column_name),
2097
- unique: B(r[0].is_unique)
2098
+ unique: V(r[0].is_unique)
2098
2099
  });
2099
2100
  }
2100
2101
  d.length > 0 && m.push({
@@ -2127,11 +2128,11 @@ BEGIN
2127
2128
  "char",
2128
2129
  "character",
2129
2130
  "nchar"
2130
- ]), V = (e, t) => {
2131
+ ]), H = (e, t) => {
2131
2132
  if (!Kn.has(e.toLowerCase())) return;
2132
2133
  let n = Number(t);
2133
2134
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2134
- }, qn = /* @__PURE__ */ new Set([D]), Jn = (e) => e.onDialectOrElse({
2135
+ }, qn = /* @__PURE__ */ new Set([O]), Jn = (e) => e.onDialectOrElse({
2135
2136
  mysql: () => zn(e),
2136
2137
  mssql: () => Un(e),
2137
2138
  sqlite: () => Vn(e),
@@ -2139,14 +2140,14 @@ BEGIN
2139
2140
  }).pipe(b.map((e) => ({
2140
2141
  ...e,
2141
2142
  tables: e.tables.filter((e) => !qn.has(e.name))
2142
- }))), H = (e, t) => e.onDialectOrElse({
2143
+ }))), U = (e, t) => e.onDialectOrElse({
2143
2144
  mysql: () => b.succeed(t.replace("T", " ").replace("Z", "")),
2144
2145
  orElse: () => b.succeed(t)
2145
2146
  }), Yn = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, Xn = (e, t) => {
2146
2147
  if (!(e.type === "text" && e.maxLength !== void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2147
2148
  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;
2148
2149
  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.`);
2149
- return A(e, t);
2150
+ return j(e, t);
2150
2151
  }, Zn = (e) => {
2151
2152
  let t = Xn(e, "postgres");
2152
2153
  return t === void 0 ? Qn(e) : t;
@@ -2192,57 +2193,57 @@ BEGIN
2192
2193
  case "interval": return "BIGINT";
2193
2194
  case "raw": return e.rawDdl ?? "LONGTEXT";
2194
2195
  }
2195
- }, U = (e) => `"${e}"`, W = (e) => `\`${e.replace(/`/g, "``")}\``, er = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, tr = (e) => `ALTER TABLE ${W(e.table)} DROP COLUMN IF EXISTS ${W(e.column)}, ALGORITHM=COPY;`, nr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, rr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Or(t)}`)};`, ir = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${ar(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, ar = (e, t) => {
2196
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, er = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, tr = (e) => `ALTER TABLE ${G(e.table)} DROP COLUMN IF EXISTS ${G(e.column)}, ALGORITHM=COPY;`, nr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, rr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${kr(t)}`)};`, ir = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${ar(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, ar = (e, t) => {
2196
2197
  let n = t(e.defaultValue);
2197
2198
  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.`);
2198
2199
  return n;
2199
- }, G = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], or = (e, t, n) => {
2200
- let r = G(e, t, n);
2200
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], or = (e, t, n) => {
2201
+ let r = K(e, t, n);
2201
2202
  return r ? Ut(n, r) : void 0;
2202
2203
  }, sr = (e, t, n) => {
2203
2204
  let r = n ?? e.nullable, i = Ze(e, "mariadb");
2204
2205
  return [
2205
- W(t),
2206
- A(e, "mariadb"),
2206
+ G(t),
2207
+ j(e, "mariadb"),
2207
2208
  r ? null : "NOT NULL",
2208
2209
  i
2209
2210
  ].filter(Boolean).join(" ");
2210
- }, cr = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? j(e, "mariadb") : null, lr = (e, t, n) => Qe(e, t ?? { type: "json" }, n), ur = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? j(e, "postgres") : null, K = (e, t) => {
2211
+ }, cr = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, lr = (e, t, n) => Qe(e, t ?? { type: "json" }, n), ur = (e, t) => e == null ? null : Array.isArray(e) ? lr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, q = (e, t) => {
2211
2212
  if (!e.generatedAs) return null;
2212
2213
  let { expr: n, stored: r } = e.generatedAs;
2213
2214
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2214
2215
  }, dr = (e) => {
2215
- if (e.type === "id" && e.idScheme?.kind === "numeric") return M(e.name, "postgres");
2216
- let t = K(e, "postgres");
2217
- if (t) return `${U(e.name)} ${Zn(e)} ${t}`;
2218
- let n = [U(e.name), Zn(e)];
2216
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2217
+ let t = q(e, "postgres");
2218
+ if (t) return `${W(e.name)} ${Zn(e)} ${t}`;
2219
+ let n = [W(e.name), Zn(e)];
2219
2220
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2220
2221
  let t = ur(e.defaultValue, e);
2221
2222
  t && n.push(t);
2222
2223
  }
2223
- return e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2224
+ return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2224
2225
  cascade: "CASCADE",
2225
2226
  restrict: "RESTRICT",
2226
2227
  setNull: "SET NULL",
2227
2228
  noAction: "NO ACTION"
2228
2229
  }[e.references.onDelete]}`)), n.join(" ");
2229
2230
  }, fr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", pr = (e) => {
2230
- let t = e.columns.map((e) => ` ${dr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${fr(e, U)}\n)`];
2231
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e.table)} (${t.columns.map(Nr).join(", ")})`);
2231
+ let t = e.columns.map((e) => ` ${dr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${fr(e, W)}\n)`];
2232
+ 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(Pr).join(", ")})`);
2232
2233
  return n;
2233
2234
  }, mr = 191, hr = (e) => {
2234
2235
  let t = $n(e).toUpperCase();
2235
2236
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2236
2237
  }, gr = (e) => {
2237
- if (e.type === "id" && e.idScheme?.kind === "numeric") return M(e.name, "mariadb");
2238
- let t = K(e, "mariadb");
2239
- if (t) return `${W(e.name)} ${$n(e)} ${t}`;
2240
- let n = [W(e.name), $n(e)];
2238
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2239
+ let t = q(e, "mariadb");
2240
+ if (t) return `${G(e.name)} ${$n(e)} ${t}`;
2241
+ let n = [G(e.name), $n(e)];
2241
2242
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !hr(e) && n.push("UNIQUE"), e.hasDefault) {
2242
2243
  let t = cr(e.defaultValue, e);
2243
2244
  t && n.push(t);
2244
2245
  }
2245
- return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2246
+ return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2246
2247
  cascade: "CASCADE",
2247
2248
  restrict: "RESTRICT",
2248
2249
  setNull: "SET NULL",
@@ -2250,11 +2251,11 @@ BEGIN
2250
2251
  }[e.references.onDelete]}`)), n.join(" ");
2251
2252
  }, _r = (e) => {
2252
2253
  let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
2253
- let n = jr(t.get(e));
2254
- return n === void 0 ? W(e) : `${W(e)}(${n})`;
2255
- }, r = e.columns.map((e) => ` ${gr(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${r}${fr(e, n)}\n)`];
2256
- for (let t of e.columns) t.unique && t.type !== "id" && hr(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${W(`${e.table}_${t.name}_key`)} ON ${W(e.table)} (${n(t.name)})`);
2257
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(n).join(", ")})`);
2254
+ let n = Mr(t.get(e));
2255
+ return n === void 0 ? G(e) : `${G(e)}(${n})`;
2256
+ }, r = e.columns.map((e) => ` ${gr(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${r}${fr(e, n)}\n)`];
2257
+ for (let t of e.columns) t.unique && t.type !== "id" && hr(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${G(`${e.table}_${t.name}_key`)} ON ${G(e.table)} (${n(t.name)})`);
2258
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(n).join(", ")})`);
2258
2259
  return i;
2259
2260
  }, vr = {
2260
2261
  cascade: "CASCADE",
@@ -2278,52 +2279,52 @@ BEGIN
2278
2279
  case "bytes": return "BLOB";
2279
2280
  default: return "TEXT";
2280
2281
  }
2281
- }, q = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? j(e, "sqlite") : null, xr = (e) => {
2282
- if (e.type === "id" && e.idScheme?.kind === "numeric") return M(e.name, "sqlite");
2283
- let t = K(e, "sqlite");
2284
- if (t) return `${U(e.name)} ${br(e)} ${t}`;
2285
- let n = [U(e.name), br(e)];
2282
+ }, xr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Sr = (e) => {
2283
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2284
+ let t = q(e, "sqlite");
2285
+ if (t) return `${W(e.name)} ${br(e)} ${t}`;
2286
+ let n = [W(e.name), br(e)];
2286
2287
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2287
- let t = q(e.defaultValue, "CURRENT_TIMESTAMP");
2288
+ let t = xr(e.defaultValue, "CURRENT_TIMESTAMP");
2288
2289
  t && n.push(t);
2289
2290
  }
2290
- if (e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${vr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2291
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${vr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2291
2292
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2292
- n.push(`CHECK (${U(e.name)} IN (${t}))`);
2293
+ n.push(`CHECK (${W(e.name)} IN (${t}))`);
2293
2294
  }
2294
2295
  return n.join(" ");
2295
- }, Sr = (e) => {
2296
- let t = e.columns.map((e) => ` ${xr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${fr(e, U)}\n)`];
2297
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e.table)} (${t.columns.map(U).join(", ")})`);
2296
+ }, Cr = (e) => {
2297
+ let t = e.columns.map((e) => ` ${Sr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${fr(e, W)}\n)`];
2298
+ 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(", ")})`);
2298
2299
  return n;
2299
2300
  }, J = (e, t) => {
2300
2301
  let n = t.find((t) => t.tableName === e);
2301
2302
  if (!n) return [];
2302
- let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => U(e.name)).join(", "), o = [
2303
- ...Sr({
2303
+ let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2304
+ ...Cr({
2304
2305
  kind: "create-table",
2305
2306
  table: i,
2306
2307
  columns: r.columns,
2307
2308
  indexes: [],
2308
2309
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
2309
2310
  }),
2310
- `INSERT INTO ${U(i)} (${a}) SELECT ${a} FROM ${U(e)}`,
2311
- `DROP TABLE ${U(e)}`,
2312
- `ALTER TABLE ${U(i)} RENAME TO ${U(e)}`
2311
+ `INSERT INTO ${W(i)} (${a}) SELECT ${a} FROM ${W(e)}`,
2312
+ `DROP TABLE ${W(e)}`,
2313
+ `ALTER TABLE ${W(i)} RENAME TO ${W(e)}`
2313
2314
  ];
2314
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e)} (${t.columns.map(U).join(", ")})`);
2315
+ for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e)} (${t.columns.map(W).join(", ")})`);
2315
2316
  return o;
2316
- }, Cr = (e, t, n, r) => {
2317
+ }, wr = (e, t, n, r) => {
2317
2318
  let i = r ?? e.nullable;
2318
- return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${A(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2319
- }, wr = (e) => {
2319
+ return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2320
+ }, Tr = (e) => {
2320
2321
  let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Y(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
2321
2322
  if (!e.hasDefault) return t;
2322
- let n = q(e.defaultValue, "SYSUTCDATETIME()");
2323
+ let n = xr(e.defaultValue, "SYSUTCDATETIME()");
2323
2324
  if (!n) return t;
2324
2325
  let r = n.replace(/^DEFAULT\s+/i, "");
2325
2326
  return `${t} ALTER TABLE ${Y(e.table)} ADD DEFAULT ${r} FOR ${Y(e.column)};`;
2326
- }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Tr = (e) => {
2327
+ }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Er = (e) => {
2327
2328
  let t = Xn(e, "mssql");
2328
2329
  if (t !== void 0) return t;
2329
2330
  switch (e.type) {
@@ -2339,44 +2340,44 @@ BEGIN
2339
2340
  case "bytes": return "VARBINARY(MAX)";
2340
2341
  default: return "NVARCHAR(MAX)";
2341
2342
  }
2342
- }, Er = (e, t) => {
2343
- if (e.type === "id" && e.idScheme?.kind === "numeric") return M(e.name, "mssql");
2344
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Tr(e), r = K(e, "mssql");
2343
+ }, Dr = (e, t) => {
2344
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2345
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Er(e), r = q(e, "mssql");
2345
2346
  if (r) return `${Y(e.name)} ${r}`;
2346
2347
  let i = [Y(e.name), n];
2347
2348
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2348
- let t = q(e.defaultValue, "SYSUTCDATETIME()");
2349
+ let t = xr(e.defaultValue, "SYSUTCDATETIME()");
2349
2350
  t && i.push(t);
2350
2351
  }
2351
2352
  return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${yr[e.references.onDelete]}`)), i.join(" ");
2352
- }, Dr = (e) => {
2353
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Er(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${fr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2353
+ }, Or = (e) => {
2354
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Dr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${fr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2354
2355
  for (let n of e.indexes) {
2355
2356
  if (n.name === `${e.table}_pkey`) continue;
2356
2357
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Y(n.name)} ON ${Y(e.table)} (${n.columns.map(Y).join(", ")})`;
2357
2358
  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)}')`);
2358
2359
  }
2359
2360
  return a;
2360
- }, Or = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, kr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Ar = (e, t, n) => {
2361
- let r = `${e.table}${Or(t)}`;
2361
+ }, kr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Ar = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, jr = (e, t, n) => {
2362
+ let r = `${e.table}${kr(t)}`;
2362
2363
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2363
- }, jr = (e) => {
2364
+ }, Mr = (e) => {
2364
2365
  if (e === void 0 || !hr(e)) return;
2365
2366
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2366
2367
  return t === void 0 ? mr : Math.min(mr, t);
2367
- }, Mr = (e, t, n) => {
2368
- let r = jr(or(e, t, n));
2369
- return r === void 0 ? W(n) : `${W(n)}(${r})`;
2370
- }, Nr = (e) => e.startsWith("(") ? e : U(e), Pr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${U(e.index.name)} ON ${U(e.table)} (${e.index.columns.map(Nr).join(", ")});`, Fr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map((n) => Mr(t, e.table, n)).join(", ")});`, Ir = (e) => `DROP INDEX IF EXISTS ${U(e.index)};`, Lr = (e) => `DROP INDEX ${W(e.index)} ON ${W(e.table)};`, Rr = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, zr = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Br = (e) => {
2368
+ }, Nr = (e, t, n) => {
2369
+ let r = Mr(or(e, t, n));
2370
+ return r === void 0 ? G(n) : `${G(n)}(${r})`;
2371
+ }, Pr = (e) => e.startsWith("(") ? e : W(e), Fr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map(Pr).join(", ")});`, Ir = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => Nr(t, e.table, n)).join(", ")});`, Lr = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, Rr = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, zr = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, Br = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Vr = (e) => {
2371
2372
  let t = (e) => e.replace(/'/g, "''");
2372
2373
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2373
- }, Vr = (e) => `ALTER INDEX ${U(e.from)} RENAME TO ${U(e.to)};`, Hr = (e) => `ALTER TABLE ${W(e.table)} RENAME INDEX ${W(e.from)} TO ${W(e.to)};`, Ur = (e) => {
2374
+ }, Hr = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, Ur = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, Wr = (e) => {
2374
2375
  let t = (e) => e.replace(/'/g, "''");
2375
2376
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2376
- }, Wr = (e) => {
2377
+ }, Gr = (e) => {
2377
2378
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Y(e.index.name)} ON ${Y(e.table)} (${e.index.columns.map(Y).join(", ")})`;
2378
2379
  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)}');`;
2379
- }, Gr = (e, t, n) => {
2380
+ }, Kr = (e, t, n) => {
2380
2381
  let r = n.find((t) => t.tableName === e);
2381
2382
  if (!r) return [];
2382
2383
  let i = [];
@@ -2385,13 +2386,13 @@ BEGIN
2385
2386
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Y(e)} ALTER COLUMN ${Y(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2386
2387
  }
2387
2388
  return i;
2388
- }, Kr = (e) => `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(`${e.table}_${e.column}_key`)} UNIQUE (${U(e.column)});`, qr = (e, t) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${Mr(t, e.table, e.column)});`, Jr = (e) => {
2389
- let t = e.fields.map((e) => U(e)).join(", ");
2390
- return `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(e.name)} UNIQUE (${t});`;
2391
- }, Yr = (e, t) => {
2392
- let n = e.fields.map((n) => Mr(t, e.table, n)).join(", ");
2393
- return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${n});`;
2394
- }, Xr = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(e.name)};`, Zr = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(e.name)};`, Qr = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_key`)};`, $r = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(`${e.table}_${e.column}_key`)};`, ei = (e, t) => {
2389
+ }, qr = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, Jr = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${Nr(t, e.table, e.column)});`, Yr = (e) => {
2390
+ let t = e.fields.map((e) => W(e)).join(", ");
2391
+ return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2392
+ }, Xr = (e, t) => {
2393
+ let n = e.fields.map((n) => Nr(t, e.table, n)).join(", ");
2394
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2395
+ }, Zr = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, Qr = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, $r = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, ei = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, ti = (e, t) => {
2395
2396
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2396
2397
  if (e.orphanPolicy) {
2397
2398
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2409,11 +2410,11 @@ BEGIN
2409
2410
  setNull: "SET NULL",
2410
2411
  noAction: "NO ACTION"
2411
2412
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2412
- }, ti = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_fkey`)};`, ni = (e) => `ALTER TABLE ${W(e.table)} DROP FOREIGN KEY ${W(`${e.table}_${e.column}_fkey`)};`, ri = (e, t) => {
2413
+ }, ni = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, ri = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, ii = (e, t) => {
2413
2414
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2414
2415
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2415
- }, ii = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_check`)};`, ai = (e) => `ALTER TABLE ${W(e.table)} DROP CHECK ${W(`${e.table}_${e.column}_check`)};`, oi = (e, t, n, r) => {
2416
- let i = e.column, a = r === "mariadb", o = a ? W : r === "mssql" ? Y : U, s = a ? $n(i) : r === "mssql" ? Tr(i) : r === "sqlite" ? br(i) : Zn(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? cr(e, i) : r === "mssql" ? q(e, "SYSUTCDATETIME()") : r === "sqlite" ? q(e, "CURRENT_TIMESTAMP") : ur(e, i), u = K(i, r);
2416
+ }, ai = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, oi = (e) => `ALTER TABLE ${G(e.table)} DROP CHECK ${G(`${e.table}_${e.column}_check`)};`, si = (e, t, n, r) => {
2417
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Y : W, s = a ? $n(i) : r === "mssql" ? Er(i) : r === "sqlite" ? br(i) : Zn(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? cr(e, i) : r === "mssql" ? xr(e, "SYSUTCDATETIME()") : r === "sqlite" ? xr(e, "CURRENT_TIMESTAMP") : ur(e, i), u = q(i, r);
2417
2418
  if (u) {
2418
2419
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2419
2420
  return {
@@ -2441,7 +2442,7 @@ BEGIN
2441
2442
  post: f ? [f] : []
2442
2443
  };
2443
2444
  return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
2444
- }, si = (e) => {
2445
+ }, ci = (e) => {
2445
2446
  let t = new Map(e.map((e) => [e.tableName, e]));
2446
2447
  return (e, n) => {
2447
2448
  let r = t.get(e);
@@ -2466,29 +2467,29 @@ BEGIN
2466
2467
  })), b.mapError((e) => {
2467
2468
  let r = ie(`applier: statement failed (op=${n})`, t, e, 400).trim();
2468
2469
  return Object.assign(e, { message: r });
2469
- }), b.map(() => void 0)), Z = (e, t, n) => b.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : i(r, t)} FROM ${i(n, t)} WHERE 1=0`).pipe(b.as(!0), b.catchAll(() => b.succeed(!1))), ci = (e, t) => b.gen(function* () {
2470
- let n = F([Fe], t).tables[0];
2470
+ }), b.map(() => void 0)), Z = (e, t, n) => b.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : i(r, t)} FROM ${i(n, t)} WHERE 1=0`).pipe(b.as(!0), b.catchAll(() => b.succeed(!1))), li = (e, t) => b.gen(function* () {
2471
+ let n = I([Fe], t).tables[0];
2471
2472
  if (!n) return yield* b.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2472
2473
  let r = {
2473
2474
  kind: "create-table",
2474
- table: D,
2475
+ table: O,
2475
2476
  columns: n.columns,
2476
2477
  indexes: []
2477
2478
  }, i = yield* e.onDialectOrElse({
2478
2479
  mysql: () => b.succeed(_r(r)),
2479
- mssql: () => b.succeed(Dr(r)),
2480
- sqlite: () => b.succeed(Sr(r)),
2480
+ mssql: () => b.succeed(Or(r)),
2481
+ sqlite: () => b.succeed(Cr(r)),
2481
2482
  orElse: () => b.succeed(pr(r))
2482
2483
  });
2483
2484
  yield* b.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2484
- }), li = (e) => e`
2485
+ }), ui = (e) => e`
2485
2486
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2486
2487
  ${e("status")}, ${e("payload")}
2487
- FROM ${e(D)}
2488
- `, ui = (e, t, n, r) => b.gen(function* () {
2489
- let i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
2488
+ FROM ${e(O)}
2489
+ `, di = (e, t, n, r) => b.gen(function* () {
2490
+ let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2490
2491
  yield* b.forEach(r, ({ index: r, planned: a }) => e`
2491
- INSERT INTO ${e(D)}
2492
+ INSERT INTO ${e(O)}
2492
2493
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2493
2494
  ${e("opKind")}, ${e("opTarget")}, ${e("status")}, ${e("payload")},
2494
2495
  ${e("createdAt")})
@@ -2497,11 +2498,11 @@ BEGIN
2497
2498
  ${a.op.kind}, ${Le(a.op)}, ${"pending"},
2498
2499
  ${JSON.stringify(a)}, ${i})
2499
2500
  `, { discard: !0 });
2500
- }), di = (e, t, n, r, i) => b.gen(function* () {
2501
- let a = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
2501
+ }), fi = (e, t, n, r, i) => b.gen(function* () {
2502
+ let a = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2502
2503
  if (r === "applied") {
2503
2504
  yield* e`
2504
- UPDATE ${e(D)}
2505
+ UPDATE ${e(O)}
2505
2506
  SET ${e("status")} = ${r}, ${e("appliedAt")} = ${a},
2506
2507
  ${e("durationMs")} = ${i ?? null}
2507
2508
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
@@ -2509,22 +2510,22 @@ BEGIN
2509
2510
  return;
2510
2511
  }
2511
2512
  yield* e`
2512
- UPDATE ${e(D)}
2513
+ UPDATE ${e(O)}
2513
2514
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2514
2515
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2515
2516
  `;
2516
- }), fi = (e, t, n, r) => b.gen(function* () {
2517
- let i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
2517
+ }), pi = (e, t, n, r) => b.gen(function* () {
2518
+ let i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2518
2519
  r.length > 0 && (yield* e`
2519
- UPDATE ${e(D)}
2520
+ UPDATE ${e(O)}
2520
2521
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
2521
2522
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(r)}
2522
2523
  `), n.length > 0 && (yield* e`
2523
- UPDATE ${e(D)}
2524
+ UPDATE ${e(O)}
2524
2525
  SET ${e("status")} = ${"pending"}
2525
2526
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2526
2527
  `);
2527
- }), pi = (e, t) => t === void 0 ? e`DELETE FROM ${e(D)}`.pipe(b.asVoid) : e`DELETE FROM ${e(D)} WHERE ${e("runId")} = ${t}`.pipe(b.asVoid), mi = (e, t, n) => b.gen(function* () {
2528
+ }), mi = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(b.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(b.asVoid), hi = (e, t, n) => b.gen(function* () {
2528
2529
  if (Ge(n.op, n.classification, t) !== "artefact-repair") return "clean";
2529
2530
  let r = n.op, a = (e) => i(e, t);
2530
2531
  if (t === "sqlite" || t === "turso") {
@@ -2535,109 +2536,109 @@ BEGIN
2535
2536
  if (r.kind !== "alter-column-type") return "clean";
2536
2537
  let o = `${r.column}${Ve}`, s = `${r.column}${He}`, c = yield* $(e, t, r.table, r.column), l = yield* $(e, t, r.table, o), u = yield* $(e, t, r.table, s), d = (e) => b.logWarning(`migration resume: ${e}`).pipe(b.annotateLogs({ scope: "voltro:migrate" }));
2537
2538
  return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(o)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${r.table}.${o}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* X(e, `ALTER TABLE ${a(r.table)} RENAME COLUMN ${a(o)} TO ${a(r.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${r.table}.${s}'`), "applied") : yield* b.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}, ${o}=${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.`));
2538
- }), hi = (e, t, n, r = "fresh") => b.gen(function* () {
2539
- let i = process.hrtime.bigint(), a = si(n.declared), o = t.op;
2539
+ }), gi = (e, t, n, r = "fresh") => b.gen(function* () {
2540
+ let i = process.hrtime.bigint(), a = ci(n.declared), o = t.op;
2540
2541
  switch (o.kind) {
2541
2542
  case "create-table": {
2542
2543
  let t = yield* e.onDialectOrElse({
2543
2544
  mysql: () => b.succeed(_r(o)),
2544
- mssql: () => b.succeed(Dr(o)),
2545
- sqlite: () => b.succeed(Sr(o)),
2545
+ mssql: () => b.succeed(Or(o)),
2546
+ sqlite: () => b.succeed(Cr(o)),
2546
2547
  orElse: () => b.succeed(pr(o))
2547
2548
  });
2548
2549
  for (let n of t) yield* X(e, n, o.kind);
2549
2550
  break;
2550
2551
  }
2551
2552
  case "drop-table": {
2552
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Ar(o, n, e) : kr(o, e);
2553
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? jr(o, n, e) : Ar(o, e);
2553
2554
  yield* e.onDialectOrElse({
2554
- mysql: () => X(e, r(W), o.kind),
2555
- orElse: () => X(e, r(U), o.kind)
2555
+ mysql: () => X(e, r(G), o.kind),
2556
+ orElse: () => X(e, r(W), o.kind)
2556
2557
  });
2557
2558
  break;
2558
2559
  }
2559
2560
  case "drop-column": {
2560
2561
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2561
2562
  yield* e.onDialectOrElse({
2562
- mysql: () => X(e, t ? rr(o, n, W) : tr(o), o.kind),
2563
- orElse: () => X(e, t ? rr(o, n, U) : er(o, U), o.kind)
2563
+ mysql: () => X(e, t ? rr(o, n, G) : tr(o), o.kind),
2564
+ orElse: () => X(e, t ? rr(o, n, W) : er(o, W), o.kind)
2564
2565
  });
2565
2566
  break;
2566
2567
  }
2567
2568
  case "rename-column":
2568
2569
  yield* e.onDialectOrElse({
2569
- mysql: () => X(e, nr(o, W), o.kind),
2570
+ mysql: () => X(e, nr(o, G), o.kind),
2570
2571
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2571
- orElse: () => X(e, nr(o, U), o.kind)
2572
+ orElse: () => X(e, nr(o, W), o.kind)
2572
2573
  });
2573
2574
  break;
2574
2575
  case "add-index":
2575
2576
  yield* e.onDialectOrElse({
2576
- mysql: () => X(e, Fr(o, n.declared), o.kind),
2577
- mssql: () => Z(e, [...Gr(o.table, o.index.columns, n.declared), Wr(o)], o.kind),
2578
- orElse: () => X(e, Pr(o, t.classification === "online-required"), o.kind)
2577
+ mysql: () => X(e, Ir(o, n.declared), o.kind),
2578
+ mssql: () => Z(e, [...Kr(o.table, o.index.columns, n.declared), Gr(o)], o.kind),
2579
+ orElse: () => X(e, Fr(o, t.classification === "online-required"), o.kind)
2579
2580
  });
2580
2581
  break;
2581
2582
  case "drop-index":
2582
2583
  yield* e.onDialectOrElse({
2583
- mysql: () => X(e, Lr(o), o.kind),
2584
- mssql: () => X(e, Rr(o), o.kind),
2585
- orElse: () => X(e, Ir(o), o.kind)
2584
+ mysql: () => X(e, Rr(o), o.kind),
2585
+ mssql: () => X(e, zr(o), o.kind),
2586
+ orElse: () => X(e, Lr(o), o.kind)
2586
2587
  });
2587
2588
  break;
2588
2589
  case "rename-table":
2589
2590
  yield* e.onDialectOrElse({
2590
- mysql: () => X(e, zr(o, W), o.kind),
2591
- mssql: () => X(e, Br(o), o.kind),
2592
- orElse: () => X(e, zr(o, U), o.kind)
2591
+ mysql: () => X(e, Br(o, G), o.kind),
2592
+ mssql: () => X(e, Vr(o), o.kind),
2593
+ orElse: () => X(e, Br(o, W), o.kind)
2593
2594
  });
2594
2595
  break;
2595
2596
  case "rename-index":
2596
2597
  yield* e.onDialectOrElse({
2597
- mysql: () => X(e, Hr(o), o.kind),
2598
- mssql: () => X(e, Ur(o), o.kind),
2599
- orElse: () => X(e, Vr(o), o.kind)
2598
+ mysql: () => X(e, Ur(o), o.kind),
2599
+ mssql: () => X(e, Wr(o), o.kind),
2600
+ orElse: () => X(e, Hr(o), o.kind)
2600
2601
  });
2601
2602
  break;
2602
2603
  case "add-unique":
2603
2604
  yield* e.onDialectOrElse({
2604
- mysql: () => X(e, qr(o, n.declared), o.kind),
2605
+ mysql: () => X(e, Jr(o, n.declared), o.kind),
2605
2606
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2606
- mssql: () => Z(e, [...Gr(o.table, [o.column], n.declared), Kr(o)], o.kind),
2607
- orElse: () => X(e, Kr(o), o.kind)
2607
+ mssql: () => Z(e, [...Kr(o.table, [o.column], n.declared), qr(o)], o.kind),
2608
+ orElse: () => X(e, qr(o), o.kind)
2608
2609
  });
2609
2610
  break;
2610
2611
  case "drop-unique":
2611
2612
  yield* e.onDialectOrElse({
2612
- mysql: () => X(e, $r(o), o.kind),
2613
+ mysql: () => X(e, ei(o), o.kind),
2613
2614
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2614
- orElse: () => X(e, Qr(o), o.kind)
2615
+ orElse: () => X(e, $r(o), o.kind)
2615
2616
  });
2616
2617
  break;
2617
2618
  case "add-unique-composite":
2618
2619
  yield* e.onDialectOrElse({
2619
- mysql: () => X(e, Yr(o, n.declared), o.kind),
2620
+ mysql: () => X(e, Xr(o, n.declared), o.kind),
2620
2621
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2621
- mssql: () => Z(e, [...Gr(o.table, o.fields, n.declared), Jr(o)], o.kind),
2622
- orElse: () => X(e, Jr(o), o.kind)
2622
+ mssql: () => Z(e, [...Kr(o.table, o.fields, n.declared), Yr(o)], o.kind),
2623
+ orElse: () => X(e, Yr(o), o.kind)
2623
2624
  });
2624
2625
  break;
2625
2626
  case "drop-unique-composite":
2626
2627
  yield* e.onDialectOrElse({
2627
- mysql: () => X(e, Zr(o), o.kind),
2628
+ mysql: () => X(e, Qr(o), o.kind),
2628
2629
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2629
- orElse: () => X(e, Xr(o), o.kind)
2630
+ orElse: () => X(e, Zr(o), o.kind)
2630
2631
  });
2631
2632
  break;
2632
2633
  case "add-foreign-key":
2633
2634
  yield* e.onDialectOrElse({
2634
- mysql: () => Z(e, ei(o, W), o.kind),
2635
+ mysql: () => Z(e, ti(o, G), o.kind),
2635
2636
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2636
- orElse: () => Z(e, ei(o, U), o.kind)
2637
+ orElse: () => Z(e, ti(o, W), o.kind)
2637
2638
  });
2638
2639
  break;
2639
2640
  case "add-column": {
2640
- let n = oi(o, t, a, yield* e.onDialectOrElse({
2641
+ let n = si(o, t, a, yield* e.onDialectOrElse({
2641
2642
  mysql: () => b.succeed("mariadb"),
2642
2643
  mssql: () => b.succeed("mssql"),
2643
2644
  sqlite: () => b.succeed("sqlite"),
@@ -2682,24 +2683,24 @@ BEGIN
2682
2683
  case "alter-column-nullability":
2683
2684
  yield* e.onDialectOrElse({
2684
2685
  mysql: () => {
2685
- let t = G(n.declared, o.table, o.column);
2686
- return t ? X(e, `ALTER TABLE ${W(o.table)} MODIFY COLUMN ${sr(t, o.column, o.toNullable)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2686
+ let t = K(n.declared, o.table, o.column);
2687
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${sr(t, o.column, o.toNullable)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2687
2688
  },
2688
2689
  mssql: () => {
2689
- let t = G(n.declared, o.table, o.column);
2690
- return t ? X(e, Cr(t, o.column, o.table, o.toNullable), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2690
+ let t = K(n.declared, o.table, o.column);
2691
+ return t ? X(e, wr(t, o.column, o.table, o.toNullable), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2691
2692
  },
2692
2693
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2693
- orElse: () => X(e, `ALTER TABLE ${U(o.table)} ALTER COLUMN ${U(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2694
+ orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2694
2695
  });
2695
2696
  break;
2696
2697
  case "alter-column-default": {
2697
2698
  let t = or(n.declared, o.table, o.column);
2698
2699
  yield* e.onDialectOrElse({
2699
- mysql: () => X(e, ir(o, W, (e) => cr(e, t)), o.kind),
2700
- mssql: () => X(e, wr(o), o.kind),
2700
+ mysql: () => X(e, ir(o, G, (e) => cr(e, t)), o.kind),
2701
+ mssql: () => X(e, Tr(o), o.kind),
2701
2702
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2702
- orElse: () => X(e, ir(o, U, (e) => ur(e, t)), o.kind)
2703
+ orElse: () => X(e, ir(o, W, (e) => ur(e, t)), o.kind)
2703
2704
  });
2704
2705
  break;
2705
2706
  }
@@ -2708,15 +2709,15 @@ BEGIN
2708
2709
  if (t.classification !== "online-required") {
2709
2710
  yield* e.onDialectOrElse({
2710
2711
  mysql: () => {
2711
- let t = G(n.declared, o.table, o.column);
2712
- return t ? X(e, `ALTER TABLE ${W(o.table)} MODIFY COLUMN ${sr(t, o.column)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2712
+ let t = K(n.declared, o.table, o.column);
2713
+ return t ? X(e, `ALTER TABLE ${G(o.table)} MODIFY COLUMN ${sr(t, o.column)};`, o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2713
2714
  },
2714
2715
  mssql: () => {
2715
- let t = G(n.declared, o.table, o.column);
2716
- return t ? X(e, Cr(t, o.column, o.table), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2716
+ let t = K(n.declared, o.table, o.column);
2717
+ return t ? X(e, wr(t, o.column, o.table), o.kind) : b.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2717
2718
  },
2718
2719
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2719
- orElse: () => X(e, `ALTER TABLE ${U(o.table)} ALTER COLUMN ${U(o.column)} TYPE ${r}${i};`, o.kind)
2720
+ orElse: () => X(e, `ALTER TABLE ${W(o.table)} ALTER COLUMN ${W(o.column)} TYPE ${r}${i};`, o.kind)
2720
2721
  });
2721
2722
  break;
2722
2723
  }
@@ -2725,35 +2726,35 @@ BEGIN
2725
2726
  orElse: () => b.void
2726
2727
  });
2727
2728
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2728
- yield* e.unsafe(`ALTER TABLE ${U(o.table)} ADD COLUMN ${U(a)} ${r}`);
2729
- let c = o.using ?? U(o.column), l;
2729
+ yield* e.unsafe(`ALTER TABLE ${W(o.table)} ADD COLUMN ${W(a)} ${r}`);
2730
+ let c = o.using ?? W(o.column), l;
2730
2731
  for (;;) {
2731
2732
  let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${Q(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${Q(e, 5e3)}`;
2732
2733
  if (t.length === 0) break;
2733
- yield* e.unsafe(`UPDATE ${U(o.table)} SET ${U(a)} = ${c} WHERE ${U(o.column)} IS NOT NULL AND ${U(a)} IS NULL AND ${U("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2734
+ yield* e.unsafe(`UPDATE ${W(o.table)} SET ${W(a)} = ${c} WHERE ${W(o.column)} IS NOT NULL AND ${W(a)} IS NULL AND ${W("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2734
2735
  }
2735
- yield* b.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${U(o.table)} RENAME COLUMN ${U(o.column)} TO ${U(s)}`), yield* e.unsafe(`ALTER TABLE ${U(o.table)} RENAME COLUMN ${U(a)} TO ${U(o.column)}`), yield* e.unsafe(`ALTER TABLE ${U(o.table)} DROP COLUMN ${U(s)}`);
2736
+ yield* b.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(o.column)} TO ${W(s)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} RENAME COLUMN ${W(a)} TO ${W(o.column)}`), yield* e.unsafe(`ALTER TABLE ${W(o.table)} DROP COLUMN ${W(s)}`);
2736
2737
  break;
2737
2738
  }
2738
2739
  case "drop-foreign-key":
2739
2740
  yield* e.onDialectOrElse({
2740
- mysql: () => X(e, ni(o), o.kind),
2741
+ mysql: () => X(e, ri(o), o.kind),
2741
2742
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2742
- orElse: () => X(e, ti(o), o.kind)
2743
+ orElse: () => X(e, ni(o), o.kind)
2743
2744
  });
2744
2745
  break;
2745
2746
  case "add-check":
2746
2747
  yield* e.onDialectOrElse({
2747
- mysql: () => X(e, ri(o, W), o.kind),
2748
+ mysql: () => X(e, ii(o, G), o.kind),
2748
2749
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2749
- orElse: () => X(e, ri(o, U), o.kind)
2750
+ orElse: () => X(e, ii(o, W), o.kind)
2750
2751
  });
2751
2752
  break;
2752
2753
  case "drop-check":
2753
2754
  yield* e.onDialectOrElse({
2754
- mysql: () => X(e, ai(o), o.kind),
2755
+ mysql: () => X(e, oi(o), o.kind),
2755
2756
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2756
- orElse: () => X(e, ii(o), o.kind)
2757
+ orElse: () => X(e, ai(o), o.kind)
2757
2758
  });
2758
2759
  break;
2759
2760
  }
@@ -2762,21 +2763,21 @@ BEGIN
2762
2763
  status: "applied",
2763
2764
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2764
2765
  };
2765
- }), gi = (e, t, n, r) => b.gen(function* () {
2766
+ }), _i = (e, t, n, r) => b.gen(function* () {
2766
2767
  let i = [...new Set(r.map((e) => e.runId))];
2767
- if (i.length > 1) return yield* b.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 \`${D}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2768
+ if (i.length > 1) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2768
2769
  let a = i[0], o = [...r].map((e) => ({
2769
2770
  index: Number(e.opIndex),
2770
2771
  status: e.status,
2771
2772
  planned: JSON.parse(e.payload)
2772
2773
  })).sort((e, t) => e.index - t.index), s = o.find((e) => e.status === "started"), c = o.filter((e) => e.status === "started").length;
2773
- if (c > 1) return yield* b.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 \`${D}\` by hand before re-running.`));
2774
+ if (c > 1) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger records ${c} operations as in-flight for run ${a}. It is written strictly sequentially, so at most one can be — this ledger is corrupt and the schema state it describes cannot be trusted.\nNothing was changed. Reconcile \`${O}\` by hand before re-running.`));
2774
2775
  if (yield* b.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} ${Le(s.planned.op)}` : ""}`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), o.every((e) => e.status === "pending")) return {
2775
2776
  kind: "discard",
2776
2777
  runId: a,
2777
2778
  why: "no operation had started — no DDL ran"
2778
2779
  };
2779
- let l = s ? yield* mi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2780
+ let l = s ? yield* hi(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2780
2781
  if (u !== n.toFingerprint) return {
2781
2782
  kind: "discard",
2782
2783
  runId: a,
@@ -2787,7 +2788,7 @@ BEGIN
2787
2788
  kind: "discard",
2788
2789
  runId: a,
2789
2790
  why: "every recorded operation had already taken effect"
2790
- } : (yield* fi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* b.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), {
2791
+ } : (yield* pi(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* b.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), {
2791
2792
  kind: "resume",
2792
2793
  runId: a,
2793
2794
  ops: f.map((e) => ({
@@ -2795,39 +2796,39 @@ BEGIN
2795
2796
  planned: e.planned
2796
2797
  }))
2797
2798
  });
2798
- }), _i = (e, t, n) => b.gen(function* () {
2799
+ }), vi = (e, t, n) => b.gen(function* () {
2799
2800
  let r = t.operations.filter((e) => e.blocked);
2800
2801
  if (r.length > 0) return yield* b.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2801
- yield* T(e, { schema: n.lockSchema });
2802
+ yield* E(e, { schema: n.lockSchema });
2802
2803
  let i = Date.now(), a = [], o = Me(e), s = Pe(o) === "plan-transactional", l = s ? t.operations.filter((e) => e.classification !== "online-required") : [], u = s ? t.operations.filter((e) => e.classification === "online-required") : t.operations, d = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, f = u.map((e, t) => ({
2803
2804
  index: t,
2804
2805
  planned: e
2805
2806
  })), p = "fresh";
2806
2807
  try {
2807
- yield* ci(e, o);
2808
- let r = yield* li(e);
2808
+ yield* li(e, o);
2809
+ let r = yield* ui(e);
2809
2810
  if (r.length > 0) {
2810
- let n = yield* gi(e, o, t, r);
2811
- n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* b.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* pi(e, n.runId));
2811
+ let n = yield* _i(e, o, t, r);
2812
+ n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* b.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(b.annotateLogs({ scope: "voltro:migrate" })), yield* mi(e, n.runId));
2812
2813
  }
2813
- p === "fresh" && f.length > 0 && (yield* ui(e, d, t.toFingerprint, f)), l.length > 0 && (yield* e.withTransaction(b.gen(function* () {
2814
+ p === "fresh" && f.length > 0 && (yield* di(e, d, t.toFingerprint, f)), l.length > 0 && (yield* e.withTransaction(b.gen(function* () {
2814
2815
  let e = yield* C.SqlClient;
2815
- for (let t of l) a.push(yield* hi(e, t, n));
2816
+ for (let t of l) a.push(yield* gi(e, t, n));
2816
2817
  })));
2817
2818
  for (let { index: t, planned: r } of f) {
2818
- yield* di(e, d, t, "started");
2819
- let i = yield* hi(e, r, n, p);
2820
- a.push(i), yield* di(e, d, t, "applied", i.durationMs);
2819
+ yield* fi(e, d, t, "started");
2820
+ let i = yield* gi(e, r, n, p);
2821
+ a.push(i), yield* fi(e, d, t, "applied", i.durationMs);
2821
2822
  }
2822
2823
  } finally {
2823
- yield* E(e, { schema: n.lockSchema }).pipe(b.orDie);
2824
+ yield* D(e, { schema: n.lockSchema }).pipe(b.orDie);
2824
2825
  }
2825
2826
  let m = yield* n.replan(e);
2826
2827
  if (m.operations.length > 0) {
2827
2828
  let e = m.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2828
2829
  return yield* b.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${m.operations.length}:\n${e}${m.operations.length > 10 ? `\n … and ${m.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2829
2830
  }
2830
- let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* H(e, v), x = [...l, ...f.map((e) => e.planned)];
2831
+ let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* U(e, v), x = [...l, ...f.map((e) => e.planned)];
2831
2832
  yield* e`
2832
2833
  INSERT INTO ${e("_voltro_migration_plans")}
2833
2834
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -2837,7 +2838,7 @@ BEGIN
2837
2838
  (${_}, ${t.toFingerprint}, ${m.fromFingerprint}, ${JSON.stringify(x)},
2838
2839
  ${n.appliedBy}, ${n.environment}, ${n.source},
2839
2840
  ${g}, ${y}, ${n.notes ?? null})
2840
- `, yield* pi(e, d);
2841
+ `, yield* mi(e, d);
2841
2842
  let S = [...new Set(x.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2842
2843
  return yield* b.promise(() => c({ changedTables: S }).catch(() => {})), {
2843
2844
  id: _,
@@ -2851,14 +2852,14 @@ BEGIN
2851
2852
  source: n.source,
2852
2853
  ...n.notes ? { notes: n.notes } : {}
2853
2854
  };
2854
- }), vi = (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"), yi = (e) => e`
2855
+ }), yi = (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"), bi = (e) => e`
2855
2856
  SELECT fingerprint
2856
2857
  FROM _voltro_migration_plans
2857
2858
  ORDER BY ${e("appliedAt")} DESC
2858
2859
  LIMIT 1
2859
- `.pipe(b.map((e) => e.length > 0 ? e[0].fingerprint : void 0), b.catchAll(() => b.succeed(void 0))), bi = (e, t, n) => b.gen(function* () {
2860
- if ((yield* yi(e)) === t.toFingerprint) return "already-current";
2861
- let r = `plan_${Date.now().toString(36)}`, i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
2860
+ `.pipe(b.map((e) => e.length > 0 ? e[0].fingerprint : void 0), b.catchAll(() => b.succeed(void 0))), xi = (e, t, n) => b.gen(function* () {
2861
+ if ((yield* bi(e)) === t.toFingerprint) return "already-current";
2862
+ let r = `plan_${Date.now().toString(36)}`, i = yield* U(e, (/* @__PURE__ */ new Date()).toISOString());
2862
2863
  return yield* e`
2863
2864
  INSERT INTO ${e("_voltro_migration_plans")}
2864
2865
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -2869,8 +2870,8 @@ BEGIN
2869
2870
  ${n.appliedBy}, ${n.environment}, ${n.source},
2870
2871
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
2871
2872
  `, "recorded";
2872
- }).pipe(b.catchAll(() => b.succeed("already-current"))), xi = (e, t) => b.gen(function* () {
2873
- let n = N(F(t, Me(e))), r = yield* yi(e);
2873
+ }).pipe(b.catchAll(() => b.succeed("already-current"))), Si = (e, t) => b.gen(function* () {
2874
+ let n = P(I(t, Me(e))), r = yield* bi(e);
2874
2875
  return r === n ? {
2875
2876
  kind: "up-to-date",
2876
2877
  fingerprint: n
@@ -2879,23 +2880,23 @@ BEGIN
2879
2880
  expected: n,
2880
2881
  ...r === void 0 ? {} : { actual: r }
2881
2882
  };
2882
- }), Si = [
2883
+ }), Ci = [
2883
2884
  "pgeagertest_",
2884
2885
  "mig_e2e_",
2885
2886
  "mig_test_",
2886
2887
  "mysqleagertest_",
2887
2888
  "mssqleagertest_",
2888
2889
  "sqliteeagertest_"
2889
- ], Ci = (e) => Si.some((t) => e.startsWith(t)), wi = (e, t) => b.gen(function* () {
2890
+ ], wi = (e) => Ci.some((t) => e.startsWith(t)), Ti = (e, t) => b.gen(function* () {
2890
2891
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2891
- let n = t.filter((e) => Ci(e.name)).map((e) => e.name);
2892
+ let n = t.filter((e) => wi(e.name)).map((e) => e.name);
2892
2893
  if (n.length === 0) return [];
2893
2894
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(b.catchAll(() => b.void));
2894
2895
  return n;
2895
- }), Ti = () => {
2896
+ }), Ei = () => {
2896
2897
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2897
2898
  return e.length > 0 ? { ignoreTables: e } : {};
2898
- }, Ei = (e) => {
2899
+ }, Di = (e) => {
2899
2900
  if (e === void 0) return;
2900
2901
  let t = e.trim();
2901
2902
  if (t === "") return;
@@ -2905,30 +2906,30 @@ BEGIN
2905
2906
  kind: "tables",
2906
2907
  tables: new Set(n)
2907
2908
  } : void 0;
2908
- }, Di = (e) => typeof e.table == "string" ? e.table : void 0, Oi = (e, t = { kind: "all" }) => ({
2909
+ }, Oi = (e) => typeof e.table == "string" ? e.table : void 0, ki = (e, t = { kind: "all" }) => ({
2909
2910
  ...e,
2910
2911
  operations: e.operations.map((e) => {
2911
2912
  if (!e.blocked || e.classification !== "lossy") return e;
2912
2913
  if (t?.kind === "tables") {
2913
- let n = Di(e.op);
2914
+ let n = Oi(e.op);
2914
2915
  if (n === void 0 || !t.tables.has(n)) return e;
2915
2916
  }
2916
2917
  let { blocked: n, ...r } = e;
2917
2918
  return r;
2918
2919
  })
2919
- }), ki = (e, t, n) => t === "postgres" ? qt(e, n).pipe(b.flatMap((e) => {
2920
+ }), Ai = (e, t, n) => t === "postgres" ? qt(e, n).pipe(b.flatMap((e) => {
2920
2921
  let t = Jt(e);
2921
2922
  return t === void 0 ? b.void : b.logWarning(`auto-migrate: ${t}`).pipe(b.annotateLogs({ scope: "voltro:migrate" }));
2922
- }), b.catchAll(() => b.void)) : b.void, Ai = (e, t, n) => b.gen(function* () {
2923
+ }), b.catchAll(() => b.void)) : b.void, ji = (e, t, n) => b.gen(function* () {
2923
2924
  let r = Me(e), i = t;
2924
2925
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2925
- let t = N(F(i, r));
2926
- if ((yield* yi(e)) === t) return yield* ki(e, r, i), {
2926
+ let t = P(I(i, r));
2927
+ if ((yield* bi(e)) === t) return yield* Ai(e, r, i), {
2927
2928
  kind: "up-to-date",
2928
2929
  fingerprint: t
2929
2930
  };
2930
2931
  }
2931
- let a = yield* Jn(e), o = yield* wi(e, a.tables);
2932
+ let a = yield* Jn(e), o = yield* Ti(e, a.tables);
2932
2933
  o.length > 0 && (yield* b.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(b.annotateLogs({
2933
2934
  scope: "voltro:migrate",
2934
2935
  count: o.length
@@ -2937,16 +2938,16 @@ BEGIN
2937
2938
  declared: i,
2938
2939
  live: { tables: c(a.tables) },
2939
2940
  dialect: r,
2940
- ...Ti()
2941
+ ...Ei()
2941
2942
  });
2942
2943
  if (l.summary.blocked > 0) {
2943
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Ei(process.env.VOLTRO_DESTRUCTIVE_OK);
2944
- if (t === void 0 || !e || (l = Oi(l, t), l.operations.some((e) => e.blocked))) return {
2944
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Di(process.env.VOLTRO_DESTRUCTIVE_OK);
2945
+ if (t === void 0 || !e || (l = ki(l, t), l.operations.some((e) => e.blocked))) return {
2945
2946
  kind: "refused-blocked",
2946
2947
  plan: l
2947
2948
  };
2948
2949
  }
2949
- return l.operations.length === 0 ? (yield* bi(e, l, {
2950
+ return l.operations.length === 0 ? (yield* xi(e, l, {
2950
2951
  appliedBy: n.appliedBy,
2951
2952
  environment: n.environment === "prod" ? "dev" : n.environment,
2952
2953
  source: "auto-diff"
@@ -2955,7 +2956,7 @@ BEGIN
2955
2956
  fingerprint: l.toFingerprint
2956
2957
  }) : {
2957
2958
  kind: "applied",
2958
- applied: yield* _i(e, l, {
2959
+ applied: yield* vi(e, l, {
2959
2960
  declared: t,
2960
2961
  appliedBy: n.appliedBy,
2961
2962
  environment: n.environment === "prod" ? "dev" : n.environment,
@@ -2966,26 +2967,26 @@ BEGIN
2966
2967
  declared: i,
2967
2968
  live: { tables: c(t.tables) },
2968
2969
  dialect: r,
2969
- ...Ti()
2970
+ ...Ei()
2970
2971
  });
2971
2972
  })
2972
2973
  }),
2973
2974
  plan: l
2974
2975
  };
2975
- }), ji = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? b.succeed({
2976
+ }), Mi = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? b.succeed({
2976
2977
  kind: "skipped",
2977
2978
  reason: "VOLTRO_AUTO_MIGRATE=0"
2978
- }) : n.environment === "prod" ? xi(e, t) : Ai(e, t, n), Mi = (e, t) => {
2979
+ }) : n.environment === "prod" ? Si(e, t) : ji(e, t, n), Ni = (e, t) => {
2979
2980
  switch (e.kind) {
2980
2981
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2981
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${P(e.fingerprint)})`;
2982
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${F(e.fingerprint)})`;
2982
2983
  case "applied": {
2983
2984
  let t = e.plan.summary;
2984
- return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${P(e.applied.fingerprint)}`;
2985
+ return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${F(e.applied.fingerprint)}`;
2985
2986
  }
2986
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${P(e.expected)}` + (e.actual ? ` live=${P(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2987
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${F(e.expected)}` + (e.actual ? ` live=${F(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2987
2988
  case "refused-blocked": {
2988
- 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` + vi(e.plan), c = [""];
2989
+ 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` + yi(e.plan), c = [""];
2989
2990
  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) {
2990
2991
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2991
2992
  for (let r of e.plan.operations) {
@@ -3002,7 +3003,7 @@ BEGIN
3002
3003
  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");
3003
3004
  }
3004
3005
  }
3005
- }, Ni = /* @__PURE__ */ new Set([
3006
+ }, Pi = /* @__PURE__ */ new Set([
3006
3007
  "node_modules",
3007
3008
  "dist",
3008
3009
  "build",
@@ -3011,11 +3012,11 @@ BEGIN
3011
3012
  ".next",
3012
3013
  ".git",
3013
3014
  ".framework"
3014
- ]), Pi = async (e) => {
3015
+ ]), Fi = async (e) => {
3015
3016
  let t = [], n = async (e) => {
3016
3017
  let r = await te.readdir(e, { withFileTypes: !0 }).catch(() => []);
3017
3018
  for (let i of r) {
3018
- if (Ni.has(i.name)) continue;
3019
+ if (Pi.has(i.name)) continue;
3019
3020
  let r = ne(e, i.name);
3020
3021
  i.isDirectory() ? await n(r) : i.isFile() && u.test(i.name) && t.push(r);
3021
3022
  }
@@ -3024,7 +3025,7 @@ BEGIN
3024
3025
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3025
3026
  return n.localeCompare(r);
3026
3027
  });
3027
- }, Fi = async (e) => {
3028
+ }, Ii = async (e) => {
3028
3029
  let t = [];
3029
3030
  for (let n of e) {
3030
3031
  let e = (await import(re(n).href)).default;
@@ -3038,11 +3039,11 @@ BEGIN
3038
3039
  });
3039
3040
  }
3040
3041
  return t;
3041
- }, Ii = (e) => e`
3042
+ }, Li = (e) => e`
3042
3043
  SELECT ${e("id")}
3043
3044
  FROM ${e("_voltro_migration_plans")}
3044
3045
  WHERE ${e("source")} = 'file'
3045
- `.pipe(b.map((e) => e.map((e) => e.id)), b.catchAll(() => b.succeed([]))), Li = class extends Error {
3046
+ `.pipe(b.map((e) => e.map((e) => e.id)), b.catchAll(() => b.succeed([]))), Ri = class extends Error {
3046
3047
  migrationId;
3047
3048
  file;
3048
3049
  cause;
@@ -3050,7 +3051,7 @@ BEGIN
3050
3051
  constructor(e, t, n) {
3051
3052
  super(`migration ${e}: up() SUCCEEDED but the ledger row could not be written.\n The change IS in the database. It is NOT recorded, so the next run would apply it AGAIN.\n Do not re-run ${t} until this is resolved.\n Cause: ${n instanceof Error ? n.message : String(n)}`), this.migrationId = e, this.file = t, this.cause = n, this.name = "FileMigrationLedgerError";
3052
3053
  }
3053
- }, Ri = (e, t, n, r) => b.gen(function* () {
3054
+ }, zi = (e, t, n, r) => b.gen(function* () {
3054
3055
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3055
3056
  sql: e,
3056
3057
  log: {
@@ -3071,7 +3072,7 @@ BEGIN
3071
3072
  });
3072
3073
  let c = Date.now() - i;
3073
3074
  !b.isEffect(s) && c < 2 && (yield* b.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(b.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3074
- let l = yield* H(e, a);
3075
+ let l = yield* U(e, a);
3075
3076
  return yield* e`
3076
3077
  INSERT INTO ${e("_voltro_migration_plans")}
3077
3078
  (${e("id")}, ${e("fingerprint")}, ${e("operations")},
@@ -3084,10 +3085,10 @@ BEGIN
3084
3085
  }])},
3085
3086
  ${r}, ${n}, ${"file"},
3086
3087
  ${c}, ${l}, ${t.migration.description})
3087
- `.pipe(b.mapError((e) => new Li(t.migration.id, t.file, e))), { durationMs: c };
3088
- }), zi = (e, t) => b.gen(function* () {
3088
+ `.pipe(b.mapError((e) => new Ri(t.migration.id, t.file, e))), { durationMs: c };
3089
+ }), Bi = (e, t) => b.gen(function* () {
3089
3090
  let n = yield* b.tryPromise({
3090
- try: () => Pi(ne(t, "migrations")),
3091
+ try: () => Fi(ne(t, "migrations")),
3091
3092
  catch: (e) => e
3092
3093
  });
3093
3094
  if (n.length === 0) return {
@@ -3095,25 +3096,25 @@ BEGIN
3095
3096
  skipped: []
3096
3097
  };
3097
3098
  let r = yield* b.tryPromise({
3098
- try: () => Fi(n),
3099
+ try: () => Ii(n),
3099
3100
  catch: (e) => e
3100
3101
  });
3101
3102
  if (r.length === 0) return {
3102
3103
  pending: [],
3103
3104
  skipped: []
3104
3105
  };
3105
- let i = new Set(yield* Ii(e));
3106
+ let i = new Set(yield* Li(e));
3106
3107
  return {
3107
3108
  pending: r.filter((e) => !i.has(e.migration.id)),
3108
3109
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3109
3110
  };
3110
- }), Bi = (e, t) => zi(e, t).pipe(b.map((e) => e.pending.map((e) => e.migration.id))), Vi = (e, t) => b.gen(function* () {
3111
- let { pending: n, skipped: r } = yield* zi(e, t.projectRoot);
3111
+ }), Vi = (e, t) => Bi(e, t).pipe(b.map((e) => e.pending.map((e) => e.migration.id))), Hi = (e, t) => b.gen(function* () {
3112
+ let { pending: n, skipped: r } = yield* Bi(e, t.projectRoot);
3112
3113
  if (n.length === 0) return {
3113
3114
  applied: [],
3114
3115
  skipped: r
3115
3116
  };
3116
- yield* T(e, { schema: t.lockSchema });
3117
+ yield* E(e, { schema: t.lockSchema });
3117
3118
  let i = [];
3118
3119
  try {
3119
3120
  for (let r of n) {
@@ -3122,7 +3123,7 @@ BEGIN
3122
3123
  id: r.migration.id,
3123
3124
  file: r.file
3124
3125
  }));
3125
- let { durationMs: n } = yield* Ri(e, r, t.env, t.appliedBy);
3126
+ let { durationMs: n } = yield* zi(e, r, t.env, t.appliedBy);
3126
3127
  i.push({
3127
3128
  id: r.migration.id,
3128
3129
  durationMs: n
@@ -3133,28 +3134,28 @@ BEGIN
3133
3134
  }));
3134
3135
  }
3135
3136
  } finally {
3136
- yield* E(e, { schema: t.lockSchema }).pipe(b.orDie);
3137
+ yield* D(e, { schema: t.lockSchema }).pipe(b.orDie);
3137
3138
  }
3138
3139
  return {
3139
3140
  applied: i,
3140
3141
  skipped: r
3141
3142
  };
3142
- }), Hi = (e, t) => e`
3143
+ }), Ui = (e, t) => e`
3143
3144
  SELECT ${e("id")}
3144
3145
  FROM ${e("_voltro_migration_plans")}
3145
3146
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3146
3147
  LIMIT 1
3147
- `, Ui = (e, t) => b.gen(function* () {
3148
- if (!(yield* Hi(e, t.id))[0]) return yield* b.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3148
+ `, Wi = (e, t) => b.gen(function* () {
3149
+ if (!(yield* Ui(e, t.id))[0]) return yield* b.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3149
3150
  let n = yield* b.tryPromise({
3150
- try: () => Pi(ne(t.projectRoot, "migrations")),
3151
+ try: () => Fi(ne(t.projectRoot, "migrations")),
3151
3152
  catch: (e) => e
3152
3153
  }), r = (yield* b.tryPromise({
3153
- try: () => Fi(n),
3154
+ try: () => Ii(n),
3154
3155
  catch: (e) => e
3155
3156
  })).find((e) => e.migration.id === t.id);
3156
3157
  if (!r) return yield* b.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
3157
- yield* T(e, { schema: t.lockSchema });
3158
+ yield* E(e, { schema: t.lockSchema });
3158
3159
  let i = Date.now();
3159
3160
  try {
3160
3161
  let n = {
@@ -3181,9 +3182,9 @@ BEGIN
3181
3182
  durationMs: o
3182
3183
  };
3183
3184
  } finally {
3184
- yield* E(e, { schema: t.lockSchema }).pipe(b.orDie);
3185
+ yield* D(e, { schema: t.lockSchema }).pipe(b.orDie);
3185
3186
  }
3186
- }), Wi = (e) => b.gen(function* () {
3187
+ }), Gi = (e) => b.gen(function* () {
3187
3188
  let t = yield* C.SqlClient, n = yield* t`
3188
3189
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3189
3190
  WHERE source = 'auto-diff'
@@ -3228,7 +3229,7 @@ BEGIN
3228
3229
  snapshotFingerprint: e.fingerprint,
3229
3230
  snapshotId: i
3230
3231
  };
3231
- }), Gi = { safe: !0 }, Ki = (e) => {
3232
+ }), Ki = { safe: !0 }, qi = (e) => {
3232
3233
  switch (e.kind) {
3233
3234
  case "drop-column": return {
3234
3235
  safe: !1,
@@ -3255,7 +3256,7 @@ BEGIN
3255
3256
  reason: `old instances read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
3256
3257
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3257
3258
  };
3258
- case "alter-column-nullability": return e.toNullable ? Gi : {
3259
+ case "alter-column-nullability": return e.toNullable ? Ki : {
3259
3260
  safe: !1,
3260
3261
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3261
3262
  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)`
@@ -3285,12 +3286,12 @@ BEGIN
3285
3286
  case "drop-unique":
3286
3287
  case "drop-unique-composite":
3287
3288
  case "drop-foreign-key":
3288
- case "drop-check": return Gi;
3289
+ case "drop-check": return Ki;
3289
3290
  }
3290
- }, qi = (e) => {
3291
+ }, Ji = (e) => {
3291
3292
  let t = [];
3292
3293
  for (let n of e) {
3293
- let e = Ki(n.op);
3294
+ let e = qi(n.op);
3294
3295
  e.safe || t.push({
3295
3296
  op: n,
3296
3297
  reason: e.reason,
@@ -3298,7 +3299,7 @@ BEGIN
3298
3299
  });
3299
3300
  }
3300
3301
  return t;
3301
- }, Ji = (e) => {
3302
+ }, Yi = (e) => {
3302
3303
  if (!e.enabled || e.unsafeCount === 0) return {
3303
3304
  refuse: !1,
3304
3305
  warnForced: !1,
@@ -3314,18 +3315,18 @@ BEGIN
3314
3315
  warnForced: !1,
3315
3316
  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.`
3316
3317
  };
3317
- }, Yi = (e) => {
3318
+ }, Xi = (e) => {
3318
3319
  let t = e.table;
3319
3320
  if (typeof t == "string") return t;
3320
3321
  let n = e.from;
3321
3322
  return typeof n == "string" ? n : void 0;
3322
- }, Xi = (e) => ({
3323
+ }, Zi = (e) => ({
3323
3324
  kind: e.op.kind,
3324
- table: Yi(e.op),
3325
+ table: Xi(e.op),
3325
3326
  classification: e.classification,
3326
3327
  reason: e.reason,
3327
3328
  blockedFix: e.blocked?.fix
3328
- }), Zi = (e) => e.operations.map(Xi), Qi = async (e) => {
3329
+ }), Qi = (e) => e.operations.map(Zi), $i = async (e) => {
3329
3330
  let t = e.log ?? (() => {}), n = {
3330
3331
  branchId: e.branchId,
3331
3332
  mechanism: e.mechanism,
@@ -3344,10 +3345,10 @@ BEGIN
3344
3345
  applied: !1,
3345
3346
  converged: !1,
3346
3347
  residual: r,
3347
- infidelity: Zi(o)
3348
+ infidelity: Qi(o)
3348
3349
  };
3349
3350
  else {
3350
- let i = await e.plan(), o = Zi(i), s = o.filter((e) => e.classification === "lossy"), c = Oi(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Xi);
3351
+ let i = await e.plan(), o = Qi(i), s = o.filter((e) => e.classification === "lossy"), c = ki(i), l = c.operations.filter((e) => e.blocked !== void 0).map(Zi);
3351
3352
  if (l.length > 0) a = {
3352
3353
  ...n,
3353
3354
  outcome: "blocked",
@@ -3372,7 +3373,7 @@ BEGIN
3372
3373
  };
3373
3374
  else {
3374
3375
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3375
- let i = Zi(await e.replan());
3376
+ let i = Qi(await e.replan());
3376
3377
  a = {
3377
3378
  ...n,
3378
3379
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3410,7 +3411,7 @@ BEGIN
3410
3411
  ...a,
3411
3412
  tornDown: o
3412
3413
  };
3413
- }, $i = (e) => {
3414
+ }, ea = (e) => {
3414
3415
  switch (e.outcome) {
3415
3416
  case "clean": return 0;
3416
3417
  case "lossy": return 2;
@@ -3419,22 +3420,22 @@ BEGIN
3419
3420
  case "infidelity": return 1;
3420
3421
  case "failed": return 1;
3421
3422
  }
3422
- }, ea = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, ta = (e) => {
3423
+ }, ta = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, na = (e) => {
3423
3424
  let t = [];
3424
3425
  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"}`);
3425
3426
  else if (e.outcome === "infidelity") {
3426
3427
  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:");
3427
- for (let n of e.infidelity) t.push(ea(n));
3428
+ for (let n of e.infidelity) t.push(ta(n));
3428
3429
  } else {
3429
3430
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3430
- for (let n of e.operations) t.push(ea(n));
3431
- if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(ea(n));
3431
+ for (let n of e.operations) t.push(ta(n));
3432
+ 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(ta(n));
3432
3433
  }
3433
3434
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3434
- }, na = (e, ...t) => ({
3435
+ }, ra = (e, ...t) => ({
3435
3436
  _tag: "RawSqlFragment",
3436
3437
  strings: [...e],
3437
3438
  values: [...t]
3438
- }), ra = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3439
+ }), ia = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3439
3440
  //#endregion
3440
- export { O as DEFAULT_CDC_CHANNEL, u as FILE_MIGRATION_PATTERN, Li as FileMigrationLedgerError, Ke as REACTIVE_TRIGGER_PREFIX, de as VOLTRO_MIGRATION_LOCK_KEY, T as acquireMigrationLock, H as appliedAtValue, Ft as applyNamespacedSchema, _i as applyPlan, Tt as applySchema, Ji as assessRollingDeployGate, $i as branchRehearsalExitCode, In as chunkTables, Ki as classifyRollingDeploySafety, F as declaredSnapshot, Qe as defaultArrayClause, Ze as defaultClause, j as defaultJsonClause, Mi as describeOutcome, Ei as destructiveScope, qt as detectReactiveTriggerDrift, Fr as emitAddIndexMysql, _r as emitCreateTableMysql, er as emitDropColumnDdl, tr as emitDropColumnDdlMysql, wt as emitFrameworkBootstrapSql, St as emitNamespaceProvisionDdl, Ct as emitNamespacedSchemaSql, xt as emitSchemaSql, N as fingerprintSchema, _e as fnv1a64, ta as formatBranchRehearsal, Jt as formatReactiveTriggerDrift, Ti as ignoreTablesFromEnv, Jn as introspectSchema, o as isFileMigration, ra as isRawSqlFragment, Dt as isReRunSafeDdl, jn as mapPgType, h as migration, ve as migrationLockKeyForSchema, ye as migrationLockNameForSchema, jr as mysqlIndexPrefixFor, Je as notifyFunctionName, M as numericIdSql, An as parseEnumCheck, Bi as pendingFileMigrationIds, kn as planMigrations, It as provisionTenantNamespace, qe as reactiveTriggerName, ft as reactiveTriggerRepairSql, bi as recordUpToDate, Qi as rehearseMigrationOnBranch, Xi as rehearsedOperation, E as releaseMigrationLock, gr as renderColumnMysql, dr as renderColumnPg, pe as resolveMigrationLockSchema, Ui as rollbackFileBasedMigration, qi as rollingDeployUnsafeOps, Vi as runFileBasedMigrations, Lt as runFrameworkBootstrap, Pt as runMigrate, ji as runPlannedMigrations, P as shortFingerprint, Ut as snapshotColumn, na as sql, A as sqlType, Wi as squashMigrationPlans, Oi as unblockLossy, je as withMigrationLock };
3441
+ export { k as DEFAULT_CDC_CHANNEL, u as FILE_MIGRATION_PATTERN, Ri as FileMigrationLedgerError, Ke as REACTIVE_TRIGGER_PREFIX, fe as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, U as appliedAtValue, Ft as applyNamespacedSchema, vi as applyPlan, Tt as applySchema, Yi as assessRollingDeployGate, ea as branchRehearsalExitCode, In as chunkTables, qi as classifyRollingDeploySafety, I as declaredSnapshot, Qe as defaultArrayClause, Ze as defaultClause, M as defaultJsonClause, Ni as describeOutcome, Di as destructiveScope, qt as detectReactiveTriggerDrift, Ir as emitAddIndexMysql, _r as emitCreateTableMysql, er as emitDropColumnDdl, tr as emitDropColumnDdlMysql, wt as emitFrameworkBootstrapSql, St as emitNamespaceProvisionDdl, Ct as emitNamespacedSchemaSql, xt as emitSchemaSql, P as fingerprintSchema, ve as fnv1a64, na as formatBranchRehearsal, Jt as formatReactiveTriggerDrift, Ei as ignoreTablesFromEnv, Jn as introspectSchema, o as isFileMigration, ia as isRawSqlFragment, Dt as isReRunSafeDdl, jn as mapPgType, h as migration, ye as migrationLockKeyForSchema, T as migrationLockNameForSchema, Mr as mysqlIndexPrefixFor, Je as notifyFunctionName, N as numericIdSql, An as parseEnumCheck, Vi as pendingFileMigrationIds, kn as planMigrations, It as provisionTenantNamespace, qe as reactiveTriggerName, ft as reactiveTriggerRepairSql, xi as recordUpToDate, $i as rehearseMigrationOnBranch, Zi as rehearsedOperation, D as releaseMigrationLock, gr as renderColumnMysql, dr as renderColumnPg, me as resolveMigrationLockSchema, Wi as rollbackFileBasedMigration, Ji as rollingDeployUnsafeOps, Hi as runFileBasedMigrations, Lt as runFrameworkBootstrap, Pt as runMigrate, Mi as runPlannedMigrations, F as shortFingerprint, Ut as snapshotColumn, ra as sql, j as sqlType, Gi as squashMigrationPlans, ki as unblockLossy, je as withMigrationLock };