@voltro/database 0.65.0 → 0.66.1

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