@voltro/database 0.12.0 → 0.13.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
@@ -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, y = (e) => e.replace(/"/g, "`"), te = (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) {
@@ -49,9 +49,9 @@ var _ = (e, t, n, r = 400) => {
49
49
  }
50
50
  let a = y(t.where), o = [];
51
51
  for (let r of t.fields) {
52
- let i = te(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 = (t, n) => {
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 = (t, n) => {
125
125
  let r = t.type;
126
126
  if (t.spatial) {
127
127
  if (n === "postgres") return `${t.spatial.kind}(${t.spatial.geomKind},${t.spatial.srid})`;
@@ -132,7 +132,7 @@ var _ = (e, t, n, r = 400) => {
132
132
  return t.rawDdl;
133
133
  }
134
134
  if (r === "array" && t.arrayElement) {
135
- if (n === "postgres") return `${D({
135
+ if (n === "postgres") return `${E({
136
136
  ...t,
137
137
  type: t.arrayElement,
138
138
  arrayElement: void 0
@@ -232,14 +232,22 @@ var _ = (e, t, n, r = 400) => {
232
232
  case "array": return "TEXT[]";
233
233
  case "interval": return "INTERVAL";
234
234
  }
235
- }, ve = (t, n) => {
235
+ }, ye = (t, n) => {
236
236
  if (!t.hasDefault || t.defaultFactory !== void 0) return null;
237
237
  let r = t.defaultValue;
238
- return r === "now" ? e(n) ? "DEFAULT CURRENT_TIMESTAMP" : n === "mssql" ? "DEFAULT SYSUTCDATETIME()" : n === "mysql" || n === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof r == "boolean" ? n === "postgres" ? `DEFAULT ${r}` : `DEFAULT ${+!!r}` : typeof r == "number" ? `DEFAULT ${r}` : typeof r == "string" ? `DEFAULT '${r.replace(/'/g, "''")}'` : typeof r == "object" && r && !Array.isArray(r) ? O(r, n) : null;
239
- }, O = (e, t) => {
238
+ return r === "now" ? e(n) ? "DEFAULT CURRENT_TIMESTAMP" : n === "mssql" ? "DEFAULT SYSUTCDATETIME()" : n === "mysql" || n === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof r == "boolean" ? n === "postgres" ? `DEFAULT ${r}` : `DEFAULT ${+!!r}` : typeof r == "number" ? `DEFAULT ${r}` : typeof r == "string" ? `DEFAULT '${r.replace(/'/g, "''")}'` : Array.isArray(r) ? be(r, t, n) : typeof r == "object" && r ? D(r, n) : 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
+ ...t,
243
+ type: t.arrayElement,
244
+ arrayElement: void 0
245
+ }, n);
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
+ }, D = (e, t) => {
240
248
  let n = JSON.stringify(e).replace(/'/g, "''");
241
249
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CAST('${n}' AS JSON))` : `DEFAULT '${n}'`;
242
- }, k = (e, t) => {
250
+ }, O = (e, t) => {
243
251
  switch (t) {
244
252
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
245
253
  case "mysql":
@@ -248,7 +256,7 @@ var _ = (e, t, n, r = 400) => {
248
256
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
249
257
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
250
258
  }
251
- }, A = (e, t) => {
259
+ }, k = (e, t) => {
252
260
  if (e === "restrict" && t === "mssql") return "NO ACTION";
253
261
  switch (e) {
254
262
  case "cascade": return "CASCADE";
@@ -256,38 +264,38 @@ var _ = (e, t, n, r = 400) => {
256
264
  case "setNull": return "SET NULL";
257
265
  case "noAction": return "NO ACTION";
258
266
  }
259
- }, ye = (e, t, n) => n === null ? u(e, t) : `${u(n, t)}.${u(e, t)}`, be = 191, xe = (e, t, n) => {
267
+ }, xe = (e, t, n) => n === null ? u(e, t) : `${u(n, t)}.${u(e, t)}`, Se = 191, Ce = (e, t, n) => {
260
268
  let r = u(e, n);
261
269
  if (n !== "mysql" && n !== "mariadb") return r;
262
270
  let i = t[e];
263
271
  if (!i) return r;
264
- let a = D(i, n).toUpperCase();
265
- return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${be})` : r;
266
- }, Se = (e, t) => {
272
+ let a = E(i, n).toUpperCase();
273
+ return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${Se})` : r;
274
+ }, we = (e, t) => {
267
275
  if (!e.generatedAs) return null;
268
276
  let { expr: n, stored: r } = e.generatedAs;
269
- 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`;
270
278
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
271
279
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
272
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.");
273
281
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
274
- }, Ce = (t, n, r, i, a = !1, o = !1) => {
275
- if (n.type === "id" && n.idScheme?.kind === "numeric") return k(t, r);
276
- let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : D(n, r), c = [u(t, r), s];
282
+ }, Te = (t, n, r, i, a = !1, o = !1) => {
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 = [u(t, r), s];
277
285
  n.type === "id" && !o && c.push("PRIMARY KEY");
278
- let l = Se(n, r);
286
+ let l = we(n, r);
279
287
  if (l) c.push(l);
280
288
  else {
281
289
  n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && c.push("UNIQUE");
282
- let e = ve(n, r);
290
+ let e = ye(n, r);
283
291
  e && c.push(e);
284
292
  }
285
293
  if (n.type === "reference" && n.references && !a) {
286
294
  let e = n.references();
287
295
  c.push(`REFERENCES ${u(e.tableName, r)} (${u("id", r)})`);
288
- let t = A(n.onDelete ?? "restrict", r);
296
+ let t = k(n.onDelete ?? "restrict", r);
289
297
  c.push(`ON DELETE ${t}`);
290
- let i = A(n.refOnUpdate ?? "noAction", r);
298
+ let i = k(n.refOnUpdate ?? "noAction", r);
291
299
  i !== "NO ACTION" && c.push(`ON UPDATE ${i}`);
292
300
  }
293
301
  if (n.oneOf && n.oneOf.length > 0) {
@@ -304,18 +312,18 @@ var _ = (e, t, n, r = 400) => {
304
312
  e(r) ? c.push(`CHECK (${n} IS NULL OR json_valid(${n}))`) : r === "mssql" && c.push(`CHECK (${n} IS NULL OR ISJSON(${n}) = 1)`);
305
313
  }
306
314
  return c.join(" ");
307
- }, we = (e, t, n = null, r) => {
315
+ }, Ee = (e, t, n = null, r) => {
308
316
  let i = /* @__PURE__ */ new Set();
309
317
  for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
310
318
  for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
311
- let a = e.appliedPrimaryKey ?? [], o = a.length > 0, s = Object.entries(e.fields).map(([e, n]) => ` ${Ce(e, n, t, i, r?.has(e) ?? !1, o)}`).join(",\n"), c = (e.appliedUniques ?? []).map((n) => {
312
- let r = n.fields.map((n) => xe(n, e.fields, t)).join(", ");
319
+ let a = e.appliedPrimaryKey ?? [], o = a.length > 0, s = Object.entries(e.fields).map(([e, n]) => ` ${Te(e, n, t, i, r?.has(e) ?? !1, o)}`).join(",\n"), c = (e.appliedUniques ?? []).map((n) => {
320
+ let r = n.fields.map((n) => Ce(n, e.fields, t)).join(", ");
313
321
  return ` CONSTRAINT ${u(n.name, t)} UNIQUE (${r})`;
314
322
  }), l = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${u(e.name, t)} CHECK (${e.expr})`), d = [
315
- ...o ? [` PRIMARY KEY (${a.map((n) => xe(n, e.fields, t)).join(", ")})`] : [],
323
+ ...o ? [` PRIMARY KEY (${a.map((n) => Ce(n, e.fields, t)).join(", ")})`] : [],
316
324
  ...c,
317
325
  ...l
318
- ], f = d.length > 0 ? `${s},\n${d.join(",\n")}` : s, p = ye(e.tableName, t, n);
326
+ ], f = d.length > 0 ? `${s},\n${d.join(",\n")}` : s, p = xe(e.tableName, t, n);
319
327
  if (t === "mssql") {
320
328
  let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${p} (\n${f}\n)`;
321
329
  return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
@@ -325,10 +333,10 @@ var _ = (e, t, n, r = 400) => {
325
333
  f,
326
334
  ");"
327
335
  ].join("\n");
328
- }, Te = (e, t, n) => {
336
+ }, De = (e, t, n) => {
329
337
  let r = `${e}_${t.name}_fts`, i = (e) => u(e, n), a = t.columns.map(i).join(", "), o = t.columns.map((e) => `new.${i(e)}`).join(", "), s = [];
330
338
  return s.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${i(r)} USING fts5(${a}, row_id UNINDEXED, tokenize='porter');`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ai`)} AFTER INSERT ON ${i(e)} BEGIN\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ad`)} AFTER DELETE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_au`)} AFTER UPDATE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s;
331
- }, Ee = (e, n, r = null) => {
339
+ }, Oe = (e, n, r = null) => {
332
340
  let i = [], o = /* @__PURE__ */ new Set(), s = (e) => e.join("\0"), c = (e, r, i, a) => {
333
341
  let o = {
334
342
  using: "",
@@ -340,21 +348,21 @@ var _ = (e, t, n, r = 400) => {
340
348
  using: " USING GIST",
341
349
  withSuffix: "",
342
350
  skip: !1
343
- } : (E(`[voltro:migrate] index '${e}' on '${r}': ${n} 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 '${r}': ${n} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
344
352
  if (i === "gin") return n === "postgres" ? {
345
353
  using: " USING GIN",
346
354
  withSuffix: "",
347
355
  skip: !1
348
- } : n === "mysql" || n === "mariadb" ? (E(`[voltro:migrate] gin index '${e}' on '${r}': ${n} 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
+ } : n === "mysql" || n === "mariadb" ? (T(`[voltro:migrate] gin index '${e}' on '${r}': ${n} 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(...).`), {
349
357
  using: "",
350
358
  withSuffix: "",
351
359
  skip: !0
352
- }) : (E(`[voltro:migrate] gin index '${e}' on '${r}': ${n} 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 '${r}': ${n} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
353
361
  if (i === "brin") return n === "postgres" ? {
354
362
  using: " USING BRIN",
355
363
  withSuffix: "",
356
364
  skip: !1
357
- } : (E(`[voltro:migrate] brin index '${e}' on '${r}': ${n} 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 '${r}': ${n} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
358
366
  if (i === "hnsw") {
359
367
  if (n === "postgres") {
360
368
  let e = a?.hnsw?.m ?? 16, n = a?.hnsw?.efConstruction ?? 64, r = a?.hnsw?.opclass ?? t(a?.hnsw?.distance);
@@ -365,7 +373,7 @@ var _ = (e, t, n, r = 400) => {
365
373
  skip: !1
366
374
  };
367
375
  }
368
- return E(`[voltro:migrate] hnsw index '${e}' on '${r}': ${n} 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 '${r}': ${n} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
369
377
  using: "",
370
378
  withSuffix: "",
371
379
  skip: !0
@@ -374,7 +382,7 @@ var _ = (e, t, n, r = 400) => {
374
382
  return o;
375
383
  }, l = (t, r) => {
376
384
  let i = t.map((t) => {
377
- if (typeof t == "string") return xe(t, e.fields, n);
385
+ if (typeof t == "string") return Ce(t, e.fields, n);
378
386
  if ("jsonPath" in t) {
379
387
  let { column: e, path: r, numeric: i } = t.jsonPath;
380
388
  return `(${a(e, r, n, { numeric: i })})`;
@@ -385,7 +393,7 @@ var _ = (e, t, n, r = 400) => {
385
393
  }, d = (e, t, i, a, o, s = "", d = !1) => {
386
394
  let f = c(e, t, a, o);
387
395
  if (f.skip) return "";
388
- let p = l(i, f.opclass), m = `${f.withSuffix}${s}`, h = ye(t, n, r), g = d ? "UNIQUE " : "";
396
+ let p = l(i, f.opclass), m = `${f.withSuffix}${s}`, h = xe(t, n, r), g = d ? "UNIQUE " : "";
389
397
  return n === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${u(e, n)} ON ${h}${f.using} (${p})${m};` : n === "mysql" ? `CREATE ${g}INDEX ${u(e, n)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${u(e, n)} ON ${h}${f.using} (${p})${m};`;
390
398
  };
391
399
  for (let t of e.appliedFullText ?? []) if (n === "postgres") {
@@ -398,15 +406,15 @@ var _ = (e, t, n, r = 400) => {
398
406
  let r = t.columns.map((e) => u(e, n)).join(", ");
399
407
  i.push(`CREATE FULLTEXT INDEX ${u(t.name, n)} ON ${u(e.tableName, n)} (${r});`);
400
408
  } else if (n === "turso") throw Error(`@voltro/sql-turso: full-text index '${t.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
401
- else n === "sqlite" ? i.push(...Te(e.tableName, t, n)) : E(`[voltro:migrate] full-text index '${t.name}' on '${e.tableName}': ${n} uses a ranked LIKE search at query time (no native FTS catalog required).`);
409
+ else n === "sqlite" ? i.push(...De(e.tableName, t, n)) : T(`[voltro:migrate] full-text index '${t.name}' on '${e.tableName}': ${n} uses a ranked LIKE search at query time (no native FTS catalog required).`);
402
410
  for (let t of e.appliedIndexes) {
403
411
  if ((n === "mariadb" || n === "mssql") && t.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
404
- E(`[voltro:migrate] json-path index '${t.name}' on '${e.tableName}': ${n} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${n}, 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 '${t.name}' on '${e.tableName}': ${n} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${n}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
405
413
  continue;
406
414
  }
407
415
  if (t.unique && t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${t.name}' on '${e.tableName}' cannot be expressed on ${n} — 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 ${n}, or move this table to postgres/sqlite/mssql.`);
408
416
  let r = "";
409
- t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb" ? E(`[voltro:migrate] partial index '${t.name}' on '${e.tableName}': ${n} does not support WHERE clauses on indexes — emitting a full index`) : r = ` WHERE ${t.where}`);
417
+ t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb" ? T(`[voltro:migrate] partial index '${t.name}' on '${e.tableName}': ${n} does not support WHERE clauses on indexes — emitting a full index`) : r = ` WHERE ${t.where}`);
410
418
  let a = d(t.name, e.tableName, t.fields, t.kind, t.kindOptions, r, t.unique === !0);
411
419
  a !== "" && i.push(a), t.fields.every((e) => typeof e == "string") && o.add(s(t.fields));
412
420
  }
@@ -416,14 +424,14 @@ var _ = (e, t, n, r = 400) => {
416
424
  i.push(d(r, e.tableName, [t])), o.add(s([t]));
417
425
  }
418
426
  return i.join("\n");
419
- }, De = "CREATE OR REPLACE FUNCTION framework_notify_change() RETURNS trigger AS $$\nDECLARE\n payload TEXT;\nBEGIN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n -- The schema the write landed in. Under namespace isolation this is\n -- the tenant schema (tenant_<id>); the CDC consumer uses it so a\n -- write in tenant A namespace does not spuriously wake tenant B\n -- subscriptions on the same-named table. public/absent = shared.\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE row_to_json(OLD) END,\n 'new', CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE row_to_json(NEW) END\n )::text;\n -- pg_notify hard-caps the payload at 8000 bytes; a wide reactive row\n -- (big text / json column) would otherwise abort the write itself.\n -- Fall back to a body-less notice — the CDC consumer treats absent\n -- old/new as \"all columns changed\" and re-queries, so correctness is\n -- preserved; only the delta-diff fast path is skipped for that write.\n IF octet_length(payload) >= 7999 THEN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', NULL,\n 'new', NULL,\n 'oversized', true\n )::text;\n END IF;\n PERFORM pg_notify('framework_changes', payload);\n RETURN COALESCE(NEW, OLD);\nEND;\n$$ LANGUAGE plpgsql;", Oe = (e) => `
427
+ }, ke = "CREATE OR REPLACE FUNCTION framework_notify_change() RETURNS trigger AS $$\nDECLARE\n payload TEXT;\nBEGIN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n -- The schema the write landed in. Under namespace isolation this is\n -- the tenant schema (tenant_<id>); the CDC consumer uses it so a\n -- write in tenant A namespace does not spuriously wake tenant B\n -- subscriptions on the same-named table. public/absent = shared.\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE row_to_json(OLD) END,\n 'new', CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE row_to_json(NEW) END\n )::text;\n -- pg_notify hard-caps the payload at 8000 bytes; a wide reactive row\n -- (big text / json column) would otherwise abort the write itself.\n -- Fall back to a body-less notice — the CDC consumer treats absent\n -- old/new as \"all columns changed\" and re-queries, so correctness is\n -- preserved; only the delta-diff fast path is skipped for that write.\n IF octet_length(payload) >= 7999 THEN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', NULL,\n 'new', NULL,\n 'oversized', true\n )::text;\n END IF;\n PERFORM pg_notify('framework_changes', payload);\n RETURN COALESCE(NEW, OLD);\nEND;\n$$ LANGUAGE plpgsql;", Ae = (e) => `
420
428
  ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL;
421
429
  DROP TRIGGER IF EXISTS framework_changes_${e.tableName} ON "${e.tableName}";
422
430
  CREATE TRIGGER framework_changes_${e.tableName}
423
431
  AFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"
424
432
  FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
425
- `.trim(), ke = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), Ae = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), je = (e) => {
426
- let t = new Map(e.map((e) => [e.tableName, e])), n = S(e.map((e) => e.tableName), (e) => {
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 = ne(e.map((e) => e.tableName), (e) => {
427
435
  let n = t.get(e);
428
436
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
429
437
  if (n.type !== "reference" || !n.references) return [];
@@ -434,7 +442,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
434
442
  }] : [];
435
443
  }) : [];
436
444
  }), r = [];
437
- 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({
438
446
  table: t.tableName,
439
447
  column: e,
440
448
  targetTable: i.references().tableName,
@@ -445,7 +453,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
445
453
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
446
454
  a.add(e.tableName);
447
455
  for (let [r, i] of Object.entries(e.fields)) {
448
- 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;
449
457
  let a = i.references();
450
458
  if (a.tableName === e.tableName) continue;
451
459
  let o = t.get(a.tableName);
@@ -459,8 +467,8 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
459
467
  sorted: o,
460
468
  cyclic: r
461
469
  };
462
- }, Me = (e, t, n = null) => {
463
- let r = (e) => n ? `${u(n, t)}.${u(e, t)}` : u(e, t), i = `${e.table}_${e.column}_fkey`, a = A(e.onDelete, t), o = A(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${u(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${u(e.column, t)}) REFERENCES ${r(e.targetTable)} (${u("id", t)})${s}`;
470
+ }, Pe = (e, t, n = null) => {
471
+ let r = (e) => n ? `${u(n, t)}.${u(e, t)}` : u(e, t), i = `${e.table}_${e.column}_fkey`, a = k(e.onDelete, t), o = k(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${u(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${u(e.column, t)}) REFERENCES ${r(e.targetTable)} (${u("id", t)})${s}`;
464
472
  switch (t) {
465
473
  case "postgres": return [
466
474
  "DO $$ BEGIN",
@@ -474,7 +482,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
474
482
  case "mariadb": return `ALTER TABLE ${r(e.table)} ${c(!0)};`;
475
483
  default: return `ALTER TABLE ${r(e.table)} ${c(!1)};`;
476
484
  }
477
- }, Ne = (t, n) => {
485
+ }, Fe = (t, n) => {
478
486
  let r = /* @__PURE__ */ new Map();
479
487
  if (e(n)) return r;
480
488
  for (let e of t) {
@@ -482,7 +490,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
482
490
  t.add(e.column), r.set(e.table, t);
483
491
  }
484
492
  return r;
485
- }, Pe = (e, t) => {
493
+ }, Ie = (e, t) => {
486
494
  if (t !== "postgres") return "";
487
495
  let n = /* @__PURE__ */ new Map();
488
496
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -498,7 +506,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
498
506
  r.push(`DO $$ BEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${e.replace(/'/g, "''")}') THEN\n CREATE TYPE "${e}" AS ENUM (${n});\n END IF;\nEND $$;`);
499
507
  }
500
508
  return r.join("\n\n");
501
- }, Fe = (e, t) => {
509
+ }, Le = (e, t) => {
502
510
  if (t !== "postgres") return "";
503
511
  let n = /* @__PURE__ */ new Set();
504
512
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
@@ -512,34 +520,34 @@ BEGIN
512
520
  SELECT oid INTO type_oid FROM pg_type WHERE typname = '${i}';\n IF type_oid IS NOT NULL\n AND EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${a}')\n AND NOT EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${o}') THEN\n IF current_setting('server_version_num')::int >= 140000 THEN\n EXECUTE format('ALTER TYPE %I RENAME VALUE %L TO %L', '${i}', '${a}', '${o}');\n ELSE\n UPDATE pg_enum SET enumlabel = '${o}' WHERE enumtypid = type_oid AND enumlabel = '${a}';\n END IF;\n END IF;\nEND $$;`);
513
521
  }
514
522
  return r.join("\n\n");
515
- }, Ie = (e) => {
523
+ }, Re = (e) => {
516
524
  let t = [], r = [];
517
525
  for (let i of e) n(i) ? r.push(i) : t.push(i);
518
526
  return {
519
527
  tables: t,
520
528
  views: r
521
529
  };
522
- }, j = (t, n) => {
523
- let { tables: i, views: a } = Ie(t), { sorted: o, cyclic: s } = je(i.map((e) => b(e, n))), c = Ne(s, n), l = [];
524
- n === "postgres" && ke(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && Ae(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
525
- let u = Fe(o, n);
530
+ }, A = (t, n) => {
531
+ let { tables: i, views: a } = Re(t), { sorted: o, cyclic: s } = Ne(i.map((e) => x(e, n))), c = Fe(s, n), l = [];
532
+ n === "postgres" && je(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && Me(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
533
+ let u = Le(o, n);
526
534
  u && l.push(u);
527
- let d = Pe(o, n);
535
+ let d = Ie(o, n);
528
536
  d && l.push(d);
529
- for (let e of o) l.push(we(e, n, null, c.get(e.tableName)));
530
- if (!e(n)) for (let e of s) l.push(Me(e, n));
537
+ for (let e of o) l.push(Ee(e, n, null, c.get(e.tableName)));
538
+ if (!e(n)) for (let e of s) l.push(Pe(e, n));
531
539
  for (let e of o) {
532
- let t = Ee(e, n);
540
+ let t = Oe(e, n);
533
541
  t && l.push(t);
534
542
  }
535
543
  let f = o.filter((e) => e.isReactive);
536
544
  if (f.length > 0 && n === "postgres") {
537
- l.push(De);
538
- for (let e of f) l.push(Oe(e));
545
+ l.push(ke);
546
+ for (let e of f) l.push(Ae(e));
539
547
  }
540
548
  for (let e of a) l.push(r(e, n));
541
549
  return l.join("\n\n") + "\n";
542
- }, Le = (e, t, n) => {
550
+ }, ze = (e, t, n) => {
543
551
  let r = u(e, t);
544
552
  switch (t) {
545
553
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
@@ -549,57 +557,57 @@ BEGIN
549
557
  case "turso":
550
558
  case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
551
559
  }
552
- }, Re = (t, n, r, i) => {
553
- let a = Le(r, n, i), o = u(r, n);
554
- if (n === "postgres") return `${a}\n\nSET search_path TO ${o};\n\n${j(t, n)}`;
555
- if (n === "mysql" || n === "mariadb") return `${a}\n\nUSE ${o};\n\n${j(t, n)}`;
556
- let { sorted: s, cyclic: c } = je(t), l = Ne(c, n), d = [a];
557
- for (let e of s) d.push(we(e, n, r, l.get(e.tableName)));
558
- if (!e(n)) for (let e of c) d.push(Me(e, n, r));
560
+ }, Be = (t, n, r, i) => {
561
+ let a = ze(r, n, i), o = u(r, n);
562
+ if (n === "postgres") return `${a}\n\nSET search_path TO ${o};\n\n${A(t, n)}`;
563
+ if (n === "mysql" || n === "mariadb") return `${a}\n\nUSE ${o};\n\n${A(t, n)}`;
564
+ let { sorted: s, cyclic: c } = Ne(t), l = Fe(c, n), d = [a];
565
+ for (let e of s) d.push(Ee(e, n, r, l.get(e.tableName)));
566
+ if (!e(n)) for (let e of c) d.push(Pe(e, n, r));
559
567
  for (let e of s) {
560
- let t = Ee(e, n, r);
568
+ let t = Oe(e, n, r);
561
569
  t && d.push(t);
562
570
  }
563
571
  return d.join("\n\n") + "\n";
564
- }, ze = (e, t) => {
565
- if (t !== "postgres") return j(e, t);
566
- let { sorted: n, cyclic: r } = je(e), i = Ne(r, t), a = [], o = Fe(n, t);
572
+ }, Ve = (e, t) => {
573
+ if (t !== "postgres") return A(e, t);
574
+ let { sorted: n, cyclic: r } = Ne(e), i = Fe(r, t), a = [], o = Le(n, t);
567
575
  o && a.push(o);
568
- let s = Pe(n, t);
576
+ let s = Ie(n, t);
569
577
  s && a.push(s);
570
- for (let e of n) a.push(we(e, t, null, i.get(e.tableName)));
571
- for (let e of r) a.push(Me(e, t));
578
+ for (let e of n) a.push(Ee(e, t, null, i.get(e.tableName)));
579
+ for (let e of r) a.push(Pe(e, t));
572
580
  for (let e of n) {
573
581
  let n = Object.entries(e.fields);
574
582
  if (n.length === 0) continue;
575
583
  let r = n.map(([n, r]) => {
576
- let a = Ce(n, r, t, void 0, i.get(e.tableName)?.has(n) ?? !1);
584
+ let a = Te(n, r, t, void 0, i.get(e.tableName)?.has(n) ?? !1);
577
585
  return `ALTER TABLE ${u(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${a};`;
578
586
  });
579
587
  a.push(r.join("\n"));
580
588
  }
581
589
  for (let e of n) {
582
- let n = Ee(e, t);
590
+ let n = Oe(e, t);
583
591
  n && a.push(n);
584
592
  }
585
593
  let c = n.filter((e) => e.isReactive);
586
594
  if (c.length > 0) {
587
- a.push(De);
588
- for (let e of c) a.push(Oe(e));
595
+ a.push(ke);
596
+ for (let e of c) a.push(Ae(e));
589
597
  }
590
598
  return a.join("\n\n") + "\n";
591
- }, Be = (e, t = "postgres") => d.gen(function* () {
599
+ }, He = (e, t = "postgres") => d.gen(function* () {
592
600
  let n = yield* p.SqlClient;
593
- yield* ge(n, Ue(n, j(e, t), t)).pipe(d.orDie);
594
- }), Ve = (e, t) => {
601
+ yield* _e(n, Ge(n, A(e, t), t)).pipe(d.orDie);
602
+ }), Ue = (e, t) => {
595
603
  let n = t.cause ?? {};
596
604
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
597
- }, He = (e) => d.gen(function* () {
605
+ }, We = (e) => d.gen(function* () {
598
606
  let t = yield* p.SqlClient;
599
- for (let n of We(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) => Ve(n, e), () => d.void), d.tapError((e) => d.sync(() => {
600
- _e.error(_("migrate: statement failed", n, e, 200));
607
+ 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(() => {
608
+ ve.error(_("migrate: statement failed", n, e, 200));
601
609
  })), d.orDieWith((e) => Error(_("migrate: statement failed", n, e, 400).trim())));
602
- }), Ue = (e, t, n) => (n === "turso" ? He(t) : e.withTransaction(He(t))).pipe(d.orDie), We = (e) => {
610
+ }), Ge = (e, t, n) => (n === "turso" ? We(t) : e.withTransaction(We(t))).pipe(d.orDie), Ke = (e) => {
603
611
  let t = [], n = "", r = !1;
604
612
  for (let i = 0; i < e.length; i++) {
605
613
  if (e.slice(i, i + 2) === "$$") {
@@ -614,40 +622,40 @@ BEGIN
614
622
  }
615
623
  let i = n.trim();
616
624
  return i.length > 0 && t.push(i), t;
617
- }, Ge = async (e, t, n = "postgres") => {
618
- await d.runPromise(Be(e, n).pipe(d.provide(t)));
619
- }, Ke = (e, t, n = "postgres") => d.gen(function* () {
620
- let r = Re(e, n, t), i = yield* p.SqlClient;
621
- yield* ge(i, Ue(i, r, n)).pipe(d.orDie);
622
- }), qe = async (e, t, n, r = "postgres") => {
623
- await d.runPromise(Ke(e, t, r).pipe(d.provide(n)));
624
- }, Je = async (e, t, n = "postgres") => {
625
+ }, qe = async (e, t, n = "postgres") => {
626
+ await d.runPromise(He(e, n).pipe(d.provide(t)));
627
+ }, Je = (e, t, n = "postgres") => d.gen(function* () {
628
+ let r = Be(e, n, t), i = yield* p.SqlClient;
629
+ yield* _e(i, Ge(i, r, n)).pipe(d.orDie);
630
+ }), Ye = async (e, t, n, r = "postgres") => {
631
+ await d.runPromise(Je(e, t, r).pipe(d.provide(n)));
632
+ }, Xe = async (e, t, n = "postgres") => {
625
633
  await d.runPromise(d.gen(function* () {
626
- let t = ze(e, n), r = yield* p.SqlClient;
627
- yield* ge(r, Ue(r, t, n)).pipe(d.orDie);
634
+ let t = Ve(e, n), r = yield* p.SqlClient;
635
+ yield* _e(r, Ge(r, t, n)).pipe(d.orDie);
628
636
  }).pipe(d.provide(t)));
629
- }, Ye = (e) => {
637
+ }, Ze = (e) => {
630
638
  if (e == null) return e;
631
- if (Array.isArray(e)) return e.map(Ye);
639
+ if (Array.isArray(e)) return e.map(Ze);
632
640
  if (typeof e != "object") return e;
633
641
  let t = {};
634
642
  for (let n of Object.keys(e).sort()) {
635
643
  let r = e[n];
636
- r !== void 0 && (t[n] = Ye(r));
644
+ r !== void 0 && (t[n] = Ze(r));
637
645
  }
638
646
  return t;
639
- }, Xe = (e) => {
647
+ }, Qe = (e) => {
640
648
  if (!e.idScheme && !e.sensitive && !e.safe) return e;
641
649
  let { idScheme: t, sensitive: n, safe: r, ...i } = e;
642
650
  return i;
643
- }, Ze = (e) => [...e].map(Xe).sort((e, t) => e.name.localeCompare(t.name)), Qe = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), $e = (e) => [...e].map((e) => ({
651
+ }, $e = (e) => [...e].map(Qe).sort((e, t) => e.name.localeCompare(t.name)), et = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), tt = (e) => [...e].map((e) => ({
644
652
  name: e.name,
645
- columns: Ze(e.columns),
646
- indexes: Qe(e.indexes)
647
- })).sort((e, t) => e.name.localeCompare(t.name)), M = (e) => {
648
- let t = { tables: $e(e.tables) }, n = JSON.stringify(Ye(t));
653
+ columns: $e(e.columns),
654
+ indexes: et(e.indexes)
655
+ })).sort((e, t) => e.name.localeCompare(t.name)), j = (e) => {
656
+ let t = { tables: tt(e.tables) }, n = JSON.stringify(Ze(t));
649
657
  return m("sha256").update(n).digest("hex");
650
- }, N = (e) => e.slice(0, 16), et = (e, t) => {
658
+ }, M = (e) => e.slice(0, 16), nt = (e, t) => {
651
659
  let n = t.references ? {
652
660
  table: t.references().tableName,
653
661
  column: "id",
@@ -677,9 +685,15 @@ BEGIN
677
685
  ...t.narrowedFrom.using === void 0 ? {} : { using: t.narrowedFrom.using }
678
686
  } } : {},
679
687
  ...t.sensitive ? { sensitive: t.sensitive } : t.encrypted && !t.safe ? { sensitive: { class: "secret" } } : {},
680
- ...t.safe ? { safe: !0 } : {}
688
+ ...t.safe ? { safe: !0 } : {},
689
+ ...t.vectorDim === void 0 ? {} : { vectorDim: t.vectorDim },
690
+ ...t.vectorPrecision === void 0 ? {} : { vectorPrecision: t.vectorPrecision },
691
+ ...t.arrayElement === void 0 ? {} : { arrayElement: t.arrayElement },
692
+ ...t.enumName === void 0 ? {} : { enumName: t.enumName },
693
+ ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
694
+ ...t.spatial === void 0 ? {} : { spatial: t.spatial }
681
695
  };
682
- }, tt = (e) => {
696
+ }, rt = (e) => {
683
697
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
684
698
  n.has(e.name) || (n.add(e.name), t.push(e));
685
699
  }, i = e.appliedPrimaryKey ?? [];
@@ -727,11 +741,11 @@ BEGIN
727
741
  });
728
742
  }
729
743
  return t;
730
- }, nt = (e) => {
744
+ }, it = (e) => {
731
745
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
732
746
  for (let [r, i] of Object.entries(e.fields)) {
733
747
  if (i.dropped) continue;
734
- let e = et(r, i);
748
+ let e = nt(r, i);
735
749
  n.push(t.has(r) ? {
736
750
  ...e,
737
751
  unique: !0
@@ -741,32 +755,32 @@ BEGIN
741
755
  return {
742
756
  name: e.tableName,
743
757
  columns: n,
744
- indexes: tt(e),
758
+ indexes: rt(e),
745
759
  ...r.length > 0 ? { primaryKey: [...r] } : {}
746
760
  };
747
- }, rt = (e) => {
761
+ }, at = (e) => {
748
762
  let t = /* @__PURE__ */ new Map();
749
763
  for (let n of e) for (let e of n.indexes) {
750
764
  let r = t.get(e.name);
751
765
  if (r !== void 0 && r !== n.name) throw Error(`duplicate index name '${e.name}' across tables '${r}' and '${n.name}'. Index names must be unique per SCHEMA, not just per table — the DB creates only one, so the other never applies and 'db plan' re-emits it forever. Give each an explicit, table-prefixed name (e.g. '${n.name}_${e.name}').`);
752
766
  t.set(e.name, n.name);
753
767
  }
754
- }, P = (e, t) => {
755
- let n = e.map((e) => nt(b(e, t)));
756
- return rt(n), { tables: n };
757
- }, it = /* @__PURE__ */ new Set(["voltro_isr_cache"]), at = (e) => it.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), ot = {
768
+ }, N = (e, t) => {
769
+ let n = e.map((e) => it(x(e, t)));
770
+ return at(n), { tables: n };
771
+ }, ot = /* @__PURE__ */ new Set(["voltro_isr_cache"]), P = (e) => ot.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), st = {
758
772
  postgres: !0,
759
773
  mysql: !0,
760
774
  mariadb: !0,
761
775
  mssql: !0,
762
776
  sqlite: !0
763
- }, st = {
777
+ }, ct = {
764
778
  postgres: !0,
765
779
  mysql: !1,
766
780
  mariadb: !1,
767
781
  mssql: !0,
768
782
  sqlite: !0
769
- }, ct = (e) => {
783
+ }, lt = (e) => {
770
784
  switch (e) {
771
785
  case "add-column":
772
786
  case "drop-column":
@@ -776,22 +790,22 @@ BEGIN
776
790
  case "add-foreign-key":
777
791
  case "add-unique":
778
792
  case "add-unique-composite":
779
- case "add-check": return st;
780
- default: return ot;
793
+ case "add-check": return ct;
794
+ default: return st;
781
795
  }
782
- }, lt = (e, t) => {
796
+ }, ut = (e, t) => {
783
797
  let n = new Map(t.tables.map((e) => [e.name, e]));
784
798
  return new Map(e.map((e) => [e.tableName, {
785
799
  table: e,
786
800
  snapshot: n.get(e.tableName),
787
801
  columnDefs: e.fields
788
802
  }]));
789
- }, ut = (e) => (t, n) => t.name === e ? -1 : n.name === e ? 1 : t.name.localeCompare(n.name), F = (e) => {
803
+ }, dt = (e) => (t, n) => t.name === e ? -1 : n.name === e ? 1 : t.name.localeCompare(n.name), F = (e) => {
790
804
  if (typeof e != "object" || !e) return JSON.stringify(e);
791
805
  if (Array.isArray(e)) return `[${e.map(F).join(",")}]`;
792
806
  let t = e;
793
807
  return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${F(t[e])}`).join(",")}}`;
794
- }, dt = (e) => {
808
+ }, ft = (e) => {
795
809
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
796
810
  let t = e.defaultValue;
797
811
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
@@ -807,8 +821,8 @@ BEGIN
807
821
  return F(JSON.parse(a));
808
822
  } catch {}
809
823
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
810
- }, ft = (e, t) => {
811
- let n = dt(e), r = dt(t);
824
+ }, pt = (e, t) => {
825
+ let n = ft(e), r = ft(t);
812
826
  if (n === r) return !0;
813
827
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
814
828
  return i(n) === i(r);
@@ -821,18 +835,18 @@ BEGIN
821
835
  onDelete: t(e.onDelete),
822
836
  onUpdate: t(e.onUpdate)
823
837
  };
824
- }, pt = (e, t) => {
838
+ }, mt = (e, t) => {
825
839
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
826
840
  if (!n && !r) return !0;
827
841
  if (!n || !r || n.length !== r.length) return !1;
828
842
  let i = [...n].sort(), a = [...r].sort();
829
843
  return i.every((e, t) => e === a[t]);
830
- }, mt = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && ft(e, t) && JSON.stringify(I(e.references)) === JSON.stringify(I(t.references)) && pt(e.oneOf, t.oneOf), ht = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
844
+ }, ht = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && pt(e, t) && JSON.stringify(I(e.references)) === JSON.stringify(I(t.references)) && mt(e.oneOf, t.oneOf), gt = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
831
845
  kind: "add-check",
832
846
  table: e,
833
847
  column: t.name,
834
848
  values: t.oneOf
835
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, gt = (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])), _t = (e, t) => {
849
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, _t = (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])), vt = (e, t) => {
836
850
  let n = new Map(t.columns.map((e) => [e.name, e])), r = new Map(e.columns.map((e) => [e.name, e])), i = [], a = [], o = [];
837
851
  for (let t of e.columns) {
838
852
  let e = n.get(t.name);
@@ -840,7 +854,7 @@ BEGIN
840
854
  i.push(t);
841
855
  continue;
842
856
  }
843
- mt(t, e) || o.push({
857
+ ht(t, e) || o.push({
844
858
  declared: t,
845
859
  live: e
846
860
  });
@@ -851,11 +865,11 @@ BEGIN
851
865
  removed: a,
852
866
  changed: o
853
867
  };
854
- }, vt = (e, t) => {
868
+ }, yt = (e, t) => {
855
869
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
856
870
  for (let t of e.indexes) {
857
871
  let e = n.get(t.name);
858
- (!e || !gt(t, e)) && i.push(t);
872
+ (!e || !_t(t, e)) && i.push(t);
859
873
  }
860
874
  for (let e of t.indexes) r.has(e.name) || a.push(e);
861
875
  return {
@@ -865,33 +879,33 @@ BEGIN
865
879
  }, L = (e, t, n, r) => ({
866
880
  op: e,
867
881
  classification: t,
868
- atomicByDialect: ct(e.kind),
882
+ atomicByDialect: lt(e.kind),
869
883
  ...n ? { reason: n } : {},
870
884
  ...r ? { blocked: r } : {}
871
- }), yt = (e, t, n) => {
885
+ }), bt = (e, t, n) => {
872
886
  let r = {
873
887
  kind: "add-column",
874
888
  table: e,
875
889
  column: t
876
890
  };
877
891
  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` });
878
- }, bt = (e, t, n) => {
892
+ }, xt = (e, t, n) => {
879
893
  let r = {
880
894
  kind: "drop-column",
881
895
  table: e,
882
896
  column: t.name
883
897
  };
884
898
  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` });
885
- }, xt = (e, t, n, r) => L({
899
+ }, St = (e, t, n, r) => L({
886
900
  kind: "create-table",
887
901
  table: e,
888
902
  columns: t,
889
903
  indexes: n,
890
904
  ...r && r.length > 0 ? { primaryKey: r } : {}
891
- }, "safe", "new table — no data to preserve"), St = (e) => L({
905
+ }, "safe", "new table — no data to preserve"), Ct = (e) => L({
892
906
  kind: "drop-table",
893
907
  table: e
894
- }, "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" }), Ct = 5e4, wt = (e, t, n, r) => {
908
+ }, "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" }), wt = 5e4, Tt = (e, t, n, r) => {
895
909
  let i = (n ?? 0) >= r, a;
896
910
  return a = t.unique ? t.columns.length === 1 ? {
897
911
  kind: "add-unique",
@@ -907,7 +921,7 @@ BEGIN
907
921
  table: e,
908
922
  index: t
909
923
  }, 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");
910
- }, Tt = (e, t) => t.unique && t.columns.length > 1 ? L({
924
+ }, Et = (e, t) => t.unique && t.columns.length > 1 ? L({
911
925
  kind: "drop-unique-composite",
912
926
  table: e,
913
927
  name: t.name
@@ -915,7 +929,7 @@ BEGIN
915
929
  kind: "drop-index",
916
930
  table: e,
917
931
  index: t.name
918
- }, "safe", "drop index (no data loss — index is derived data)"), Et = (e, t) => {
932
+ }, "safe", "drop index (no data loss — index is derived data)"), Dt = (e, t) => {
919
933
  if (e === "reference") return "text";
920
934
  switch (t) {
921
935
  case "sqlite":
@@ -923,7 +937,7 @@ BEGIN
923
937
  case "mssql": return e === "json" ? "text" : e;
924
938
  default: return e;
925
939
  }
926
- }, Dt = (e, t, n, r, i, a) => {
940
+ }, Ot = (e, t, n, r, i, a) => {
927
941
  let o = [];
928
942
  if (t.nullable !== n.nullable) {
929
943
  let n = {
@@ -946,7 +960,7 @@ BEGIN
946
960
  table: e,
947
961
  column: t.name
948
962
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
949
- if (Et(t.type, r) !== Et(n.type, r)) {
963
+ if (Dt(t.type, r) !== Dt(n.type, r)) {
950
964
  let r = t.narrowedFrom;
951
965
  if (r && r.from === n.type) {
952
966
  let i = {
@@ -969,7 +983,7 @@ BEGIN
969
983
  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` }));
970
984
  }
971
985
  }
972
- if (!ft(t, n)) {
986
+ if (!pt(t, n)) {
973
987
  let n = {
974
988
  kind: "alter-column-default",
975
989
  table: e,
@@ -979,13 +993,13 @@ BEGIN
979
993
  };
980
994
  o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
981
995
  }
982
- if (!pt(t.oneOf, n.oneOf)) {
996
+ if (!mt(t.oneOf, n.oneOf)) {
983
997
  n.oneOf && n.oneOf.length > 0 && o.push(L({
984
998
  kind: "drop-check",
985
999
  table: e,
986
1000
  column: t.name
987
1001
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
988
- let r = ht(e, t);
1002
+ let r = gt(e, t);
989
1003
  r && o.push(r);
990
1004
  }
991
1005
  if (JSON.stringify(I(t.references)) !== JSON.stringify(I(n.references)) && (n.references && o.push(L({
@@ -1008,7 +1022,7 @@ BEGIN
1008
1022
  }, "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')`));
1009
1023
  }
1010
1024
  return o;
1011
- }, Ot = (e, t, n) => {
1025
+ }, kt = (e, t, n) => {
1012
1026
  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));
1013
1027
  for (let [n, c] of Object.entries(t)) {
1014
1028
  let t = c.renamedFrom;
@@ -1024,7 +1038,7 @@ BEGIN
1024
1038
  consumedAddedNames: i,
1025
1039
  consumedRemovedNames: a
1026
1040
  };
1027
- }, kt = (e) => {
1041
+ }, At = (e) => {
1028
1042
  let t = {
1029
1043
  safe: 0,
1030
1044
  needsDefault: 0,
@@ -1059,37 +1073,37 @@ BEGIN
1059
1073
  break;
1060
1074
  }
1061
1075
  return t;
1062
- }, At = (e) => {
1063
- let t = P(e.declared, e.dialect), n = lt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Ct, a = [];
1076
+ }, jt = (e) => {
1077
+ let t = N(e.declared, e.dialect), n = ut(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? wt, a = [];
1064
1078
  for (let e of t.tables) if (!r.has(e.name)) {
1065
- a.push(xt(e.name, e.columns, e.indexes, e.primaryKey));
1079
+ a.push(St(e.name, e.columns, e.indexes, e.primaryKey));
1066
1080
  for (let t of e.columns) {
1067
- let n = ht(e.name, t);
1081
+ let n = gt(e.name, t);
1068
1082
  n && a.push(n);
1069
1083
  }
1070
1084
  }
1071
1085
  let o = new Set(e.ignoreTables ?? []);
1072
- for (let t of e.live.tables) n.has(t.name) || at(t.name) || o.has(t.name) || a.push(St(t.name));
1086
+ for (let t of e.live.tables) n.has(t.name) || P(t.name) || o.has(t.name) || a.push(Ct(t.name));
1073
1087
  for (let o of t.tables) {
1074
1088
  let t = r.get(o.name);
1075
1089
  if (!t) continue;
1076
- let s = n.get(o.name), c = _t(o, t), l = vt(o, t), u = Ot(s.table, s.columnDefs, c);
1090
+ let s = n.get(o.name), c = vt(o, t), l = yt(o, t), u = kt(s.table, s.columnDefs, c);
1077
1091
  a.push(...u.ops);
1078
1092
  for (let e of c.removed) {
1079
1093
  if (u.consumedRemovedNames.has(e.name)) continue;
1080
1094
  let t = s.columnDefs[e.name];
1081
- a.push(bt(o.name, e, t));
1095
+ a.push(xt(o.name, e, t));
1082
1096
  }
1083
1097
  for (let e of c.added) {
1084
1098
  if (u.consumedAddedNames.has(e.name)) continue;
1085
1099
  let t = s.columnDefs[e.name];
1086
- a.push(yt(o.name, e, t));
1087
- let n = ht(o.name, e);
1100
+ a.push(bt(o.name, e, t));
1101
+ let n = gt(o.name, e);
1088
1102
  n && a.push(n);
1089
1103
  }
1090
- for (let e of l.added) a.push(wt(o.name, e, t.rowCount, i));
1091
- for (let e of l.removed) a.push(Tt(o.name, e));
1092
- for (let { declared: n, live: r } of c.changed) a.push(...Dt(o.name, n, r, e.dialect, t.rowCount, i));
1104
+ for (let e of l.added) a.push(Tt(o.name, e, t.rowCount, i));
1105
+ for (let e of l.removed) a.push(Et(o.name, e));
1106
+ for (let { declared: n, live: r } of c.changed) a.push(...Ot(o.name, n, r, e.dialect, t.rowCount, i));
1093
1107
  }
1094
1108
  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) => {
1095
1109
  let t = c.get(e);
@@ -1097,8 +1111,8 @@ BEGIN
1097
1111
  column: e.name,
1098
1112
  target: e.references.table
1099
1113
  }] : []) : [];
1100
- }, u = S([...s], l), d = [];
1101
- 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({
1114
+ }, u = ne([...s], l), d = [];
1115
+ for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(S(e.name, t.name)) || d.push(L({
1102
1116
  kind: "add-foreign-key",
1103
1117
  table: e.name,
1104
1118
  column: t.name,
@@ -1113,8 +1127,8 @@ BEGIN
1113
1127
  let n = a[t];
1114
1128
  if (n.op.kind !== "create-table") continue;
1115
1129
  let r = n.op;
1116
- if (!r.columns.some((e) => u.has(x(r.table, e.name)))) continue;
1117
- let i = r.columns.map((t) => u.has(x(r.table, t.name)) ? e(t) : t);
1130
+ if (!r.columns.some((e) => u.has(S(r.table, e.name)))) continue;
1131
+ let i = r.columns.map((t) => u.has(S(r.table, t.name)) ? e(t) : t);
1118
1132
  a[t] = {
1119
1133
  ...n,
1120
1134
  op: {
@@ -1134,7 +1148,7 @@ BEGIN
1134
1148
  let i = new Set(t).add(e), a = 0;
1135
1149
  for (let t of r.columns) {
1136
1150
  let n = t.references?.table;
1137
- n && n !== e && !u.has(x(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
1151
+ n && n !== e && !u.has(S(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
1138
1152
  }
1139
1153
  return p.set(e, a), a;
1140
1154
  }, h = (e) => e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, g = (e) => {
@@ -1169,11 +1183,11 @@ BEGIN
1169
1183
  });
1170
1184
  return {
1171
1185
  operations: v,
1172
- fromFingerprint: M(e.live),
1173
- toFingerprint: M(t),
1174
- summary: kt(v)
1186
+ fromFingerprint: j(e.live),
1187
+ toFingerprint: j(t),
1188
+ summary: At(v)
1175
1189
  };
1176
- }, jt = (e) => {
1190
+ }, Mt = (e) => {
1177
1191
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1178
1192
  if (!t) return null;
1179
1193
  let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
@@ -1181,7 +1195,7 @@ BEGIN
1181
1195
  column: t[1],
1182
1196
  values: n
1183
1197
  };
1184
- }, Mt = (e, t) => {
1198
+ }, Nt = (e, t) => {
1185
1199
  if (t === "vector") return "vector";
1186
1200
  switch (e) {
1187
1201
  case "text":
@@ -1216,25 +1230,25 @@ BEGIN
1216
1230
  case "SET DEFAULT": return "noAction";
1217
1231
  default: return "noAction";
1218
1232
  }
1219
- }, Nt = (e, t) => {
1233
+ }, Pt = (e, t) => {
1220
1234
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1221
1235
  return Number.isInteger(n) && n > 0 ? n : t;
1222
- }, Pt = () => Nt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Ft = 300, It = () => {
1236
+ }, Ft = () => Pt(process.env.VOLTRO_INTROSPECT_BATCH, 20), It = 300, Lt = () => {
1223
1237
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1224
- return e !== void 0 && e.trim() === "0" ? 0 : Nt(e, 3e4);
1225
- }, Lt = (e, t) => {
1238
+ return e !== void 0 && e.trim() === "0" ? 0 : Pt(e, 3e4);
1239
+ }, Rt = (e, t) => {
1226
1240
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1227
1241
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1228
1242
  return r;
1229
- }, Rt = (e) => {
1230
- let t = It(), n = d.gen(function* () {
1243
+ }, zt = (e) => {
1244
+ let t = Lt(), n = d.gen(function* () {
1231
1245
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1232
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Pt(), a = (e, t) => d.gen(function* () {
1246
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Ft(), a = (e, t) => d.gen(function* () {
1233
1247
  let r = [];
1234
- for (let a of Lt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1248
+ for (let a of Rt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1235
1249
  return r;
1236
1250
  }), o = [];
1237
- for (let t = 0;; t += Ft) {
1251
+ for (let t = 0;; t += It) {
1238
1252
  let n = yield* e`
1239
1253
  SELECT c.relname AS table_name,
1240
1254
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1242,9 +1256,9 @@ BEGIN
1242
1256
  JOIN pg_namespace n ON n.oid = c.relnamespace
1243
1257
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1244
1258
  ORDER BY c.relname
1245
- LIMIT ${r(Ft)} OFFSET ${r(t)}
1259
+ LIMIT ${r(It)} OFFSET ${r(t)}
1246
1260
  `;
1247
- if (o.push(...n), n.length < Ft) break;
1261
+ if (o.push(...n), n.length < It) break;
1248
1262
  }
1249
1263
  let s = /* @__PURE__ */ new Set(), c = [];
1250
1264
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1329,7 +1343,7 @@ BEGIN
1329
1343
  AND c.relname IN ${t}
1330
1344
  )
1331
1345
  SELECT * FROM ix ORDER BY table_name, index_name, position
1332
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), ne = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
1346
+ `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
1333
1347
  for (let e of u) {
1334
1348
  let t = _.get(e.table_name);
1335
1349
  t || (t = [], _.set(e.table_name, t)), t.push(e);
@@ -1338,25 +1352,25 @@ BEGIN
1338
1352
  let t = v.get(e.table_name);
1339
1353
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1340
1354
  }
1341
- let x = /* @__PURE__ */ new Map();
1355
+ let S = /* @__PURE__ */ new Map();
1342
1356
  for (let e of p) {
1343
- let t = `${e.table_name}${e.constraint_name}`, n = x.get(t);
1357
+ let t = `${e.table_name}${e.constraint_name}`, n = S.get(t);
1344
1358
  n || (n = {
1345
1359
  table: e.table_name,
1346
1360
  columns: []
1347
- }, x.set(t, n)), n.columns.push({
1361
+ }, S.set(t, n)), n.columns.push({
1348
1362
  name: e.column_name,
1349
1363
  position: e.position
1350
1364
  });
1351
1365
  }
1352
- for (let [e, t] of x) {
1366
+ for (let [e, t] of S) {
1353
1367
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1354
1368
  if (n.length === 1) {
1355
1369
  let e = y.get(t.table);
1356
1370
  e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
1357
1371
  } else {
1358
- let r = te.get(t.table);
1359
- r || (r = [], te.set(t.table, r)), r.push({
1372
+ let r = b.get(t.table);
1373
+ r || (r = [], b.set(t.table, r)), r.push({
1360
1374
  name: e.slice(e.indexOf("\0") + 1),
1361
1375
  table: t.table,
1362
1376
  columns: n,
@@ -1365,19 +1379,19 @@ BEGIN
1365
1379
  }
1366
1380
  }
1367
1381
  for (let e of g) {
1368
- let t = ne.get(e.source_table);
1369
- t || (t = [], ne.set(e.source_table, t)), t.push(e);
1382
+ let t = te.get(e.source_table);
1383
+ t || (t = [], te.set(e.source_table, t)), t.push(e);
1370
1384
  }
1371
1385
  for (let e of ee) {
1372
- let t = b.get(e.table_name);
1373
- t || (t = /* @__PURE__ */ new Map(), b.set(e.table_name, t));
1386
+ let t = x.get(e.table_name);
1387
+ t || (t = /* @__PURE__ */ new Map(), x.set(e.table_name, t));
1374
1388
  let n = t.get(e.index_name);
1375
1389
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1376
1390
  }
1377
- let S = [];
1391
+ let ne = [];
1378
1392
  for (let e of c) {
1379
- 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 = 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) => {
1380
- 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" : Mt(t.data_type, t.udt_name), c = a ? {
1393
+ 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) => {
1394
+ 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" : Nt(t.data_type, t.udt_name), c = a ? {
1381
1395
  table: a.target_table,
1382
1396
  column: a.target_column,
1383
1397
  onDelete: R(a.delete_rule),
@@ -1393,7 +1407,7 @@ BEGIN
1393
1407
  ...c ? { references: c } : {},
1394
1408
  ...l ? { oneOf: l } : {}
1395
1409
  };
1396
- }), l = [], u = b.get(e.table_name);
1410
+ }), l = [], u = x.get(e.table_name);
1397
1411
  if (u) for (let [t, n] of u) {
1398
1412
  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) => {
1399
1413
  let t = e.position;
@@ -1409,7 +1423,7 @@ BEGIN
1409
1423
  ...a ? { expression: !0 } : {}
1410
1424
  });
1411
1425
  }
1412
- for (let t of te.get(e.table_name) ?? []) l.push(t);
1426
+ for (let t of b.get(e.table_name) ?? []) l.push(t);
1413
1427
  r.size > 0 && l.push({
1414
1428
  name: `${e.table_name}_pkey`,
1415
1429
  table: e.table_name,
@@ -1417,20 +1431,20 @@ BEGIN
1417
1431
  unique: !0
1418
1432
  });
1419
1433
  let d = Number(e.row_count ?? 0);
1420
- S.push({
1434
+ ne.push({
1421
1435
  name: e.table_name,
1422
1436
  columns: c,
1423
1437
  indexes: l,
1424
1438
  ...d > 0 ? { rowCount: d } : {}
1425
1439
  });
1426
1440
  }
1427
- return { tables: S };
1441
+ return { tables: ne };
1428
1442
  });
1429
1443
  return (t > 0 ? e.withTransaction(n) : n).pipe(d.catchAll((e) => {
1430
1444
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1431
1445
  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);
1432
1446
  }));
1433
- }, zt = (e, t) => {
1447
+ }, Bt = (e, t) => {
1434
1448
  switch (e.toLowerCase()) {
1435
1449
  case "varchar":
1436
1450
  case "char":
@@ -1466,7 +1480,7 @@ BEGIN
1466
1480
  let t = e, n = {};
1467
1481
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1468
1482
  return n;
1469
- }), Bt = (e) => d.gen(function* () {
1483
+ }), Vt = (e) => d.gen(function* () {
1470
1484
  let t = z(yield* e`
1471
1485
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1472
1486
  FROM information_schema.tables
@@ -1499,7 +1513,7 @@ BEGIN
1499
1513
  o.add(`${e.table_name}.${t[1]}`);
1500
1514
  continue;
1501
1515
  }
1502
- let n = jt(e.check_clause);
1516
+ let n = Mt(e.check_clause);
1503
1517
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1504
1518
  }
1505
1519
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1522,7 +1536,7 @@ BEGIN
1522
1536
  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);
1523
1537
  if (d) for (let e of d.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1524
1538
  let p = t.map((t) => {
1525
- 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" : zt(t.data_type, t.column_type), u = c ? {
1539
+ 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" : Bt(t.data_type, t.column_type), u = c ? {
1526
1540
  table: c.target_table,
1527
1541
  column: c.target_column,
1528
1542
  onDelete: R(c.delete_rule),
@@ -1563,10 +1577,10 @@ BEGIN
1563
1577
  });
1564
1578
  }
1565
1579
  return { tables: f };
1566
- }), Vt = (e) => {
1580
+ }), Ht = (e) => {
1567
1581
  let t = e.toUpperCase();
1568
1582
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1569
- }, Ht = (e) => d.gen(function* () {
1583
+ }, Ut = (e) => d.gen(function* () {
1570
1584
  let t = yield* e`
1571
1585
  SELECT name, sql FROM sqlite_master
1572
1586
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1583,7 +1597,7 @@ BEGIN
1583
1597
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1584
1598
  }
1585
1599
  let p = o.map((e) => {
1586
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Vt(e.type), a = r ? {
1600
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Ht(e.type), a = r ? {
1587
1601
  table: r.table,
1588
1602
  column: r.to,
1589
1603
  onDelete: R(r.on_delete),
@@ -1622,7 +1636,7 @@ BEGIN
1622
1636
  });
1623
1637
  }
1624
1638
  return { tables: r };
1625
- }), Ut = (e) => {
1639
+ }), Wt = (e) => {
1626
1640
  switch (e.toLowerCase()) {
1627
1641
  case "int":
1628
1642
  case "smallint":
@@ -1644,7 +1658,7 @@ BEGIN
1644
1658
  case "image": return "bytes";
1645
1659
  default: return "text";
1646
1660
  }
1647
- }, B = (e) => e === !0 || e === 1, Wt = (e) => d.gen(function* () {
1661
+ }, B = (e) => e === !0 || e === 1, Gt = (e) => d.gen(function* () {
1648
1662
  let t = yield* e`
1649
1663
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
1650
1664
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -1704,12 +1718,12 @@ BEGIN
1704
1718
  else B(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1705
1719
  }
1706
1720
  let p = t.map((t) => {
1707
- 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" : Ut(t.data_type), s = i ? {
1721
+ 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" : Wt(t.data_type), s = i ? {
1708
1722
  table: i.target_table,
1709
1723
  column: i.target_column,
1710
- onDelete: Gt(i.delete_rule),
1711
- onUpdate: Gt(i.update_rule)
1712
- } : void 0, c = t.column_default === null ? null : Kt(t.column_default), l = o.get(`${e}.${t.column_name}`);
1724
+ onDelete: Kt(i.delete_rule),
1725
+ onUpdate: Kt(i.update_rule)
1726
+ } : void 0, c = t.column_default === null ? null : qt(t.column_default), l = o.get(`${e}.${t.column_name}`);
1713
1727
  return {
1714
1728
  name: t.column_name,
1715
1729
  type: a,
@@ -1742,23 +1756,31 @@ BEGIN
1742
1756
  });
1743
1757
  }
1744
1758
  return { tables: u };
1745
- }), Gt = (e) => {
1759
+ }), Kt = (e) => {
1746
1760
  switch (e.toUpperCase().replace(/_/g, " ")) {
1747
1761
  case "CASCADE": return "cascade";
1748
1762
  case "SET NULL": return "setNull";
1749
1763
  case "SET DEFAULT": return "noAction";
1750
1764
  default: return "noAction";
1751
1765
  }
1752
- }, Kt = (e) => {
1766
+ }, qt = (e) => {
1753
1767
  let t = e.trim();
1754
1768
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
1755
1769
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
1756
- }, qt = (e) => e.onDialectOrElse({
1757
- mysql: () => Bt(e),
1758
- mssql: () => Wt(e),
1759
- sqlite: () => Ht(e),
1760
- orElse: () => Rt(e)
1761
- }), Jt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, V = (e) => {
1770
+ }, V = (e) => e.onDialectOrElse({
1771
+ mysql: () => Vt(e),
1772
+ mssql: () => Gt(e),
1773
+ sqlite: () => Ut(e),
1774
+ orElse: () => zt(e)
1775
+ }), Jt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
1776
+ if (!e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
1777
+ 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;
1778
+ 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.`);
1779
+ return E(e, t);
1780
+ }, U = (e) => {
1781
+ let t = H(e, "postgres");
1782
+ return t === void 0 ? Yt(e) : t;
1783
+ }, Yt = (e) => {
1762
1784
  switch (e.type) {
1763
1785
  case "id": return "text";
1764
1786
  case "text": return "text";
@@ -1772,13 +1794,15 @@ BEGIN
1772
1794
  case "json": return "jsonb";
1773
1795
  case "bytes": return "bytea";
1774
1796
  case "reference": return "text";
1775
- case "vector": return "text";
1776
- case "enum": return "text";
1777
- case "array": return "text";
1797
+ case "vector":
1798
+ case "enum":
1799
+ case "array": throw Error(`snapshotPgType: '${e.type}' must go through parameterisedSqlType`);
1778
1800
  case "interval": return "interval";
1779
1801
  case "raw": return e.rawDdl ?? "text";
1780
1802
  }
1781
- }, H = (e) => {
1803
+ }, W = (e) => {
1804
+ let t = H(e, "mariadb");
1805
+ if (t !== void 0) return t;
1782
1806
  switch (e.type) {
1783
1807
  case "id": return "VARCHAR(64)";
1784
1808
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
@@ -1792,80 +1816,89 @@ BEGIN
1792
1816
  case "json": return "JSON";
1793
1817
  case "bytes": return "LONGBLOB";
1794
1818
  case "reference": return "VARCHAR(64)";
1795
- case "vector": return "BLOB";
1796
- case "enum": return "TEXT";
1797
- case "array": return "JSON";
1819
+ case "vector":
1820
+ case "enum":
1821
+ case "array": throw Error(`snapshotMysqlType: '${e.type}' must go through parameterisedSqlType`);
1798
1822
  case "interval": return "BIGINT";
1799
1823
  case "raw": return e.rawDdl ?? "LONGTEXT";
1800
1824
  }
1801
- }, U = (e) => `"${e}"`, W = (e) => `\`${e.replace(/`/g, "``")}\``, Yt = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, Xt = (e) => `ALTER TABLE ${W(e.table)} DROP COLUMN IF EXISTS ${W(e.column)}, ALGORITHM=COPY;`, Zt = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, Qt = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${yn(t)}`)};`, $t = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${n(e.defaultValue) ?? "DEFAULT NULL"};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, G = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], en = (e, t, n) => {
1802
- let r = n ?? e.nullable, i = ve(e, "mariadb");
1825
+ }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, Xt = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, Zt = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, Qt = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, $t = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Tn(t)}`)};`, en = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${tn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, tn = (e, t) => {
1826
+ let n = t(e.defaultValue);
1827
+ 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.`);
1828
+ return n;
1829
+ }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], nn = (e, t, n) => {
1830
+ let r = q(e, t, n);
1831
+ return r ? nt(n, r) : void 0;
1832
+ }, rn = (e, t, n) => {
1833
+ let r = n ?? e.nullable, i = ye(e, "mariadb");
1803
1834
  return [
1804
- W(t),
1805
- D(e, "mariadb"),
1835
+ K(t),
1836
+ E(e, "mariadb"),
1806
1837
  r ? null : "NOT NULL",
1807
1838
  i
1808
1839
  ].filter(Boolean).join(" ");
1809
- }, tn = (e) => e == null ? null : 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" && !Array.isArray(e) ? O(e, "mysql") : null, nn = (e) => e == null ? null : 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" && !Array.isArray(e) ? O(e, "postgres") : null, K = (e, t) => {
1840
+ }, an = (e, t) => e == null ? null : Array.isArray(e) ? on(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, on = (e, t, n) => be(e, t ?? { type: "json" }, n), sn = (e, t) => e == null ? null : Array.isArray(e) ? on(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) => {
1810
1841
  if (!e.generatedAs) return null;
1811
1842
  let { expr: n, stored: r } = e.generatedAs;
1812
1843
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
1813
- }, rn = (e) => {
1814
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "postgres");
1815
- let t = K(e, "postgres");
1816
- if (t) return `${U(e.name)} ${V(e)} ${t}`;
1817
- let n = [U(e.name), V(e)];
1844
+ }, cn = (e) => {
1845
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "postgres");
1846
+ let t = J(e, "postgres");
1847
+ if (t) return `${G(e.name)} ${U(e)} ${t}`;
1848
+ let n = [G(e.name), U(e)];
1818
1849
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
1819
- let t = nn(e.defaultValue);
1850
+ let t = sn(e.defaultValue, e);
1820
1851
  t && n.push(t);
1821
1852
  }
1822
- return e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1853
+ return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1823
1854
  cascade: "CASCADE",
1824
1855
  restrict: "RESTRICT",
1825
1856
  setNull: "SET NULL",
1826
1857
  noAction: "NO ACTION"
1827
1858
  }[e.references.onDelete]}`)), n.join(" ");
1828
- }, q = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", an = (e) => {
1829
- let t = e.columns.map((e) => ` ${rn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${q(e, U)}\n)`];
1830
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e.table)} (${t.columns.map(wn).join(", ")})`);
1859
+ }, ln = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", un = (e) => {
1860
+ let t = e.columns.map((e) => ` ${cn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${ln(e, G)}\n)`];
1861
+ 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(An).join(", ")})`);
1831
1862
  return n;
1832
- }, on = 191, J = (e) => {
1833
- let t = H(e).toUpperCase();
1863
+ }, dn = 191, fn = (e) => {
1864
+ let t = W(e).toUpperCase();
1834
1865
  return t.endsWith("TEXT") || t.endsWith("BLOB");
1835
- }, sn = (e) => {
1836
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mariadb");
1837
- let t = K(e, "mariadb");
1838
- if (t) return `${W(e.name)} ${H(e)} ${t}`;
1839
- let n = [W(e.name), H(e)];
1840
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !J(e) && n.push("UNIQUE"), e.hasDefault) {
1841
- let t = tn(e.defaultValue);
1866
+ }, pn = (e) => {
1867
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mariadb");
1868
+ let t = J(e, "mariadb");
1869
+ if (t) return `${K(e.name)} ${W(e)} ${t}`;
1870
+ let n = [K(e.name), W(e)];
1871
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !fn(e) && n.push("UNIQUE"), e.hasDefault) {
1872
+ let t = an(e.defaultValue, e);
1842
1873
  t && n.push(t);
1843
1874
  }
1844
- return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1875
+ return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1845
1876
  cascade: "CASCADE",
1846
1877
  restrict: "RESTRICT",
1847
1878
  setNull: "SET NULL",
1848
1879
  noAction: "NO ACTION"
1849
1880
  }[e.references.onDelete]}`)), n.join(" ");
1850
- }, cn = (e) => {
1881
+ }, mn = (e) => {
1851
1882
  let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
1852
1883
  let n = t.get(e);
1853
- return n && J(n) ? `${W(e)}(${on})` : W(e);
1854
- }, r = e.columns.map((e) => ` ${sn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${r}${q(e, n)}\n)`];
1855
- for (let t of e.columns) t.unique && t.type !== "id" && J(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${W(`${e.table}_${t.name}_key`)} ON ${W(e.table)} (${n(t.name)})`);
1856
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(n).join(", ")})`);
1884
+ return n && fn(n) ? `${K(e)}(${dn})` : K(e);
1885
+ }, r = e.columns.map((e) => ` ${pn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${ln(e, n)}\n)`];
1886
+ for (let t of e.columns) t.unique && t.type !== "id" && fn(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
1887
+ 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(", ")})`);
1857
1888
  return i;
1858
- }, ln = {
1889
+ }, hn = {
1859
1890
  cascade: "CASCADE",
1860
1891
  restrict: "RESTRICT",
1861
1892
  setNull: "SET NULL",
1862
1893
  noAction: "NO ACTION"
1863
- }, un = {
1894
+ }, gn = {
1864
1895
  cascade: "CASCADE",
1865
1896
  restrict: "NO ACTION",
1866
1897
  setNull: "SET NULL",
1867
1898
  noAction: "NO ACTION"
1868
- }, dn = (e) => {
1899
+ }, _n = (e) => {
1900
+ let t = H(e, "sqlite");
1901
+ if (t !== void 0) return t;
1869
1902
  switch (e.type) {
1870
1903
  case "integer":
1871
1904
  case "boolean": return "INTEGER";
@@ -1875,52 +1908,54 @@ BEGIN
1875
1908
  case "bytes": return "BLOB";
1876
1909
  default: return "TEXT";
1877
1910
  }
1878
- }, 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" && !Array.isArray(e) ? O(e, "sqlite") : null, fn = (e) => {
1879
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "sqlite");
1880
- let t = K(e, "sqlite");
1881
- if (t) return `${U(e.name)} ${dn(e)} ${t}`;
1882
- let n = [U(e.name), dn(e)];
1911
+ }, 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, vn = (e) => {
1912
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "sqlite");
1913
+ let t = J(e, "sqlite");
1914
+ if (t) return `${G(e.name)} ${_n(e)} ${t}`;
1915
+ let n = [G(e.name), _n(e)];
1883
1916
  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
1917
  let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
1885
1918
  t && n.push(t);
1886
1919
  }
1887
- if (e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${ln[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
1920
+ if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${hn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
1888
1921
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
1889
- n.push(`CHECK (${U(e.name)} IN (${t}))`);
1922
+ n.push(`CHECK (${G(e.name)} IN (${t}))`);
1890
1923
  }
1891
1924
  return n.join(" ");
1892
- }, pn = (e) => {
1893
- let t = e.columns.map((e) => ` ${fn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${q(e, U)}\n)`];
1894
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e.table)} (${t.columns.map(U).join(", ")})`);
1925
+ }, yn = (e) => {
1926
+ let t = e.columns.map((e) => ` ${vn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${ln(e, G)}\n)`];
1927
+ 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(", ")})`);
1895
1928
  return n;
1896
1929
  }, X = (e, t) => {
1897
1930
  let n = t.find((t) => t.tableName === e);
1898
1931
  if (!n) return [];
1899
- let r = P([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => U(e.name)).join(", "), o = [
1900
- ...pn({
1932
+ let r = N([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
1933
+ ...yn({
1901
1934
  kind: "create-table",
1902
1935
  table: i,
1903
1936
  columns: r.columns,
1904
1937
  indexes: [],
1905
1938
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
1906
1939
  }),
1907
- `INSERT INTO ${U(i)} (${a}) SELECT ${a} FROM ${U(e)}`,
1908
- `DROP TABLE ${U(e)}`,
1909
- `ALTER TABLE ${U(i)} RENAME TO ${U(e)}`
1940
+ `INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
1941
+ `DROP TABLE ${G(e)}`,
1942
+ `ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
1910
1943
  ];
1911
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e)} (${t.columns.map(U).join(", ")})`);
1944
+ 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(", ")})`);
1912
1945
  return o;
1913
- }, mn = (e, t, n, r) => {
1946
+ }, bn = (e, t, n, r) => {
1914
1947
  let i = r ?? e.nullable;
1915
- return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${D(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
1916
- }, hn = (e) => {
1948
+ return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${E(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
1949
+ }, xn = (e) => {
1917
1950
  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 + ']');`;
1918
1951
  if (!e.hasDefault) return t;
1919
1952
  let n = Y(e.defaultValue, "SYSUTCDATETIME()");
1920
1953
  if (!n) return t;
1921
1954
  let r = n.replace(/^DEFAULT\s+/i, "");
1922
1955
  return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
1923
- }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, gn = (e) => {
1956
+ }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, Sn = (e) => {
1957
+ let t = H(e, "mssql");
1958
+ if (t !== void 0) return t;
1924
1959
  switch (e.type) {
1925
1960
  case "id":
1926
1961
  case "reference": return "NVARCHAR(64)";
@@ -1934,34 +1969,34 @@ BEGIN
1934
1969
  case "bytes": return "VARBINARY(MAX)";
1935
1970
  default: return "NVARCHAR(MAX)";
1936
1971
  }
1937
- }, _n = (e, t) => {
1938
- if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mssql");
1939
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : gn(e), r = K(e, "mssql");
1972
+ }, Cn = (e, t) => {
1973
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mssql");
1974
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Sn(e), r = J(e, "mssql");
1940
1975
  if (r) return `${Z(e.name)} ${r}`;
1941
1976
  let i = [Z(e.name), n];
1942
1977
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
1943
1978
  let t = Y(e.defaultValue, "SYSUTCDATETIME()");
1944
1979
  t && i.push(t);
1945
1980
  }
1946
- return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${un[e.references.onDelete]}`)), i.join(" ");
1947
- }, vn = (e) => {
1948
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${_n(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${q(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
1981
+ return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${gn[e.references.onDelete]}`)), i.join(" ");
1982
+ }, wn = (e) => {
1983
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Cn(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${ln(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
1949
1984
  for (let n of e.indexes) {
1950
1985
  if (n.name === `${e.table}_pkey`) continue;
1951
1986
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
1952
1987
  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)}')`);
1953
1988
  }
1954
1989
  return a;
1955
- }, yn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, bn = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, xn = (e, t, n) => {
1956
- let r = `${e.table}${yn(t)}`;
1990
+ }, Tn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, En = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Dn = (e, t, n) => {
1991
+ let r = `${e.table}${Tn(t)}`;
1957
1992
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
1958
- }, Sn = (e, t, n) => {
1959
- let r = G(e, t, n);
1960
- return r ? J({ type: r.type }) : !1;
1961
- }, Cn = (e, t, n) => Sn(e, t, n) ? `${W(n)}(${on})` : W(n), wn = (e) => e.startsWith("(") ? e : U(e), Tn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${U(e.index.name)} ON ${U(e.table)} (${e.index.columns.map(wn).join(", ")});`, En = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map((n) => Cn(t, e.table, n)).join(", ")});`, Dn = (e) => `DROP INDEX IF EXISTS ${U(e.index)};`, On = (e) => `DROP INDEX ${W(e.index)} ON ${W(e.table)};`, kn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, An = (e) => {
1993
+ }, On = (e, t, n) => {
1994
+ let r = q(e, t, n);
1995
+ return r ? fn({ type: r.type }) : !1;
1996
+ }, kn = (e, t, n) => On(e, t, n) ? `${K(n)}(${dn})` : K(n), An = (e) => e.startsWith("(") ? e : G(e), jn = (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(An).join(", ")});`, Mn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => kn(t, e.table, n)).join(", ")});`, Nn = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Pn = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, Fn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, In = (e) => {
1962
1997
  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(", ")})`;
1963
1998
  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)}');`;
1964
- }, jn = (e, t, n) => {
1999
+ }, Ln = (e, t, n) => {
1965
2000
  let r = n.find((t) => t.tableName === e);
1966
2001
  if (!r) return [];
1967
2002
  let i = [];
@@ -1970,13 +2005,13 @@ BEGIN
1970
2005
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
1971
2006
  }
1972
2007
  return i;
1973
- }, Mn = (e) => `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(`${e.table}_${e.column}_key`)} UNIQUE (${U(e.column)});`, Nn = (e, t) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${Cn(t, e.table, e.column)});`, Pn = (e) => {
1974
- let t = e.fields.map((e) => U(e)).join(", ");
1975
- return `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(e.name)} UNIQUE (${t});`;
1976
- }, Fn = (e, t) => {
1977
- let n = e.fields.map((n) => Cn(t, e.table, n)).join(", ");
1978
- return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${n});`;
1979
- }, In = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(e.name)};`, Ln = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(e.name)};`, Rn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_key`)};`, zn = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(`${e.table}_${e.column}_key`)};`, Bn = (e, t) => {
2008
+ }, Rn = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, zn = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${kn(t, e.table, e.column)});`, Bn = (e) => {
2009
+ let t = e.fields.map((e) => G(e)).join(", ");
2010
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2011
+ }, Vn = (e, t) => {
2012
+ let n = e.fields.map((n) => kn(t, e.table, n)).join(", ");
2013
+ return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2014
+ }, Hn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, Un = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, Wn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, Gn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, Kn = (e, t) => {
1980
2015
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
1981
2016
  if (e.orphanPolicy) {
1982
2017
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -1994,11 +2029,11 @@ BEGIN
1994
2029
  setNull: "SET NULL",
1995
2030
  noAction: "NO ACTION"
1996
2031
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
1997
- }, Vn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_fkey`)};`, Hn = (e) => `ALTER TABLE ${W(e.table)} DROP FOREIGN KEY ${W(`${e.table}_${e.column}_fkey`)};`, Un = (e, t) => {
2032
+ }, qn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, Jn = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, Yn = (e, t) => {
1998
2033
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
1999
2034
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2000
- }, Wn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_check`)};`, Gn = (e) => `ALTER TABLE ${W(e.table)} DROP CHECK ${W(`${e.table}_${e.column}_check`)};`, Kn = (e, t, n, r) => {
2001
- let i = e.column, a = r === "mariadb", o = a ? W : r === "mssql" ? Z : U, s = a ? H(i) : r === "mssql" ? gn(i) : r === "sqlite" ? dn(i) : V(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? tn(e) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : nn(e), u = K(i, r);
2035
+ }, Xn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, Zn = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, Qn = (e, t, n, r) => {
2036
+ let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? Sn(i) : r === "sqlite" ? _n(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? an(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : sn(e, i), u = J(i, r);
2002
2037
  if (u) {
2003
2038
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2004
2039
  return {
@@ -2014,7 +2049,8 @@ BEGIN
2014
2049
  };
2015
2050
  }
2016
2051
  if (t.classification === "needs-default") {
2017
- let t = l(i.defaultValue) ?? "DEFAULT NULL";
2052
+ let t = l(i.defaultValue);
2053
+ if (t === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${i.name}' (${JSON.stringify(i.defaultValue)}) while adding it NOT NULL to a populated table. This is a framework bug — report the column type + default.`);
2018
2054
  return {
2019
2055
  pre: [`ALTER TABLE ${o(e.table)} ${c} ${o(i.name)} ${s} NOT NULL ${t};`],
2020
2056
  post: []
@@ -2025,7 +2061,7 @@ BEGIN
2025
2061
  post: f ? [f] : []
2026
2062
  };
2027
2063
  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;
2028
- }, qn = (e) => {
2064
+ }, $n = (e) => {
2029
2065
  let t = new Map(e.map((e) => [e.tableName, e]));
2030
2066
  return (e, n) => {
2031
2067
  let r = t.get(e);
@@ -2047,95 +2083,95 @@ BEGIN
2047
2083
  };
2048
2084
  }, Q = (e, t, n) => e.unsafe(t).pipe(d.tapError((e) => d.sync(() => {
2049
2085
  process.stderr.write(_(`applier: statement failed (op=${n})`, t, e, 400));
2050
- })), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), Jn = (e, t, n) => d.gen(function* () {
2051
- let r = process.hrtime.bigint(), i = qn(n.declared), a = t.op;
2086
+ })), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), er = (e, t, n) => d.gen(function* () {
2087
+ let r = process.hrtime.bigint(), i = $n(n.declared), a = t.op;
2052
2088
  switch (a.kind) {
2053
2089
  case "create-table": {
2054
2090
  let t = yield* e.onDialectOrElse({
2055
- mysql: () => d.succeed(cn(a)),
2056
- mssql: () => d.succeed(vn(a)),
2057
- sqlite: () => d.succeed(pn(a)),
2058
- orElse: () => d.succeed(an(a))
2091
+ mysql: () => d.succeed(mn(a)),
2092
+ mssql: () => d.succeed(wn(a)),
2093
+ sqlite: () => d.succeed(yn(a)),
2094
+ orElse: () => d.succeed(un(a))
2059
2095
  });
2060
2096
  for (let n of t) yield* Q(e, n, a.kind);
2061
2097
  break;
2062
2098
  }
2063
2099
  case "drop-table": {
2064
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? xn(a, n, e) : bn(a, e);
2100
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Dn(a, n, e) : En(a, e);
2065
2101
  yield* e.onDialectOrElse({
2066
- mysql: () => Q(e, r(W), a.kind),
2067
- orElse: () => Q(e, r(U), a.kind)
2102
+ mysql: () => Q(e, r(K), a.kind),
2103
+ orElse: () => Q(e, r(G), a.kind)
2068
2104
  });
2069
2105
  break;
2070
2106
  }
2071
2107
  case "drop-column": {
2072
2108
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2073
2109
  yield* e.onDialectOrElse({
2074
- mysql: () => Q(e, t ? Qt(a, n, W) : Xt(a), a.kind),
2075
- orElse: () => Q(e, t ? Qt(a, n, U) : Yt(a, U), a.kind)
2110
+ mysql: () => Q(e, t ? $t(a, n, K) : Zt(a), a.kind),
2111
+ orElse: () => Q(e, t ? $t(a, n, G) : Xt(a, G), a.kind)
2076
2112
  });
2077
2113
  break;
2078
2114
  }
2079
2115
  case "rename-column":
2080
2116
  yield* e.onDialectOrElse({
2081
- mysql: () => Q(e, Zt(a, W), a.kind),
2117
+ mysql: () => Q(e, Qt(a, K), a.kind),
2082
2118
  mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
2083
- orElse: () => Q(e, Zt(a, U), a.kind)
2119
+ orElse: () => Q(e, Qt(a, G), a.kind)
2084
2120
  });
2085
2121
  break;
2086
2122
  case "add-index":
2087
2123
  yield* e.onDialectOrElse({
2088
- mysql: () => Q(e, En(a, n.declared), a.kind),
2089
- mssql: () => $(e, [...jn(a.table, a.index.columns, n.declared), An(a)], a.kind),
2090
- orElse: () => Q(e, Tn(a, t.classification === "online-required"), a.kind)
2124
+ mysql: () => Q(e, Mn(a, n.declared), a.kind),
2125
+ mssql: () => $(e, [...Ln(a.table, a.index.columns, n.declared), In(a)], a.kind),
2126
+ orElse: () => Q(e, jn(a, t.classification === "online-required"), a.kind)
2091
2127
  });
2092
2128
  break;
2093
2129
  case "drop-index":
2094
2130
  yield* e.onDialectOrElse({
2095
- mysql: () => Q(e, On(a), a.kind),
2096
- mssql: () => Q(e, kn(a), a.kind),
2097
- orElse: () => Q(e, Dn(a), a.kind)
2131
+ mysql: () => Q(e, Pn(a), a.kind),
2132
+ mssql: () => Q(e, Fn(a), a.kind),
2133
+ orElse: () => Q(e, Nn(a), a.kind)
2098
2134
  });
2099
2135
  break;
2100
2136
  case "add-unique":
2101
2137
  yield* e.onDialectOrElse({
2102
- mysql: () => Q(e, Nn(a, n.declared), a.kind),
2138
+ mysql: () => Q(e, zn(a, n.declared), a.kind),
2103
2139
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2104
- mssql: () => $(e, [...jn(a.table, [a.column], n.declared), Mn(a)], a.kind),
2105
- orElse: () => Q(e, Mn(a), a.kind)
2140
+ mssql: () => $(e, [...Ln(a.table, [a.column], n.declared), Rn(a)], a.kind),
2141
+ orElse: () => Q(e, Rn(a), a.kind)
2106
2142
  });
2107
2143
  break;
2108
2144
  case "drop-unique":
2109
2145
  yield* e.onDialectOrElse({
2110
- mysql: () => Q(e, zn(a), a.kind),
2146
+ mysql: () => Q(e, Gn(a), a.kind),
2111
2147
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2112
- orElse: () => Q(e, Rn(a), a.kind)
2148
+ orElse: () => Q(e, Wn(a), a.kind)
2113
2149
  });
2114
2150
  break;
2115
2151
  case "add-unique-composite":
2116
2152
  yield* e.onDialectOrElse({
2117
- mysql: () => Q(e, Fn(a, n.declared), a.kind),
2153
+ mysql: () => Q(e, Vn(a, n.declared), a.kind),
2118
2154
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2119
- mssql: () => $(e, [...jn(a.table, a.fields, n.declared), Pn(a)], a.kind),
2120
- orElse: () => Q(e, Pn(a), a.kind)
2155
+ mssql: () => $(e, [...Ln(a.table, a.fields, n.declared), Bn(a)], a.kind),
2156
+ orElse: () => Q(e, Bn(a), a.kind)
2121
2157
  });
2122
2158
  break;
2123
2159
  case "drop-unique-composite":
2124
2160
  yield* e.onDialectOrElse({
2125
- mysql: () => Q(e, Ln(a), a.kind),
2161
+ mysql: () => Q(e, Un(a), a.kind),
2126
2162
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2127
- orElse: () => Q(e, In(a), a.kind)
2163
+ orElse: () => Q(e, Hn(a), a.kind)
2128
2164
  });
2129
2165
  break;
2130
2166
  case "add-foreign-key":
2131
2167
  yield* e.onDialectOrElse({
2132
- mysql: () => $(e, Bn(a, W), a.kind),
2168
+ mysql: () => $(e, Kn(a, K), a.kind),
2133
2169
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2134
- orElse: () => $(e, Bn(a, U), a.kind)
2170
+ orElse: () => $(e, Kn(a, G), a.kind)
2135
2171
  });
2136
2172
  break;
2137
2173
  case "add-column": {
2138
- let n = Kn(a, t, i, yield* e.onDialectOrElse({
2174
+ let n = Qn(a, t, i, yield* e.onDialectOrElse({
2139
2175
  mysql: () => d.succeed("mariadb"),
2140
2176
  mssql: () => d.succeed("mssql"),
2141
2177
  sqlite: () => d.succeed("sqlite"),
@@ -2180,39 +2216,41 @@ BEGIN
2180
2216
  case "alter-column-nullability":
2181
2217
  yield* e.onDialectOrElse({
2182
2218
  mysql: () => {
2183
- let t = G(n.declared, a.table, a.column);
2184
- return t ? Q(e, `ALTER TABLE ${W(a.table)} MODIFY COLUMN ${en(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.`));
2219
+ let t = q(n.declared, a.table, a.column);
2220
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${rn(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.`));
2185
2221
  },
2186
2222
  mssql: () => {
2187
- let t = G(n.declared, a.table, a.column);
2188
- return t ? Q(e, mn(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}'.`));
2223
+ let t = q(n.declared, a.table, a.column);
2224
+ return t ? Q(e, bn(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}'.`));
2189
2225
  },
2190
2226
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2191
- orElse: () => Q(e, `ALTER TABLE ${U(a.table)} ALTER COLUMN ${U(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2227
+ orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2192
2228
  });
2193
2229
  break;
2194
- case "alter-column-default":
2230
+ case "alter-column-default": {
2231
+ let t = nn(n.declared, a.table, a.column);
2195
2232
  yield* e.onDialectOrElse({
2196
- mysql: () => Q(e, $t(a, W, tn), a.kind),
2197
- mssql: () => Q(e, hn(a), a.kind),
2233
+ mysql: () => Q(e, en(a, K, (e) => an(e, t)), a.kind),
2234
+ mssql: () => Q(e, xn(a), a.kind),
2198
2235
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2199
- orElse: () => Q(e, $t(a, U, nn), a.kind)
2236
+ orElse: () => Q(e, en(a, G, (e) => sn(e, t)), a.kind)
2200
2237
  });
2201
2238
  break;
2239
+ }
2202
2240
  case "alter-column-type": {
2203
- let r = V({ type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2241
+ let r = U(nn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2204
2242
  if (t.classification !== "online-required") {
2205
2243
  yield* e.onDialectOrElse({
2206
2244
  mysql: () => {
2207
- let t = G(n.declared, a.table, a.column);
2208
- return t ? Q(e, `ALTER TABLE ${W(a.table)} MODIFY COLUMN ${en(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.`));
2245
+ let t = q(n.declared, a.table, a.column);
2246
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${rn(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.`));
2209
2247
  },
2210
2248
  mssql: () => {
2211
- let t = G(n.declared, a.table, a.column);
2212
- return t ? Q(e, mn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2249
+ let t = q(n.declared, a.table, a.column);
2250
+ return t ? Q(e, bn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2213
2251
  },
2214
2252
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2215
- orElse: () => Q(e, `ALTER TABLE ${U(a.table)} ALTER COLUMN ${U(a.column)} TYPE ${r}${i};`, a.kind)
2253
+ orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
2216
2254
  });
2217
2255
  break;
2218
2256
  }
@@ -2221,35 +2259,35 @@ BEGIN
2221
2259
  orElse: () => d.void
2222
2260
  });
2223
2261
  let o = `${a.column}__shadow`, s = `${a.column}__old`;
2224
- yield* e.unsafe(`ALTER TABLE ${U(a.table)} ADD COLUMN ${U(o)} ${r}`);
2225
- let c = a.using ?? U(a.column), l;
2262
+ yield* e.unsafe(`ALTER TABLE ${G(a.table)} ADD COLUMN ${G(o)} ${r}`);
2263
+ let c = a.using ?? G(a.column), l;
2226
2264
  for (;;) {
2227
2265
  let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(o)} IS NULL ORDER BY ${e("id")} LIMIT 5000` : yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(o)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} LIMIT 5000`;
2228
2266
  if (t.length === 0) break;
2229
- yield* e.unsafe(`UPDATE ${U(a.table)} SET ${U(o)} = ${c} WHERE ${U(a.column)} IS NOT NULL AND ${U(o)} IS NULL AND ${U("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2267
+ yield* e.unsafe(`UPDATE ${G(a.table)} SET ${G(o)} = ${c} WHERE ${G(a.column)} IS NOT NULL AND ${G(o)} IS NULL AND ${G("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2230
2268
  }
2231
- yield* d.logInfo(`alter-column-type shadow ${a.table}.${a.column}: shadow populated`).pipe(d.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${U(a.table)} RENAME COLUMN ${U(a.column)} TO ${U(s)}`), yield* e.unsafe(`ALTER TABLE ${U(a.table)} RENAME COLUMN ${U(o)} TO ${U(a.column)}`), yield* e.unsafe(`ALTER TABLE ${U(a.table)} DROP COLUMN ${U(s)}`);
2269
+ yield* d.logInfo(`alter-column-type shadow ${a.table}.${a.column}: shadow populated`).pipe(d.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${G(a.table)} RENAME COLUMN ${G(a.column)} TO ${G(s)}`), yield* e.unsafe(`ALTER TABLE ${G(a.table)} RENAME COLUMN ${G(o)} TO ${G(a.column)}`), yield* e.unsafe(`ALTER TABLE ${G(a.table)} DROP COLUMN ${G(s)}`);
2232
2270
  break;
2233
2271
  }
2234
2272
  case "drop-foreign-key":
2235
2273
  yield* e.onDialectOrElse({
2236
- mysql: () => Q(e, Hn(a), a.kind),
2274
+ mysql: () => Q(e, Jn(a), a.kind),
2237
2275
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2238
- orElse: () => Q(e, Vn(a), a.kind)
2276
+ orElse: () => Q(e, qn(a), a.kind)
2239
2277
  });
2240
2278
  break;
2241
2279
  case "add-check":
2242
2280
  yield* e.onDialectOrElse({
2243
- mysql: () => Q(e, Un(a, W), a.kind),
2281
+ mysql: () => Q(e, Yn(a, K), a.kind),
2244
2282
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2245
- orElse: () => Q(e, Un(a, U), a.kind)
2283
+ orElse: () => Q(e, Yn(a, G), a.kind)
2246
2284
  });
2247
2285
  break;
2248
2286
  case "drop-check":
2249
2287
  yield* e.onDialectOrElse({
2250
- mysql: () => Q(e, Gn(a), a.kind),
2288
+ mysql: () => Q(e, Zn(a), a.kind),
2251
2289
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2252
- orElse: () => Q(e, Wn(a), a.kind)
2290
+ orElse: () => Q(e, Xn(a), a.kind)
2253
2291
  });
2254
2292
  break;
2255
2293
  }
@@ -2258,10 +2296,10 @@ BEGIN
2258
2296
  status: "applied",
2259
2297
  durationMs: Number((process.hrtime.bigint() - r) / 1000000n)
2260
2298
  };
2261
- }), Yn = (e, t, n) => d.gen(function* () {
2299
+ }), tr = (e, t, n) => d.gen(function* () {
2262
2300
  let r = t.operations.filter((e) => e.blocked);
2263
2301
  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.`));
2264
- yield* w(e);
2302
+ yield* C(e);
2265
2303
  let i = Date.now(), a = [];
2266
2304
  try {
2267
2305
  let r = yield* e.onDialectOrElse({
@@ -2271,15 +2309,20 @@ BEGIN
2271
2309
  }), i = r ? t.operations.filter((e) => e.classification !== "online-required") : [], o = r ? t.operations.filter((e) => e.classification === "online-required") : t.operations;
2272
2310
  i.length > 0 && (yield* e.withTransaction(d.gen(function* () {
2273
2311
  let e = yield* p.SqlClient;
2274
- for (let t of i) a.push(yield* Jn(e, t, n));
2312
+ for (let t of i) a.push(yield* er(e, t, n));
2275
2313
  })));
2276
- for (let t of o) a.push(yield* Jn(e, t, n));
2314
+ for (let t of o) a.push(yield* er(e, t, n));
2277
2315
  } finally {
2278
- yield* T(e).pipe(d.orDie);
2316
+ yield* w(e).pipe(d.orDie);
2279
2317
  }
2280
- let o = Date.now() - i, s = `plan_${Date.now().toString(36)}`, c = (/* @__PURE__ */ new Date()).toISOString(), l = yield* e.onDialectOrElse({
2281
- mysql: () => d.succeed(c.replace("T", " ").replace("Z", "")),
2282
- orElse: () => d.succeed(c)
2318
+ let o = yield* n.replan(e);
2319
+ if (o.operations.length > 0) {
2320
+ let e = o.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2321
+ return yield* d.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${o.operations.length}:\n${e}${o.operations.length > 10 ? `\n … and ${o.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug: the DDL for these operations is a no-op. Report the operation kinds above with the column types involved.`));
2322
+ }
2323
+ let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), f = yield* e.onDialectOrElse({
2324
+ mysql: () => d.succeed(u.replace("T", " ").replace("Z", "")),
2325
+ orElse: () => d.succeed(u)
2283
2326
  });
2284
2327
  return yield* e`
2285
2328
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -2287,33 +2330,34 @@ BEGIN
2287
2330
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
2288
2331
  ${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
2289
2332
  VALUES
2290
- (${s}, ${t.toFingerprint}, ${JSON.stringify(t.operations)},
2333
+ (${l}, ${t.toFingerprint}, ${JSON.stringify(t.operations)},
2291
2334
  ${n.appliedBy}, ${n.environment}, ${n.source},
2292
- ${o}, ${l}, ${n.notes ?? null})
2335
+ ${c}, ${f}, ${n.notes ?? null})
2293
2336
  `, {
2294
- id: s,
2295
- appliedAt: c,
2337
+ id: l,
2338
+ appliedAt: u,
2296
2339
  fingerprint: t.toFingerprint,
2297
2340
  operations: t.operations,
2298
2341
  appliedBy: n.appliedBy,
2299
2342
  environment: n.environment,
2300
- durationMs: o,
2343
+ durationMs: c,
2344
+ appliedOps: s,
2301
2345
  source: n.source,
2302
2346
  ...n.notes ? { notes: n.notes } : {}
2303
2347
  };
2304
- }), Xn = (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"), Zn = (e) => e`
2348
+ }), nr = (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"), rr = (e) => e`
2305
2349
  SELECT fingerprint
2306
2350
  FROM _voltro_migration_plans
2307
2351
  ORDER BY ${e("appliedAt")} DESC
2308
2352
  LIMIT 1
2309
- `.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), Qn = (e) => e.onDialectOrElse({
2353
+ `.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), ir = (e) => e.onDialectOrElse({
2310
2354
  pg: () => "postgres",
2311
2355
  mysql: () => "mysql",
2312
2356
  mssql: () => "mssql",
2313
2357
  sqlite: () => "sqlite",
2314
2358
  orElse: () => "sqlite"
2315
- }), $n = (e, t) => d.gen(function* () {
2316
- let n = M(P(t, Qn(e))), r = yield* Zn(e);
2359
+ }), ar = (e, t) => d.gen(function* () {
2360
+ let n = j(N(t, ir(e))), r = yield* rr(e);
2317
2361
  return r === n ? {
2318
2362
  kind: "up-to-date",
2319
2363
  fingerprint: n
@@ -2322,48 +2366,48 @@ BEGIN
2322
2366
  expected: n,
2323
2367
  ...r === void 0 ? {} : { actual: r }
2324
2368
  };
2325
- }), er = [
2369
+ }), or = [
2326
2370
  "pgeagertest_",
2327
2371
  "mig_e2e_",
2328
2372
  "mig_test_",
2329
2373
  "mysqleagertest_",
2330
2374
  "mssqleagertest_",
2331
2375
  "sqliteeagertest_"
2332
- ], tr = (e) => er.some((t) => e.startsWith(t)), nr = (e, t) => d.gen(function* () {
2376
+ ], sr = (e) => or.some((t) => e.startsWith(t)), cr = (e, t) => d.gen(function* () {
2333
2377
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2334
- let n = t.filter((e) => tr(e.name)).map((e) => e.name);
2378
+ let n = t.filter((e) => sr(e.name)).map((e) => e.name);
2335
2379
  if (n.length === 0) return [];
2336
2380
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(d.catchAll(() => d.void));
2337
2381
  return n;
2338
- }), rr = () => {
2382
+ }), lr = () => {
2339
2383
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2340
2384
  return e.length > 0 ? { ignoreTables: e } : {};
2341
- }, ir = (e) => ({
2385
+ }, ur = (e) => ({
2342
2386
  ...e,
2343
2387
  operations: e.operations.map((e) => {
2344
2388
  if (!e.blocked || e.classification !== "lossy") return e;
2345
2389
  let { blocked: t, ...n } = e;
2346
2390
  return n;
2347
2391
  })
2348
- }), ar = (e, t, n) => d.gen(function* () {
2349
- let r = Qn(e), i = t.filter((e) => !at(e.tableName));
2392
+ }), dr = (e, t, n) => d.gen(function* () {
2393
+ let r = ir(e), i = t.filter((e) => !P(e.tableName));
2350
2394
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2351
- let t = M(P(i, r));
2352
- if ((yield* Zn(e)) === t) return {
2395
+ let t = j(N(i, r));
2396
+ if ((yield* rr(e)) === t) return {
2353
2397
  kind: "up-to-date",
2354
2398
  fingerprint: t
2355
2399
  };
2356
2400
  }
2357
- let a = yield* qt(e), o = yield* nr(e, a.tables);
2401
+ let a = yield* V(e), o = yield* cr(e, a.tables);
2358
2402
  o.length > 0 && (yield* d.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(d.annotateLogs({
2359
2403
  scope: "voltro:migrate",
2360
2404
  count: o.length
2361
- })), a = yield* qt(e));
2362
- let s = At({
2405
+ })), a = yield* V(e));
2406
+ let s = jt({
2363
2407
  declared: i,
2364
- live: { tables: a.tables.filter((e) => !at(e.name)) },
2408
+ live: { tables: a.tables.filter((e) => !P(e.name)) },
2365
2409
  dialect: r,
2366
- ...rr()
2410
+ ...lr()
2367
2411
  });
2368
2412
  if (s.summary.blocked > 0) {
2369
2413
  let e = s.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy");
@@ -2371,39 +2415,48 @@ BEGIN
2371
2415
  kind: "refused-blocked",
2372
2416
  plan: s
2373
2417
  };
2374
- s = ir(s);
2418
+ s = ur(s);
2375
2419
  }
2376
2420
  return s.operations.length === 0 ? {
2377
2421
  kind: "up-to-date",
2378
2422
  fingerprint: s.toFingerprint
2379
2423
  } : {
2380
2424
  kind: "applied",
2381
- applied: yield* Yn(e, s, {
2425
+ applied: yield* tr(e, s, {
2382
2426
  declared: t,
2383
2427
  appliedBy: n.appliedBy,
2384
2428
  environment: n.environment === "prod" ? "dev" : n.environment,
2385
- source: "auto-diff"
2429
+ source: "auto-diff",
2430
+ replan: (e) => d.gen(function* () {
2431
+ let t = yield* V(e);
2432
+ return jt({
2433
+ declared: i,
2434
+ live: { tables: t.tables.filter((e) => !P(e.name)) },
2435
+ dialect: r,
2436
+ ...lr()
2437
+ });
2438
+ })
2386
2439
  }),
2387
2440
  plan: s
2388
2441
  };
2389
- }), or = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2442
+ }), fr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2390
2443
  kind: "skipped",
2391
2444
  reason: "VOLTRO_AUTO_MIGRATE=0"
2392
- }) : n.environment === "prod" ? $n(e, t) : ar(e, t, n), sr = (e, t) => {
2445
+ }) : n.environment === "prod" ? ar(e, t) : dr(e, t, n), pr = (e, t) => {
2393
2446
  switch (e.kind) {
2394
2447
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2395
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${N(e.fingerprint)})`;
2448
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${M(e.fingerprint)})`;
2396
2449
  case "applied": {
2397
2450
  let t = e.plan.summary;
2398
- return `auto-migrate: applied ${e.plan.operations.length} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${N(e.applied.fingerprint)}`;
2451
+ return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${M(e.applied.fingerprint)}`;
2399
2452
  }
2400
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${N(e.expected)}` + (e.actual ? ` live=${N(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2453
+ 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.";
2401
2454
  case "refused-blocked": {
2402
- 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 === "add-column").length, i = t.filter((e) => e.op.kind === "drop-column").length, a = t.filter((e) => e.classification === "needs-rename-annotation").length, o = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + Xn(e.plan), s = [""];
2455
+ 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 === "add-column").length, i = t.filter((e) => e.op.kind === "drop-column").length, a = t.filter((e) => e.classification === "needs-rename-annotation").length, o = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + nr(e.plan), s = [""];
2403
2456
  return n > 0 && s.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=${t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean).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.", " → Add it to your declared set + chain `.dropped()` on it, OR", " write a file-based migration in `migrations/` that DROPs it, OR", " set `VOLTRO_DESTRUCTIVE_OK=1` for ONE `voltro dev` run (acknowledges data loss).", " 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`)."), r > 0 && s.push(`${r} 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."), i > 0 && s.push(`${i} column(s) are missing from your declared schema.`, " → If intentional: chain `.dropped()` on the column slot in the table declaration.", " → If a typo: restore the field. Data survives until you drop it."), a > 0 && s.push(`${a} 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."), s.push("", "See `voltro db plan` for the full machine-readable diff."), o + "\n" + s.join("\n");
2404
2457
  }
2405
2458
  }
2406
- }, cr = /* @__PURE__ */ new Set([
2459
+ }, mr = /* @__PURE__ */ new Set([
2407
2460
  "node_modules",
2408
2461
  "dist",
2409
2462
  "build",
@@ -2412,11 +2465,11 @@ BEGIN
2412
2465
  ".next",
2413
2466
  ".git",
2414
2467
  ".framework"
2415
- ]), lr = async (e) => {
2468
+ ]), hr = async (e) => {
2416
2469
  let t = [], n = async (e) => {
2417
2470
  let r = await h.readdir(e, { withFileTypes: !0 }).catch(() => []);
2418
2471
  for (let i of r) {
2419
- if (cr.has(i.name)) continue;
2472
+ if (mr.has(i.name)) continue;
2420
2473
  let r = g(e, i.name);
2421
2474
  i.isDirectory() ? await n(r) : i.isFile() && l.test(i.name) && t.push(r);
2422
2475
  }
@@ -2425,7 +2478,7 @@ BEGIN
2425
2478
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
2426
2479
  return n.localeCompare(r);
2427
2480
  });
2428
- }, ur = async (e) => {
2481
+ }, gr = async (e) => {
2429
2482
  let t = [];
2430
2483
  for (let n of e) {
2431
2484
  let e = (await import(ee(n).href)).default;
@@ -2439,11 +2492,11 @@ BEGIN
2439
2492
  });
2440
2493
  }
2441
2494
  return t;
2442
- }, dr = (e) => e`
2495
+ }, _r = (e) => e`
2443
2496
  SELECT ${e("id")}
2444
2497
  FROM ${e("_voltro_migration_plans")}
2445
2498
  WHERE ${e("source")} = 'file'
2446
- `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), fr = (e, t, n, r) => d.gen(function* () {
2499
+ `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), vr = (e, t, n, r) => d.gen(function* () {
2447
2500
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
2448
2501
  sql: e,
2449
2502
  log: {
@@ -2476,9 +2529,9 @@ BEGIN
2476
2529
  ${r}, ${n}, ${"file"},
2477
2530
  ${c}, ${a}, ${t.migration.description})
2478
2531
  `, { durationMs: c };
2479
- }), pr = (e, t) => d.gen(function* () {
2532
+ }), yr = (e, t) => d.gen(function* () {
2480
2533
  let n = yield* d.tryPromise({
2481
- try: () => lr(g(t.projectRoot, "migrations")),
2534
+ try: () => hr(g(t.projectRoot, "migrations")),
2482
2535
  catch: (e) => e
2483
2536
  });
2484
2537
  if (n.length === 0) return {
@@ -2486,19 +2539,19 @@ BEGIN
2486
2539
  skipped: []
2487
2540
  };
2488
2541
  let r = yield* d.tryPromise({
2489
- try: () => ur(n),
2542
+ try: () => gr(n),
2490
2543
  catch: (e) => e
2491
2544
  });
2492
2545
  if (r.length === 0) return {
2493
2546
  applied: [],
2494
2547
  skipped: []
2495
2548
  };
2496
- let i = new Set(yield* dr(e)), a = r.filter((e) => !i.has(e.migration.id)), o = r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id);
2549
+ let i = new Set(yield* _r(e)), a = r.filter((e) => !i.has(e.migration.id)), o = r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id);
2497
2550
  if (a.length === 0) return {
2498
2551
  applied: [],
2499
2552
  skipped: o
2500
2553
  };
2501
- yield* w(e);
2554
+ yield* C(e);
2502
2555
  let s = [];
2503
2556
  try {
2504
2557
  for (let n of a) {
@@ -2507,7 +2560,7 @@ BEGIN
2507
2560
  id: n.migration.id,
2508
2561
  file: n.file
2509
2562
  }));
2510
- let { durationMs: r } = yield* fr(e, n, t.env, t.appliedBy);
2563
+ let { durationMs: r } = yield* vr(e, n, t.env, t.appliedBy);
2511
2564
  s.push({
2512
2565
  id: n.migration.id,
2513
2566
  durationMs: r
@@ -2518,28 +2571,28 @@ BEGIN
2518
2571
  }));
2519
2572
  }
2520
2573
  } finally {
2521
- yield* T(e).pipe(d.orDie);
2574
+ yield* w(e).pipe(d.orDie);
2522
2575
  }
2523
2576
  return {
2524
2577
  applied: s,
2525
2578
  skipped: o
2526
2579
  };
2527
- }), mr = (e, t) => e`
2580
+ }), br = (e, t) => e`
2528
2581
  SELECT ${e("id")}
2529
2582
  FROM ${e("_voltro_migration_plans")}
2530
2583
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
2531
2584
  LIMIT 1
2532
- `, hr = (e, t) => d.gen(function* () {
2533
- if (!(yield* mr(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2585
+ `, xr = (e, t) => d.gen(function* () {
2586
+ if (!(yield* br(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2534
2587
  let n = yield* d.tryPromise({
2535
- try: () => lr(g(t.projectRoot, "migrations")),
2588
+ try: () => hr(g(t.projectRoot, "migrations")),
2536
2589
  catch: (e) => e
2537
2590
  }), r = (yield* d.tryPromise({
2538
- try: () => ur(n),
2591
+ try: () => gr(n),
2539
2592
  catch: (e) => e
2540
2593
  })).find((e) => e.migration.id === t.id);
2541
2594
  if (!r) return yield* d.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
2542
- yield* w(e);
2595
+ yield* C(e);
2543
2596
  let i = Date.now();
2544
2597
  try {
2545
2598
  let n = {
@@ -2566,9 +2619,9 @@ BEGIN
2566
2619
  durationMs: o
2567
2620
  };
2568
2621
  } finally {
2569
- yield* T(e).pipe(d.orDie);
2622
+ yield* w(e).pipe(d.orDie);
2570
2623
  }
2571
- }), gr = (e) => d.gen(function* () {
2624
+ }), Sr = (e) => d.gen(function* () {
2572
2625
  let t = yield* p.SqlClient, n = yield* t`
2573
2626
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
2574
2627
  WHERE source = 'auto-diff'
@@ -2613,10 +2666,10 @@ BEGIN
2613
2666
  snapshotFingerprint: e.fingerprint,
2614
2667
  snapshotId: i
2615
2668
  };
2616
- }), _r = (e, ...t) => ({
2669
+ }), Cr = (e, ...t) => ({
2617
2670
  _tag: "RawSqlFragment",
2618
2671
  strings: [...e],
2619
2672
  values: [...t]
2620
- }), vr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2673
+ }), wr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2621
2674
  //#endregion
2622
- export { l as FILE_MIGRATION_PATTERN, C as VOLTRO_MIGRATION_LOCK_KEY, ut as _internalCmp, w as acquireMigrationLock, Ke as applyNamespacedSchema, Yn as applyPlan, Be as applySchema, Lt as chunkTables, P as declaredSnapshot, ve as defaultClause, O as defaultJsonClause, sr as describeOutcome, Yt as emitDropColumnDdl, Xt as emitDropColumnDdlMysql, ze as emitFrameworkBootstrapSql, Le as emitNamespaceProvisionDdl, Re as emitNamespacedSchemaSql, j as emitSchemaSql, M as fingerprintSchema, rr as ignoreTablesFromEnv, qt as introspectSchema, o as isFileMigration, vr as isRawSqlFragment, Mt as mapPgType, c as migration, k as numericIdSql, jt as parseEnumCheck, At as planMigrations, qe as provisionTenantNamespace, T as releaseMigrationLock, sn as renderColumnMysql, rn as renderColumnPg, hr as rollbackFileBasedMigration, pr as runFileBasedMigrations, Je as runFrameworkBootstrap, Ge as runMigrate, or as runPlannedMigrations, N as shortFingerprint, _r as sql, D as sqlType, gr as squashMigrationPlans, ir as unblockLossy, ge as withMigrationLock };
2675
+ export { l as FILE_MIGRATION_PATTERN, re as VOLTRO_MIGRATION_LOCK_KEY, dt as _internalCmp, C as acquireMigrationLock, Je as applyNamespacedSchema, tr as applyPlan, He as applySchema, Rt as chunkTables, N as declaredSnapshot, be as defaultArrayClause, ye as defaultClause, D as defaultJsonClause, pr as describeOutcome, Xt as emitDropColumnDdl, Zt as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, lr as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, wr as isRawSqlFragment, Nt as mapPgType, c as migration, O as numericIdSql, Mt as parseEnumCheck, jt as planMigrations, Ye as provisionTenantNamespace, w as releaseMigrationLock, pn as renderColumnMysql, cn as renderColumnPg, xr as rollbackFileBasedMigration, yr as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, fr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, Cr as sql, E as sqlType, Sr as squashMigrationPlans, ur as unblockLossy, _e as withMigrationLock };