@voltro/database 0.20.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sql.js CHANGED
@@ -1,4 +1,4 @@
1
- import { B as e, W as t, a as n, c as r, i, lt as a, n as o, r as s, rt as c, t as l, z as u } from "./fileBased-Dfuv6JWP.js";
1
+ import { B as e, W as t, a as n, c as r, i, lt as a, n as o, r as s, rt as c, t as l, z as u } from "./fileBased-CDnutVVk.js";
2
2
  import { Effect as d } from "effect";
3
3
  import { createLogger as f } from "@voltro/logger";
4
4
  import { SqlClient as p } from "@effect/sql";
@@ -39,7 +39,7 @@ var _ = (e, t, n, r = 400) => {
39
39
  t !== void 0 && s.push(`db.${e}: ${t}`);
40
40
  }
41
41
  return s.push(""), s.join("\n");
42
- }, v = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, te = (e) => e.replace(/"/g, "`"), y = (e) => typeof e == "string" ? e : e.name ?? String(e), ne = (e, t) => `_ua_${t}_${e}`.slice(0, 64), b = (e, t) => {
42
+ }, v = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, y = (e) => e.replace(/"/g, "`"), b = (e) => typeof e == "string" ? e : e.name ?? String(e), te = (e, t) => `_ua_${t}_${e}`.slice(0, 64), x = (e, t) => {
43
43
  if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(v)) return e;
44
44
  let n = { ...e.fields }, r = [], i = [];
45
45
  for (let t of e.appliedIndexes) {
@@ -47,11 +47,11 @@ var _ = (e, t, n, r = 400) => {
47
47
  r.push(t);
48
48
  continue;
49
49
  }
50
- let a = te(t.where), o = [];
50
+ let a = y(t.where), o = [];
51
51
  for (let r of t.fields) {
52
- let i = y(r);
52
+ let i = b(r);
53
53
  if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
54
- let s = ne(t.name, i);
54
+ let s = te(t.name, i);
55
55
  o.push(s), n[s] = {
56
56
  type: "text",
57
57
  nullable: !0,
@@ -74,54 +74,54 @@ var _ = (e, t, n, r = 400) => {
74
74
  appliedIndexes: r,
75
75
  appliedUniques: [...e.appliedUniques ?? [], ...i]
76
76
  };
77
- }, x = (e, t) => `${e}::${t}`, S = (e, t) => {
77
+ }, S = (e, t) => `${e}::${t}`, ne = (e, t) => {
78
78
  let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
79
79
  n.add(e);
80
80
  let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
81
- for (let t of o) n.has(t.target) ? i.add(x(e, t.column)) : r.has(t.target) || a(t.target);
81
+ for (let t of o) n.has(t.target) ? i.add(S(e, t.column)) : r.has(t.target) || a(t.target);
82
82
  n.delete(e), r.add(e);
83
83
  };
84
84
  for (let t of [...e].sort()) r.has(t) || a(t);
85
85
  return i;
86
- }, C = 6322741009312437n, re = 250, ie = () => {
86
+ }, re = 6322741009312437n, ie = 250, ae = () => {
87
87
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
88
88
  return Number.isFinite(e) && e > 0 ? e : 3e4;
89
- }, ae = (e) => d.gen(function* () {
90
- let t = ie(), n = Date.now();
89
+ }, oe = (e) => d.gen(function* () {
90
+ let t = ae(), n = Date.now();
91
91
  for (;;) {
92
92
  if ((yield* e`
93
93
  SELECT pg_try_advisory_lock(${"6322741009312437"}::bigint) AS got`)[0]?.got) return;
94
- Date.now() - n >= t && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(t / 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* d.sleep(`${re} millis`);
94
+ Date.now() - n >= t && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(t / 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* d.sleep(`${ie} millis`);
95
95
  }
96
- }), oe = (e) => d.gen(function* () {
97
- yield* e`SELECT pg_advisory_unlock(${C.toString()}::bigint)`;
98
- }), se = `voltro_migration_${C.toString(36)}`, ce = 30, le = (e) => d.gen(function* () {
96
+ }), se = (e) => d.gen(function* () {
97
+ yield* e`SELECT pg_advisory_unlock(${re.toString()}::bigint)`;
98
+ }), ce = `voltro_migration_${re.toString(36)}`, le = 30, ue = (e) => d.gen(function* () {
99
99
  (yield* e`
100
- SELECT GET_LOCK(${se}, ${ce}) AS got`)[0]?.got !== 1 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${se}' within ${ce}s (another migration is in progress, or a prior one left it held).`)));
101
- }), ue = (e) => d.gen(function* () {
102
- yield* e`SELECT RELEASE_LOCK(${se})`;
103
- }), de = `voltro_migration_${C.toString(36)}`, fe = 3e4, pe = (e) => d.gen(function* () {
100
+ SELECT GET_LOCK(${ce}, ${le}) AS got`)[0]?.got !== 1 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${ce}' within ${le}s (another migration is in progress, or a prior one left it held).`)));
101
+ }), de = (e) => d.gen(function* () {
102
+ yield* e`SELECT RELEASE_LOCK(${ce})`;
103
+ }), fe = `voltro_migration_${re.toString(36)}`, pe = 3e4, me = (e) => d.gen(function* () {
104
104
  let t = yield* e`
105
105
  DECLARE @res int;
106
- EXEC @res = sp_getapplock @Resource = ${de}, @LockMode = 'Exclusive',
107
- @LockOwner = 'Session', @LockTimeout = ${fe};
106
+ EXEC @res = sp_getapplock @Resource = ${fe}, @LockMode = 'Exclusive',
107
+ @LockOwner = 'Session', @LockTimeout = ${pe};
108
108
  SELECT @res AS res`;
109
- (t[0]?.res ?? -999) < 0 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${de}' (sp_getapplock returned ${t[0]?.res ?? "no row"}; another migration is in progress).`)));
110
- }), me = (e) => d.gen(function* () {
111
- yield* e`EXEC sp_releaseapplock @Resource = ${de}, @LockOwner = 'Session'`;
112
- }), he = d.void, w = (e) => e.onDialectOrElse({
113
- mysql: () => le(e),
114
- mssql: () => pe(e),
115
- sqlite: () => he,
116
- orElse: () => ae(e)
117
- }), T = (e) => e.onDialectOrElse({
109
+ (t[0]?.res ?? -999) < 0 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${fe}' (sp_getapplock returned ${t[0]?.res ?? "no row"}; another migration is in progress).`)));
110
+ }), he = (e) => d.gen(function* () {
111
+ yield* e`EXEC sp_releaseapplock @Resource = ${fe}, @LockOwner = 'Session'`;
112
+ }), ge = d.void, C = (e) => e.onDialectOrElse({
118
113
  mysql: () => ue(e),
119
114
  mssql: () => me(e),
120
- sqlite: () => he,
115
+ sqlite: () => ge,
121
116
  orElse: () => oe(e)
122
- }), ge = (e, t) => d.acquireUseRelease(w(e), () => t, () => T(e).pipe(d.orDie)), _e = f({ scope: "voltro:migrate" }), E = (e) => {
123
- _e.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
124
- }, D = (e, t) => {
117
+ }), w = (e) => e.onDialectOrElse({
118
+ mysql: () => de(e),
119
+ mssql: () => he(e),
120
+ sqlite: () => ge,
121
+ orElse: () => se(e)
122
+ }), _e = (e, t) => d.acquireUseRelease(C(e), () => t, () => w(e).pipe(d.orDie)), ve = f({ scope: "voltro:migrate" }), T = (e) => {
123
+ ve.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
124
+ }, E = (e, t) => {
125
125
  let n = e.type;
126
126
  if (e.spatial) {
127
127
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -132,7 +132,7 @@ var _ = (e, t, n, r = 400) => {
132
132
  return e.rawDdl;
133
133
  }
134
134
  if (n === "array" && e.arrayElement) {
135
- if (t === "postgres") return `${D({
135
+ if (t === "postgres") return `${E({
136
136
  ...e,
137
137
  type: e.arrayElement,
138
138
  arrayElement: void 0
@@ -232,22 +232,22 @@ var _ = (e, t, n, r = 400) => {
232
232
  case "array": return "TEXT[]";
233
233
  case "interval": return "INTERVAL";
234
234
  }
235
- }, ve = (e, t) => {
235
+ }, ye = (e, t) => {
236
236
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
237
237
  let n = e.defaultValue;
238
- return n === "now" ? u(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? ye(n, e, t) : typeof n == "object" && n ? O(n, t) : null;
239
- }, ye = (e, t, n) => {
240
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return O(e, n);
241
- let r = D({
238
+ return n === "now" ? u(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? be(n, e, t) : typeof n == "object" && n ? D(n, t) : null;
239
+ }, be = (e, t, n) => {
240
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return D(e, n);
241
+ let r = E({
242
242
  ...t,
243
243
  type: t.arrayElement,
244
244
  arrayElement: void 0
245
245
  }, n);
246
246
  return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
247
- }, O = (e, t) => {
247
+ }, D = (e, t) => {
248
248
  let n = JSON.stringify(e).replace(/'/g, "''");
249
249
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CAST('${n}' AS JSON))` : `DEFAULT '${n}'`;
250
- }, k = (e, t) => {
250
+ }, O = (e, t) => {
251
251
  switch (t) {
252
252
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
253
253
  case "mysql":
@@ -256,7 +256,7 @@ var _ = (e, t, n, r = 400) => {
256
256
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
257
257
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
258
258
  }
259
- }, be = (e, t) => {
259
+ }, k = (e, t) => {
260
260
  if (e === "restrict" && t === "mssql") return "NO ACTION";
261
261
  switch (e) {
262
262
  case "cascade": return "CASCADE";
@@ -269,33 +269,33 @@ var _ = (e, t, n, r = 400) => {
269
269
  if (r !== "mysql" && r !== "mariadb") return i;
270
270
  let a = n[t];
271
271
  if (!a) return i;
272
- let o = D(a, r).toUpperCase();
272
+ let o = E(a, r).toUpperCase();
273
273
  return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${Se})` : i;
274
274
  }, we = (e, t) => {
275
275
  if (!e.generatedAs) return null;
276
276
  let { expr: n, stored: r } = e.generatedAs;
277
- if (t === "postgres") return r || E("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
277
+ if (t === "postgres") return r || T("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
278
278
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
279
279
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
280
280
  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.");
281
281
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
282
282
  }, Te = (t, n, r, i, a = !1, o = !1) => {
283
- if (n.type === "id" && n.idScheme?.kind === "numeric") return k(t, r);
284
- let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : D(n, r), c = [e(t, r), s];
283
+ if (n.type === "id" && n.idScheme?.kind === "numeric") return O(t, r);
284
+ let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : E(n, r), c = [e(t, r), s];
285
285
  n.type === "id" && !o && c.push("PRIMARY KEY");
286
286
  let l = we(n, r);
287
287
  if (l) c.push(l);
288
288
  else {
289
289
  n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && c.push("UNIQUE");
290
- let e = ve(n, r);
290
+ let e = ye(n, r);
291
291
  e && c.push(e);
292
292
  }
293
293
  if (n.type === "reference" && n.references && !a) {
294
294
  let t = n.references();
295
295
  c.push(`REFERENCES ${e(t.tableName, r)} (${e("id", r)})`);
296
- let i = be(n.onDelete ?? "restrict", r);
296
+ let i = k(n.onDelete ?? "restrict", r);
297
297
  c.push(`ON DELETE ${i}`);
298
- let a = be(n.refOnUpdate ?? "noAction", r);
298
+ let a = k(n.refOnUpdate ?? "noAction", r);
299
299
  a !== "NO ACTION" && c.push(`ON UPDATE ${a}`);
300
300
  }
301
301
  if (n.oneOf && n.oneOf.length > 0) {
@@ -348,21 +348,21 @@ var _ = (e, t, n, r = 400) => {
348
348
  using: " USING GIST",
349
349
  withSuffix: "",
350
350
  skip: !1
351
- } : (E(`[voltro:migrate] index '${e}' on '${n}': ${r} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
351
+ } : (T(`[voltro:migrate] index '${e}' on '${n}': ${r} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
352
352
  if (i === "gin") return r === "postgres" ? {
353
353
  using: " USING GIN",
354
354
  withSuffix: "",
355
355
  skip: !1
356
- } : r === "mysql" || r === "mariadb" ? (E(`[voltro:migrate] gin index '${e}' on '${n}': ${r} 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(...).`), {
356
+ } : r === "mysql" || r === "mariadb" ? (T(`[voltro:migrate] gin index '${e}' on '${n}': ${r} 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(...).`), {
357
357
  using: "",
358
358
  withSuffix: "",
359
359
  skip: !0
360
- }) : (E(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
360
+ }) : (T(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
361
361
  if (i === "brin") return r === "postgres" ? {
362
362
  using: " USING BRIN",
363
363
  withSuffix: "",
364
364
  skip: !1
365
- } : (E(`[voltro:migrate] brin index '${e}' on '${n}': ${r} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
365
+ } : (T(`[voltro:migrate] brin index '${e}' on '${n}': ${r} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
366
366
  if (i === "hnsw") {
367
367
  if (r === "postgres") {
368
368
  let e = a?.hnsw?.m ?? 16, n = a?.hnsw?.efConstruction ?? 64, r = a?.hnsw?.opclass ?? t(a?.hnsw?.distance);
@@ -373,7 +373,7 @@ var _ = (e, t, n, r = 400) => {
373
373
  skip: !1
374
374
  };
375
375
  }
376
- return E(`[voltro:migrate] hnsw index '${e}' on '${n}': ${r} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
376
+ return T(`[voltro:migrate] hnsw index '${e}' on '${n}': ${r} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
377
377
  using: "",
378
378
  withSuffix: "",
379
379
  skip: !0
@@ -406,15 +406,15 @@ var _ = (e, t, n, r = 400) => {
406
406
  let i = t.columns.map((t) => e(t, r)).join(", ");
407
407
  o.push(`CREATE FULLTEXT INDEX ${e(t.name, r)} ON ${e(n.tableName, r)} (${i});`);
408
408
  } else if (r === "turso") throw Error(`@voltro/sql-turso: full-text index '${t.name}' on '${n.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
409
- else r === "sqlite" ? o.push(...De(n.tableName, t, r)) : E(`[voltro:migrate] full-text index '${t.name}' on '${n.tableName}': ${r} uses a ranked LIKE search at query time (no native FTS catalog required).`);
409
+ else r === "sqlite" ? o.push(...De(n.tableName, t, r)) : T(`[voltro:migrate] full-text index '${t.name}' on '${n.tableName}': ${r} uses a ranked LIKE search at query time (no native FTS catalog required).`);
410
410
  for (let e of n.appliedIndexes) {
411
411
  if ((r === "mariadb" || r === "mssql") && e.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
412
- E(`[voltro:migrate] json-path index '${e.name}' on '${n.tableName}': ${r} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${r}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
412
+ T(`[voltro:migrate] json-path index '${e.name}' on '${n.tableName}': ${r} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${r}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
413
413
  continue;
414
414
  }
415
415
  if (e.unique && e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${e.name}' on '${n.tableName}' cannot be expressed on ${r} — 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 ${r}, or move this table to postgres/sqlite/mssql.`);
416
416
  let t = "";
417
- e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb" ? E(`[voltro:migrate] partial index '${e.name}' on '${n.tableName}': ${r} does not support WHERE clauses on indexes — emitting a full index`) : t = ` WHERE ${e.where}`);
417
+ e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb" ? T(`[voltro:migrate] partial index '${e.name}' on '${n.tableName}': ${r} does not support WHERE clauses on indexes — emitting a full index`) : t = ` WHERE ${e.where}`);
418
418
  let i = d(e.name, n.tableName, e.fields, e.kind, e.kindOptions, t, e.unique === !0);
419
419
  i !== "" && o.push(i), e.fields.every((e) => typeof e == "string") && s.add(c(e.fields));
420
420
  }
@@ -431,7 +431,7 @@ CREATE TRIGGER framework_changes_${e.tableName}
431
431
  AFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"
432
432
  FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
433
433
  `.trim(), je = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), Me = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), Ne = (e) => {
434
- let t = new Map(e.map((e) => [e.tableName, e])), n = S(e.map((e) => e.tableName), (e) => {
434
+ let t = new Map(e.map((e) => [e.tableName, e])), n = ne(e.map((e) => e.tableName), (e) => {
435
435
  let n = t.get(e);
436
436
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
437
437
  if (n.type !== "reference" || !n.references) return [];
@@ -442,7 +442,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
442
442
  }] : [];
443
443
  }) : [];
444
444
  }), r = [];
445
- for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(x(t.tableName, e)) && r.push({
445
+ for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(S(t.tableName, e)) && r.push({
446
446
  table: t.tableName,
447
447
  column: e,
448
448
  targetTable: i.references().tableName,
@@ -453,7 +453,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
453
453
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
454
454
  a.add(e.tableName);
455
455
  for (let [r, i] of Object.entries(e.fields)) {
456
- if (i.type !== "reference" || !i.references || n.has(x(e.tableName, r))) continue;
456
+ if (i.type !== "reference" || !i.references || n.has(S(e.tableName, r))) continue;
457
457
  let a = i.references();
458
458
  if (a.tableName === e.tableName) continue;
459
459
  let o = t.get(a.tableName);
@@ -468,7 +468,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
468
468
  cyclic: r
469
469
  };
470
470
  }, Pe = (t, n, r = null) => {
471
- let i = (t) => r ? `${e(r, n)}.${e(t, n)}` : e(t, n), a = `${t.table}_${t.column}_fkey`, o = be(t.onDelete, n), s = be(t.onUpdate, n), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${e(a, n)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${e(t.column, n)}) REFERENCES ${i(t.targetTable)} (${e("id", n)})${c}`;
471
+ let i = (t) => r ? `${e(r, n)}.${e(t, n)}` : e(t, n), a = `${t.table}_${t.column}_fkey`, o = k(t.onDelete, n), s = k(t.onUpdate, n), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${e(a, n)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${e(t.column, n)}) REFERENCES ${i(t.targetTable)} (${e("id", n)})${c}`;
472
472
  switch (n) {
473
473
  case "postgres": return [
474
474
  "DO $$ BEGIN",
@@ -528,7 +528,7 @@ BEGIN
528
528
  views: r
529
529
  };
530
530
  }, A = (e, t) => {
531
- let { tables: n, views: i } = Re(e), { sorted: a, cyclic: o } = Ne(n.map((e) => b(e, t))), s = Fe(o, t), c = [];
531
+ let { tables: n, views: i } = Re(e), { sorted: a, cyclic: o } = Ne(n.map((e) => x(e, t))), s = Fe(o, t), c = [];
532
532
  t === "postgres" && je(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && Me(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
533
533
  let l = Le(a, t);
534
534
  l && c.push(l);
@@ -569,43 +569,29 @@ BEGIN
569
569
  t && d.push(t);
570
570
  }
571
571
  return d.join("\n\n") + "\n";
572
- }, Ve = (t, n) => {
573
- if (n !== "postgres") return A(t, n);
574
- let { sorted: r, cyclic: i } = Ne(t), a = Fe(i, n), o = [], s = Le(r, n);
575
- s && o.push(s);
576
- let c = Ie(r, n);
577
- c && o.push(c);
578
- for (let e of r) o.push(Ee(e, n, null, a.get(e.tableName)));
579
- for (let e of i) o.push(Pe(e, n));
580
- for (let t of r) {
581
- let r = Object.entries(t.fields);
582
- if (r.length === 0) continue;
583
- let i = r.map(([r, i]) => {
584
- let o = Te(r, i, n, void 0, a.get(t.tableName)?.has(r) ?? !1);
585
- return `ALTER TABLE ${e(t.tableName, n)} ADD COLUMN IF NOT EXISTS ${o};`;
586
- });
587
- o.push(i.join("\n"));
588
- }
589
- for (let e of r) {
590
- let t = Oe(e, n);
591
- t && o.push(t);
592
- }
593
- let l = r.filter((e) => e.isReactive);
594
- if (l.length > 0) {
595
- o.push(ke);
596
- for (let e of l) o.push(Ae(e));
597
- }
598
- return o.join("\n\n") + "\n";
572
+ }, Ve = (e, t) => {
573
+ let { sorted: n, cyclic: r } = Ne(e), i = Fe(r, t), a = [], o = Le(n, t);
574
+ o && a.push(o);
575
+ let s = Ie(n, t);
576
+ s && a.push(s);
577
+ for (let e of n) a.push(Ee(e, t, null, i.get(e.tableName)));
578
+ for (let e of r) a.push(Pe(e, t));
579
+ let c = n.filter((e) => e.isReactive);
580
+ if (c.length > 0) {
581
+ a.push(ke);
582
+ for (let e of c) a.push(Ae(e));
583
+ }
584
+ return a.join("\n\n") + "\n";
599
585
  }, He = (e, t = "postgres") => d.gen(function* () {
600
586
  let n = yield* p.SqlClient;
601
- yield* ge(n, Ge(n, A(e, t), t)).pipe(d.orDie);
587
+ yield* _e(n, Ge(n, A(e, t), t)).pipe(d.orDie);
602
588
  }), Ue = (e, t) => {
603
589
  let n = t.cause ?? {};
604
590
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
605
591
  }, We = (e) => d.gen(function* () {
606
592
  let t = yield* p.SqlClient;
607
- for (let n of Ke(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && _e.debug(`EXEC: ${n.replace(/\s+/g, " ").slice(0, 180)}`), yield* t.unsafe(n).pipe(d.catchIf((e) => Ue(n, e), () => d.void), d.tapError((e) => d.sync(() => {
608
- _e.error(_("migrate: statement failed", n, e, 200));
593
+ for (let n of Ke(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && ve.debug(`EXEC: ${n.replace(/\s+/g, " ").slice(0, 180)}`), yield* t.unsafe(n).pipe(d.catchIf((e) => Ue(n, e), () => d.void), d.tapError((e) => d.sync(() => {
594
+ ve.error(_("migrate: statement failed", n, e, 200));
609
595
  })), d.orDieWith((e) => Error(_("migrate: statement failed", n, e, 400).trim())));
610
596
  }), Ge = (e, t, n) => (n === "turso" ? We(t) : e.withTransaction(We(t))).pipe(d.orDie), Ke = (e) => {
611
597
  let t = [], n = "", r = !1;
@@ -626,13 +612,13 @@ BEGIN
626
612
  await d.runPromise(He(e, n).pipe(d.provide(t)));
627
613
  }, Je = (e, t, n = "postgres") => d.gen(function* () {
628
614
  let r = Be(e, n, t), i = yield* p.SqlClient;
629
- yield* ge(i, Ge(i, r, n)).pipe(d.orDie);
615
+ yield* _e(i, Ge(i, r, n)).pipe(d.orDie);
630
616
  }), Ye = async (e, t, n, r = "postgres") => {
631
617
  await d.runPromise(Je(e, t, r).pipe(d.provide(n)));
632
618
  }, Xe = async (e, t, n = "postgres") => {
633
619
  await d.runPromise(d.gen(function* () {
634
620
  let t = Ve(e, n), r = yield* p.SqlClient;
635
- yield* ge(r, Ge(r, t, n)).pipe(d.orDie);
621
+ yield* _e(r, Ge(r, t, n)).pipe(d.orDie);
636
622
  }).pipe(d.provide(t)));
637
623
  }, Ze = (e) => {
638
624
  if (e == null) return e;
@@ -674,6 +660,7 @@ BEGIN
674
660
  ...t.oneOf && t.oneOf.length > 0 ? { oneOf: t.oneOf } : {},
675
661
  ...t.idScheme ? { idScheme: { kind: t.idScheme.kind } } : {},
676
662
  ...t.rawDdl === void 0 ? {} : { rawDdl: t.rawDdl },
663
+ ...t.maxLength === void 0 ? {} : { maxLength: t.maxLength },
677
664
  ...t.precision === void 0 ? {} : { precision: t.precision },
678
665
  ...t.scale === void 0 ? {} : { scale: t.scale },
679
666
  ...t.generatedAs ? { generatedAs: {
@@ -751,12 +738,13 @@ BEGIN
751
738
  unique: !0
752
739
  } : e);
753
740
  }
754
- let r = e.appliedPrimaryKey ?? [];
741
+ let r = e.appliedPrimaryKey ?? [], i = e.previousTableName;
755
742
  return {
756
743
  name: e.tableName,
757
744
  columns: n,
758
745
  indexes: rt(e),
759
- ...r.length > 0 ? { primaryKey: [...r] } : {}
746
+ ...r.length > 0 ? { primaryKey: [...r] } : {},
747
+ ...i === void 0 ? {} : { renamedFrom: i }
760
748
  };
761
749
  }, at = (e) => {
762
750
  let t = /* @__PURE__ */ new Map();
@@ -766,7 +754,7 @@ BEGIN
766
754
  t.set(e.name, n.name);
767
755
  }
768
756
  }, N = (e, t) => {
769
- let n = e.map((e) => it(b(e, t)));
757
+ let n = e.map((e) => it(x(e, t)));
770
758
  return at(n), { tables: n };
771
759
  }, ot = "framework_changes_", st = (e, t) => d.gen(function* () {
772
760
  let n = t.filter((e) => !e.tableName.startsWith("_voltro_"));
@@ -802,19 +790,19 @@ BEGIN
802
790
  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.`);
803
791
  }
804
792
  return t.length > 0 ? t.join("\n") : void 0;
805
- }, lt = /* @__PURE__ */ new Set(["voltro_isr_cache"]), P = (e) => lt.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), ut = /__dropped_\d{14}$/, dt = (e) => ut.test(e), ft = {
793
+ }, lt = /* @__PURE__ */ new Set(["voltro_isr_cache"]), ut = (e) => lt.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), dt = /__dropped_\d{14}$/, ft = (e) => dt.test(e), pt = {
806
794
  postgres: !0,
807
795
  mysql: !0,
808
796
  mariadb: !0,
809
797
  mssql: !0,
810
798
  sqlite: !0
811
- }, pt = {
799
+ }, mt = {
812
800
  postgres: !0,
813
801
  mysql: !1,
814
802
  mariadb: !1,
815
803
  mssql: !0,
816
804
  sqlite: !0
817
- }, mt = (e) => {
805
+ }, ht = (e) => {
818
806
  switch (e) {
819
807
  case "add-column":
820
808
  case "drop-column":
@@ -824,43 +812,43 @@ BEGIN
824
812
  case "add-foreign-key":
825
813
  case "add-unique":
826
814
  case "add-unique-composite":
827
- case "add-check": return pt;
828
- default: return ft;
815
+ case "add-check": return mt;
816
+ default: return pt;
829
817
  }
830
- }, ht = (e, t) => {
818
+ }, gt = (e, t) => {
831
819
  let n = new Map(t.tables.map((e) => [e.name, e]));
832
820
  return new Map(e.map((e) => [e.tableName, {
833
821
  table: e,
834
822
  snapshot: n.get(e.tableName),
835
823
  columnDefs: e.fields
836
824
  }]));
837
- }, F = (e) => {
825
+ }, P = (e) => {
838
826
  if (typeof e != "object" || !e) return JSON.stringify(e);
839
- if (Array.isArray(e)) return `[${e.map(F).join(",")}]`;
827
+ if (Array.isArray(e)) return `[${e.map(P).join(",")}]`;
840
828
  let t = e;
841
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${F(t[e])}`).join(",")}}`;
842
- }, gt = (e) => {
829
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${P(t[e])}`).join(",")}}`;
830
+ }, _t = (e) => {
843
831
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
844
832
  let t = e.defaultValue;
845
833
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
846
834
  if (typeof t == "number") return String(t);
847
- if (typeof t != "string") return F(t);
835
+ if (typeof t != "string") return P(t);
848
836
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
849
837
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
850
838
  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);
851
839
  if (o) try {
852
- return F(JSON.parse(o[1]));
840
+ return P(JSON.parse(o[1]));
853
841
  } catch {}
854
842
  if (a.startsWith("{") || a.startsWith("[")) try {
855
- return F(JSON.parse(a));
843
+ return P(JSON.parse(a));
856
844
  } catch {}
857
845
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
858
- }, _t = (e, t) => {
859
- let n = gt(e), r = gt(t);
846
+ }, vt = (e, t) => {
847
+ let n = _t(e), r = _t(t);
860
848
  if (n === r) return !0;
861
849
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
862
850
  return i(n) === i(r);
863
- }, I = (e) => {
851
+ }, F = (e) => {
864
852
  if (!e) return null;
865
853
  let t = (e) => e === "restrict" ? "noAction" : e;
866
854
  return {
@@ -869,77 +857,84 @@ BEGIN
869
857
  onDelete: t(e.onDelete),
870
858
  onUpdate: t(e.onUpdate)
871
859
  };
872
- }, vt = (e, t) => {
860
+ }, yt = (e, t) => {
873
861
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
874
862
  if (!n && !r) return !0;
875
863
  if (!n || !r || n.length !== r.length) return !1;
876
864
  let i = [...n].sort(), a = [...r].sort();
877
865
  return i.every((e, t) => e === a[t]);
878
- }, yt = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && _t(e, t) && JSON.stringify(I(e.references)) === JSON.stringify(I(t.references)) && vt(e.oneOf, t.oneOf), bt = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
866
+ }, bt = (e, t) => {
867
+ try {
868
+ let n = /\((\d+)\)/.exec(E(e, t));
869
+ return n ? Number(n[1]) : void 0;
870
+ } catch {
871
+ return;
872
+ }
873
+ }, xt = (e, t, n) => n === void 0 || u(n) ? !0 : e.type !== "text" || t.type !== "text" || bt(e, n) === t.maxLength, St = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && vt(e, t) && xt(e, t, n) && JSON.stringify(F(e.references)) === JSON.stringify(F(t.references)) && yt(e.oneOf, t.oneOf), Ct = (e, t) => t.oneOf && t.oneOf.length > 0 ? I({
879
874
  kind: "add-check",
880
875
  table: e,
881
876
  column: t.name,
882
877
  values: t.oneOf
883
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, xt = (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])), St = (e, t) => {
884
- let n = new Map(t.columns.map((e) => [e.name, e])), r = new Map(e.columns.map((e) => [e.name, e])), i = [], a = [], o = [];
878
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, wt = (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])), Tt = (e, t, n) => {
879
+ let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [];
885
880
  for (let t of e.columns) {
886
- let e = n.get(t.name);
881
+ let e = r.get(t.name);
887
882
  if (!e) {
888
- i.push(t);
883
+ a.push(t);
889
884
  continue;
890
885
  }
891
- yt(t, e) || o.push({
886
+ St(t, e, n) || s.push({
892
887
  declared: t,
893
888
  live: e
894
889
  });
895
890
  }
896
- for (let e of t.columns) r.has(e.name) || a.push(e);
891
+ for (let e of t.columns) i.has(e.name) || o.push(e);
897
892
  return {
898
- added: i,
899
- removed: a,
900
- changed: o
893
+ added: a,
894
+ removed: o,
895
+ changed: s
901
896
  };
902
- }, Ct = (e, t) => {
897
+ }, Et = (e, t) => {
903
898
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
904
899
  for (let t of e.indexes) {
905
900
  let e = n.get(t.name);
906
- (!e || !xt(t, e)) && i.push(t);
901
+ (!e || !wt(t, e)) && i.push(t);
907
902
  }
908
903
  for (let e of t.indexes) r.has(e.name) || a.push(e);
909
904
  return {
910
905
  added: i,
911
906
  removed: a
912
907
  };
913
- }, L = (e, t, n, r) => ({
908
+ }, I = (e, t, n, r) => ({
914
909
  op: e,
915
910
  classification: t,
916
- atomicByDialect: mt(e.kind),
911
+ atomicByDialect: ht(e.kind),
917
912
  ...n ? { reason: n } : {},
918
913
  ...r ? { blocked: r } : {}
919
- }), wt = (e, t, n) => {
914
+ }), Dt = (e, t, n) => {
920
915
  let r = {
921
916
  kind: "add-column",
922
917
  table: e,
923
918
  column: t
924
919
  };
925
- 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` });
926
- }, Tt = (e, t, n) => {
920
+ return t.nullable ? I(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? I(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? I(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : I(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` });
921
+ }, Ot = (e, t, n) => {
927
922
  let r = {
928
923
  kind: "drop-column",
929
924
  table: e,
930
925
  column: t.name
931
926
  };
932
- 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` });
933
- }, Et = (e, t, n, r) => L({
927
+ return n?.dropped ? I(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : I(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
928
+ }, kt = (e, t, n, r, i) => I({
934
929
  kind: "create-table",
935
930
  table: e,
936
931
  columns: t,
937
932
  indexes: n,
938
933
  ...r && r.length > 0 ? { primaryKey: r } : {}
939
- }, "safe", "new table — no data to preserve"), Dt = (e) => L({
934
+ }, "safe", i ?? "new table — no data to preserve"), At = (e) => I({
940
935
  kind: "drop-table",
941
936
  table: e
942
- }, "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" }), Ot = 5e4, kt = (e, t, n, r) => {
937
+ }, "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" }), jt = 5e4, Mt = (e, t, n, r) => {
943
938
  let i = (n ?? 0) >= r, a;
944
939
  return a = t.unique ? t.columns.length === 1 ? {
945
940
  kind: "add-unique",
@@ -954,16 +949,16 @@ BEGIN
954
949
  kind: "add-index",
955
950
  table: e,
956
951
  index: t
957
- }, 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");
958
- }, At = (e, t) => t.unique && t.columns.length > 1 ? L({
952
+ }, i ? I(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : I(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
953
+ }, Nt = (e, t) => t.unique && t.columns.length > 1 ? I({
959
954
  kind: "drop-unique-composite",
960
955
  table: e,
961
956
  name: t.name
962
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
957
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : I({
963
958
  kind: "drop-index",
964
959
  table: e,
965
960
  index: t.name
966
- }, "safe", "drop index (no data loss — index is derived data)"), jt = (e, t) => {
961
+ }, "safe", "drop index (no data loss — index is derived data)"), Pt = (e, t) => {
967
962
  if (e === "reference") return "text";
968
963
  switch (t) {
969
964
  case "sqlite":
@@ -971,7 +966,7 @@ BEGIN
971
966
  case "mssql": return e === "json" ? "text" : e;
972
967
  default: return e;
973
968
  }
974
- }, Mt = (e, t, n, r, i, a) => {
969
+ }, Ft = (e, t, n, r, i, a) => {
975
970
  let o = [];
976
971
  if (t.nullable !== n.nullable) {
977
972
  let n = {
@@ -980,7 +975,7 @@ BEGIN
980
975
  column: t.name,
981
976
  toNullable: t.nullable
982
977
  };
983
- 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`));
978
+ o.push(t.nullable ? I(n, "safe", `loosen ${e}.${t.name} to nullable`) : I(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
984
979
  }
985
980
  if (t.unique !== n.unique) if (t.unique) {
986
981
  let n = {
@@ -988,13 +983,13 @@ BEGIN
988
983
  table: e,
989
984
  column: t.name
990
985
  }, r = (i ?? 0) >= a;
991
- 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)`));
992
- } else o.push(L({
986
+ o.push(r ? I(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : I(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
987
+ } else o.push(I({
993
988
  kind: "drop-unique",
994
989
  table: e,
995
990
  column: t.name
996
991
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
997
- if (jt(t.type, r) !== jt(n.type, r)) {
992
+ if (Pt(t.type, r) !== Pt(n.type, r)) {
998
993
  let r = t.narrowedFrom;
999
994
  if (r && r.from === n.type) {
1000
995
  let i = {
@@ -1005,7 +1000,7 @@ BEGIN
1005
1000
  to: t.type,
1006
1001
  ...r.using === void 0 ? {} : { using: r.using }
1007
1002
  };
1008
- o.push(L(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1003
+ o.push(I(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1009
1004
  } else {
1010
1005
  let r = {
1011
1006
  kind: "alter-column-type",
@@ -1014,10 +1009,20 @@ BEGIN
1014
1009
  from: n.type,
1015
1010
  to: t.type
1016
1011
  };
1017
- o.push(L(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1012
+ o.push(I(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1018
1013
  }
1019
1014
  }
1020
- if (!_t(t, n)) {
1015
+ if (t.type === "text" && n.type === "text" && !u(r ?? "postgres") && t.maxLength !== n.maxLength) {
1016
+ 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})`;
1017
+ o.push(I({
1018
+ kind: "alter-column-type",
1019
+ table: e,
1020
+ column: t.name,
1021
+ from: "text",
1022
+ to: "text"
1023
+ }, 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)}`));
1024
+ }
1025
+ if (!vt(t, n)) {
1021
1026
  let n = {
1022
1027
  kind: "alter-column-default",
1023
1028
  table: e,
@@ -1025,18 +1030,18 @@ BEGIN
1025
1030
  hasDefault: t.hasDefault,
1026
1031
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1027
1032
  };
1028
- o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1033
+ o.push(I(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1029
1034
  }
1030
- if (!vt(t.oneOf, n.oneOf)) {
1031
- n.oneOf && n.oneOf.length > 0 && o.push(L({
1035
+ if (!yt(t.oneOf, n.oneOf)) {
1036
+ n.oneOf && n.oneOf.length > 0 && o.push(I({
1032
1037
  kind: "drop-check",
1033
1038
  table: e,
1034
1039
  column: t.name
1035
1040
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1036
- let r = bt(e, t);
1041
+ let r = Ct(e, t);
1037
1042
  r && o.push(r);
1038
1043
  }
1039
- if (JSON.stringify(I(t.references)) !== JSON.stringify(I(n.references)) && (n.references && o.push(L({
1044
+ if (JSON.stringify(F(t.references)) !== JSON.stringify(F(n.references)) && (n.references && o.push(I({
1040
1045
  kind: "drop-foreign-key",
1041
1046
  table: e,
1042
1047
  column: t.name
@@ -1050,17 +1055,17 @@ BEGIN
1050
1055
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1051
1056
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1052
1057
  };
1053
- r === "null" && !t.nullable ? o.push(L(i, "lossy", `add FK ${e}.${t.name} → ${n}: 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` })) : r === "null" || r === "delete" ? o.push(L({
1058
+ r === "null" && !t.nullable ? o.push(I(i, "lossy", `add FK ${e}.${t.name} → ${n}: 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` })) : r === "null" || r === "delete" ? o.push(I({
1054
1059
  ...i,
1055
1060
  orphanPolicy: r
1056
- }, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(L(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
1061
+ }, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(I(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
1057
1062
  }
1058
1063
  return o;
1059
- }, Nt = (e, t, n) => {
1064
+ }, It = (e, t, n) => {
1060
1065
  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));
1061
1066
  for (let [n, c] of Object.entries(t)) {
1062
1067
  let t = c.renamedFrom;
1063
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1068
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(I({
1064
1069
  kind: "rename-column",
1065
1070
  table: e.tableName,
1066
1071
  from: t,
@@ -1072,7 +1077,109 @@ BEGIN
1072
1077
  consumedAddedNames: i,
1073
1078
  consumedRemovedNames: a
1074
1079
  };
1075
- }, Pt = (e) => {
1080
+ }, Lt = /* @__PURE__ */ new Set([
1081
+ "postgres",
1082
+ "mysql",
1083
+ "mariadb",
1084
+ "mssql"
1085
+ ]), Rt = {
1086
+ ops: [],
1087
+ consumedAddedNames: /* @__PURE__ */ new Set(),
1088
+ consumedRemovedNames: /* @__PURE__ */ new Set()
1089
+ }, zt = (e) => !e.unique && !e.expression, Bt = (e, t, n, r, i) => {
1090
+ if (i === void 0 || !Lt.has(i)) return Rt;
1091
+ let a = t.added.filter((e) => zt(e) && !r.has(e.name));
1092
+ if (a.length === 0) return Rt;
1093
+ 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();
1094
+ for (let n of t.removed) {
1095
+ if (!zt(n)) continue;
1096
+ let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1097
+ if (r.length !== 1) continue;
1098
+ let i = r[0];
1099
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(I({
1100
+ kind: "rename-index",
1101
+ table: e,
1102
+ from: n.name,
1103
+ to: i.name
1104
+ }, "safe", "rename index in place — catalog-only, no rebuild")));
1105
+ }
1106
+ return {
1107
+ ops: c,
1108
+ consumedAddedNames: l,
1109
+ consumedRemovedNames: u
1110
+ };
1111
+ }, Vt = (e, t, n) => {
1112
+ let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1113
+ for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1114
+ for (let c of e.tables) {
1115
+ let e = c.renamedFrom;
1116
+ if (e !== void 0 && e !== c.name && t.has(e)) {
1117
+ if (t.has(c.name)) {
1118
+ r.push(I({
1119
+ kind: "rename-table",
1120
+ from: e,
1121
+ to: c.name
1122
+ }, "needs-rename-annotation", `.renamedFrom('${e}') cannot be applied — both '${e}' and '${c.name}' exist in the database`, { fix: `decide which holds the real rows: move them into '${c.name}' and drop '${e}', or drop the empty '${c.name}' so the rename can run. '${e}' is left untouched until you do.` }));
1123
+ continue;
1124
+ }
1125
+ if (n.has(e)) {
1126
+ o.set(c.name, `.renamedFrom('${e}') NOT applied — '${e}' is still declared by this schema, so it belongs to that declaration. This table is created empty; that is the intended outcome when an app owns a table of the same name.`);
1127
+ continue;
1128
+ }
1129
+ if ((s.get(e) ?? 0) !== 1) {
1130
+ r.push(I({
1131
+ kind: "rename-table",
1132
+ from: e,
1133
+ to: c.name
1134
+ }, "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.` }));
1135
+ continue;
1136
+ }
1137
+ i.set(c.name, e), a.add(e), r.push(I({
1138
+ kind: "rename-table",
1139
+ from: e,
1140
+ to: c.name
1141
+ }, "safe", `rename via \`.renamedFrom('${e}')\` — catalog-only, the rows stay put`));
1142
+ }
1143
+ }
1144
+ return {
1145
+ ops: r,
1146
+ renamedInto: i,
1147
+ renamedFromNames: a,
1148
+ claimedOldNames: c,
1149
+ refusals: o
1150
+ };
1151
+ }, Ht = (e, t, n, r) => {
1152
+ if (t === void 0) return {
1153
+ live: e,
1154
+ ops: []
1155
+ };
1156
+ let i = r !== void 0 && Lt.has(r), a = [], o = e.indexes.map((e) => {
1157
+ if (!e.name.startsWith(t)) return e;
1158
+ let r = `${n}${e.name.slice(t.length)}`;
1159
+ return r === e.name ? e : e.name === `${t}_pkey` ? {
1160
+ ...e,
1161
+ name: r,
1162
+ table: n
1163
+ } : i ? (a.push(I({
1164
+ kind: "rename-index",
1165
+ table: n,
1166
+ from: e.name,
1167
+ to: r
1168
+ }, "safe", "auto-named index follows its renamed table — catalog-only, no rebuild")), {
1169
+ ...e,
1170
+ name: r,
1171
+ table: n
1172
+ }) : e;
1173
+ });
1174
+ return {
1175
+ live: {
1176
+ ...e,
1177
+ indexes: o,
1178
+ name: n
1179
+ },
1180
+ ops: a
1181
+ };
1182
+ }, Ut = (e) => {
1076
1183
  let t = {
1077
1184
  safe: 0,
1078
1185
  needsDefault: 0,
@@ -1107,46 +1214,51 @@ BEGIN
1107
1214
  break;
1108
1215
  }
1109
1216
  return t;
1110
- }, Ft = (e) => {
1111
- let t = N(e.declared, e.dialect), n = ht(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Ot, a = [];
1112
- for (let e of t.tables) if (!r.has(e.name)) {
1113
- a.push(Et(e.name, e.columns, e.indexes, e.primaryKey));
1217
+ }, Wt = (e) => {
1218
+ let t = N(e.declared, e.dialect), n = gt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? jt, a = [], o = Vt(t, r, n);
1219
+ a.push(...o.ops);
1220
+ for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1221
+ a.push(kt(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1114
1222
  for (let t of e.columns) {
1115
- let n = bt(e.name, t);
1223
+ let n = Ct(e.name, t);
1116
1224
  n && a.push(n);
1117
1225
  }
1118
1226
  }
1119
- let o = new Set(e.ignoreTables ?? []);
1120
- for (let t of e.live.tables) n.has(t.name) || P(t.name) || dt(t.name) || o.has(t.name) || a.push(Dt(t.name));
1121
- for (let o of t.tables) {
1122
- let t = r.get(o.name);
1123
- if (!t) continue;
1124
- let s = n.get(o.name), c = St(o, t), l = Ct(o, t), u = Nt(s.table, s.columnDefs, c);
1125
- a.push(...u.ops);
1126
- for (let e of c.removed) {
1127
- if (u.consumedRemovedNames.has(e.name) || dt(e.name)) continue;
1128
- let t = s.columnDefs[e.name];
1129
- a.push(Tt(o.name, e, t));
1227
+ let s = new Set(e.ignoreTables ?? []);
1228
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || ut(t.name) || ft(t.name) || s.has(t.name) || a.push(At(t.name));
1229
+ for (let s of t.tables) {
1230
+ let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1231
+ if (!c) continue;
1232
+ let l = Ht(c, t, s.name, e.dialect);
1233
+ a.push(...l.ops);
1234
+ let u = l.live, d = n.get(s.name), f = Tt(s, u, e.dialect), p = Et(s, u), m = It(d.table, d.columnDefs, f);
1235
+ a.push(...m.ops);
1236
+ for (let e of f.removed) {
1237
+ if (m.consumedRemovedNames.has(e.name) || ft(e.name)) continue;
1238
+ let t = d.columnDefs[e.name];
1239
+ a.push(Ot(s.name, e, t));
1130
1240
  }
1131
- for (let e of c.added) {
1132
- if (u.consumedAddedNames.has(e.name)) continue;
1133
- let t = s.columnDefs[e.name];
1134
- a.push(wt(o.name, e, t));
1135
- let n = bt(o.name, e);
1241
+ for (let e of f.added) {
1242
+ if (m.consumedAddedNames.has(e.name)) continue;
1243
+ let t = d.columnDefs[e.name];
1244
+ a.push(Dt(s.name, e, t));
1245
+ let n = Ct(s.name, e);
1136
1246
  n && a.push(n);
1137
1247
  }
1138
- for (let e of l.added) a.push(kt(o.name, e, t.rowCount, i));
1139
- for (let e of l.removed) a.push(At(o.name, e));
1140
- for (let { declared: n, live: r } of c.changed) a.push(...Mt(o.name, n, r, e.dialect, t.rowCount, i));
1141
- }
1142
- let s = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), c = new Map(t.tables.map((e) => [e.name, e])), l = (e) => {
1143
- let t = c.get(e);
1144
- return t ? t.columns.flatMap((e) => e.references && s.has(e.references.table) ? [{
1248
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Bt(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1249
+ a.push(...g.ops);
1250
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(Mt(s.name, e, u.rowCount, i));
1251
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(Nt(s.name, e));
1252
+ for (let { declared: t, live: n } of f.changed) a.push(...Ft(s.name, t, n, e.dialect, u.rowCount, i));
1253
+ }
1254
+ 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) => {
1255
+ let t = l.get(e);
1256
+ return t ? t.columns.flatMap((e) => e.references && c.has(e.references.table) ? [{
1145
1257
  column: e.name,
1146
1258
  target: e.references.table
1147
1259
  }] : []) : [];
1148
- }, u = S([...s], l), d = [];
1149
- for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(x(e.name, t.name)) || d.push(L({
1260
+ }, d = ne([...c], u), f = [];
1261
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(S(e.name, t.name)) || f.push(I({
1150
1262
  kind: "add-foreign-key",
1151
1263
  table: e.name,
1152
1264
  column: t.name,
@@ -1155,14 +1267,14 @@ BEGIN
1155
1267
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1156
1268
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1157
1269
  }, "safe", `deferred FK ${e.name}.${t.name} → ${t.references.table} — breaks a create-time table cycle`));
1158
- if (u.size > 0) {
1270
+ if (d.size > 0) {
1159
1271
  let e = (e) => e.references ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "references")) : e;
1160
1272
  for (let t = 0; t < a.length; t += 1) {
1161
1273
  let n = a[t];
1162
1274
  if (n.op.kind !== "create-table") continue;
1163
1275
  let r = n.op;
1164
- if (!r.columns.some((e) => u.has(x(r.table, e.name)))) continue;
1165
- let i = r.columns.map((t) => u.has(x(r.table, t.name)) ? e(t) : t);
1276
+ if (!r.columns.some((e) => d.has(S(r.table, e.name)))) continue;
1277
+ let i = r.columns.map((t) => d.has(S(r.table, t.name)) ? e(t) : t);
1166
1278
  a[t] = {
1167
1279
  ...n,
1168
1280
  op: {
@@ -1171,26 +1283,27 @@ BEGIN
1171
1283
  }
1172
1284
  };
1173
1285
  }
1174
- a.push(...d);
1286
+ a.push(...f);
1175
1287
  }
1176
- let f = new Map(t.tables.map((e) => [e.name, e])), p = /* @__PURE__ */ new Map(), m = (e, t = /* @__PURE__ */ new Set()) => {
1177
- let n = p.get(e);
1288
+ let p = new Map(t.tables.map((e) => [e.name, e])), m = /* @__PURE__ */ new Map(), h = (e, t = /* @__PURE__ */ new Set()) => {
1289
+ let n = m.get(e);
1178
1290
  if (n !== void 0) return n;
1179
1291
  if (t.has(e)) return 0;
1180
- let r = f.get(e);
1292
+ let r = p.get(e);
1181
1293
  if (!r) return 0;
1182
1294
  let i = new Set(t).add(e), a = 0;
1183
1295
  for (let t of r.columns) {
1184
1296
  let n = t.references?.table;
1185
- n && n !== e && !u.has(x(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
1297
+ n && n !== e && !d.has(S(e, t.name)) && (a = Math.max(a, h(n, i) + 1));
1186
1298
  }
1187
- return p.set(e, a), a;
1188
- }, h = (e) => e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, g = (e) => {
1299
+ return m.set(e, a), a;
1300
+ }, g = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, ee = (e) => {
1189
1301
  let t = "table" in e ? e.table : "";
1190
- return e.kind === "create-table" ? m(t) : e.kind === "drop-table" ? -m(t) : 0;
1191
- }, ee = {
1302
+ return e.kind === "create-table" ? h(t) : e.kind === "drop-table" ? -h(t) : 0;
1303
+ }, _ = {
1192
1304
  "add-column": 0,
1193
1305
  "rename-column": 1,
1306
+ "rename-index": 1,
1194
1307
  "alter-column-nullability": 2,
1195
1308
  "alter-column-type": 2,
1196
1309
  "alter-column-default": 2,
@@ -1205,23 +1318,23 @@ BEGIN
1205
1318
  "add-unique-composite": 5,
1206
1319
  "add-foreign-key": 5,
1207
1320
  "add-check": 5
1208
- }, _ = (e) => ee[e] ?? 9, v = [...a].sort((e, t) => {
1209
- let n = h(e.op.kind), r = h(t.op.kind);
1321
+ }, v = (e) => _[e] ?? 9, y = [...a].sort((e, t) => {
1322
+ let n = g(e.op.kind), r = g(t.op.kind);
1210
1323
  if (n !== r) return n - r;
1211
- let i = g(e.op), a = g(t.op);
1324
+ let i = ee(e.op), a = ee(t.op);
1212
1325
  if (i !== a) return i - a;
1213
1326
  let o = "table" in e.op ? e.op.table : "", s = "table" in t.op ? t.op.table : "";
1214
1327
  if (o !== s) return o.localeCompare(s);
1215
- let c = _(e.op.kind), l = _(t.op.kind);
1328
+ let c = v(e.op.kind), l = v(t.op.kind);
1216
1329
  return c === l ? e.op.kind.localeCompare(t.op.kind) : c - l;
1217
1330
  });
1218
1331
  return {
1219
- operations: v,
1332
+ operations: y,
1220
1333
  fromFingerprint: j(e.live),
1221
1334
  toFingerprint: j(t),
1222
- summary: Pt(v)
1335
+ summary: Ut(y)
1223
1336
  };
1224
- }, It = (e) => {
1337
+ }, Gt = (e) => {
1225
1338
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1226
1339
  if (!t) return null;
1227
1340
  let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
@@ -1229,7 +1342,7 @@ BEGIN
1229
1342
  column: t[1],
1230
1343
  values: n
1231
1344
  };
1232
- }, Lt = (e, t) => {
1345
+ }, Kt = (e, t) => {
1233
1346
  if (t === "vector") return "vector";
1234
1347
  switch (e) {
1235
1348
  case "text":
@@ -1256,7 +1369,7 @@ BEGIN
1256
1369
  case "USER-DEFINED": return "text";
1257
1370
  default: return "text";
1258
1371
  }
1259
- }, R = (e) => {
1372
+ }, L = (e) => {
1260
1373
  switch (e.toUpperCase()) {
1261
1374
  case "CASCADE": return "cascade";
1262
1375
  case "RESTRICT": return "restrict";
@@ -1264,25 +1377,25 @@ BEGIN
1264
1377
  case "SET DEFAULT": return "noAction";
1265
1378
  default: return "noAction";
1266
1379
  }
1267
- }, Rt = (e, t) => {
1380
+ }, qt = (e, t) => {
1268
1381
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1269
1382
  return Number.isInteger(n) && n > 0 ? n : t;
1270
- }, zt = () => Rt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Bt = 300, Vt = () => {
1383
+ }, Jt = () => qt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Yt = 300, Xt = () => {
1271
1384
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1272
- return e !== void 0 && e.trim() === "0" ? 0 : Rt(e, 3e4);
1273
- }, Ht = (e, t) => {
1385
+ return e !== void 0 && e.trim() === "0" ? 0 : qt(e, 3e4);
1386
+ }, Zt = (e, t) => {
1274
1387
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1275
1388
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1276
1389
  return r;
1277
- }, Ut = (e) => {
1278
- let t = Vt(), n = d.gen(function* () {
1390
+ }, Qt = (e) => {
1391
+ let t = Xt(), n = d.gen(function* () {
1279
1392
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1280
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = zt(), a = (e, t) => d.gen(function* () {
1393
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Jt(), a = (e, t) => d.gen(function* () {
1281
1394
  let r = [];
1282
- for (let a of Ht(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1395
+ for (let a of Zt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1283
1396
  return r;
1284
1397
  }), o = [];
1285
- for (let t = 0;; t += Bt) {
1398
+ for (let t = 0;; t += Yt) {
1286
1399
  let n = yield* e`
1287
1400
  SELECT c.relname AS table_name,
1288
1401
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1290,14 +1403,15 @@ BEGIN
1290
1403
  JOIN pg_namespace n ON n.oid = c.relnamespace
1291
1404
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1292
1405
  ORDER BY c.relname
1293
- LIMIT ${r(Bt)} OFFSET ${r(t)}
1406
+ LIMIT ${r(Yt)} OFFSET ${r(t)}
1294
1407
  `;
1295
- if (o.push(...n), n.length < Bt) break;
1408
+ if (o.push(...n), n.length < Yt) break;
1296
1409
  }
1297
1410
  let s = /* @__PURE__ */ new Set(), c = [];
1298
1411
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
1299
1412
  let l = c.map((e) => e.table_name), u = yield* a(l, (t) => e`
1300
- SELECT table_name, column_name, data_type, udt_name, is_nullable, column_default
1413
+ SELECT table_name, column_name, data_type, udt_name, is_nullable, column_default,
1414
+ character_maximum_length
1301
1415
  FROM information_schema.columns
1302
1416
  WHERE table_schema = current_schema() AND table_name IN ${t}
1303
1417
  ORDER BY table_name, ordinal_position
@@ -1377,7 +1491,7 @@ BEGIN
1377
1491
  AND c.relname IN ${t}
1378
1492
  )
1379
1493
  SELECT * FROM ix ORDER BY table_name, index_name, position
1380
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), ne = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
1494
+ `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
1381
1495
  for (let e of u) {
1382
1496
  let t = _.get(e.table_name);
1383
1497
  t || (t = [], _.set(e.table_name, t)), t.push(e);
@@ -1386,25 +1500,25 @@ BEGIN
1386
1500
  let t = v.get(e.table_name);
1387
1501
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1388
1502
  }
1389
- let x = /* @__PURE__ */ new Map();
1503
+ let S = /* @__PURE__ */ new Map();
1390
1504
  for (let e of p) {
1391
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = x.get(t);
1505
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = S.get(t);
1392
1506
  n || (n = {
1393
1507
  table: e.table_name,
1394
1508
  columns: []
1395
- }, x.set(t, n)), n.columns.push({
1509
+ }, S.set(t, n)), n.columns.push({
1396
1510
  name: e.column_name,
1397
1511
  position: e.position
1398
1512
  });
1399
1513
  }
1400
- for (let [e, t] of x) {
1514
+ for (let [e, t] of S) {
1401
1515
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1402
1516
  if (n.length === 1) {
1403
- let e = te.get(t.table);
1404
- e || (e = /* @__PURE__ */ new Set(), te.set(t.table, e)), e.add(n[0]);
1517
+ let e = y.get(t.table);
1518
+ e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
1405
1519
  } else {
1406
- let r = y.get(t.table);
1407
- r || (r = [], y.set(t.table, r)), r.push({
1520
+ let r = b.get(t.table);
1521
+ r || (r = [], b.set(t.table, r)), r.push({
1408
1522
  name: e.slice(e.indexOf("\0") + 1),
1409
1523
  table: t.table,
1410
1524
  columns: n,
@@ -1413,27 +1527,28 @@ BEGIN
1413
1527
  }
1414
1528
  }
1415
1529
  for (let e of g) {
1416
- let t = ne.get(e.source_table);
1417
- t || (t = [], ne.set(e.source_table, t)), t.push(e);
1530
+ let t = te.get(e.source_table);
1531
+ t || (t = [], te.set(e.source_table, t)), t.push(e);
1418
1532
  }
1419
1533
  for (let e of ee) {
1420
- let t = b.get(e.table_name);
1421
- t || (t = /* @__PURE__ */ new Map(), b.set(e.table_name, t));
1534
+ let t = x.get(e.table_name);
1535
+ t || (t = /* @__PURE__ */ new Map(), x.set(e.table_name, t));
1422
1536
  let n = t.get(e.index_name);
1423
1537
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1424
1538
  }
1425
- let S = [];
1539
+ let ne = [];
1426
1540
  for (let e of c) {
1427
- let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = te.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = ne.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) => {
1428
- 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" : Lt(t.data_type, t.udt_name), c = a ? {
1541
+ let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (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 = te.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1542
+ 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" : Kt(t.data_type, t.udt_name), c = a ? {
1429
1543
  table: a.target_table,
1430
1544
  column: a.target_column,
1431
- onDelete: R(a.delete_rule),
1432
- onUpdate: R(a.update_rule)
1545
+ onDelete: L(a.delete_rule),
1546
+ onUpdate: L(a.update_rule)
1433
1547
  } : void 0, l = h.get(`${e.table_name}.${t.column_name}`);
1434
1548
  return {
1435
1549
  name: t.column_name,
1436
1550
  type: s,
1551
+ ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1437
1552
  nullable: t.is_nullable === "YES",
1438
1553
  unique: i.has(t.column_name) || n && t.column_name === "id",
1439
1554
  hasDefault: t.column_default !== null,
@@ -1441,7 +1556,7 @@ BEGIN
1441
1556
  ...c ? { references: c } : {},
1442
1557
  ...l ? { oneOf: l } : {}
1443
1558
  };
1444
- }), l = [], u = b.get(e.table_name);
1559
+ }), l = [], u = x.get(e.table_name);
1445
1560
  if (u) for (let [t, n] of u) {
1446
1561
  let r = /* @__PURE__ */ new Set(), i = [...n].filter((e) => e.column_name !== null && e.position !== null).sort((e, t) => (e.position ?? 0) - (t.position ?? 0)).filter((e) => {
1447
1562
  let t = e.position;
@@ -1457,7 +1572,7 @@ BEGIN
1457
1572
  ...a ? { expression: !0 } : {}
1458
1573
  });
1459
1574
  }
1460
- for (let t of y.get(e.table_name) ?? []) l.push(t);
1575
+ for (let t of b.get(e.table_name) ?? []) l.push(t);
1461
1576
  r.size > 0 && l.push({
1462
1577
  name: `${e.table_name}_pkey`,
1463
1578
  table: e.table_name,
@@ -1465,20 +1580,20 @@ BEGIN
1465
1580
  unique: !0
1466
1581
  });
1467
1582
  let d = Number(e.row_count ?? 0);
1468
- S.push({
1583
+ ne.push({
1469
1584
  name: e.table_name,
1470
1585
  columns: c,
1471
1586
  indexes: l,
1472
1587
  ...d > 0 ? { rowCount: d } : {}
1473
1588
  });
1474
1589
  }
1475
- return { tables: S };
1590
+ return { tables: ne };
1476
1591
  });
1477
1592
  return (t > 0 ? e.withTransaction(n) : n).pipe(d.catchAll((e) => {
1478
1593
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1479
1594
  return n.includes("statement timeout") || n.includes("57014") ? d.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.`)) : d.fail(e);
1480
1595
  }));
1481
- }, Wt = (e, t) => {
1596
+ }, $t = (e, t) => {
1482
1597
  switch (e.toLowerCase()) {
1483
1598
  case "varchar":
1484
1599
  case "char":
@@ -1510,20 +1625,21 @@ BEGIN
1510
1625
  case "json": return "json";
1511
1626
  default: return "text";
1512
1627
  }
1513
- }, z = (e) => e.map((e) => {
1628
+ }, R = (e) => e.map((e) => {
1514
1629
  let t = e, n = {};
1515
1630
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1516
1631
  return n;
1517
- }), Gt = (e) => d.gen(function* () {
1518
- let t = z(yield* e`
1632
+ }), en = (e) => d.gen(function* () {
1633
+ let t = R(yield* e`
1519
1634
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1520
1635
  FROM information_schema.tables
1521
1636
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1522
- ORDER BY table_name`), n = z(yield* e`
1523
- SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key
1637
+ ORDER BY table_name`), n = R(yield* e`
1638
+ SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1639
+ character_maximum_length
1524
1640
  FROM information_schema.columns
1525
1641
  WHERE table_schema = DATABASE()
1526
- ORDER BY table_name, ordinal_position`), r = z(yield* e`
1642
+ ORDER BY table_name, ordinal_position`), r = R(yield* e`
1527
1643
  SELECT k.table_name AS source_table,
1528
1644
  k.column_name AS source_column,
1529
1645
  k.referenced_table_name AS target_table,
@@ -1533,11 +1649,11 @@ BEGIN
1533
1649
  JOIN information_schema.referential_constraints r
1534
1650
  ON k.constraint_name = r.constraint_name
1535
1651
  AND k.table_schema = r.constraint_schema
1536
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
1652
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = R(yield* e`
1537
1653
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1538
1654
  FROM information_schema.statistics
1539
1655
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1540
- ORDER BY table_name, index_name, seq_in_index`), a = z(yield* e`
1656
+ ORDER BY table_name, index_name, seq_in_index`), a = R(yield* e`
1541
1657
  SELECT table_name, check_clause
1542
1658
  FROM information_schema.check_constraints
1543
1659
  WHERE constraint_schema = DATABASE()`.unprepared.pipe(d.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
@@ -1547,7 +1663,7 @@ BEGIN
1547
1663
  o.add(`${e.table_name}.${t[1]}`);
1548
1664
  continue;
1549
1665
  }
1550
- let n = It(e.check_clause);
1666
+ let n = Gt(e.check_clause);
1551
1667
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1552
1668
  }
1553
1669
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1570,16 +1686,17 @@ BEGIN
1570
1686
  let t = c.get(e.table_name) ?? [], n = l.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(), d = u.get(e.table_name);
1571
1687
  if (d) for (let e of d.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1572
1688
  let p = t.map((t) => {
1573
- let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Wt(t.data_type, t.column_type), u = c ? {
1689
+ let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : $t(t.data_type, t.column_type), u = c ? {
1574
1690
  table: c.target_table,
1575
1691
  column: c.target_column,
1576
- onDelete: R(c.delete_rule),
1577
- onUpdate: R(c.update_rule)
1692
+ onDelete: L(c.delete_rule),
1693
+ onUpdate: L(c.update_rule)
1578
1694
  } : void 0, d = a.has(t.column_name) || n && t.column_name === "id", f = t.column_default === "NULL" ? null : t.column_default, p = s.get(`${e.table_name}.${t.column_name}`);
1579
1695
  return {
1580
1696
  name: t.column_name,
1581
1697
  type: l,
1582
1698
  nullable: t.is_nullable === "YES",
1699
+ ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1583
1700
  unique: d,
1584
1701
  hasDefault: f !== null,
1585
1702
  ...f === null ? {} : { defaultValue: f },
@@ -1611,10 +1728,10 @@ BEGIN
1611
1728
  });
1612
1729
  }
1613
1730
  return { tables: f };
1614
- }), Kt = (e) => {
1731
+ }), tn = (e) => {
1615
1732
  let t = e.toUpperCase();
1616
1733
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1617
- }, qt = (e) => d.gen(function* () {
1734
+ }, nn = (e) => d.gen(function* () {
1618
1735
  let t = yield* e`
1619
1736
  SELECT name, sql FROM sqlite_master
1620
1737
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1631,11 +1748,11 @@ BEGIN
1631
1748
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1632
1749
  }
1633
1750
  let p = o.map((e) => {
1634
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Kt(e.type), a = r ? {
1751
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : tn(e.type), a = r ? {
1635
1752
  table: r.table,
1636
1753
  column: r.to,
1637
- onDelete: R(r.on_delete),
1638
- onUpdate: R(r.on_update)
1754
+ onDelete: L(r.on_delete),
1755
+ onUpdate: L(r.on_update)
1639
1756
  } : void 0, o = t.get(e.name);
1640
1757
  return {
1641
1758
  name: e.name,
@@ -1670,7 +1787,7 @@ BEGIN
1670
1787
  });
1671
1788
  }
1672
1789
  return { tables: r };
1673
- }), Jt = (e) => {
1790
+ }), rn = (e) => {
1674
1791
  switch (e.toLowerCase()) {
1675
1792
  case "int":
1676
1793
  case "smallint":
@@ -1692,12 +1809,13 @@ BEGIN
1692
1809
  case "image": return "bytes";
1693
1810
  default: return "text";
1694
1811
  }
1695
- }, B = (e) => e === !0 || e === 1, Yt = (e) => d.gen(function* () {
1812
+ }, z = (e) => e === !0 || e === 1, an = (e) => d.gen(function* () {
1696
1813
  let t = yield* e`
1697
1814
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
1698
1815
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
1699
1816
  SELECT TABLE_NAME AS table_name, COLUMN_NAME AS column_name, DATA_TYPE AS data_type,
1700
- IS_NULLABLE AS is_nullable, COLUMN_DEFAULT AS column_default
1817
+ IS_NULLABLE AS is_nullable, COLUMN_DEFAULT AS column_default,
1818
+ CHARACTER_MAXIMUM_LENGTH AS character_maximum_length
1701
1819
  FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* e`
1702
1820
  SELECT st.name AS source_table, sc.name AS source_column,
1703
1821
  tt.name AS target_table, tc.name AS target_column,
@@ -1748,20 +1866,21 @@ BEGIN
1748
1866
  let t = s.get(e) ?? [], n = c.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = new Set(n.map((e) => e.source_column)), a = l.get(e), d = [], f = /* @__PURE__ */ new Set();
1749
1867
  if (a) for (let [, e] of a) {
1750
1868
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
1751
- if (B(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1752
- else B(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1869
+ if (z(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1870
+ else z(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1753
1871
  }
1754
1872
  let p = t.map((t) => {
1755
- let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Jt(t.data_type), s = i ? {
1873
+ let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : rn(t.data_type), s = i ? {
1756
1874
  table: i.target_table,
1757
1875
  column: i.target_column,
1758
- onDelete: Xt(i.delete_rule),
1759
- onUpdate: Xt(i.update_rule)
1760
- } : void 0, c = t.column_default === null ? null : Zt(t.column_default), l = o.get(`${e}.${t.column_name}`);
1876
+ onDelete: on(i.delete_rule),
1877
+ onUpdate: on(i.update_rule)
1878
+ } : void 0, c = t.column_default === null ? null : sn(t.column_default), l = o.get(`${e}.${t.column_name}`);
1761
1879
  return {
1762
1880
  name: t.column_name,
1763
1881
  type: a,
1764
1882
  nullable: t.is_nullable === "YES",
1883
+ ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1765
1884
  unique: f.has(t.column_name) || n && t.column_name === "id",
1766
1885
  hasDefault: c !== null,
1767
1886
  ...c === null ? {} : { defaultValue: c },
@@ -1771,11 +1890,11 @@ BEGIN
1771
1890
  }), m = [];
1772
1891
  if (a) for (let [t, n] of a) {
1773
1892
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
1774
- B(r[0].is_primary) || r.length === 1 && B(r[0].is_unique) || r.length === 1 && !B(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1893
+ z(r[0].is_primary) || r.length === 1 && z(r[0].is_unique) || r.length === 1 && !z(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1775
1894
  name: t,
1776
1895
  table: e,
1777
1896
  columns: r.map((e) => e.column_name),
1778
- unique: B(r[0].is_unique)
1897
+ unique: z(r[0].is_unique)
1779
1898
  });
1780
1899
  }
1781
1900
  d.length > 0 && m.push({
@@ -1790,37 +1909,48 @@ BEGIN
1790
1909
  });
1791
1910
  }
1792
1911
  return { tables: u };
1793
- }), Xt = (e) => {
1912
+ }), on = (e) => {
1794
1913
  switch (e.toUpperCase().replace(/_/g, " ")) {
1795
1914
  case "CASCADE": return "cascade";
1796
1915
  case "SET NULL": return "setNull";
1797
1916
  case "SET DEFAULT": return "noAction";
1798
1917
  default: return "noAction";
1799
1918
  }
1800
- }, Zt = (e) => {
1919
+ }, sn = (e) => {
1801
1920
  let t = e.trim();
1802
1921
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
1803
1922
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
1923
+ }, cn = /* @__PURE__ */ new Set([
1924
+ "character varying",
1925
+ "varchar",
1926
+ "nvarchar",
1927
+ "char",
1928
+ "character",
1929
+ "nchar"
1930
+ ]), B = (e, t) => {
1931
+ if (!cn.has(e.toLowerCase())) return;
1932
+ let n = Number(t);
1933
+ if (!(!Number.isFinite(n) || n <= 0)) return n;
1804
1934
  }, V = (e) => e.onDialectOrElse({
1805
- mysql: () => Gt(e),
1806
- mssql: () => Yt(e),
1807
- sqlite: () => qt(e),
1808
- orElse: () => Ut(e)
1809
- }), Qt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
1810
- if (!e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
1935
+ mysql: () => en(e),
1936
+ mssql: () => an(e),
1937
+ sqlite: () => nn(e),
1938
+ orElse: () => Qt(e)
1939
+ }), ln = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
1940
+ if (!(e.type === "text" && e.maxLength !== void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
1811
1941
  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;
1812
1942
  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.`);
1813
- return D(e, t);
1943
+ return E(e, t);
1814
1944
  }, U = (e) => {
1815
1945
  let t = H(e, "postgres");
1816
- return t === void 0 ? $t(e) : t;
1817
- }, $t = (e) => {
1946
+ return t === void 0 ? un(e) : t;
1947
+ }, un = (e) => {
1818
1948
  switch (e.type) {
1819
1949
  case "id": return "text";
1820
1950
  case "text": return "text";
1821
1951
  case "integer": return "integer";
1822
1952
  case "real": return "double precision";
1823
- case "decimal": return Qt(e, "NUMERIC");
1953
+ case "decimal": return ln(e, "NUMERIC");
1824
1954
  case "bigint": return "bigint";
1825
1955
  case "boolean": return "boolean";
1826
1956
  case "timestamp": return "timestamptz";
@@ -1842,7 +1972,7 @@ BEGIN
1842
1972
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
1843
1973
  case "integer": return "INT";
1844
1974
  case "real": return "DOUBLE";
1845
- case "decimal": return Qt(e, "DECIMAL");
1975
+ case "decimal": return ln(e, "DECIMAL");
1846
1976
  case "bigint": return "BIGINT";
1847
1977
  case "boolean": return "TINYINT(1)";
1848
1978
  case "timestamp": return "DATETIME(6)";
@@ -1856,32 +1986,32 @@ BEGIN
1856
1986
  case "interval": return "BIGINT";
1857
1987
  case "raw": return e.rawDdl ?? "LONGTEXT";
1858
1988
  }
1859
- }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, en = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, tn = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, nn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, rn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${kn(t)}`)};`, an = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${on(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, on = (e, t) => {
1989
+ }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, dn = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, fn = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, pn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, mn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${zn(t)}`)};`, hn = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${gn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, gn = (e, t) => {
1860
1990
  let n = t(e.defaultValue);
1861
1991
  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.`);
1862
1992
  return n;
1863
- }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], sn = (e, t, n) => {
1993
+ }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], _n = (e, t, n) => {
1864
1994
  let r = q(e, t, n);
1865
1995
  return r ? nt(n, r) : void 0;
1866
- }, cn = (e, t, n) => {
1867
- let r = n ?? e.nullable, i = ve(e, "mariadb");
1996
+ }, vn = (e, t, n) => {
1997
+ let r = n ?? e.nullable, i = ye(e, "mariadb");
1868
1998
  return [
1869
1999
  K(t),
1870
- D(e, "mariadb"),
2000
+ E(e, "mariadb"),
1871
2001
  r ? null : "NOT NULL",
1872
2002
  i
1873
2003
  ].filter(Boolean).join(" ");
1874
- }, ln = (e, t) => e == null ? null : Array.isArray(e) ? un(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" ? O(e, "mysql") : null, un = (e, t, n) => ye(e, t ?? { type: "json" }, n), dn = (e, t) => e == null ? null : Array.isArray(e) ? un(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" ? O(e, "postgres") : null, J = (e, t) => {
2004
+ }, yn = (e, t) => e == null ? null : Array.isArray(e) ? bn(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" ? D(e, "mysql") : null, bn = (e, t, n) => be(e, t ?? { type: "json" }, n), xn = (e, t) => e == null ? null : Array.isArray(e) ? bn(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" ? D(e, "postgres") : null, J = (e, t) => {
1875
2005
  if (!e.generatedAs) return null;
1876
2006
  let { expr: n, stored: r } = e.generatedAs;
1877
2007
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
1878
- }, fn = (e) => {
1879
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "postgres");
2008
+ }, Sn = (e) => {
2009
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "postgres");
1880
2010
  let t = J(e, "postgres");
1881
2011
  if (t) return `${G(e.name)} ${U(e)} ${t}`;
1882
2012
  let n = [G(e.name), U(e)];
1883
2013
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
1884
- let t = dn(e.defaultValue, e);
2014
+ let t = xn(e.defaultValue, e);
1885
2015
  t && n.push(t);
1886
2016
  }
1887
2017
  return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
@@ -1890,20 +2020,20 @@ BEGIN
1890
2020
  setNull: "SET NULL",
1891
2021
  noAction: "NO ACTION"
1892
2022
  }[e.references.onDelete]}`)), n.join(" ");
1893
- }, pn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", mn = (e) => {
1894
- let t = e.columns.map((e) => ` ${fn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${pn(e, G)}\n)`];
1895
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(Pn).join(", ")})`);
2023
+ }, Cn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", wn = (e) => {
2024
+ let t = e.columns.map((e) => ` ${Sn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Cn(e, G)}\n)`];
2025
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(Wn).join(", ")})`);
1896
2026
  return n;
1897
- }, hn = 191, gn = (e) => {
2027
+ }, Tn = 191, En = (e) => {
1898
2028
  let t = W(e).toUpperCase();
1899
2029
  return t.endsWith("TEXT") || t.endsWith("BLOB");
1900
- }, _n = (e) => {
1901
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mariadb");
2030
+ }, Dn = (e) => {
2031
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mariadb");
1902
2032
  let t = J(e, "mariadb");
1903
2033
  if (t) return `${K(e.name)} ${W(e)} ${t}`;
1904
2034
  let n = [K(e.name), W(e)];
1905
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !gn(e) && n.push("UNIQUE"), e.hasDefault) {
1906
- let t = ln(e.defaultValue, e);
2035
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !En(e) && n.push("UNIQUE"), e.hasDefault) {
2036
+ let t = yn(e.defaultValue, e);
1907
2037
  t && n.push(t);
1908
2038
  }
1909
2039
  return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
@@ -1912,25 +2042,25 @@ BEGIN
1912
2042
  setNull: "SET NULL",
1913
2043
  noAction: "NO ACTION"
1914
2044
  }[e.references.onDelete]}`)), n.join(" ");
1915
- }, vn = (e) => {
2045
+ }, On = (e) => {
1916
2046
  let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
1917
2047
  let n = t.get(e);
1918
- return n && gn(n) ? `${K(e)}(${hn})` : K(e);
1919
- }, r = e.columns.map((e) => ` ${_n(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${pn(e, n)}\n)`];
1920
- for (let t of e.columns) t.unique && t.type !== "id" && gn(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
2048
+ return n && En(n) ? `${K(e)}(${Tn})` : K(e);
2049
+ }, r = e.columns.map((e) => ` ${Dn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${Cn(e, n)}\n)`];
2050
+ for (let t of e.columns) t.unique && t.type !== "id" && En(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
1921
2051
  for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(n).join(", ")})`);
1922
2052
  return i;
1923
- }, yn = {
2053
+ }, kn = {
1924
2054
  cascade: "CASCADE",
1925
2055
  restrict: "RESTRICT",
1926
2056
  setNull: "SET NULL",
1927
2057
  noAction: "NO ACTION"
1928
- }, bn = {
2058
+ }, An = {
1929
2059
  cascade: "CASCADE",
1930
2060
  restrict: "NO ACTION",
1931
2061
  setNull: "SET NULL",
1932
2062
  noAction: "NO ACTION"
1933
- }, xn = (e) => {
2063
+ }, jn = (e) => {
1934
2064
  let t = H(e, "sqlite");
1935
2065
  if (t !== void 0) return t;
1936
2066
  switch (e.type) {
@@ -1942,29 +2072,29 @@ BEGIN
1942
2072
  case "bytes": return "BLOB";
1943
2073
  default: return "TEXT";
1944
2074
  }
1945
- }, Y = (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" ? O(e, "sqlite") : null, Sn = (e) => {
1946
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "sqlite");
2075
+ }, Y = (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" ? D(e, "sqlite") : null, Mn = (e) => {
2076
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "sqlite");
1947
2077
  let t = J(e, "sqlite");
1948
- if (t) return `${G(e.name)} ${xn(e)} ${t}`;
1949
- let n = [G(e.name), xn(e)];
2078
+ if (t) return `${G(e.name)} ${jn(e)} ${t}`;
2079
+ let n = [G(e.name), jn(e)];
1950
2080
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
1951
2081
  let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
1952
2082
  t && n.push(t);
1953
2083
  }
1954
- if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${yn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2084
+ if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${kn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
1955
2085
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
1956
2086
  n.push(`CHECK (${G(e.name)} IN (${t}))`);
1957
2087
  }
1958
2088
  return n.join(" ");
1959
- }, Cn = (e) => {
1960
- let t = e.columns.map((e) => ` ${Sn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${pn(e, G)}\n)`];
2089
+ }, Nn = (e) => {
2090
+ let t = e.columns.map((e) => ` ${Mn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Cn(e, G)}\n)`];
1961
2091
  for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
1962
2092
  return n;
1963
2093
  }, X = (e, t) => {
1964
2094
  let n = t.find((t) => t.tableName === e);
1965
2095
  if (!n) return [];
1966
2096
  let r = N([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
1967
- ...Cn({
2097
+ ...Nn({
1968
2098
  kind: "create-table",
1969
2099
  table: i,
1970
2100
  columns: r.columns,
@@ -1977,17 +2107,17 @@ BEGIN
1977
2107
  ];
1978
2108
  for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
1979
2109
  return o;
1980
- }, wn = (e, t, n, r) => {
2110
+ }, Pn = (e, t, n, r) => {
1981
2111
  let i = r ?? e.nullable;
1982
- return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${D(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
1983
- }, Tn = (e) => {
2112
+ return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${E(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2113
+ }, Fn = (e) => {
1984
2114
  let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Z(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
1985
2115
  if (!e.hasDefault) return t;
1986
2116
  let n = Y(e.defaultValue, "SYSUTCDATETIME()");
1987
2117
  if (!n) return t;
1988
2118
  let r = n.replace(/^DEFAULT\s+/i, "");
1989
2119
  return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
1990
- }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, En = (e) => {
2120
+ }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, In = (e) => {
1991
2121
  let t = H(e, "mssql");
1992
2122
  if (t !== void 0) return t;
1993
2123
  switch (e.type) {
@@ -1995,7 +2125,7 @@ BEGIN
1995
2125
  case "reference": return "NVARCHAR(64)";
1996
2126
  case "integer": return "INT";
1997
2127
  case "real": return "FLOAT";
1998
- case "decimal": return Qt(e, "DECIMAL");
2128
+ case "decimal": return ln(e, "DECIMAL");
1999
2129
  case "bigint": return "BIGINT";
2000
2130
  case "boolean": return "BIT";
2001
2131
  case "timestamp": return "DATETIME2(6)";
@@ -2003,34 +2133,40 @@ BEGIN
2003
2133
  case "bytes": return "VARBINARY(MAX)";
2004
2134
  default: return "NVARCHAR(MAX)";
2005
2135
  }
2006
- }, Dn = (e, t) => {
2007
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mssql");
2008
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : En(e), r = J(e, "mssql");
2136
+ }, Ln = (e, t) => {
2137
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mssql");
2138
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : In(e), r = J(e, "mssql");
2009
2139
  if (r) return `${Z(e.name)} ${r}`;
2010
2140
  let i = [Z(e.name), n];
2011
2141
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2012
2142
  let t = Y(e.defaultValue, "SYSUTCDATETIME()");
2013
2143
  t && i.push(t);
2014
2144
  }
2015
- return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${bn[e.references.onDelete]}`)), i.join(" ");
2016
- }, On = (e) => {
2017
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Dn(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${pn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2145
+ return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${An[e.references.onDelete]}`)), i.join(" ");
2146
+ }, Rn = (e) => {
2147
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Ln(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${Cn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2018
2148
  for (let n of e.indexes) {
2019
2149
  if (n.name === `${e.table}_pkey`) continue;
2020
2150
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
2021
2151
  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)}')`);
2022
2152
  }
2023
2153
  return a;
2024
- }, kn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, An = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, jn = (e, t, n) => {
2025
- let r = `${e.table}${kn(t)}`;
2154
+ }, zn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Bn = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Vn = (e, t, n) => {
2155
+ let r = `${e.table}${zn(t)}`;
2026
2156
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2027
- }, Mn = (e, t, n) => {
2157
+ }, Hn = (e, t, n) => {
2028
2158
  let r = q(e, t, n);
2029
- return r ? gn({ type: r.type }) : !1;
2030
- }, Nn = (e, t, n) => Mn(e, t, n) ? `${K(n)}(${hn})` : K(n), Pn = (e) => e.startsWith("(") ? e : G(e), Fn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(Pn).join(", ")});`, In = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Nn(t, e.table, n)).join(", ")});`, Ln = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Rn = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, zn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, Bn = (e) => {
2159
+ return r ? En({ type: r.type }) : !1;
2160
+ }, Un = (e, t, n) => Hn(e, t, n) ? `${K(n)}(${Tn})` : K(n), Wn = (e) => e.startsWith("(") ? e : G(e), Gn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(Wn).join(", ")});`, Kn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Un(t, e.table, n)).join(", ")});`, qn = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Jn = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, Yn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, Xn = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Zn = (e) => {
2161
+ let t = (e) => e.replace(/'/g, "''");
2162
+ return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2163
+ }, Qn = (e) => `ALTER INDEX ${G(e.from)} RENAME TO ${G(e.to)};`, $n = (e) => `ALTER TABLE ${K(e.table)} RENAME INDEX ${K(e.from)} TO ${K(e.to)};`, er = (e) => {
2164
+ let t = (e) => e.replace(/'/g, "''");
2165
+ return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2166
+ }, tr = (e) => {
2031
2167
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Z(e.index.name)} ON ${Z(e.table)} (${e.index.columns.map(Z).join(", ")})`;
2032
2168
  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)}');`;
2033
- }, Vn = (e, t, n) => {
2169
+ }, nr = (e, t, n) => {
2034
2170
  let r = n.find((t) => t.tableName === e);
2035
2171
  if (!r) return [];
2036
2172
  let i = [];
@@ -2039,13 +2175,13 @@ BEGIN
2039
2175
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2040
2176
  }
2041
2177
  return i;
2042
- }, Hn = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, Un = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Nn(t, e.table, e.column)});`, Wn = (e) => {
2178
+ }, rr = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, ir = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Un(t, e.table, e.column)});`, ar = (e) => {
2043
2179
  let t = e.fields.map((e) => G(e)).join(", ");
2044
2180
  return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2045
- }, Gn = (e, t) => {
2046
- let n = e.fields.map((n) => Nn(t, e.table, n)).join(", ");
2181
+ }, or = (e, t) => {
2182
+ let n = e.fields.map((n) => Un(t, e.table, n)).join(", ");
2047
2183
  return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2048
- }, Kn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, qn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, Jn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, Yn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, Xn = (e, t) => {
2184
+ }, sr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, cr = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, lr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, ur = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, dr = (e, t) => {
2049
2185
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2050
2186
  if (e.orphanPolicy) {
2051
2187
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2063,11 +2199,11 @@ BEGIN
2063
2199
  setNull: "SET NULL",
2064
2200
  noAction: "NO ACTION"
2065
2201
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2066
- }, Zn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, Qn = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, $n = (e, t) => {
2202
+ }, fr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, pr = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, mr = (e, t) => {
2067
2203
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2068
2204
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2069
- }, er = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, tr = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, nr = (e, t, n, r) => {
2070
- let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? En(i) : r === "sqlite" ? xn(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? ln(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : dn(e, i), u = J(i, r);
2205
+ }, hr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, gr = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, _r = (e, t, n, r) => {
2206
+ let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? In(i) : r === "sqlite" ? jn(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? yn(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : xn(e, i), u = J(i, r);
2071
2207
  if (u) {
2072
2208
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2073
2209
  return {
@@ -2095,7 +2231,7 @@ BEGIN
2095
2231
  post: f ? [f] : []
2096
2232
  };
2097
2233
  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;
2098
- }, rr = (e) => {
2234
+ }, vr = (e) => {
2099
2235
  let t = new Map(e.map((e) => [e.tableName, e]));
2100
2236
  return (e, n) => {
2101
2237
  let r = t.get(e);
@@ -2120,21 +2256,21 @@ BEGIN
2120
2256
  })), d.mapError((e) => {
2121
2257
  let r = _(`applier: statement failed (op=${n})`, t, e, 400).trim();
2122
2258
  return Object.assign(e, { message: r });
2123
- }), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), ir = (e, t, n) => d.gen(function* () {
2124
- let r = process.hrtime.bigint(), i = rr(n.declared), a = t.op;
2259
+ }), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), yr = (e, t, n) => d.gen(function* () {
2260
+ let r = process.hrtime.bigint(), i = vr(n.declared), a = t.op;
2125
2261
  switch (a.kind) {
2126
2262
  case "create-table": {
2127
2263
  let t = yield* e.onDialectOrElse({
2128
- mysql: () => d.succeed(vn(a)),
2129
- mssql: () => d.succeed(On(a)),
2130
- sqlite: () => d.succeed(Cn(a)),
2131
- orElse: () => d.succeed(mn(a))
2264
+ mysql: () => d.succeed(On(a)),
2265
+ mssql: () => d.succeed(Rn(a)),
2266
+ sqlite: () => d.succeed(Nn(a)),
2267
+ orElse: () => d.succeed(wn(a))
2132
2268
  });
2133
2269
  for (let n of t) yield* Q(e, n, a.kind);
2134
2270
  break;
2135
2271
  }
2136
2272
  case "drop-table": {
2137
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? jn(a, n, e) : An(a, e);
2273
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Vn(a, n, e) : Bn(a, e);
2138
2274
  yield* e.onDialectOrElse({
2139
2275
  mysql: () => Q(e, r(K), a.kind),
2140
2276
  orElse: () => Q(e, r(G), a.kind)
@@ -2144,71 +2280,85 @@ BEGIN
2144
2280
  case "drop-column": {
2145
2281
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2146
2282
  yield* e.onDialectOrElse({
2147
- mysql: () => Q(e, t ? rn(a, n, K) : tn(a), a.kind),
2148
- orElse: () => Q(e, t ? rn(a, n, G) : en(a, G), a.kind)
2283
+ mysql: () => Q(e, t ? mn(a, n, K) : fn(a), a.kind),
2284
+ orElse: () => Q(e, t ? mn(a, n, G) : dn(a, G), a.kind)
2149
2285
  });
2150
2286
  break;
2151
2287
  }
2152
2288
  case "rename-column":
2153
2289
  yield* e.onDialectOrElse({
2154
- mysql: () => Q(e, nn(a, K), a.kind),
2290
+ mysql: () => Q(e, pn(a, K), a.kind),
2155
2291
  mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
2156
- orElse: () => Q(e, nn(a, G), a.kind)
2292
+ orElse: () => Q(e, pn(a, G), a.kind)
2157
2293
  });
2158
2294
  break;
2159
2295
  case "add-index":
2160
2296
  yield* e.onDialectOrElse({
2161
- mysql: () => Q(e, In(a, n.declared), a.kind),
2162
- mssql: () => $(e, [...Vn(a.table, a.index.columns, n.declared), Bn(a)], a.kind),
2163
- orElse: () => Q(e, Fn(a, t.classification === "online-required"), a.kind)
2297
+ mysql: () => Q(e, Kn(a, n.declared), a.kind),
2298
+ mssql: () => $(e, [...nr(a.table, a.index.columns, n.declared), tr(a)], a.kind),
2299
+ orElse: () => Q(e, Gn(a, t.classification === "online-required"), a.kind)
2164
2300
  });
2165
2301
  break;
2166
2302
  case "drop-index":
2167
2303
  yield* e.onDialectOrElse({
2168
- mysql: () => Q(e, Rn(a), a.kind),
2169
- mssql: () => Q(e, zn(a), a.kind),
2170
- orElse: () => Q(e, Ln(a), a.kind)
2304
+ mysql: () => Q(e, Jn(a), a.kind),
2305
+ mssql: () => Q(e, Yn(a), a.kind),
2306
+ orElse: () => Q(e, qn(a), a.kind)
2307
+ });
2308
+ break;
2309
+ case "rename-table":
2310
+ yield* e.onDialectOrElse({
2311
+ mysql: () => Q(e, Xn(a, K), a.kind),
2312
+ mssql: () => Q(e, Zn(a), a.kind),
2313
+ orElse: () => Q(e, Xn(a, G), a.kind)
2314
+ });
2315
+ break;
2316
+ case "rename-index":
2317
+ yield* e.onDialectOrElse({
2318
+ mysql: () => Q(e, $n(a), a.kind),
2319
+ mssql: () => Q(e, er(a), a.kind),
2320
+ orElse: () => Q(e, Qn(a), a.kind)
2171
2321
  });
2172
2322
  break;
2173
2323
  case "add-unique":
2174
2324
  yield* e.onDialectOrElse({
2175
- mysql: () => Q(e, Un(a, n.declared), a.kind),
2325
+ mysql: () => Q(e, ir(a, n.declared), a.kind),
2176
2326
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2177
- mssql: () => $(e, [...Vn(a.table, [a.column], n.declared), Hn(a)], a.kind),
2178
- orElse: () => Q(e, Hn(a), a.kind)
2327
+ mssql: () => $(e, [...nr(a.table, [a.column], n.declared), rr(a)], a.kind),
2328
+ orElse: () => Q(e, rr(a), a.kind)
2179
2329
  });
2180
2330
  break;
2181
2331
  case "drop-unique":
2182
2332
  yield* e.onDialectOrElse({
2183
- mysql: () => Q(e, Yn(a), a.kind),
2333
+ mysql: () => Q(e, ur(a), a.kind),
2184
2334
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2185
- orElse: () => Q(e, Jn(a), a.kind)
2335
+ orElse: () => Q(e, lr(a), a.kind)
2186
2336
  });
2187
2337
  break;
2188
2338
  case "add-unique-composite":
2189
2339
  yield* e.onDialectOrElse({
2190
- mysql: () => Q(e, Gn(a, n.declared), a.kind),
2340
+ mysql: () => Q(e, or(a, n.declared), a.kind),
2191
2341
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2192
- mssql: () => $(e, [...Vn(a.table, a.fields, n.declared), Wn(a)], a.kind),
2193
- orElse: () => Q(e, Wn(a), a.kind)
2342
+ mssql: () => $(e, [...nr(a.table, a.fields, n.declared), ar(a)], a.kind),
2343
+ orElse: () => Q(e, ar(a), a.kind)
2194
2344
  });
2195
2345
  break;
2196
2346
  case "drop-unique-composite":
2197
2347
  yield* e.onDialectOrElse({
2198
- mysql: () => Q(e, qn(a), a.kind),
2348
+ mysql: () => Q(e, cr(a), a.kind),
2199
2349
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2200
- orElse: () => Q(e, Kn(a), a.kind)
2350
+ orElse: () => Q(e, sr(a), a.kind)
2201
2351
  });
2202
2352
  break;
2203
2353
  case "add-foreign-key":
2204
2354
  yield* e.onDialectOrElse({
2205
- mysql: () => $(e, Xn(a, K), a.kind),
2355
+ mysql: () => $(e, dr(a, K), a.kind),
2206
2356
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2207
- orElse: () => $(e, Xn(a, G), a.kind)
2357
+ orElse: () => $(e, dr(a, G), a.kind)
2208
2358
  });
2209
2359
  break;
2210
2360
  case "add-column": {
2211
- let n = nr(a, t, i, yield* e.onDialectOrElse({
2361
+ let n = _r(a, t, i, yield* e.onDialectOrElse({
2212
2362
  mysql: () => d.succeed("mariadb"),
2213
2363
  mssql: () => d.succeed("mssql"),
2214
2364
  sqlite: () => d.succeed("sqlite"),
@@ -2254,37 +2404,37 @@ BEGIN
2254
2404
  yield* e.onDialectOrElse({
2255
2405
  mysql: () => {
2256
2406
  let t = q(n.declared, a.table, a.column);
2257
- return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${cn(t, a.column, a.toNullable)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2407
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${vn(t, a.column, a.toNullable)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2258
2408
  },
2259
2409
  mssql: () => {
2260
2410
  let t = q(n.declared, a.table, a.column);
2261
- return t ? Q(e, wn(t, a.column, a.table, a.toNullable), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
2411
+ return t ? Q(e, Pn(t, a.column, a.table, a.toNullable), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
2262
2412
  },
2263
2413
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2264
2414
  orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2265
2415
  });
2266
2416
  break;
2267
2417
  case "alter-column-default": {
2268
- let t = sn(n.declared, a.table, a.column);
2418
+ let t = _n(n.declared, a.table, a.column);
2269
2419
  yield* e.onDialectOrElse({
2270
- mysql: () => Q(e, an(a, K, (e) => ln(e, t)), a.kind),
2271
- mssql: () => Q(e, Tn(a), a.kind),
2420
+ mysql: () => Q(e, hn(a, K, (e) => yn(e, t)), a.kind),
2421
+ mssql: () => Q(e, Fn(a), a.kind),
2272
2422
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2273
- orElse: () => Q(e, an(a, G, (e) => dn(e, t)), a.kind)
2423
+ orElse: () => Q(e, hn(a, G, (e) => xn(e, t)), a.kind)
2274
2424
  });
2275
2425
  break;
2276
2426
  }
2277
2427
  case "alter-column-type": {
2278
- let r = U(sn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2428
+ let r = U(_n(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2279
2429
  if (t.classification !== "online-required") {
2280
2430
  yield* e.onDialectOrElse({
2281
2431
  mysql: () => {
2282
2432
  let t = q(n.declared, a.table, a.column);
2283
- return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${cn(t, a.column)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2433
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${vn(t, a.column)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2284
2434
  },
2285
2435
  mssql: () => {
2286
2436
  let t = q(n.declared, a.table, a.column);
2287
- return t ? Q(e, wn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2437
+ return t ? Q(e, Pn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2288
2438
  },
2289
2439
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2290
2440
  orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
@@ -2308,23 +2458,23 @@ BEGIN
2308
2458
  }
2309
2459
  case "drop-foreign-key":
2310
2460
  yield* e.onDialectOrElse({
2311
- mysql: () => Q(e, Qn(a), a.kind),
2461
+ mysql: () => Q(e, pr(a), a.kind),
2312
2462
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2313
- orElse: () => Q(e, Zn(a), a.kind)
2463
+ orElse: () => Q(e, fr(a), a.kind)
2314
2464
  });
2315
2465
  break;
2316
2466
  case "add-check":
2317
2467
  yield* e.onDialectOrElse({
2318
- mysql: () => Q(e, $n(a, K), a.kind),
2468
+ mysql: () => Q(e, mr(a, K), a.kind),
2319
2469
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2320
- orElse: () => Q(e, $n(a, G), a.kind)
2470
+ orElse: () => Q(e, mr(a, G), a.kind)
2321
2471
  });
2322
2472
  break;
2323
2473
  case "drop-check":
2324
2474
  yield* e.onDialectOrElse({
2325
- mysql: () => Q(e, tr(a), a.kind),
2475
+ mysql: () => Q(e, gr(a), a.kind),
2326
2476
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2327
- orElse: () => Q(e, er(a), a.kind)
2477
+ orElse: () => Q(e, hr(a), a.kind)
2328
2478
  });
2329
2479
  break;
2330
2480
  }
@@ -2333,10 +2483,10 @@ BEGIN
2333
2483
  status: "applied",
2334
2484
  durationMs: Number((process.hrtime.bigint() - r) / 1000000n)
2335
2485
  };
2336
- }), ar = (e, t, n) => d.gen(function* () {
2486
+ }), br = (e, t, n) => d.gen(function* () {
2337
2487
  let r = t.operations.filter((e) => e.blocked);
2338
2488
  if (r.length > 0) return yield* d.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2339
- yield* w(e);
2489
+ yield* C(e);
2340
2490
  let i = Date.now(), a = [];
2341
2491
  try {
2342
2492
  let r = yield* e.onDialectOrElse({
@@ -2346,11 +2496,11 @@ BEGIN
2346
2496
  }), i = r ? t.operations.filter((e) => e.classification !== "online-required") : [], o = r ? t.operations.filter((e) => e.classification === "online-required") : t.operations;
2347
2497
  i.length > 0 && (yield* e.withTransaction(d.gen(function* () {
2348
2498
  let e = yield* p.SqlClient;
2349
- for (let t of i) a.push(yield* ir(e, t, n));
2499
+ for (let t of i) a.push(yield* yr(e, t, n));
2350
2500
  })));
2351
- for (let t of o) a.push(yield* ir(e, t, n));
2501
+ for (let t of o) a.push(yield* yr(e, t, n));
2352
2502
  } finally {
2353
- yield* T(e).pipe(d.orDie);
2503
+ yield* w(e).pipe(d.orDie);
2354
2504
  }
2355
2505
  let o = yield* n.replan(e);
2356
2506
  if (o.operations.length > 0) {
@@ -2382,19 +2532,19 @@ BEGIN
2382
2532
  source: n.source,
2383
2533
  ...n.notes ? { notes: n.notes } : {}
2384
2534
  };
2385
- }), or = (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"), sr = (e) => e`
2535
+ }), xr = (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"), Sr = (e) => e`
2386
2536
  SELECT fingerprint
2387
2537
  FROM _voltro_migration_plans
2388
2538
  ORDER BY ${e("appliedAt")} DESC
2389
2539
  LIMIT 1
2390
- `.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), cr = (e) => e.onDialectOrElse({
2540
+ `.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), Cr = (e) => e.onDialectOrElse({
2391
2541
  pg: () => "postgres",
2392
2542
  mysql: () => "mysql",
2393
2543
  mssql: () => "mssql",
2394
2544
  sqlite: () => "sqlite",
2395
2545
  orElse: () => "sqlite"
2396
- }), lr = (e, t) => d.gen(function* () {
2397
- let n = j(N(t, cr(e))), r = yield* sr(e);
2546
+ }), wr = (e, t) => d.gen(function* () {
2547
+ let n = j(N(t, Cr(e))), r = yield* Sr(e);
2398
2548
  return r === n ? {
2399
2549
  kind: "up-to-date",
2400
2550
  fingerprint: n
@@ -2403,23 +2553,23 @@ BEGIN
2403
2553
  expected: n,
2404
2554
  ...r === void 0 ? {} : { actual: r }
2405
2555
  };
2406
- }), ur = [
2556
+ }), Tr = [
2407
2557
  "pgeagertest_",
2408
2558
  "mig_e2e_",
2409
2559
  "mig_test_",
2410
2560
  "mysqleagertest_",
2411
2561
  "mssqleagertest_",
2412
2562
  "sqliteeagertest_"
2413
- ], dr = (e) => ur.some((t) => e.startsWith(t)), fr = (e, t) => d.gen(function* () {
2563
+ ], Er = (e) => Tr.some((t) => e.startsWith(t)), Dr = (e, t) => d.gen(function* () {
2414
2564
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2415
- let n = t.filter((e) => dr(e.name)).map((e) => e.name);
2565
+ let n = t.filter((e) => Er(e.name)).map((e) => e.name);
2416
2566
  if (n.length === 0) return [];
2417
2567
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(d.catchAll(() => d.void));
2418
2568
  return n;
2419
- }), pr = () => {
2569
+ }), Or = () => {
2420
2570
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2421
2571
  return e.length > 0 ? { ignoreTables: e } : {};
2422
- }, mr = (e) => {
2572
+ }, kr = (e) => {
2423
2573
  if (e === void 0) return;
2424
2574
  let t = e.trim();
2425
2575
  if (t === "") return;
@@ -2429,73 +2579,73 @@ BEGIN
2429
2579
  kind: "tables",
2430
2580
  tables: new Set(n)
2431
2581
  } : void 0;
2432
- }, hr = (e) => typeof e.table == "string" ? e.table : void 0, gr = (e, t = { kind: "all" }) => ({
2582
+ }, Ar = (e) => typeof e.table == "string" ? e.table : void 0, jr = (e, t = { kind: "all" }) => ({
2433
2583
  ...e,
2434
2584
  operations: e.operations.map((e) => {
2435
2585
  if (!e.blocked || e.classification !== "lossy") return e;
2436
2586
  if (t?.kind === "tables") {
2437
- let n = hr(e.op);
2587
+ let n = Ar(e.op);
2438
2588
  if (n === void 0 || !t.tables.has(n)) return e;
2439
2589
  }
2440
2590
  let { blocked: n, ...r } = e;
2441
2591
  return r;
2442
2592
  })
2443
- }), _r = (e, t, n) => t === "postgres" ? st(e, n).pipe(d.flatMap((e) => {
2593
+ }), Mr = (e, t, n) => t === "postgres" ? st(e, n).pipe(d.flatMap((e) => {
2444
2594
  let t = ct(e);
2445
2595
  return t === void 0 ? d.void : d.logWarning(`auto-migrate: ${t}`).pipe(d.annotateLogs({ scope: "voltro:migrate" }));
2446
- }), d.catchAll(() => d.void)) : d.void, vr = (e, t, n) => d.gen(function* () {
2447
- let r = cr(e), i = t.filter((e) => !P(e.tableName));
2596
+ }), d.catchAll(() => d.void)) : d.void, Nr = (e, t, n) => d.gen(function* () {
2597
+ let r = Cr(e), i = t;
2448
2598
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2449
2599
  let t = j(N(i, r));
2450
- if ((yield* sr(e)) === t) return yield* _r(e, r, i), {
2600
+ if ((yield* Sr(e)) === t) return yield* Mr(e, r, i), {
2451
2601
  kind: "up-to-date",
2452
2602
  fingerprint: t
2453
2603
  };
2454
2604
  }
2455
- let a = yield* V(e), o = yield* fr(e, a.tables);
2605
+ let a = yield* V(e), o = yield* Dr(e, a.tables);
2456
2606
  o.length > 0 && (yield* d.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(d.annotateLogs({
2457
2607
  scope: "voltro:migrate",
2458
2608
  count: o.length
2459
2609
  })), a = yield* V(e));
2460
- let s = Ft({
2610
+ let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !ut(e.name) || s.has(e.name)), l = Wt({
2461
2611
  declared: i,
2462
- live: { tables: a.tables.filter((e) => !P(e.name)) },
2612
+ live: { tables: c(a.tables) },
2463
2613
  dialect: r,
2464
- ...pr()
2614
+ ...Or()
2465
2615
  });
2466
- if (s.summary.blocked > 0) {
2467
- let e = s.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = mr(process.env.VOLTRO_DESTRUCTIVE_OK);
2468
- if (t === void 0 || !e || (s = gr(s, t), s.operations.some((e) => e.blocked))) return {
2616
+ if (l.summary.blocked > 0) {
2617
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = kr(process.env.VOLTRO_DESTRUCTIVE_OK);
2618
+ if (t === void 0 || !e || (l = jr(l, t), l.operations.some((e) => e.blocked))) return {
2469
2619
  kind: "refused-blocked",
2470
- plan: s
2620
+ plan: l
2471
2621
  };
2472
2622
  }
2473
- return s.operations.length === 0 ? {
2623
+ return l.operations.length === 0 ? {
2474
2624
  kind: "up-to-date",
2475
- fingerprint: s.toFingerprint
2625
+ fingerprint: l.toFingerprint
2476
2626
  } : {
2477
2627
  kind: "applied",
2478
- applied: yield* ar(e, s, {
2628
+ applied: yield* br(e, l, {
2479
2629
  declared: t,
2480
2630
  appliedBy: n.appliedBy,
2481
2631
  environment: n.environment === "prod" ? "dev" : n.environment,
2482
2632
  source: "auto-diff",
2483
2633
  replan: (e) => d.gen(function* () {
2484
2634
  let t = yield* V(e);
2485
- return Ft({
2635
+ return Wt({
2486
2636
  declared: i,
2487
- live: { tables: t.tables.filter((e) => !P(e.name)) },
2637
+ live: { tables: c(t.tables) },
2488
2638
  dialect: r,
2489
- ...pr()
2639
+ ...Or()
2490
2640
  });
2491
2641
  })
2492
2642
  }),
2493
- plan: s
2643
+ plan: l
2494
2644
  };
2495
- }), yr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2645
+ }), Pr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2496
2646
  kind: "skipped",
2497
2647
  reason: "VOLTRO_AUTO_MIGRATE=0"
2498
- }) : n.environment === "prod" ? lr(e, t) : vr(e, t, n), br = (e, t) => {
2648
+ }) : n.environment === "prod" ? wr(e, t) : Nr(e, t, n), Fr = (e, t) => {
2499
2649
  switch (e.kind) {
2500
2650
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2501
2651
  case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${M(e.fingerprint)})`;
@@ -2505,7 +2655,7 @@ BEGIN
2505
2655
  }
2506
2656
  case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${M(e.expected)}` + (e.actual ? ` live=${M(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2507
2657
  case "refused-blocked": {
2508
- 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` + or(e.plan), c = [""];
2658
+ 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` + xr(e.plan), c = [""];
2509
2659
  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) {
2510
2660
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2511
2661
  for (let r of e.plan.operations) {
@@ -2522,7 +2672,7 @@ BEGIN
2522
2672
  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");
2523
2673
  }
2524
2674
  }
2525
- }, xr = /* @__PURE__ */ new Set([
2675
+ }, Ir = /* @__PURE__ */ new Set([
2526
2676
  "node_modules",
2527
2677
  "dist",
2528
2678
  "build",
@@ -2531,11 +2681,11 @@ BEGIN
2531
2681
  ".next",
2532
2682
  ".git",
2533
2683
  ".framework"
2534
- ]), Sr = async (e) => {
2684
+ ]), Lr = async (e) => {
2535
2685
  let t = [], n = async (e) => {
2536
2686
  let r = await h.readdir(e, { withFileTypes: !0 }).catch(() => []);
2537
2687
  for (let i of r) {
2538
- if (xr.has(i.name)) continue;
2688
+ if (Ir.has(i.name)) continue;
2539
2689
  let r = g(e, i.name);
2540
2690
  i.isDirectory() ? await n(r) : i.isFile() && l.test(i.name) && t.push(r);
2541
2691
  }
@@ -2544,7 +2694,7 @@ BEGIN
2544
2694
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
2545
2695
  return n.localeCompare(r);
2546
2696
  });
2547
- }, Cr = async (e) => {
2697
+ }, Rr = async (e) => {
2548
2698
  let t = [];
2549
2699
  for (let n of e) {
2550
2700
  let e = (await import(ee(n).href)).default;
@@ -2558,11 +2708,11 @@ BEGIN
2558
2708
  });
2559
2709
  }
2560
2710
  return t;
2561
- }, wr = (e) => e`
2711
+ }, zr = (e) => e`
2562
2712
  SELECT ${e("id")}
2563
2713
  FROM ${e("_voltro_migration_plans")}
2564
2714
  WHERE ${e("source")} = 'file'
2565
- `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), Tr = (e, t, n, r) => d.gen(function* () {
2715
+ `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), Br = (e, t, n, r) => d.gen(function* () {
2566
2716
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
2567
2717
  sql: e,
2568
2718
  log: {
@@ -2595,9 +2745,9 @@ BEGIN
2595
2745
  ${r}, ${n}, ${"file"},
2596
2746
  ${c}, ${a}, ${t.migration.description})
2597
2747
  `, { durationMs: c };
2598
- }), Er = (e, t) => d.gen(function* () {
2748
+ }), Vr = (e, t) => d.gen(function* () {
2599
2749
  let n = yield* d.tryPromise({
2600
- try: () => Sr(g(t, "migrations")),
2750
+ try: () => Lr(g(t, "migrations")),
2601
2751
  catch: (e) => e
2602
2752
  });
2603
2753
  if (n.length === 0) return {
@@ -2605,25 +2755,25 @@ BEGIN
2605
2755
  skipped: []
2606
2756
  };
2607
2757
  let r = yield* d.tryPromise({
2608
- try: () => Cr(n),
2758
+ try: () => Rr(n),
2609
2759
  catch: (e) => e
2610
2760
  });
2611
2761
  if (r.length === 0) return {
2612
2762
  pending: [],
2613
2763
  skipped: []
2614
2764
  };
2615
- let i = new Set(yield* wr(e));
2765
+ let i = new Set(yield* zr(e));
2616
2766
  return {
2617
2767
  pending: r.filter((e) => !i.has(e.migration.id)),
2618
2768
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
2619
2769
  };
2620
- }), Dr = (e, t) => Er(e, t).pipe(d.map((e) => e.pending.map((e) => e.migration.id))), Or = (e, t) => d.gen(function* () {
2621
- let { pending: n, skipped: r } = yield* Er(e, t.projectRoot);
2770
+ }), Hr = (e, t) => Vr(e, t).pipe(d.map((e) => e.pending.map((e) => e.migration.id))), Ur = (e, t) => d.gen(function* () {
2771
+ let { pending: n, skipped: r } = yield* Vr(e, t.projectRoot);
2622
2772
  if (n.length === 0) return {
2623
2773
  applied: [],
2624
2774
  skipped: r
2625
2775
  };
2626
- yield* w(e);
2776
+ yield* C(e);
2627
2777
  let i = [];
2628
2778
  try {
2629
2779
  for (let r of n) {
@@ -2632,7 +2782,7 @@ BEGIN
2632
2782
  id: r.migration.id,
2633
2783
  file: r.file
2634
2784
  }));
2635
- let { durationMs: n } = yield* Tr(e, r, t.env, t.appliedBy);
2785
+ let { durationMs: n } = yield* Br(e, r, t.env, t.appliedBy);
2636
2786
  i.push({
2637
2787
  id: r.migration.id,
2638
2788
  durationMs: n
@@ -2643,28 +2793,28 @@ BEGIN
2643
2793
  }));
2644
2794
  }
2645
2795
  } finally {
2646
- yield* T(e).pipe(d.orDie);
2796
+ yield* w(e).pipe(d.orDie);
2647
2797
  }
2648
2798
  return {
2649
2799
  applied: i,
2650
2800
  skipped: r
2651
2801
  };
2652
- }), kr = (e, t) => e`
2802
+ }), Wr = (e, t) => e`
2653
2803
  SELECT ${e("id")}
2654
2804
  FROM ${e("_voltro_migration_plans")}
2655
2805
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
2656
2806
  LIMIT 1
2657
- `, Ar = (e, t) => d.gen(function* () {
2658
- if (!(yield* kr(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2807
+ `, Gr = (e, t) => d.gen(function* () {
2808
+ if (!(yield* Wr(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2659
2809
  let n = yield* d.tryPromise({
2660
- try: () => Sr(g(t.projectRoot, "migrations")),
2810
+ try: () => Lr(g(t.projectRoot, "migrations")),
2661
2811
  catch: (e) => e
2662
2812
  }), r = (yield* d.tryPromise({
2663
- try: () => Cr(n),
2813
+ try: () => Rr(n),
2664
2814
  catch: (e) => e
2665
2815
  })).find((e) => e.migration.id === t.id);
2666
2816
  if (!r) return yield* d.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
2667
- yield* w(e);
2817
+ yield* C(e);
2668
2818
  let i = Date.now();
2669
2819
  try {
2670
2820
  let n = {
@@ -2691,9 +2841,9 @@ BEGIN
2691
2841
  durationMs: o
2692
2842
  };
2693
2843
  } finally {
2694
- yield* T(e).pipe(d.orDie);
2844
+ yield* w(e).pipe(d.orDie);
2695
2845
  }
2696
- }), jr = (e) => d.gen(function* () {
2846
+ }), Kr = (e) => d.gen(function* () {
2697
2847
  let t = yield* p.SqlClient, n = yield* t`
2698
2848
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
2699
2849
  WHERE source = 'auto-diff'
@@ -2738,10 +2888,10 @@ BEGIN
2738
2888
  snapshotFingerprint: e.fingerprint,
2739
2889
  snapshotId: i
2740
2890
  };
2741
- }), Mr = (e, ...t) => ({
2891
+ }), qr = (e, ...t) => ({
2742
2892
  _tag: "RawSqlFragment",
2743
2893
  strings: [...e],
2744
2894
  values: [...t]
2745
- }), Nr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2895
+ }), Jr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2746
2896
  //#endregion
2747
- export { l as FILE_MIGRATION_PATTERN, ot as REACTIVE_TRIGGER_PREFIX, C as VOLTRO_MIGRATION_LOCK_KEY, w as acquireMigrationLock, Je as applyNamespacedSchema, ar as applyPlan, He as applySchema, Ht as chunkTables, N as declaredSnapshot, ye as defaultArrayClause, ve as defaultClause, O as defaultJsonClause, br as describeOutcome, mr as destructiveScope, st as detectReactiveTriggerDrift, en as emitDropColumnDdl, tn as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, ct as formatReactiveTriggerDrift, pr as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, Nr as isRawSqlFragment, Lt as mapPgType, s as migration, k as numericIdSql, It as parseEnumCheck, Dr as pendingFileMigrationIds, Ft as planMigrations, Ye as provisionTenantNamespace, T as releaseMigrationLock, _n as renderColumnMysql, fn as renderColumnPg, Ar as rollbackFileBasedMigration, Or as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, yr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, Mr as sql, D as sqlType, jr as squashMigrationPlans, gr as unblockLossy, ge as withMigrationLock };
2897
+ export { l as FILE_MIGRATION_PATTERN, ot as REACTIVE_TRIGGER_PREFIX, re as VOLTRO_MIGRATION_LOCK_KEY, C as acquireMigrationLock, Je as applyNamespacedSchema, br as applyPlan, He as applySchema, Zt as chunkTables, N as declaredSnapshot, be as defaultArrayClause, ye as defaultClause, D as defaultJsonClause, Fr as describeOutcome, kr as destructiveScope, st as detectReactiveTriggerDrift, dn as emitDropColumnDdl, fn as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, ct as formatReactiveTriggerDrift, Or as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, Jr as isRawSqlFragment, Kt as mapPgType, s as migration, O as numericIdSql, Gt as parseEnumCheck, Hr as pendingFileMigrationIds, Wt as planMigrations, Ye as provisionTenantNamespace, w as releaseMigrationLock, Dn as renderColumnMysql, Sn as renderColumnPg, Gr as rollbackFileBasedMigration, Ur as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, Pr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, qr as sql, E as sqlType, Kr as squashMigrationPlans, jr as unblockLossy, _e as withMigrationLock };