@voltro/database 0.14.0 → 0.16.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, "`"), b = (e) => typeof e == "string" ? e : e.name ?? String(e), x = (e, t) => `_ua_${t}_${e}`.slice(0, 64), S = (e, t) => {
42
+ }, v = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, te = (e) => e.replace(/"/g, "`"), y = (e) => typeof e == "string" ? e : e.name ?? String(e), b = (e, t) => `_ua_${t}_${e}`.slice(0, 64), x = (e, t) => {
43
43
  if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(v)) return e;
44
44
  let n = { ...e.fields }, r = [], i = [];
45
45
  for (let t of e.appliedIndexes) {
@@ -47,11 +47,11 @@ var _ = (e, t, n, r = 400) => {
47
47
  r.push(t);
48
48
  continue;
49
49
  }
50
- let a = y(t.where), o = [];
50
+ let a = te(t.where), o = [];
51
51
  for (let r of t.fields) {
52
- let i = b(r);
52
+ let i = y(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 = x(t.name, i);
54
+ let s = b(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
- }, C = (e, t) => `${e}::${t}`, w = (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(C(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
- }, te = 6322741009312437n, ne = 250, re = () => {
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
- }, ie = (e) => d.gen(function* () {
90
- let t = re(), 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(`${ne} 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
- }), ae = (e) => d.gen(function* () {
97
- yield* e`SELECT pg_advisory_unlock(${te.toString()}::bigint)`;
98
- }), oe = `voltro_migration_${te.toString(36)}`, se = 30, ce = (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(${oe}, ${se}) AS got`)[0]?.got !== 1 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${oe}' within ${se}s (another migration is in progress, or a prior one left it held).`)));
101
- }), le = (e) => d.gen(function* () {
102
- yield* e`SELECT RELEASE_LOCK(${oe})`;
103
- }), ue = `voltro_migration_${te.toString(36)}`, de = 3e4, fe = (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 = ${ue}, @LockMode = 'Exclusive',
107
- @LockOwner = 'Session', @LockTimeout = ${de};
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 '${ue}' (sp_getapplock returned ${t[0]?.res ?? "no row"}; another migration is in progress).`)));
110
- }), pe = (e) => d.gen(function* () {
111
- yield* e`EXEC sp_releaseapplock @Resource = ${ue}, @LockOwner = 'Session'`;
112
- }), me = d.void, T = (e) => e.onDialectOrElse({
113
- mysql: () => ce(e),
114
- mssql: () => fe(e),
115
- sqlite: () => me,
116
- orElse: () => ie(e)
117
- }), E = (e) => e.onDialectOrElse({
118
- mysql: () => le(e),
119
- mssql: () => pe(e),
120
- sqlite: () => me,
121
- orElse: () => ae(e)
122
- }), he = (e, t) => d.acquireUseRelease(T(e), () => t, () => E(e).pipe(d.orDie)), ge = f({ scope: "voltro:migrate" }), D = (e) => {
123
- ge.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
124
- }, O = (e, t) => {
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({
113
+ mysql: () => ue(e),
114
+ mssql: () => me(e),
115
+ sqlite: () => ge,
116
+ orElse: () => oe(e)
117
+ }), w = (e) => e.onDialectOrElse({
118
+ mysql: () => de(e),
119
+ mssql: () => he(e),
120
+ sqlite: () => ge,
121
+ orElse: () => se(e)
122
+ }), _e = (e, t) => d.acquireUseRelease(C(e), () => t, () => w(e).pipe(d.orDie)), ve = f({ scope: "voltro:migrate" }), T = (e) => {
123
+ ve.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
124
+ }, E = (e, t) => {
125
125
  let n = e.type;
126
126
  if (e.spatial) {
127
127
  if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
@@ -132,7 +132,7 @@ var _ = (e, t, n, r = 400) => {
132
132
  return e.rawDdl;
133
133
  }
134
134
  if (n === "array" && e.arrayElement) {
135
- if (t === "postgres") return `${O({
135
+ if (t === "postgres") return `${E({
136
136
  ...e,
137
137
  type: e.arrayElement,
138
138
  arrayElement: void 0
@@ -232,22 +232,22 @@ var _ = (e, t, n, r = 400) => {
232
232
  case "array": return "TEXT[]";
233
233
  case "interval": return "INTERVAL";
234
234
  }
235
- }, _e = (e, t) => {
235
+ }, ye = (e, t) => {
236
236
  if (!e.hasDefault || e.defaultFactory !== void 0) return null;
237
237
  let n = e.defaultValue;
238
- return n === "now" ? u(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? ve(n, e, t) : typeof n == "object" && n ? k(n, t) : null;
239
- }, ve = (e, t, n) => {
240
- if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return k(e, n);
241
- let r = O({
238
+ return n === "now" ? u(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? be(n, e, t) : typeof n == "object" && n ? D(n, t) : null;
239
+ }, be = (e, t, n) => {
240
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return D(e, n);
241
+ let r = E({
242
242
  ...t,
243
243
  type: t.arrayElement,
244
244
  arrayElement: void 0
245
245
  }, n);
246
246
  return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
247
- }, k = (e, t) => {
247
+ }, D = (e, t) => {
248
248
  let n = JSON.stringify(e).replace(/'/g, "''");
249
249
  return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CAST('${n}' AS JSON))` : `DEFAULT '${n}'`;
250
- }, A = (e, t) => {
250
+ }, O = (e, t) => {
251
251
  switch (t) {
252
252
  case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
253
253
  case "mysql":
@@ -256,7 +256,7 @@ var _ = (e, t, n, r = 400) => {
256
256
  case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
257
257
  case "turso": return `"${e}" INTEGER PRIMARY KEY`;
258
258
  }
259
- }, j = (e, t) => {
259
+ }, k = (e, t) => {
260
260
  if (e === "restrict" && t === "mssql") return "NO ACTION";
261
261
  switch (e) {
262
262
  case "cascade": return "CASCADE";
@@ -264,38 +264,38 @@ var _ = (e, t, n, r = 400) => {
264
264
  case "setNull": return "SET NULL";
265
265
  case "noAction": return "NO ACTION";
266
266
  }
267
- }, ye = (t, n, r) => r === null ? e(t, n) : `${e(r, n)}.${e(t, n)}`, be = 191, xe = (t, n, r) => {
267
+ }, xe = (t, n, r) => r === null ? e(t, n) : `${e(r, n)}.${e(t, n)}`, Se = 191, Ce = (t, n, r) => {
268
268
  let i = e(t, r);
269
269
  if (r !== "mysql" && r !== "mariadb") return i;
270
270
  let a = n[t];
271
271
  if (!a) return i;
272
- let o = O(a, r).toUpperCase();
273
- return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${be})` : i;
274
- }, Se = (e, t) => {
272
+ let o = E(a, r).toUpperCase();
273
+ return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${Se})` : i;
274
+ }, we = (e, t) => {
275
275
  if (!e.generatedAs) return null;
276
276
  let { expr: n, stored: r } = e.generatedAs;
277
- if (t === "postgres") return r || D("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
277
+ if (t === "postgres") return r || T("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
278
278
  if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
279
279
  if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
280
280
  if (t === "turso") throw Error("@voltro/sql-turso: generated columns (.generatedAs(...)) are not supported — Turso's MVCC mode (journal_mode=experimental_mvcc) rejects them. Drop the generated column, or use the 'sqlite' / 'postgres' dialect for this table.");
281
281
  return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
282
- }, Ce = (t, n, r, i, a = !1, o = !1) => {
283
- if (n.type === "id" && n.idScheme?.kind === "numeric") return A(t, r);
284
- let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : O(n, r), c = [e(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 = [e(t, r), s];
285
285
  n.type === "id" && !o && c.push("PRIMARY KEY");
286
- let l = Se(n, r);
286
+ let l = we(n, r);
287
287
  if (l) c.push(l);
288
288
  else {
289
289
  n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && c.push("UNIQUE");
290
- let e = _e(n, r);
290
+ let e = ye(n, r);
291
291
  e && c.push(e);
292
292
  }
293
293
  if (n.type === "reference" && n.references && !a) {
294
294
  let t = n.references();
295
295
  c.push(`REFERENCES ${e(t.tableName, r)} (${e("id", r)})`);
296
- let i = j(n.onDelete ?? "restrict", r);
296
+ let i = k(n.onDelete ?? "restrict", r);
297
297
  c.push(`ON DELETE ${i}`);
298
- let a = j(n.refOnUpdate ?? "noAction", r);
298
+ let a = k(n.refOnUpdate ?? "noAction", r);
299
299
  a !== "NO ACTION" && c.push(`ON UPDATE ${a}`);
300
300
  }
301
301
  if (n.oneOf && n.oneOf.length > 0) {
@@ -312,18 +312,18 @@ var _ = (e, t, n, r = 400) => {
312
312
  u(r) ? c.push(`CHECK (${n} IS NULL OR json_valid(${n}))`) : r === "mssql" && c.push(`CHECK (${n} IS NULL OR ISJSON(${n}) = 1)`);
313
313
  }
314
314
  return c.join(" ");
315
- }, we = (t, n, r = null, i) => {
315
+ }, Ee = (t, n, r = null, i) => {
316
316
  let a = /* @__PURE__ */ new Set();
317
317
  for (let e of t.appliedIndexes ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
318
318
  for (let e of t.appliedUniques ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
319
- let o = t.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(t.fields).map(([e, t]) => ` ${Ce(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (t.appliedUniques ?? []).map((r) => {
320
- let i = r.fields.map((e) => xe(e, t.fields, n)).join(", ");
319
+ let o = t.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(t.fields).map(([e, t]) => ` ${Te(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (t.appliedUniques ?? []).map((r) => {
320
+ let i = r.fields.map((e) => Ce(e, t.fields, n)).join(", ");
321
321
  return ` CONSTRAINT ${e(r.name, n)} UNIQUE (${i})`;
322
322
  }), u = (t.appliedChecks ?? []).map((t) => ` CONSTRAINT ${e(t.name, n)} CHECK (${t.expr})`), d = [
323
- ...s ? [` PRIMARY KEY (${o.map((e) => xe(e, t.fields, n)).join(", ")})`] : [],
323
+ ...s ? [` PRIMARY KEY (${o.map((e) => Ce(e, t.fields, n)).join(", ")})`] : [],
324
324
  ...l,
325
325
  ...u
326
- ], f = d.length > 0 ? `${c},\n${d.join(",\n")}` : c, p = ye(t.tableName, n, r);
326
+ ], f = d.length > 0 ? `${c},\n${d.join(",\n")}` : c, p = xe(t.tableName, n, r);
327
327
  if (n === "mssql") {
328
328
  let e = r === null ? t.tableName : `${r}.${t.tableName}`, n = `CREATE TABLE ${p} (\n${f}\n)`;
329
329
  return `IF OBJECT_ID('${e.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
@@ -333,10 +333,10 @@ var _ = (e, t, n, r = 400) => {
333
333
  f,
334
334
  ");"
335
335
  ].join("\n");
336
- }, Te = (t, n, r) => {
336
+ }, De = (t, n, r) => {
337
337
  let i = `${t}_${n.name}_fts`, a = (t) => e(t, r), o = n.columns.map(a).join(", "), s = n.columns.map((e) => `new.${a(e)}`).join(", "), c = [];
338
338
  return c.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${a(i)} USING fts5(${o}, row_id UNINDEXED, tokenize='porter');`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_ai`)} AFTER INSERT ON ${a(t)} BEGIN\n INSERT INTO ${a(i)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_ad`)} AFTER DELETE ON ${a(t)} BEGIN\n DELETE FROM ${a(i)} WHERE row_id = old.${a("id")};\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${i}_au`)} AFTER UPDATE ON ${a(t)} BEGIN\n DELETE FROM ${a(i)} WHERE row_id = old.${a("id")};\n INSERT INTO ${a(i)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c;
339
- }, Ee = (n, r, a = null) => {
339
+ }, Oe = (n, r, a = null) => {
340
340
  let o = [], s = /* @__PURE__ */ new Set(), c = (e) => e.join("\0"), l = (e, n, i, a) => {
341
341
  let o = {
342
342
  using: "",
@@ -348,21 +348,21 @@ var _ = (e, t, n, r = 400) => {
348
348
  using: " USING GIST",
349
349
  withSuffix: "",
350
350
  skip: !1
351
- } : (D(`[voltro:migrate] index '${e}' on '${n}': ${r} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
351
+ } : (T(`[voltro:migrate] index '${e}' on '${n}': ${r} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
352
352
  if (i === "gin") return r === "postgres" ? {
353
353
  using: " USING GIN",
354
354
  withSuffix: "",
355
355
  skip: !1
356
- } : r === "mysql" || r === "mariadb" ? (D(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
356
+ } : r === "mysql" || r === "mariadb" ? (T(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
357
357
  using: "",
358
358
  withSuffix: "",
359
359
  skip: !0
360
- }) : (D(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
360
+ }) : (T(`[voltro:migrate] gin index '${e}' on '${n}': ${r} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
361
361
  if (i === "brin") return r === "postgres" ? {
362
362
  using: " USING BRIN",
363
363
  withSuffix: "",
364
364
  skip: !1
365
- } : (D(`[voltro:migrate] brin index '${e}' on '${n}': ${r} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
365
+ } : (T(`[voltro:migrate] brin index '${e}' on '${n}': ${r} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
366
366
  if (i === "hnsw") {
367
367
  if (r === "postgres") {
368
368
  let e = a?.hnsw?.m ?? 16, n = a?.hnsw?.efConstruction ?? 64, r = a?.hnsw?.opclass ?? t(a?.hnsw?.distance);
@@ -373,7 +373,7 @@ var _ = (e, t, n, r = 400) => {
373
373
  skip: !1
374
374
  };
375
375
  }
376
- return D(`[voltro:migrate] hnsw index '${e}' on '${n}': ${r} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
376
+ return T(`[voltro:migrate] hnsw index '${e}' on '${n}': ${r} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
377
377
  using: "",
378
378
  withSuffix: "",
379
379
  skip: !0
@@ -382,7 +382,7 @@ var _ = (e, t, n, r = 400) => {
382
382
  return o;
383
383
  }, u = (e, t) => {
384
384
  let a = e.map((e) => {
385
- if (typeof e == "string") return xe(e, n.fields, r);
385
+ if (typeof e == "string") return Ce(e, n.fields, r);
386
386
  if ("jsonPath" in e) {
387
387
  let { column: t, path: n, numeric: a } = e.jsonPath;
388
388
  return `(${i(t, n, r, { numeric: a })})`;
@@ -393,7 +393,7 @@ var _ = (e, t, n, r = 400) => {
393
393
  }, d = (t, n, i, o, s, c = "", d = !1) => {
394
394
  let f = l(t, n, o, s);
395
395
  if (f.skip) return "";
396
- let p = u(i, f.opclass), m = `${f.withSuffix}${c}`, h = ye(n, r, a), g = d ? "UNIQUE " : "";
396
+ let p = u(i, f.opclass), m = `${f.withSuffix}${c}`, h = xe(n, r, a), g = d ? "UNIQUE " : "";
397
397
  return r === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${t}') CREATE ${g}INDEX ${e(t, r)} ON ${h}${f.using} (${p})${m};` : r === "mysql" ? `CREATE ${g}INDEX ${e(t, r)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${e(t, r)} ON ${h}${f.using} (${p})${m};`;
398
398
  };
399
399
  for (let t of n.appliedFullText ?? []) if (r === "postgres") {
@@ -406,15 +406,15 @@ var _ = (e, t, n, r = 400) => {
406
406
  let i = t.columns.map((t) => e(t, r)).join(", ");
407
407
  o.push(`CREATE FULLTEXT INDEX ${e(t.name, r)} ON ${e(n.tableName, r)} (${i});`);
408
408
  } else if (r === "turso") throw Error(`@voltro/sql-turso: full-text index '${t.name}' on '${n.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
409
- else r === "sqlite" ? o.push(...Te(n.tableName, t, r)) : D(`[voltro:migrate] full-text index '${t.name}' on '${n.tableName}': ${r} uses a ranked LIKE search at query time (no native FTS catalog required).`);
409
+ else r === "sqlite" ? o.push(...De(n.tableName, t, r)) : T(`[voltro:migrate] full-text index '${t.name}' on '${n.tableName}': ${r} uses a ranked LIKE search at query time (no native FTS catalog required).`);
410
410
  for (let e of n.appliedIndexes) {
411
411
  if ((r === "mariadb" || r === "mssql") && e.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
412
- D(`[voltro:migrate] json-path index '${e.name}' on '${n.tableName}': ${r} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${r}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
412
+ T(`[voltro:migrate] json-path index '${e.name}' on '${n.tableName}': ${r} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${r}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
413
413
  continue;
414
414
  }
415
415
  if (e.unique && e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${e.name}' on '${n.tableName}' cannot be expressed on ${r} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${r}, or move this table to postgres/sqlite/mssql.`);
416
416
  let t = "";
417
- e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb" ? D(`[voltro:migrate] partial index '${e.name}' on '${n.tableName}': ${r} does not support WHERE clauses on indexes — emitting a full index`) : t = ` WHERE ${e.where}`);
417
+ e.where !== void 0 && e.where.length > 0 && (r === "mysql" || r === "mariadb" ? T(`[voltro:migrate] partial index '${e.name}' on '${n.tableName}': ${r} does not support WHERE clauses on indexes — emitting a full index`) : t = ` WHERE ${e.where}`);
418
418
  let i = d(e.name, n.tableName, e.fields, e.kind, e.kindOptions, t, e.unique === !0);
419
419
  i !== "" && o.push(i), e.fields.every((e) => typeof e == "string") && s.add(c(e.fields));
420
420
  }
@@ -424,14 +424,14 @@ var _ = (e, t, n, r = 400) => {
424
424
  o.push(d(r, n.tableName, [e])), s.add(c([e]));
425
425
  }
426
426
  return o.join("\n");
427
- }, 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) => `
428
428
  ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL;
429
429
  DROP TRIGGER IF EXISTS framework_changes_${e.tableName} ON "${e.tableName}";
430
430
  CREATE TRIGGER framework_changes_${e.tableName}
431
431
  AFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"
432
432
  FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
433
- `.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) => {
434
- let t = new Map(e.map((e) => [e.tableName, e])), n = w(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) => {
435
435
  let n = t.get(e);
436
436
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
437
437
  if (n.type !== "reference" || !n.references) return [];
@@ -442,7 +442,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
442
442
  }] : [];
443
443
  }) : [];
444
444
  }), r = [];
445
- for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(C(t.tableName, e)) && r.push({
445
+ for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(S(t.tableName, e)) && r.push({
446
446
  table: t.tableName,
447
447
  column: e,
448
448
  targetTable: i.references().tableName,
@@ -453,7 +453,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
453
453
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
454
454
  a.add(e.tableName);
455
455
  for (let [r, i] of Object.entries(e.fields)) {
456
- if (i.type !== "reference" || !i.references || n.has(C(e.tableName, r))) continue;
456
+ if (i.type !== "reference" || !i.references || n.has(S(e.tableName, r))) continue;
457
457
  let a = i.references();
458
458
  if (a.tableName === e.tableName) continue;
459
459
  let o = t.get(a.tableName);
@@ -467,8 +467,8 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
467
467
  sorted: o,
468
468
  cyclic: r
469
469
  };
470
- }, Me = (t, n, r = null) => {
471
- let i = (t) => r ? `${e(r, n)}.${e(t, n)}` : e(t, n), a = `${t.table}_${t.column}_fkey`, o = j(t.onDelete, n), s = j(t.onUpdate, n), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${e(a, n)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${e(t.column, n)}) REFERENCES ${i(t.targetTable)} (${e("id", n)})${c}`;
470
+ }, Pe = (t, n, r = null) => {
471
+ let i = (t) => r ? `${e(r, n)}.${e(t, n)}` : e(t, n), a = `${t.table}_${t.column}_fkey`, o = k(t.onDelete, n), s = k(t.onUpdate, n), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${e(a, n)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${e(t.column, n)}) REFERENCES ${i(t.targetTable)} (${e("id", n)})${c}`;
472
472
  switch (n) {
473
473
  case "postgres": return [
474
474
  "DO $$ BEGIN",
@@ -482,7 +482,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
482
482
  case "mariadb": return `ALTER TABLE ${i(t.table)} ${l(!0)};`;
483
483
  default: return `ALTER TABLE ${i(t.table)} ${l(!1)};`;
484
484
  }
485
- }, Ne = (e, t) => {
485
+ }, Fe = (e, t) => {
486
486
  let n = /* @__PURE__ */ new Map();
487
487
  if (u(t)) return n;
488
488
  for (let t of e) {
@@ -490,7 +490,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
490
490
  e.add(t.column), n.set(t.table, e);
491
491
  }
492
492
  return n;
493
- }, Pe = (e, t) => {
493
+ }, Ie = (e, t) => {
494
494
  if (t !== "postgres") return "";
495
495
  let n = /* @__PURE__ */ new Map();
496
496
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -506,7 +506,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
506
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 $$;`);
507
507
  }
508
508
  return r.join("\n\n");
509
- }, Fe = (e, t) => {
509
+ }, Le = (e, t) => {
510
510
  if (t !== "postgres") return "";
511
511
  let n = /* @__PURE__ */ new Set();
512
512
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
@@ -520,34 +520,34 @@ BEGIN
520
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 $$;`);
521
521
  }
522
522
  return r.join("\n\n");
523
- }, Ie = (e) => {
523
+ }, Re = (e) => {
524
524
  let t = [], r = [];
525
525
  for (let i of e) n(i) ? r.push(i) : t.push(i);
526
526
  return {
527
527
  tables: t,
528
528
  views: r
529
529
  };
530
- }, M = (e, t) => {
531
- let { tables: n, views: i } = Ie(e), { sorted: a, cyclic: o } = je(n.map((e) => S(e, t))), s = Ne(o, t), c = [];
532
- t === "postgres" && ke(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && Ae(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
533
- let l = Fe(a, t);
530
+ }, A = (e, t) => {
531
+ let { tables: n, views: i } = Re(e), { sorted: a, cyclic: o } = Ne(n.map((e) => x(e, t))), s = Fe(o, t), c = [];
532
+ t === "postgres" && je(a) && c.push("CREATE EXTENSION IF NOT EXISTS vector;"), t === "postgres" && Me(a) && c.push("CREATE EXTENSION IF NOT EXISTS postgis;");
533
+ let l = Le(a, t);
534
534
  l && c.push(l);
535
- let d = Pe(a, t);
535
+ let d = Ie(a, t);
536
536
  d && c.push(d);
537
- for (let e of a) c.push(we(e, t, null, s.get(e.tableName)));
538
- if (!u(t)) for (let e of o) c.push(Me(e, t));
537
+ for (let e of a) c.push(Ee(e, t, null, s.get(e.tableName)));
538
+ if (!u(t)) for (let e of o) c.push(Pe(e, t));
539
539
  for (let e of a) {
540
- let n = Ee(e, t);
540
+ let n = Oe(e, t);
541
541
  n && c.push(n);
542
542
  }
543
543
  let f = a.filter((e) => e.isReactive !== !1);
544
544
  if (f.length > 0 && t === "postgres") {
545
- c.push(De);
546
- for (let e of f) c.push(Oe(e));
545
+ c.push(ke);
546
+ for (let e of f) c.push(Ae(e));
547
547
  }
548
548
  for (let e of i) c.push(r(e, t));
549
549
  return c.join("\n\n") + "\n";
550
- }, Le = (t, n, r) => {
550
+ }, ze = (t, n, r) => {
551
551
  let i = e(t, n);
552
552
  switch (n) {
553
553
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${i};`;
@@ -557,57 +557,57 @@ BEGIN
557
557
  case "turso":
558
558
  case "sqlite": return `ATTACH DATABASE '${(r ?? `${t}.db`).replace(/'/g, "''")}' AS ${i};`;
559
559
  }
560
- }, Re = (t, n, r, i) => {
561
- let a = Le(r, n, i), o = e(r, n);
562
- if (n === "postgres") return `${a}\n\nSET search_path TO ${o};\n\n${M(t, n)}`;
563
- if (n === "mysql" || n === "mariadb") return `${a}\n\nUSE ${o};\n\n${M(t, n)}`;
564
- let { sorted: s, cyclic: c } = je(t), l = Ne(c, n), d = [a];
565
- for (let e of s) d.push(we(e, n, r, l.get(e.tableName)));
566
- if (!u(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 = e(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 (!u(n)) for (let e of c) d.push(Pe(e, n, r));
567
567
  for (let e of s) {
568
- let t = Ee(e, n, r);
568
+ let t = Oe(e, n, r);
569
569
  t && d.push(t);
570
570
  }
571
571
  return d.join("\n\n") + "\n";
572
- }, ze = (t, n) => {
573
- if (n !== "postgres") return M(t, n);
574
- let { sorted: r, cyclic: i } = je(t), a = Ne(i, n), o = [], s = Fe(r, n);
572
+ }, Ve = (t, n) => {
573
+ if (n !== "postgres") return A(t, n);
574
+ let { sorted: r, cyclic: i } = Ne(t), a = Fe(i, n), o = [], s = Le(r, n);
575
575
  s && o.push(s);
576
- let c = Pe(r, n);
576
+ let c = Ie(r, n);
577
577
  c && o.push(c);
578
- for (let e of r) o.push(we(e, n, null, a.get(e.tableName)));
579
- for (let e of i) o.push(Me(e, n));
578
+ for (let e of r) o.push(Ee(e, n, null, a.get(e.tableName)));
579
+ for (let e of i) o.push(Pe(e, n));
580
580
  for (let t of r) {
581
581
  let r = Object.entries(t.fields);
582
582
  if (r.length === 0) continue;
583
583
  let i = r.map(([r, i]) => {
584
- let o = Ce(r, i, n, void 0, a.get(t.tableName)?.has(r) ?? !1);
584
+ let o = Te(r, i, n, void 0, a.get(t.tableName)?.has(r) ?? !1);
585
585
  return `ALTER TABLE ${e(t.tableName, n)} ADD COLUMN IF NOT EXISTS ${o};`;
586
586
  });
587
587
  o.push(i.join("\n"));
588
588
  }
589
589
  for (let e of r) {
590
- let t = Ee(e, n);
590
+ let t = Oe(e, n);
591
591
  t && o.push(t);
592
592
  }
593
593
  let l = r.filter((e) => e.isReactive);
594
594
  if (l.length > 0) {
595
- o.push(De);
596
- for (let e of l) o.push(Oe(e));
595
+ o.push(ke);
596
+ for (let e of l) o.push(Ae(e));
597
597
  }
598
598
  return o.join("\n\n") + "\n";
599
- }, Be = (e, t = "postgres") => d.gen(function* () {
599
+ }, He = (e, t = "postgres") => d.gen(function* () {
600
600
  let n = yield* p.SqlClient;
601
- yield* he(n, Ue(n, M(e, t), t)).pipe(d.orDie);
602
- }), Ve = (e, t) => {
601
+ yield* _e(n, Ge(n, A(e, t), t)).pipe(d.orDie);
602
+ }), Ue = (e, t) => {
603
603
  let n = t.cause ?? {};
604
604
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
605
- }, He = (e) => d.gen(function* () {
605
+ }, We = (e) => d.gen(function* () {
606
606
  let t = yield* p.SqlClient;
607
- for (let n of We(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && ge.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(() => {
608
- ge.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));
609
609
  })), d.orDieWith((e) => Error(_("migrate: statement failed", n, e, 400).trim())));
610
- }), 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) => {
611
611
  let t = [], n = "", r = !1;
612
612
  for (let i = 0; i < e.length; i++) {
613
613
  if (e.slice(i, i + 2) === "$$") {
@@ -622,40 +622,40 @@ BEGIN
622
622
  }
623
623
  let i = n.trim();
624
624
  return i.length > 0 && t.push(i), t;
625
- }, Ge = async (e, t, n = "postgres") => {
626
- await d.runPromise(Be(e, n).pipe(d.provide(t)));
627
- }, Ke = (e, t, n = "postgres") => d.gen(function* () {
628
- let r = Re(e, n, t), i = yield* p.SqlClient;
629
- yield* he(i, Ue(i, r, n)).pipe(d.orDie);
630
- }), qe = async (e, t, n, r = "postgres") => {
631
- await d.runPromise(Ke(e, t, r).pipe(d.provide(n)));
632
- }, 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") => {
633
633
  await d.runPromise(d.gen(function* () {
634
- let t = ze(e, n), r = yield* p.SqlClient;
635
- yield* he(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);
636
636
  }).pipe(d.provide(t)));
637
- }, Ye = (e) => {
637
+ }, Ze = (e) => {
638
638
  if (e == null) return e;
639
- if (Array.isArray(e)) return e.map(Ye);
639
+ if (Array.isArray(e)) return e.map(Ze);
640
640
  if (typeof e != "object") return e;
641
641
  let t = {};
642
642
  for (let n of Object.keys(e).sort()) {
643
643
  let r = e[n];
644
- r !== void 0 && (t[n] = Ye(r));
644
+ r !== void 0 && (t[n] = Ze(r));
645
645
  }
646
646
  return t;
647
- }, Xe = (e) => {
647
+ }, Qe = (e) => {
648
648
  if (!e.idScheme && !e.sensitive && !e.safe) return e;
649
649
  let { idScheme: t, sensitive: n, safe: r, ...i } = e;
650
650
  return i;
651
- }, 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) => ({
652
652
  name: e.name,
653
- columns: Ze(e.columns),
654
- indexes: Qe(e.indexes)
655
- })).sort((e, t) => e.name.localeCompare(t.name)), N = (e) => {
656
- 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));
657
657
  return m("sha256").update(n).digest("hex");
658
- }, P = (e) => e.slice(0, 16), et = (e, t) => {
658
+ }, M = (e) => e.slice(0, 16), nt = (e, t) => {
659
659
  let n = t.references ? {
660
660
  table: t.references().tableName,
661
661
  column: "id",
@@ -693,7 +693,7 @@ BEGIN
693
693
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
694
694
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
695
695
  };
696
- }, tt = (e) => {
696
+ }, rt = (e) => {
697
697
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
698
698
  n.has(e.name) || (n.add(e.name), t.push(e));
699
699
  }, i = e.appliedPrimaryKey ?? [];
@@ -741,11 +741,11 @@ BEGIN
741
741
  });
742
742
  }
743
743
  return t;
744
- }, nt = (e) => {
744
+ }, it = (e) => {
745
745
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
746
746
  for (let [r, i] of Object.entries(e.fields)) {
747
747
  if (i.dropped) continue;
748
- let e = et(r, i);
748
+ let e = nt(r, i);
749
749
  n.push(t.has(r) ? {
750
750
  ...e,
751
751
  unique: !0
@@ -755,20 +755,20 @@ BEGIN
755
755
  return {
756
756
  name: e.tableName,
757
757
  columns: n,
758
- indexes: tt(e),
758
+ indexes: rt(e),
759
759
  ...r.length > 0 ? { primaryKey: [...r] } : {}
760
760
  };
761
- }, rt = (e) => {
761
+ }, at = (e) => {
762
762
  let t = /* @__PURE__ */ new Map();
763
763
  for (let n of e) for (let e of n.indexes) {
764
764
  let r = t.get(e.name);
765
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}').`);
766
766
  t.set(e.name, n.name);
767
767
  }
768
- }, F = (e, t) => {
769
- let n = e.map((e) => nt(S(e, t)));
770
- return rt(n), { tables: n };
771
- }, it = "framework_changes_", at = (e, t) => d.gen(function* () {
768
+ }, N = (e, t) => {
769
+ let n = e.map((e) => it(x(e, t)));
770
+ return at(n), { tables: n };
771
+ }, ot = "framework_changes_", st = (e, t) => d.gen(function* () {
772
772
  let n = t.filter((e) => !e.tableName.startsWith("_voltro_"));
773
773
  if (n.length === 0) return {
774
774
  missing: [],
@@ -781,17 +781,17 @@ BEGIN
781
781
  JOIN pg_namespace n ON n.oid = c.relnamespace
782
782
  WHERE NOT t.tgisinternal
783
783
  AND n.nspname = current_schema()
784
- AND t.tgname LIKE ${`${it}%`}
784
+ AND t.tgname LIKE ${`${ot}%`}
785
785
  `, i = new Set(r.map((e) => e.tgname)), a = [], o = [];
786
786
  for (let e of n) {
787
- let t = i.has(`${it}${e.tableName}`), n = e.isReactive !== !1;
787
+ let t = i.has(`${ot}${e.tableName}`), n = e.isReactive !== !1;
788
788
  n && !t && a.push(e.tableName), !n && t && o.push(e.tableName);
789
789
  }
790
790
  return {
791
791
  missing: a.sort(),
792
792
  stale: o.sort()
793
793
  };
794
- }), ot = (e) => {
794
+ }), ct = (e) => {
795
795
  let t = [];
796
796
  if (e.missing.length > 0) {
797
797
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -802,19 +802,19 @@ BEGIN
802
802
  t.push(`${e.stale.length} .nonReactive() table(s) still carry a change trigger — ${n}. They keep paying REPLICA IDENTITY FULL and a NOTIFY on every write for a subscription nobody receives. \`voltro db apply\` removes them.`);
803
803
  }
804
804
  return t.length > 0 ? t.join("\n") : void 0;
805
- }, st = /* @__PURE__ */ new Set(["voltro_isr_cache"]), I = (e) => st.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), ct = {
805
+ }, lt = /* @__PURE__ */ new Set(["voltro_isr_cache"]), P = (e) => lt.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), ut = {
806
806
  postgres: !0,
807
807
  mysql: !0,
808
808
  mariadb: !0,
809
809
  mssql: !0,
810
810
  sqlite: !0
811
- }, lt = {
811
+ }, dt = {
812
812
  postgres: !0,
813
813
  mysql: !1,
814
814
  mariadb: !1,
815
815
  mssql: !0,
816
816
  sqlite: !0
817
- }, ut = (e) => {
817
+ }, ft = (e) => {
818
818
  switch (e) {
819
819
  case "add-column":
820
820
  case "drop-column":
@@ -824,43 +824,43 @@ BEGIN
824
824
  case "add-foreign-key":
825
825
  case "add-unique":
826
826
  case "add-unique-composite":
827
- case "add-check": return lt;
828
- default: return ct;
827
+ case "add-check": return dt;
828
+ default: return ut;
829
829
  }
830
- }, dt = (e, t) => {
830
+ }, pt = (e, t) => {
831
831
  let n = new Map(t.tables.map((e) => [e.name, e]));
832
832
  return new Map(e.map((e) => [e.tableName, {
833
833
  table: e,
834
834
  snapshot: n.get(e.tableName),
835
835
  columnDefs: e.fields
836
836
  }]));
837
- }, ft = (e) => (t, n) => t.name === e ? -1 : n.name === e ? 1 : t.name.localeCompare(n.name), L = (e) => {
837
+ }, mt = (e) => (t, n) => t.name === e ? -1 : n.name === e ? 1 : t.name.localeCompare(n.name), F = (e) => {
838
838
  if (typeof e != "object" || !e) return JSON.stringify(e);
839
- if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
839
+ if (Array.isArray(e)) return `[${e.map(F).join(",")}]`;
840
840
  let t = e;
841
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
842
- }, pt = (e) => {
841
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${F(t[e])}`).join(",")}}`;
842
+ }, ht = (e) => {
843
843
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
844
844
  let t = e.defaultValue;
845
845
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
846
846
  if (typeof t == "number") return String(t);
847
- if (typeof t != "string") return L(t);
847
+ if (typeof t != "string") return F(t);
848
848
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
849
849
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
850
850
  let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
851
851
  if (o) try {
852
- return L(JSON.parse(o[1]));
852
+ return F(JSON.parse(o[1]));
853
853
  } catch {}
854
854
  if (a.startsWith("{") || a.startsWith("[")) try {
855
- return L(JSON.parse(a));
855
+ return F(JSON.parse(a));
856
856
  } catch {}
857
857
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
858
- }, mt = (e, t) => {
859
- let n = pt(e), r = pt(t);
858
+ }, gt = (e, t) => {
859
+ let n = ht(e), r = ht(t);
860
860
  if (n === r) return !0;
861
861
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
862
862
  return i(n) === i(r);
863
- }, R = (e) => {
863
+ }, I = (e) => {
864
864
  if (!e) return null;
865
865
  let t = (e) => e === "restrict" ? "noAction" : e;
866
866
  return {
@@ -869,18 +869,18 @@ BEGIN
869
869
  onDelete: t(e.onDelete),
870
870
  onUpdate: t(e.onUpdate)
871
871
  };
872
- }, ht = (e, t) => {
872
+ }, _t = (e, t) => {
873
873
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
874
874
  if (!n && !r) return !0;
875
875
  if (!n || !r || n.length !== r.length) return !1;
876
876
  let i = [...n].sort(), a = [...r].sort();
877
877
  return i.every((e, t) => e === a[t]);
878
- }, gt = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && mt(e, t) && JSON.stringify(R(e.references)) === JSON.stringify(R(t.references)) && ht(e.oneOf, t.oneOf), _t = (e, t) => t.oneOf && t.oneOf.length > 0 ? z({
878
+ }, vt = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && gt(e, t) && JSON.stringify(I(e.references)) === JSON.stringify(I(t.references)) && _t(e.oneOf, t.oneOf), yt = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
879
879
  kind: "add-check",
880
880
  table: e,
881
881
  column: t.name,
882
882
  values: t.oneOf
883
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, vt = (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])), yt = (e, t) => {
883
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, bt = (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])), xt = (e, t) => {
884
884
  let n = new Map(t.columns.map((e) => [e.name, e])), r = new Map(e.columns.map((e) => [e.name, e])), i = [], a = [], o = [];
885
885
  for (let t of e.columns) {
886
886
  let e = n.get(t.name);
@@ -888,7 +888,7 @@ BEGIN
888
888
  i.push(t);
889
889
  continue;
890
890
  }
891
- gt(t, e) || o.push({
891
+ vt(t, e) || o.push({
892
892
  declared: t,
893
893
  live: e
894
894
  });
@@ -899,47 +899,47 @@ BEGIN
899
899
  removed: a,
900
900
  changed: o
901
901
  };
902
- }, bt = (e, t) => {
902
+ }, St = (e, t) => {
903
903
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
904
904
  for (let t of e.indexes) {
905
905
  let e = n.get(t.name);
906
- (!e || !vt(t, e)) && i.push(t);
906
+ (!e || !bt(t, e)) && i.push(t);
907
907
  }
908
908
  for (let e of t.indexes) r.has(e.name) || a.push(e);
909
909
  return {
910
910
  added: i,
911
911
  removed: a
912
912
  };
913
- }, z = (e, t, n, r) => ({
913
+ }, L = (e, t, n, r) => ({
914
914
  op: e,
915
915
  classification: t,
916
- atomicByDialect: ut(e.kind),
916
+ atomicByDialect: ft(e.kind),
917
917
  ...n ? { reason: n } : {},
918
918
  ...r ? { blocked: r } : {}
919
- }), xt = (e, t, n) => {
919
+ }), Ct = (e, t, n) => {
920
920
  let r = {
921
921
  kind: "add-column",
922
922
  table: e,
923
923
  column: t
924
924
  };
925
- return t.nullable ? z(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? z(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? z(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : z(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
926
- }, St = (e, t, n) => {
925
+ return t.nullable ? L(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? L(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? L(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : L(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
926
+ }, wt = (e, t, n) => {
927
927
  let r = {
928
928
  kind: "drop-column",
929
929
  table: e,
930
930
  column: t.name
931
931
  };
932
- return n?.dropped ? z(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : z(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
933
- }, Ct = (e, t, n, r) => z({
932
+ return n?.dropped ? L(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : L(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
933
+ }, Tt = (e, t, n, r) => L({
934
934
  kind: "create-table",
935
935
  table: e,
936
936
  columns: t,
937
937
  indexes: n,
938
938
  ...r && r.length > 0 ? { primaryKey: r } : {}
939
- }, "safe", "new table — no data to preserve"), wt = (e) => z({
939
+ }, "safe", "new table — no data to preserve"), Et = (e) => L({
940
940
  kind: "drop-table",
941
941
  table: e
942
- }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), Tt = 5e4, Et = (e, t, n, r) => {
942
+ }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), Dt = 5e4, Ot = (e, t, n, r) => {
943
943
  let i = (n ?? 0) >= r, a;
944
944
  return a = t.unique ? t.columns.length === 1 ? {
945
945
  kind: "add-unique",
@@ -954,16 +954,16 @@ BEGIN
954
954
  kind: "add-index",
955
955
  table: e,
956
956
  index: t
957
- }, i ? z(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
958
- }, Dt = (e, t) => t.unique && t.columns.length > 1 ? z({
957
+ }, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
958
+ }, kt = (e, t) => t.unique && t.columns.length > 1 ? L({
959
959
  kind: "drop-unique-composite",
960
960
  table: e,
961
961
  name: t.name
962
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : z({
962
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : L({
963
963
  kind: "drop-index",
964
964
  table: e,
965
965
  index: t.name
966
- }, "safe", "drop index (no data loss — index is derived data)"), Ot = (e, t) => {
966
+ }, "safe", "drop index (no data loss — index is derived data)"), At = (e, t) => {
967
967
  if (e === "reference") return "text";
968
968
  switch (t) {
969
969
  case "sqlite":
@@ -971,7 +971,7 @@ BEGIN
971
971
  case "mssql": return e === "json" ? "text" : e;
972
972
  default: return e;
973
973
  }
974
- }, kt = (e, t, n, r, i, a) => {
974
+ }, jt = (e, t, n, r, i, a) => {
975
975
  let o = [];
976
976
  if (t.nullable !== n.nullable) {
977
977
  let n = {
@@ -980,7 +980,7 @@ BEGIN
980
980
  column: t.name,
981
981
  toNullable: t.nullable
982
982
  };
983
- o.push(t.nullable ? z(n, "safe", `loosen ${e}.${t.name} to nullable`) : z(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
983
+ o.push(t.nullable ? L(n, "safe", `loosen ${e}.${t.name} to nullable`) : L(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
984
984
  }
985
985
  if (t.unique !== n.unique) if (t.unique) {
986
986
  let n = {
@@ -988,13 +988,13 @@ BEGIN
988
988
  table: e,
989
989
  column: t.name
990
990
  }, r = (i ?? 0) >= a;
991
- o.push(r ? z(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
992
- } else o.push(z({
991
+ o.push(r ? L(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
992
+ } else o.push(L({
993
993
  kind: "drop-unique",
994
994
  table: e,
995
995
  column: t.name
996
996
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
997
- if (Ot(t.type, r) !== Ot(n.type, r)) {
997
+ if (At(t.type, r) !== At(n.type, r)) {
998
998
  let r = t.narrowedFrom;
999
999
  if (r && r.from === n.type) {
1000
1000
  let i = {
@@ -1005,7 +1005,7 @@ BEGIN
1005
1005
  to: t.type,
1006
1006
  ...r.using === void 0 ? {} : { using: r.using }
1007
1007
  };
1008
- o.push(z(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1008
+ o.push(L(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1009
1009
  } else {
1010
1010
  let r = {
1011
1011
  kind: "alter-column-type",
@@ -1014,10 +1014,10 @@ BEGIN
1014
1014
  from: n.type,
1015
1015
  to: t.type
1016
1016
  };
1017
- o.push(z(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` }));
1017
+ o.push(L(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1018
1018
  }
1019
1019
  }
1020
- if (!mt(t, n)) {
1020
+ if (!gt(t, n)) {
1021
1021
  let n = {
1022
1022
  kind: "alter-column-default",
1023
1023
  table: e,
@@ -1025,18 +1025,18 @@ BEGIN
1025
1025
  hasDefault: t.hasDefault,
1026
1026
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1027
1027
  };
1028
- o.push(z(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1028
+ o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1029
1029
  }
1030
- if (!ht(t.oneOf, n.oneOf)) {
1031
- n.oneOf && n.oneOf.length > 0 && o.push(z({
1030
+ if (!_t(t.oneOf, n.oneOf)) {
1031
+ n.oneOf && n.oneOf.length > 0 && o.push(L({
1032
1032
  kind: "drop-check",
1033
1033
  table: e,
1034
1034
  column: t.name
1035
1035
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1036
- let r = _t(e, t);
1036
+ let r = yt(e, t);
1037
1037
  r && o.push(r);
1038
1038
  }
1039
- if (JSON.stringify(R(t.references)) !== JSON.stringify(R(n.references)) && (n.references && o.push(z({
1039
+ if (JSON.stringify(I(t.references)) !== JSON.stringify(I(n.references)) && (n.references && o.push(L({
1040
1040
  kind: "drop-foreign-key",
1041
1041
  table: e,
1042
1042
  column: t.name
@@ -1050,17 +1050,17 @@ BEGIN
1050
1050
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1051
1051
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1052
1052
  };
1053
- r === "null" && !t.nullable ? o.push(z(i, "lossy", `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : r === "null" || r === "delete" ? o.push(z({
1053
+ r === "null" && !t.nullable ? o.push(L(i, "lossy", `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : r === "null" || r === "delete" ? o.push(L({
1054
1054
  ...i,
1055
1055
  orphanPolicy: r
1056
- }, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(z(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
1056
+ }, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(L(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
1057
1057
  }
1058
1058
  return o;
1059
- }, At = (e, t, n) => {
1059
+ }, Mt = (e, t, n) => {
1060
1060
  let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = new Set(n.removed.map((e) => e.name)), s = new Set(n.added.map((e) => e.name));
1061
1061
  for (let [n, c] of Object.entries(t)) {
1062
1062
  let t = c.renamedFrom;
1063
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(z({
1063
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(L({
1064
1064
  kind: "rename-column",
1065
1065
  table: e.tableName,
1066
1066
  from: t,
@@ -1072,7 +1072,7 @@ BEGIN
1072
1072
  consumedAddedNames: i,
1073
1073
  consumedRemovedNames: a
1074
1074
  };
1075
- }, jt = (e) => {
1075
+ }, Nt = (e) => {
1076
1076
  let t = {
1077
1077
  safe: 0,
1078
1078
  needsDefault: 0,
@@ -1107,37 +1107,37 @@ BEGIN
1107
1107
  break;
1108
1108
  }
1109
1109
  return t;
1110
- }, Mt = (e) => {
1111
- let t = F(e.declared, e.dialect), n = dt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Tt, a = [];
1110
+ }, Pt = (e) => {
1111
+ let t = N(e.declared, e.dialect), n = pt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Dt, a = [];
1112
1112
  for (let e of t.tables) if (!r.has(e.name)) {
1113
- a.push(Ct(e.name, e.columns, e.indexes, e.primaryKey));
1113
+ a.push(Tt(e.name, e.columns, e.indexes, e.primaryKey));
1114
1114
  for (let t of e.columns) {
1115
- let n = _t(e.name, t);
1115
+ let n = yt(e.name, t);
1116
1116
  n && a.push(n);
1117
1117
  }
1118
1118
  }
1119
1119
  let o = new Set(e.ignoreTables ?? []);
1120
- for (let t of e.live.tables) n.has(t.name) || I(t.name) || o.has(t.name) || a.push(wt(t.name));
1120
+ for (let t of e.live.tables) n.has(t.name) || P(t.name) || o.has(t.name) || a.push(Et(t.name));
1121
1121
  for (let o of t.tables) {
1122
1122
  let t = r.get(o.name);
1123
1123
  if (!t) continue;
1124
- let s = n.get(o.name), c = yt(o, t), l = bt(o, t), u = At(s.table, s.columnDefs, c);
1124
+ let s = n.get(o.name), c = xt(o, t), l = St(o, t), u = Mt(s.table, s.columnDefs, c);
1125
1125
  a.push(...u.ops);
1126
1126
  for (let e of c.removed) {
1127
1127
  if (u.consumedRemovedNames.has(e.name)) continue;
1128
1128
  let t = s.columnDefs[e.name];
1129
- a.push(St(o.name, e, t));
1129
+ a.push(wt(o.name, e, t));
1130
1130
  }
1131
1131
  for (let e of c.added) {
1132
1132
  if (u.consumedAddedNames.has(e.name)) continue;
1133
1133
  let t = s.columnDefs[e.name];
1134
- a.push(xt(o.name, e, t));
1135
- let n = _t(o.name, e);
1134
+ a.push(Ct(o.name, e, t));
1135
+ let n = yt(o.name, e);
1136
1136
  n && a.push(n);
1137
1137
  }
1138
- for (let e of l.added) a.push(Et(o.name, e, t.rowCount, i));
1139
- for (let e of l.removed) a.push(Dt(o.name, e));
1140
- for (let { declared: n, live: r } of c.changed) a.push(...kt(o.name, n, r, e.dialect, t.rowCount, i));
1138
+ for (let e of l.added) a.push(Ot(o.name, e, t.rowCount, i));
1139
+ for (let e of l.removed) a.push(kt(o.name, e));
1140
+ for (let { declared: n, live: r } of c.changed) a.push(...jt(o.name, n, r, e.dialect, t.rowCount, i));
1141
1141
  }
1142
1142
  let s = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), c = new Map(t.tables.map((e) => [e.name, e])), l = (e) => {
1143
1143
  let t = c.get(e);
@@ -1145,8 +1145,8 @@ BEGIN
1145
1145
  column: e.name,
1146
1146
  target: e.references.table
1147
1147
  }] : []) : [];
1148
- }, u = w([...s], l), d = [];
1149
- for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(C(e.name, t.name)) || d.push(z({
1148
+ }, u = ne([...s], l), d = [];
1149
+ for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(S(e.name, t.name)) || d.push(L({
1150
1150
  kind: "add-foreign-key",
1151
1151
  table: e.name,
1152
1152
  column: t.name,
@@ -1161,8 +1161,8 @@ BEGIN
1161
1161
  let n = a[t];
1162
1162
  if (n.op.kind !== "create-table") continue;
1163
1163
  let r = n.op;
1164
- if (!r.columns.some((e) => u.has(C(r.table, e.name)))) continue;
1165
- let i = r.columns.map((t) => u.has(C(r.table, t.name)) ? e(t) : t);
1164
+ if (!r.columns.some((e) => u.has(S(r.table, e.name)))) continue;
1165
+ let i = r.columns.map((t) => u.has(S(r.table, t.name)) ? e(t) : t);
1166
1166
  a[t] = {
1167
1167
  ...n,
1168
1168
  op: {
@@ -1182,7 +1182,7 @@ BEGIN
1182
1182
  let i = new Set(t).add(e), a = 0;
1183
1183
  for (let t of r.columns) {
1184
1184
  let n = t.references?.table;
1185
- n && n !== e && !u.has(C(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
1185
+ n && n !== e && !u.has(S(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
1186
1186
  }
1187
1187
  return p.set(e, a), a;
1188
1188
  }, h = (e) => e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, g = (e) => {
@@ -1217,11 +1217,11 @@ BEGIN
1217
1217
  });
1218
1218
  return {
1219
1219
  operations: v,
1220
- fromFingerprint: N(e.live),
1221
- toFingerprint: N(t),
1222
- summary: jt(v)
1220
+ fromFingerprint: j(e.live),
1221
+ toFingerprint: j(t),
1222
+ summary: Nt(v)
1223
1223
  };
1224
- }, Nt = (e) => {
1224
+ }, Ft = (e) => {
1225
1225
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1226
1226
  if (!t) return null;
1227
1227
  let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
@@ -1229,7 +1229,7 @@ BEGIN
1229
1229
  column: t[1],
1230
1230
  values: n
1231
1231
  };
1232
- }, Pt = (e, t) => {
1232
+ }, It = (e, t) => {
1233
1233
  if (t === "vector") return "vector";
1234
1234
  switch (e) {
1235
1235
  case "text":
@@ -1256,7 +1256,7 @@ BEGIN
1256
1256
  case "USER-DEFINED": return "text";
1257
1257
  default: return "text";
1258
1258
  }
1259
- }, B = (e) => {
1259
+ }, R = (e) => {
1260
1260
  switch (e.toUpperCase()) {
1261
1261
  case "CASCADE": return "cascade";
1262
1262
  case "RESTRICT": return "restrict";
@@ -1264,25 +1264,25 @@ BEGIN
1264
1264
  case "SET DEFAULT": return "noAction";
1265
1265
  default: return "noAction";
1266
1266
  }
1267
- }, Ft = (e, t) => {
1267
+ }, Lt = (e, t) => {
1268
1268
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1269
1269
  return Number.isInteger(n) && n > 0 ? n : t;
1270
- }, It = () => Ft(process.env.VOLTRO_INTROSPECT_BATCH, 20), Lt = 300, Rt = () => {
1270
+ }, Rt = () => Lt(process.env.VOLTRO_INTROSPECT_BATCH, 20), zt = 300, Bt = () => {
1271
1271
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1272
- return e !== void 0 && e.trim() === "0" ? 0 : Ft(e, 3e4);
1273
- }, zt = (e, t) => {
1272
+ return e !== void 0 && e.trim() === "0" ? 0 : Lt(e, 3e4);
1273
+ }, Vt = (e, t) => {
1274
1274
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1275
1275
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1276
1276
  return r;
1277
- }, Bt = (e) => {
1278
- let t = Rt(), n = d.gen(function* () {
1277
+ }, Ht = (e) => {
1278
+ let t = Bt(), n = d.gen(function* () {
1279
1279
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1280
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = It(), a = (e, t) => d.gen(function* () {
1280
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Rt(), a = (e, t) => d.gen(function* () {
1281
1281
  let r = [];
1282
- for (let a of zt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1282
+ for (let a of Vt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1283
1283
  return r;
1284
1284
  }), o = [];
1285
- for (let t = 0;; t += Lt) {
1285
+ for (let t = 0;; t += zt) {
1286
1286
  let n = yield* e`
1287
1287
  SELECT c.relname AS table_name,
1288
1288
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1290,9 +1290,9 @@ BEGIN
1290
1290
  JOIN pg_namespace n ON n.oid = c.relnamespace
1291
1291
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1292
1292
  ORDER BY c.relname
1293
- LIMIT ${r(Lt)} OFFSET ${r(t)}
1293
+ LIMIT ${r(zt)} OFFSET ${r(t)}
1294
1294
  `;
1295
- if (o.push(...n), n.length < Lt) break;
1295
+ if (o.push(...n), n.length < zt) break;
1296
1296
  }
1297
1297
  let s = /* @__PURE__ */ new Set(), c = [];
1298
1298
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1377,7 +1377,7 @@ BEGIN
1377
1377
  AND c.relname IN ${t}
1378
1378
  )
1379
1379
  SELECT * FROM ix ORDER BY table_name, index_name, position
1380
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
1380
+ `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
1381
1381
  for (let e of u) {
1382
1382
  let t = _.get(e.table_name);
1383
1383
  t || (t = [], _.set(e.table_name, t)), t.push(e);
@@ -1386,25 +1386,25 @@ BEGIN
1386
1386
  let t = v.get(e.table_name);
1387
1387
  t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1388
1388
  }
1389
- let C = /* @__PURE__ */ new Map();
1389
+ let S = /* @__PURE__ */ new Map();
1390
1390
  for (let e of p) {
1391
- let t = `${e.table_name}${e.constraint_name}`, n = C.get(t);
1391
+ let t = `${e.table_name}${e.constraint_name}`, n = S.get(t);
1392
1392
  n || (n = {
1393
1393
  table: e.table_name,
1394
1394
  columns: []
1395
- }, C.set(t, n)), n.columns.push({
1395
+ }, S.set(t, n)), n.columns.push({
1396
1396
  name: e.column_name,
1397
1397
  position: e.position
1398
1398
  });
1399
1399
  }
1400
- for (let [e, t] of C) {
1400
+ for (let [e, t] of S) {
1401
1401
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1402
1402
  if (n.length === 1) {
1403
- let e = y.get(t.table);
1404
- e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
1403
+ let e = te.get(t.table);
1404
+ e || (e = /* @__PURE__ */ new Set(), te.set(t.table, e)), e.add(n[0]);
1405
1405
  } else {
1406
- let r = b.get(t.table);
1407
- r || (r = [], b.set(t.table, r)), r.push({
1406
+ let r = y.get(t.table);
1407
+ r || (r = [], y.set(t.table, r)), r.push({
1408
1408
  name: e.slice(e.indexOf("\0") + 1),
1409
1409
  table: t.table,
1410
1410
  columns: n,
@@ -1413,23 +1413,23 @@ BEGIN
1413
1413
  }
1414
1414
  }
1415
1415
  for (let e of g) {
1416
- let t = x.get(e.source_table);
1417
- t || (t = [], x.set(e.source_table, t)), t.push(e);
1416
+ let t = b.get(e.source_table);
1417
+ t || (t = [], b.set(e.source_table, t)), t.push(e);
1418
1418
  }
1419
1419
  for (let e of ee) {
1420
- let t = S.get(e.table_name);
1421
- t || (t = /* @__PURE__ */ new Map(), S.set(e.table_name, t));
1420
+ let t = x.get(e.table_name);
1421
+ t || (t = /* @__PURE__ */ new Map(), x.set(e.table_name, t));
1422
1422
  let n = t.get(e.index_name);
1423
1423
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1424
1424
  }
1425
- let w = [];
1425
+ let ne = [];
1426
1426
  for (let e of c) {
1427
- let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = x.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1428
- let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Pt(t.data_type, t.udt_name), c = a ? {
1427
+ let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = te.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = b.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1428
+ let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : It(t.data_type, t.udt_name), c = a ? {
1429
1429
  table: a.target_table,
1430
1430
  column: a.target_column,
1431
- onDelete: B(a.delete_rule),
1432
- onUpdate: B(a.update_rule)
1431
+ onDelete: R(a.delete_rule),
1432
+ onUpdate: R(a.update_rule)
1433
1433
  } : void 0, l = h.get(`${e.table_name}.${t.column_name}`);
1434
1434
  return {
1435
1435
  name: t.column_name,
@@ -1441,7 +1441,7 @@ BEGIN
1441
1441
  ...c ? { references: c } : {},
1442
1442
  ...l ? { oneOf: l } : {}
1443
1443
  };
1444
- }), l = [], u = S.get(e.table_name);
1444
+ }), l = [], u = x.get(e.table_name);
1445
1445
  if (u) for (let [t, n] of u) {
1446
1446
  let r = /* @__PURE__ */ new Set(), i = [...n].filter((e) => e.column_name !== null && e.position !== null).sort((e, t) => (e.position ?? 0) - (t.position ?? 0)).filter((e) => {
1447
1447
  let t = e.position;
@@ -1457,7 +1457,7 @@ BEGIN
1457
1457
  ...a ? { expression: !0 } : {}
1458
1458
  });
1459
1459
  }
1460
- for (let t of b.get(e.table_name) ?? []) l.push(t);
1460
+ for (let t of y.get(e.table_name) ?? []) l.push(t);
1461
1461
  r.size > 0 && l.push({
1462
1462
  name: `${e.table_name}_pkey`,
1463
1463
  table: e.table_name,
@@ -1465,20 +1465,20 @@ BEGIN
1465
1465
  unique: !0
1466
1466
  });
1467
1467
  let d = Number(e.row_count ?? 0);
1468
- w.push({
1468
+ ne.push({
1469
1469
  name: e.table_name,
1470
1470
  columns: c,
1471
1471
  indexes: l,
1472
1472
  ...d > 0 ? { rowCount: d } : {}
1473
1473
  });
1474
1474
  }
1475
- return { tables: w };
1475
+ return { tables: ne };
1476
1476
  });
1477
1477
  return (t > 0 ? e.withTransaction(n) : n).pipe(d.catchAll((e) => {
1478
1478
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1479
1479
  return n.includes("statement timeout") || n.includes("57014") ? d.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : d.fail(e);
1480
1480
  }));
1481
- }, Vt = (e, t) => {
1481
+ }, Ut = (e, t) => {
1482
1482
  switch (e.toLowerCase()) {
1483
1483
  case "varchar":
1484
1484
  case "char":
@@ -1510,20 +1510,20 @@ BEGIN
1510
1510
  case "json": return "json";
1511
1511
  default: return "text";
1512
1512
  }
1513
- }, V = (e) => e.map((e) => {
1513
+ }, z = (e) => e.map((e) => {
1514
1514
  let t = e, n = {};
1515
1515
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1516
1516
  return n;
1517
- }), Ht = (e) => d.gen(function* () {
1518
- let t = V(yield* e`
1517
+ }), Wt = (e) => d.gen(function* () {
1518
+ let t = z(yield* e`
1519
1519
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1520
1520
  FROM information_schema.tables
1521
1521
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1522
- ORDER BY table_name`), n = V(yield* e`
1522
+ ORDER BY table_name`), n = z(yield* e`
1523
1523
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key
1524
1524
  FROM information_schema.columns
1525
1525
  WHERE table_schema = DATABASE()
1526
- ORDER BY table_name, ordinal_position`), r = V(yield* e`
1526
+ ORDER BY table_name, ordinal_position`), r = z(yield* e`
1527
1527
  SELECT k.table_name AS source_table,
1528
1528
  k.column_name AS source_column,
1529
1529
  k.referenced_table_name AS target_table,
@@ -1533,11 +1533,11 @@ BEGIN
1533
1533
  JOIN information_schema.referential_constraints r
1534
1534
  ON k.constraint_name = r.constraint_name
1535
1535
  AND k.table_schema = r.constraint_schema
1536
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = V(yield* e`
1536
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = z(yield* e`
1537
1537
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1538
1538
  FROM information_schema.statistics
1539
1539
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1540
- ORDER BY table_name, index_name, seq_in_index`), a = V(yield* e`
1540
+ ORDER BY table_name, index_name, seq_in_index`), a = z(yield* e`
1541
1541
  SELECT table_name, check_clause
1542
1542
  FROM information_schema.check_constraints
1543
1543
  WHERE constraint_schema = DATABASE()`.unprepared.pipe(d.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
@@ -1547,7 +1547,7 @@ BEGIN
1547
1547
  o.add(`${e.table_name}.${t[1]}`);
1548
1548
  continue;
1549
1549
  }
1550
- let n = Nt(e.check_clause);
1550
+ let n = Ft(e.check_clause);
1551
1551
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1552
1552
  }
1553
1553
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1570,11 +1570,11 @@ BEGIN
1570
1570
  let t = c.get(e.table_name) ?? [], n = l.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), d = u.get(e.table_name);
1571
1571
  if (d) for (let e of d.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1572
1572
  let p = t.map((t) => {
1573
- let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Vt(t.data_type, t.column_type), u = c ? {
1573
+ let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Ut(t.data_type, t.column_type), u = c ? {
1574
1574
  table: c.target_table,
1575
1575
  column: c.target_column,
1576
- onDelete: B(c.delete_rule),
1577
- onUpdate: B(c.update_rule)
1576
+ onDelete: R(c.delete_rule),
1577
+ onUpdate: R(c.update_rule)
1578
1578
  } : void 0, d = a.has(t.column_name) || n && t.column_name === "id", f = t.column_default === "NULL" ? null : t.column_default, p = s.get(`${e.table_name}.${t.column_name}`);
1579
1579
  return {
1580
1580
  name: t.column_name,
@@ -1611,10 +1611,10 @@ BEGIN
1611
1611
  });
1612
1612
  }
1613
1613
  return { tables: f };
1614
- }), Ut = (e) => {
1614
+ }), Gt = (e) => {
1615
1615
  let t = e.toUpperCase();
1616
1616
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1617
- }, Wt = (e) => d.gen(function* () {
1617
+ }, Kt = (e) => d.gen(function* () {
1618
1618
  let t = yield* e`
1619
1619
  SELECT name, sql FROM sqlite_master
1620
1620
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1631,11 +1631,11 @@ BEGIN
1631
1631
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1632
1632
  }
1633
1633
  let p = o.map((e) => {
1634
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Ut(e.type), a = r ? {
1634
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Gt(e.type), a = r ? {
1635
1635
  table: r.table,
1636
1636
  column: r.to,
1637
- onDelete: B(r.on_delete),
1638
- onUpdate: B(r.on_update)
1637
+ onDelete: R(r.on_delete),
1638
+ onUpdate: R(r.on_update)
1639
1639
  } : void 0, o = t.get(e.name);
1640
1640
  return {
1641
1641
  name: e.name,
@@ -1670,7 +1670,7 @@ BEGIN
1670
1670
  });
1671
1671
  }
1672
1672
  return { tables: r };
1673
- }), Gt = (e) => {
1673
+ }), qt = (e) => {
1674
1674
  switch (e.toLowerCase()) {
1675
1675
  case "int":
1676
1676
  case "smallint":
@@ -1692,7 +1692,7 @@ BEGIN
1692
1692
  case "image": return "bytes";
1693
1693
  default: return "text";
1694
1694
  }
1695
- }, H = (e) => e === !0 || e === 1, Kt = (e) => d.gen(function* () {
1695
+ }, B = (e) => e === !0 || e === 1, Jt = (e) => d.gen(function* () {
1696
1696
  let t = yield* e`
1697
1697
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
1698
1698
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -1748,16 +1748,16 @@ BEGIN
1748
1748
  let t = s.get(e) ?? [], n = c.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = new Set(n.map((e) => e.source_column)), a = l.get(e), d = [], f = /* @__PURE__ */ new Set();
1749
1749
  if (a) for (let [, e] of a) {
1750
1750
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
1751
- if (H(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1752
- else H(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1751
+ if (B(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1752
+ else B(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1753
1753
  }
1754
1754
  let p = t.map((t) => {
1755
- let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Gt(t.data_type), s = i ? {
1755
+ let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : qt(t.data_type), s = i ? {
1756
1756
  table: i.target_table,
1757
1757
  column: i.target_column,
1758
- onDelete: qt(i.delete_rule),
1759
- onUpdate: qt(i.update_rule)
1760
- } : void 0, c = t.column_default === null ? null : Jt(t.column_default), l = o.get(`${e}.${t.column_name}`);
1758
+ onDelete: Yt(i.delete_rule),
1759
+ onUpdate: Yt(i.update_rule)
1760
+ } : void 0, c = t.column_default === null ? null : Xt(t.column_default), l = o.get(`${e}.${t.column_name}`);
1761
1761
  return {
1762
1762
  name: t.column_name,
1763
1763
  type: a,
@@ -1771,11 +1771,11 @@ BEGIN
1771
1771
  }), m = [];
1772
1772
  if (a) for (let [t, n] of a) {
1773
1773
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
1774
- H(r[0].is_primary) || r.length === 1 && H(r[0].is_unique) || r.length === 1 && !H(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1774
+ B(r[0].is_primary) || r.length === 1 && B(r[0].is_unique) || r.length === 1 && !B(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1775
1775
  name: t,
1776
1776
  table: e,
1777
1777
  columns: r.map((e) => e.column_name),
1778
- unique: H(r[0].is_unique)
1778
+ unique: B(r[0].is_unique)
1779
1779
  });
1780
1780
  }
1781
1781
  d.length > 0 && m.push({
@@ -1790,37 +1790,37 @@ BEGIN
1790
1790
  });
1791
1791
  }
1792
1792
  return { tables: u };
1793
- }), qt = (e) => {
1793
+ }), Yt = (e) => {
1794
1794
  switch (e.toUpperCase().replace(/_/g, " ")) {
1795
1795
  case "CASCADE": return "cascade";
1796
1796
  case "SET NULL": return "setNull";
1797
1797
  case "SET DEFAULT": return "noAction";
1798
1798
  default: return "noAction";
1799
1799
  }
1800
- }, Jt = (e) => {
1800
+ }, Xt = (e) => {
1801
1801
  let t = e.trim();
1802
1802
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
1803
1803
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
1804
- }, Yt = (e) => e.onDialectOrElse({
1805
- mysql: () => Ht(e),
1806
- mssql: () => Kt(e),
1807
- sqlite: () => Wt(e),
1808
- orElse: () => Bt(e)
1809
- }), Xt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, Zt = (e, t) => {
1804
+ }, V = (e) => e.onDialectOrElse({
1805
+ mysql: () => Wt(e),
1806
+ mssql: () => Jt(e),
1807
+ sqlite: () => Kt(e),
1808
+ orElse: () => Ht(e)
1809
+ }), Zt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
1810
1810
  if (!e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
1811
1811
  let n = e.type === "vector" && e.vectorDim === void 0 ? "vector dimension" : e.type === "array" && e.arrayElement === void 0 ? "array element type" : e.type === "enum" && e.enumName === void 0 && e.enumValues === void 0 ? "enum name/values" : void 0;
1812
1812
  if (n !== void 0) throw Error(`migration applier: cannot render '${e.name}' (${e.type}) — the schema snapshot carries no ${n}. Rendering it as 'text' would emit DDL that applies successfully and changes nothing, so this fails instead. This is a framework bug: declaredSchema.ts must carry the parameter into the ColumnSnapshot.`);
1813
- return O(e, t);
1813
+ return E(e, t);
1814
+ }, U = (e) => {
1815
+ let t = H(e, "postgres");
1816
+ return t === void 0 ? Qt(e) : t;
1814
1817
  }, Qt = (e) => {
1815
- let t = Zt(e, "postgres");
1816
- return t === void 0 ? $t(e) : t;
1817
- }, $t = (e) => {
1818
1818
  switch (e.type) {
1819
1819
  case "id": return "text";
1820
1820
  case "text": return "text";
1821
1821
  case "integer": return "integer";
1822
1822
  case "real": return "double precision";
1823
- case "decimal": return Xt(e, "NUMERIC");
1823
+ case "decimal": return Zt(e, "NUMERIC");
1824
1824
  case "bigint": return "bigint";
1825
1825
  case "boolean": return "boolean";
1826
1826
  case "timestamp": return "timestamptz";
@@ -1834,15 +1834,15 @@ BEGIN
1834
1834
  case "interval": return "interval";
1835
1835
  case "raw": return e.rawDdl ?? "text";
1836
1836
  }
1837
- }, en = (e) => {
1838
- let t = Zt(e, "mariadb");
1837
+ }, W = (e) => {
1838
+ let t = H(e, "mariadb");
1839
1839
  if (t !== void 0) return t;
1840
1840
  switch (e.type) {
1841
1841
  case "id": return "VARCHAR(64)";
1842
1842
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
1843
1843
  case "integer": return "INT";
1844
1844
  case "real": return "DOUBLE";
1845
- case "decimal": return Xt(e, "DECIMAL");
1845
+ case "decimal": return Zt(e, "DECIMAL");
1846
1846
  case "bigint": return "BIGINT";
1847
1847
  case "boolean": return "TINYINT(1)";
1848
1848
  case "timestamp": return "DATETIME(6)";
@@ -1856,57 +1856,57 @@ BEGIN
1856
1856
  case "interval": return "BIGINT";
1857
1857
  case "raw": return e.rawDdl ?? "LONGTEXT";
1858
1858
  }
1859
- }, U = (e) => `"${e}"`, W = (e) => `\`${e.replace(/`/g, "``")}\``, tn = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, nn = (e) => `ALTER TABLE ${W(e.table)} DROP COLUMN IF EXISTS ${W(e.column)}, ALGORITHM=COPY;`, rn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, an = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${On(t)}`)};`, on = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${sn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, sn = (e, t) => {
1859
+ }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, $t = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, en = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, tn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, nn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${On(t)}`)};`, rn = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${an(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, an = (e, t) => {
1860
1860
  let n = t(e.defaultValue);
1861
1861
  if (n === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${e.column}' (${JSON.stringify(e.defaultValue)}). Emitting 'DEFAULT NULL' would apply cleanly and drop the default silently, so this fails instead. This is a framework bug — report the column type + default.`);
1862
1862
  return n;
1863
- }, G = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], cn = (e, t, n) => {
1864
- let r = G(e, t, n);
1865
- return r ? et(n, r) : void 0;
1866
- }, ln = (e, t, n) => {
1867
- let r = n ?? e.nullable, i = _e(e, "mariadb");
1863
+ }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], on = (e, t, n) => {
1864
+ let r = q(e, t, n);
1865
+ return r ? nt(n, r) : void 0;
1866
+ }, sn = (e, t, n) => {
1867
+ let r = n ?? e.nullable, i = ye(e, "mariadb");
1868
1868
  return [
1869
- W(t),
1870
- O(e, "mariadb"),
1869
+ K(t),
1870
+ E(e, "mariadb"),
1871
1871
  r ? null : "NOT NULL",
1872
1872
  i
1873
1873
  ].filter(Boolean).join(" ");
1874
- }, un = (e, t) => e == null ? null : Array.isArray(e) ? dn(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" ? k(e, "mysql") : null, dn = (e, t, n) => ve(e, t ?? { type: "json" }, n), fn = (e, t) => e == null ? null : Array.isArray(e) ? dn(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" ? k(e, "postgres") : null, K = (e, t) => {
1874
+ }, cn = (e, t) => e == null ? null : Array.isArray(e) ? ln(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, ln = (e, t, n) => be(e, t ?? { type: "json" }, n), un = (e, t) => e == null ? null : Array.isArray(e) ? ln(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "postgres") : null, J = (e, t) => {
1875
1875
  if (!e.generatedAs) return null;
1876
1876
  let { expr: n, stored: r } = e.generatedAs;
1877
1877
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
1878
- }, pn = (e) => {
1879
- if (e.type === "id" && e.idScheme?.kind === "numeric") return A(e.name, "postgres");
1880
- let t = K(e, "postgres");
1881
- if (t) return `${U(e.name)} ${Qt(e)} ${t}`;
1882
- let n = [U(e.name), Qt(e)];
1878
+ }, dn = (e) => {
1879
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "postgres");
1880
+ let t = J(e, "postgres");
1881
+ if (t) return `${G(e.name)} ${U(e)} ${t}`;
1882
+ let n = [G(e.name), U(e)];
1883
1883
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
1884
- let t = fn(e.defaultValue, e);
1884
+ let t = un(e.defaultValue, e);
1885
1885
  t && n.push(t);
1886
1886
  }
1887
- return e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1887
+ return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1888
1888
  cascade: "CASCADE",
1889
1889
  restrict: "RESTRICT",
1890
1890
  setNull: "SET NULL",
1891
1891
  noAction: "NO ACTION"
1892
1892
  }[e.references.onDelete]}`)), n.join(" ");
1893
- }, q = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", mn = (e) => {
1894
- let t = e.columns.map((e) => ` ${pn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${q(e, U)}\n)`];
1895
- 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(Nn).join(", ")})`);
1893
+ }, fn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", pn = (e) => {
1894
+ let t = e.columns.map((e) => ` ${dn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${fn(e, G)}\n)`];
1895
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(Nn).join(", ")})`);
1896
1896
  return n;
1897
- }, hn = 191, J = (e) => {
1898
- let t = en(e).toUpperCase();
1897
+ }, mn = 191, hn = (e) => {
1898
+ let t = W(e).toUpperCase();
1899
1899
  return t.endsWith("TEXT") || t.endsWith("BLOB");
1900
1900
  }, gn = (e) => {
1901
- if (e.type === "id" && e.idScheme?.kind === "numeric") return A(e.name, "mariadb");
1902
- let t = K(e, "mariadb");
1903
- if (t) return `${W(e.name)} ${en(e)} ${t}`;
1904
- let n = [W(e.name), en(e)];
1905
- 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) {
1906
- let t = un(e.defaultValue, e);
1901
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mariadb");
1902
+ let t = J(e, "mariadb");
1903
+ if (t) return `${K(e.name)} ${W(e)} ${t}`;
1904
+ let n = [K(e.name), W(e)];
1905
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !hn(e) && n.push("UNIQUE"), e.hasDefault) {
1906
+ let t = cn(e.defaultValue, e);
1907
1907
  t && n.push(t);
1908
1908
  }
1909
- return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1909
+ return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
1910
1910
  cascade: "CASCADE",
1911
1911
  restrict: "RESTRICT",
1912
1912
  setNull: "SET NULL",
@@ -1915,10 +1915,10 @@ BEGIN
1915
1915
  }, _n = (e) => {
1916
1916
  let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
1917
1917
  let n = t.get(e);
1918
- return n && J(n) ? `${W(e)}(${hn})` : W(e);
1919
- }, r = e.columns.map((e) => ` ${gn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${r}${q(e, n)}\n)`];
1920
- 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)})`);
1921
- 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(", ")})`);
1918
+ return n && hn(n) ? `${K(e)}(${mn})` : K(e);
1919
+ }, r = e.columns.map((e) => ` ${gn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${fn(e, n)}\n)`];
1920
+ for (let t of e.columns) t.unique && t.type !== "id" && hn(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
1921
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(n).join(", ")})`);
1922
1922
  return i;
1923
1923
  }, vn = {
1924
1924
  cascade: "CASCADE",
@@ -1931,7 +1931,7 @@ BEGIN
1931
1931
  setNull: "SET NULL",
1932
1932
  noAction: "NO ACTION"
1933
1933
  }, bn = (e) => {
1934
- let t = Zt(e, "sqlite");
1934
+ let t = H(e, "sqlite");
1935
1935
  if (t !== void 0) return t;
1936
1936
  switch (e.type) {
1937
1937
  case "integer":
@@ -1942,28 +1942,28 @@ BEGIN
1942
1942
  case "bytes": return "BLOB";
1943
1943
  default: return "TEXT";
1944
1944
  }
1945
- }, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? k(e, "sqlite") : null, xn = (e) => {
1946
- if (e.type === "id" && e.idScheme?.kind === "numeric") return A(e.name, "sqlite");
1947
- let t = K(e, "sqlite");
1948
- if (t) return `${U(e.name)} ${bn(e)} ${t}`;
1949
- let n = [U(e.name), bn(e)];
1945
+ }, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "sqlite") : null, xn = (e) => {
1946
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "sqlite");
1947
+ let t = J(e, "sqlite");
1948
+ if (t) return `${G(e.name)} ${bn(e)} ${t}`;
1949
+ let n = [G(e.name), bn(e)];
1950
1950
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
1951
1951
  let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
1952
1952
  t && n.push(t);
1953
1953
  }
1954
- if (e.references && (n.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${vn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
1954
+ if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${vn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
1955
1955
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
1956
- n.push(`CHECK (${U(e.name)} IN (${t}))`);
1956
+ n.push(`CHECK (${G(e.name)} IN (${t}))`);
1957
1957
  }
1958
1958
  return n.join(" ");
1959
1959
  }, Sn = (e) => {
1960
- let t = e.columns.map((e) => ` ${xn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${q(e, U)}\n)`];
1961
- 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(", ")})`);
1960
+ let t = e.columns.map((e) => ` ${xn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${fn(e, G)}\n)`];
1961
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
1962
1962
  return n;
1963
1963
  }, X = (e, t) => {
1964
1964
  let n = t.find((t) => t.tableName === e);
1965
1965
  if (!n) return [];
1966
- let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => U(e.name)).join(", "), o = [
1966
+ let r = N([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
1967
1967
  ...Sn({
1968
1968
  kind: "create-table",
1969
1969
  table: i,
@@ -1971,15 +1971,15 @@ BEGIN
1971
1971
  indexes: [],
1972
1972
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
1973
1973
  }),
1974
- `INSERT INTO ${U(i)} (${a}) SELECT ${a} FROM ${U(e)}`,
1975
- `DROP TABLE ${U(e)}`,
1976
- `ALTER TABLE ${U(i)} RENAME TO ${U(e)}`
1974
+ `INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
1975
+ `DROP TABLE ${G(e)}`,
1976
+ `ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
1977
1977
  ];
1978
- 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(", ")})`);
1978
+ for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
1979
1979
  return o;
1980
1980
  }, Cn = (e, t, n, r) => {
1981
1981
  let i = r ?? e.nullable;
1982
- return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${O(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
1982
+ return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${E(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
1983
1983
  }, wn = (e) => {
1984
1984
  let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Z(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
1985
1985
  if (!e.hasDefault) return t;
@@ -1988,14 +1988,14 @@ BEGIN
1988
1988
  let r = n.replace(/^DEFAULT\s+/i, "");
1989
1989
  return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
1990
1990
  }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, Tn = (e) => {
1991
- let t = Zt(e, "mssql");
1991
+ let t = H(e, "mssql");
1992
1992
  if (t !== void 0) return t;
1993
1993
  switch (e.type) {
1994
1994
  case "id":
1995
1995
  case "reference": return "NVARCHAR(64)";
1996
1996
  case "integer": return "INT";
1997
1997
  case "real": return "FLOAT";
1998
- case "decimal": return Xt(e, "DECIMAL");
1998
+ case "decimal": return Zt(e, "DECIMAL");
1999
1999
  case "bigint": return "BIGINT";
2000
2000
  case "boolean": return "BIT";
2001
2001
  case "timestamp": return "DATETIME2(6)";
@@ -2004,8 +2004,8 @@ BEGIN
2004
2004
  default: return "NVARCHAR(MAX)";
2005
2005
  }
2006
2006
  }, En = (e, t) => {
2007
- if (e.type === "id" && e.idScheme?.kind === "numeric") return A(e.name, "mssql");
2008
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Tn(e), r = K(e, "mssql");
2007
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mssql");
2008
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Tn(e), r = J(e, "mssql");
2009
2009
  if (r) return `${Z(e.name)} ${r}`;
2010
2010
  let i = [Z(e.name), n];
2011
2011
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
@@ -2014,7 +2014,7 @@ BEGIN
2014
2014
  }
2015
2015
  return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${yn[e.references.onDelete]}`)), i.join(" ");
2016
2016
  }, Dn = (e) => {
2017
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${En(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)}')`];
2017
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${En(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${fn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2018
2018
  for (let n of e.indexes) {
2019
2019
  if (n.name === `${e.table}_pkey`) continue;
2020
2020
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
@@ -2025,9 +2025,9 @@ BEGIN
2025
2025
  let r = `${e.table}${On(t)}`;
2026
2026
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2027
2027
  }, jn = (e, t, n) => {
2028
- let r = G(e, t, n);
2029
- return r ? J({ type: r.type }) : !1;
2030
- }, Mn = (e, t, n) => jn(e, t, n) ? `${W(n)}(${hn})` : W(n), Nn = (e) => e.startsWith("(") ? e : U(e), Pn = (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(Nn).join(", ")});`, Fn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map((n) => Mn(t, e.table, n)).join(", ")});`, In = (e) => `DROP INDEX IF EXISTS ${U(e.index)};`, Ln = (e) => `DROP INDEX ${W(e.index)} ON ${W(e.table)};`, Rn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, zn = (e) => {
2028
+ let r = q(e, t, n);
2029
+ return r ? hn({ type: r.type }) : !1;
2030
+ }, Mn = (e, t, n) => jn(e, t, n) ? `${K(n)}(${mn})` : K(n), Nn = (e) => e.startsWith("(") ? e : G(e), Pn = (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(Nn).join(", ")});`, Fn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Mn(t, e.table, n)).join(", ")});`, In = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Ln = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, Rn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, zn = (e) => {
2031
2031
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Z(e.index.name)} ON ${Z(e.table)} (${e.index.columns.map(Z).join(", ")})`;
2032
2032
  return `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(e.index.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(n)}');`;
2033
2033
  }, Bn = (e, t, n) => {
@@ -2039,13 +2039,13 @@ BEGIN
2039
2039
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2040
2040
  }
2041
2041
  return i;
2042
- }, Vn = (e) => `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(`${e.table}_${e.column}_key`)} UNIQUE (${U(e.column)});`, Hn = (e, t) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${Mn(t, e.table, e.column)});`, Un = (e) => {
2043
- let t = e.fields.map((e) => U(e)).join(", ");
2044
- return `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(e.name)} UNIQUE (${t});`;
2042
+ }, Vn = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, Hn = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Mn(t, e.table, e.column)});`, Un = (e) => {
2043
+ let t = e.fields.map((e) => G(e)).join(", ");
2044
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2045
2045
  }, Wn = (e, t) => {
2046
2046
  let n = e.fields.map((n) => Mn(t, e.table, n)).join(", ");
2047
- return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${n});`;
2048
- }, Gn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(e.name)};`, Kn = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(e.name)};`, qn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_key`)};`, Jn = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(`${e.table}_${e.column}_key`)};`, Yn = (e, t) => {
2047
+ return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2048
+ }, Gn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, Kn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, qn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, Jn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, Yn = (e, t) => {
2049
2049
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2050
2050
  if (e.orphanPolicy) {
2051
2051
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2063,11 +2063,11 @@ BEGIN
2063
2063
  setNull: "SET NULL",
2064
2064
  noAction: "NO ACTION"
2065
2065
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2066
- }, Xn = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_fkey`)};`, Zn = (e) => `ALTER TABLE ${W(e.table)} DROP FOREIGN KEY ${W(`${e.table}_${e.column}_fkey`)};`, Qn = (e, t) => {
2066
+ }, Xn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, Zn = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, Qn = (e, t) => {
2067
2067
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2068
2068
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2069
- }, $n = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_check`)};`, er = (e) => `ALTER TABLE ${W(e.table)} DROP CHECK ${W(`${e.table}_${e.column}_check`)};`, tr = (e, t, n, r) => {
2070
- let i = e.column, a = r === "mariadb", o = a ? W : r === "mssql" ? Z : U, s = a ? en(i) : r === "mssql" ? Tn(i) : r === "sqlite" ? bn(i) : Qt(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? un(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : fn(e, i), u = K(i, r);
2069
+ }, $n = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, er = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, tr = (e, t, n, r) => {
2070
+ let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? Tn(i) : r === "sqlite" ? bn(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? cn(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : un(e, i), u = J(i, r);
2071
2071
  if (u) {
2072
2072
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2073
2073
  return {
@@ -2117,7 +2117,10 @@ BEGIN
2117
2117
  };
2118
2118
  }, Q = (e, t, n) => e.unsafe(t).pipe(d.tapError((e) => d.sync(() => {
2119
2119
  process.stderr.write(_(`applier: statement failed (op=${n})`, t, e, 400));
2120
- })), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), rr = (e, t, n) => d.gen(function* () {
2120
+ })), d.mapError((e) => {
2121
+ let r = _(`applier: statement failed (op=${n})`, t, e, 400).trim();
2122
+ return Object.assign(e, { message: r });
2123
+ }), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), rr = (e, t, n) => d.gen(function* () {
2121
2124
  let r = process.hrtime.bigint(), i = nr(n.declared), a = t.op;
2122
2125
  switch (a.kind) {
2123
2126
  case "create-table": {
@@ -2125,7 +2128,7 @@ BEGIN
2125
2128
  mysql: () => d.succeed(_n(a)),
2126
2129
  mssql: () => d.succeed(Dn(a)),
2127
2130
  sqlite: () => d.succeed(Sn(a)),
2128
- orElse: () => d.succeed(mn(a))
2131
+ orElse: () => d.succeed(pn(a))
2129
2132
  });
2130
2133
  for (let n of t) yield* Q(e, n, a.kind);
2131
2134
  break;
@@ -2133,24 +2136,24 @@ BEGIN
2133
2136
  case "drop-table": {
2134
2137
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? An(a, n, e) : kn(a, e);
2135
2138
  yield* e.onDialectOrElse({
2136
- mysql: () => Q(e, r(W), a.kind),
2137
- orElse: () => Q(e, r(U), a.kind)
2139
+ mysql: () => Q(e, r(K), a.kind),
2140
+ orElse: () => Q(e, r(G), a.kind)
2138
2141
  });
2139
2142
  break;
2140
2143
  }
2141
2144
  case "drop-column": {
2142
2145
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2143
2146
  yield* e.onDialectOrElse({
2144
- mysql: () => Q(e, t ? an(a, n, W) : nn(a), a.kind),
2145
- orElse: () => Q(e, t ? an(a, n, U) : tn(a, U), a.kind)
2147
+ mysql: () => Q(e, t ? nn(a, n, K) : en(a), a.kind),
2148
+ orElse: () => Q(e, t ? nn(a, n, G) : $t(a, G), a.kind)
2146
2149
  });
2147
2150
  break;
2148
2151
  }
2149
2152
  case "rename-column":
2150
2153
  yield* e.onDialectOrElse({
2151
- mysql: () => Q(e, rn(a, W), a.kind),
2154
+ mysql: () => Q(e, tn(a, K), a.kind),
2152
2155
  mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
2153
- orElse: () => Q(e, rn(a, U), a.kind)
2156
+ orElse: () => Q(e, tn(a, G), a.kind)
2154
2157
  });
2155
2158
  break;
2156
2159
  case "add-index":
@@ -2199,9 +2202,9 @@ BEGIN
2199
2202
  break;
2200
2203
  case "add-foreign-key":
2201
2204
  yield* e.onDialectOrElse({
2202
- mysql: () => $(e, Yn(a, W), a.kind),
2205
+ mysql: () => $(e, Yn(a, K), a.kind),
2203
2206
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2204
- orElse: () => $(e, Yn(a, U), a.kind)
2207
+ orElse: () => $(e, Yn(a, G), a.kind)
2205
2208
  });
2206
2209
  break;
2207
2210
  case "add-column": {
@@ -2250,41 +2253,41 @@ BEGIN
2250
2253
  case "alter-column-nullability":
2251
2254
  yield* e.onDialectOrElse({
2252
2255
  mysql: () => {
2253
- let t = G(n.declared, a.table, a.column);
2254
- return t ? Q(e, `ALTER TABLE ${W(a.table)} MODIFY COLUMN ${ln(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.`));
2256
+ let t = q(n.declared, a.table, a.column);
2257
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${sn(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.`));
2255
2258
  },
2256
2259
  mssql: () => {
2257
- let t = G(n.declared, a.table, a.column);
2260
+ let t = q(n.declared, a.table, a.column);
2258
2261
  return t ? Q(e, Cn(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}'.`));
2259
2262
  },
2260
2263
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2261
- orElse: () => Q(e, `ALTER TABLE ${U(a.table)} ALTER COLUMN ${U(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2264
+ orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2262
2265
  });
2263
2266
  break;
2264
2267
  case "alter-column-default": {
2265
- let t = cn(n.declared, a.table, a.column);
2268
+ let t = on(n.declared, a.table, a.column);
2266
2269
  yield* e.onDialectOrElse({
2267
- mysql: () => Q(e, on(a, W, (e) => un(e, t)), a.kind),
2270
+ mysql: () => Q(e, rn(a, K, (e) => cn(e, t)), a.kind),
2268
2271
  mssql: () => Q(e, wn(a), a.kind),
2269
2272
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2270
- orElse: () => Q(e, on(a, U, (e) => fn(e, t)), a.kind)
2273
+ orElse: () => Q(e, rn(a, G, (e) => un(e, t)), a.kind)
2271
2274
  });
2272
2275
  break;
2273
2276
  }
2274
2277
  case "alter-column-type": {
2275
- let r = Qt(cn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2278
+ let r = U(on(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2276
2279
  if (t.classification !== "online-required") {
2277
2280
  yield* e.onDialectOrElse({
2278
2281
  mysql: () => {
2279
- let t = G(n.declared, a.table, a.column);
2280
- return t ? Q(e, `ALTER TABLE ${W(a.table)} MODIFY COLUMN ${ln(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.`));
2282
+ let t = q(n.declared, a.table, a.column);
2283
+ return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${sn(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.`));
2281
2284
  },
2282
2285
  mssql: () => {
2283
- let t = G(n.declared, a.table, a.column);
2286
+ let t = q(n.declared, a.table, a.column);
2284
2287
  return t ? Q(e, Cn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2285
2288
  },
2286
2289
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2287
- orElse: () => Q(e, `ALTER TABLE ${U(a.table)} ALTER COLUMN ${U(a.column)} TYPE ${r}${i};`, a.kind)
2290
+ orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
2288
2291
  });
2289
2292
  break;
2290
2293
  }
@@ -2293,14 +2296,14 @@ BEGIN
2293
2296
  orElse: () => d.void
2294
2297
  });
2295
2298
  let o = `${a.column}__shadow`, s = `${a.column}__old`;
2296
- yield* e.unsafe(`ALTER TABLE ${U(a.table)} ADD COLUMN ${U(o)} ${r}`);
2297
- let c = a.using ?? U(a.column), l;
2299
+ yield* e.unsafe(`ALTER TABLE ${G(a.table)} ADD COLUMN ${G(o)} ${r}`);
2300
+ let c = a.using ?? G(a.column), l;
2298
2301
  for (;;) {
2299
2302
  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`;
2300
2303
  if (t.length === 0) break;
2301
- 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;
2304
+ 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;
2302
2305
  }
2303
- 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)}`);
2306
+ 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)}`);
2304
2307
  break;
2305
2308
  }
2306
2309
  case "drop-foreign-key":
@@ -2312,9 +2315,9 @@ BEGIN
2312
2315
  break;
2313
2316
  case "add-check":
2314
2317
  yield* e.onDialectOrElse({
2315
- mysql: () => Q(e, Qn(a, W), a.kind),
2318
+ mysql: () => Q(e, Qn(a, K), a.kind),
2316
2319
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2317
- orElse: () => Q(e, Qn(a, U), a.kind)
2320
+ orElse: () => Q(e, Qn(a, G), a.kind)
2318
2321
  });
2319
2322
  break;
2320
2323
  case "drop-check":
@@ -2333,7 +2336,7 @@ BEGIN
2333
2336
  }), ir = (e, t, n) => d.gen(function* () {
2334
2337
  let r = t.operations.filter((e) => e.blocked);
2335
2338
  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.`));
2336
- yield* T(e);
2339
+ yield* C(e);
2337
2340
  let i = Date.now(), a = [];
2338
2341
  try {
2339
2342
  let r = yield* e.onDialectOrElse({
@@ -2347,7 +2350,7 @@ BEGIN
2347
2350
  })));
2348
2351
  for (let t of o) a.push(yield* rr(e, t, n));
2349
2352
  } finally {
2350
- yield* E(e).pipe(d.orDie);
2353
+ yield* w(e).pipe(d.orDie);
2351
2354
  }
2352
2355
  let o = yield* n.replan(e);
2353
2356
  if (o.operations.length > 0) {
@@ -2391,7 +2394,7 @@ BEGIN
2391
2394
  sqlite: () => "sqlite",
2392
2395
  orElse: () => "sqlite"
2393
2396
  }), cr = (e, t) => d.gen(function* () {
2394
- let n = N(F(t, sr(e))), r = yield* or(e);
2397
+ let n = j(N(t, sr(e))), r = yield* or(e);
2395
2398
  return r === n ? {
2396
2399
  kind: "up-to-date",
2397
2400
  fingerprint: n
@@ -2416,43 +2419,56 @@ BEGIN
2416
2419
  }), fr = () => {
2417
2420
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2418
2421
  return e.length > 0 ? { ignoreTables: e } : {};
2419
- }, pr = (e) => ({
2422
+ }, pr = (e) => {
2423
+ if (e === void 0) return;
2424
+ let t = e.trim();
2425
+ if (t === "") return;
2426
+ if (t === "1" || t.toLowerCase() === "true") return { kind: "all" };
2427
+ let n = t.split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2428
+ return n.length > 0 ? {
2429
+ kind: "tables",
2430
+ tables: new Set(n)
2431
+ } : void 0;
2432
+ }, mr = (e) => typeof e.table == "string" ? e.table : void 0, hr = (e, t = { kind: "all" }) => ({
2420
2433
  ...e,
2421
2434
  operations: e.operations.map((e) => {
2422
2435
  if (!e.blocked || e.classification !== "lossy") return e;
2423
- let { blocked: t, ...n } = e;
2424
- return n;
2436
+ if (t?.kind === "tables") {
2437
+ let n = mr(e.op);
2438
+ if (n === void 0 || !t.tables.has(n)) return e;
2439
+ }
2440
+ let { blocked: n, ...r } = e;
2441
+ return r;
2425
2442
  })
2426
- }), mr = (e, t, n) => t === "postgres" ? at(e, n).pipe(d.flatMap((e) => {
2427
- let t = ot(e);
2443
+ }), gr = (e, t, n) => t === "postgres" ? st(e, n).pipe(d.flatMap((e) => {
2444
+ let t = ct(e);
2428
2445
  return t === void 0 ? d.void : d.logWarning(`auto-migrate: ${t}`).pipe(d.annotateLogs({ scope: "voltro:migrate" }));
2429
- }), d.catchAll(() => d.void)) : d.void, hr = (e, t, n) => d.gen(function* () {
2430
- let r = sr(e), i = t.filter((e) => !I(e.tableName));
2446
+ }), d.catchAll(() => d.void)) : d.void, _r = (e, t, n) => d.gen(function* () {
2447
+ let r = sr(e), i = t.filter((e) => !P(e.tableName));
2431
2448
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2432
- let t = N(F(i, r));
2433
- if ((yield* or(e)) === t) return yield* mr(e, r, i), {
2449
+ let t = j(N(i, r));
2450
+ if ((yield* or(e)) === t) return yield* gr(e, r, i), {
2434
2451
  kind: "up-to-date",
2435
2452
  fingerprint: t
2436
2453
  };
2437
2454
  }
2438
- let a = yield* Yt(e), o = yield* dr(e, a.tables);
2455
+ let a = yield* V(e), o = yield* dr(e, a.tables);
2439
2456
  o.length > 0 && (yield* d.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(d.annotateLogs({
2440
2457
  scope: "voltro:migrate",
2441
2458
  count: o.length
2442
- })), a = yield* Yt(e));
2443
- let s = Mt({
2459
+ })), a = yield* V(e));
2460
+ let s = Pt({
2444
2461
  declared: i,
2445
- live: { tables: a.tables.filter((e) => !I(e.name)) },
2462
+ live: { tables: a.tables.filter((e) => !P(e.name)) },
2446
2463
  dialect: r,
2447
2464
  ...fr()
2448
2465
  });
2449
2466
  if (s.summary.blocked > 0) {
2450
- let e = s.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy");
2451
- if (process.env.VOLTRO_DESTRUCTIVE_OK !== "1" || !e) return {
2467
+ let e = s.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = pr(process.env.VOLTRO_DESTRUCTIVE_OK);
2468
+ if (t === void 0 || !e || (s = hr(s, t), s.operations.some((e) => e.blocked))) return {
2452
2469
  kind: "refused-blocked",
2453
2470
  plan: s
2454
2471
  };
2455
- s = pr(s);
2456
2472
  }
2457
2473
  return s.operations.length === 0 ? {
2458
2474
  kind: "up-to-date",
@@ -2465,10 +2481,10 @@ BEGIN
2465
2481
  environment: n.environment === "prod" ? "dev" : n.environment,
2466
2482
  source: "auto-diff",
2467
2483
  replan: (e) => d.gen(function* () {
2468
- let t = yield* Yt(e);
2469
- return Mt({
2484
+ let t = yield* V(e);
2485
+ return Pt({
2470
2486
  declared: i,
2471
- live: { tables: t.tables.filter((e) => !I(e.name)) },
2487
+ live: { tables: t.tables.filter((e) => !P(e.name)) },
2472
2488
  dialect: r,
2473
2489
  ...fr()
2474
2490
  });
@@ -2476,24 +2492,37 @@ BEGIN
2476
2492
  }),
2477
2493
  plan: s
2478
2494
  };
2479
- }), gr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2495
+ }), vr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2480
2496
  kind: "skipped",
2481
2497
  reason: "VOLTRO_AUTO_MIGRATE=0"
2482
- }) : n.environment === "prod" ? cr(e, t) : hr(e, t, n), _r = (e, t) => {
2498
+ }) : n.environment === "prod" ? cr(e, t) : _r(e, t, n), yr = (e, t) => {
2483
2499
  switch (e.kind) {
2484
2500
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2485
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${P(e.fingerprint)})`;
2501
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${M(e.fingerprint)})`;
2486
2502
  case "applied": {
2487
2503
  let t = e.plan.summary;
2488
- return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${P(e.applied.fingerprint)}`;
2504
+ 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)}`;
2489
2505
  }
2490
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${P(e.expected)}` + (e.actual ? ` live=${P(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2506
+ 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.";
2491
2507
  case "refused-blocked": {
2492
- 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` + ar(e.plan), s = [""];
2493
- 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");
2508
+ let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + ar(e.plan), c = [""];
2509
+ if (n > 0 && c.push(`${n} table(s) exist in the live DB but aren't in your declared schema.`, "This is usually one of three things:", " (a) You're iterating on the schema — the table file got renamed, moved, or temporarily commented out.", " → Restore the declaration. Your data stays intact.", " (b) You want to KEEP the table but NOT manage it with Voltro (a leftover from another tool —", " a Strapi/Rails/legacy migration artifact, or an externally-owned table).", ` → Set \`VOLTRO_DB_IGNORE_TABLES=${r.join(",")}\` (comma-separated).`, " The planner excludes those tables from the diff entirely — it never drops them, and they", " stop blocking your OTHER (additive) changes. This is the fix when a leftover freezes your schema.", " (c) You actually want to drop the table.", `Set \`VOLTRO_DESTRUCTIVE_OK=${r.join(",")}\` for ONE run — it acknowledges`, " the data loss for THOSE tables only; every other lossy op in this plan stays blocked.", " (`VOLTRO_DESTRUCTIVE_OK=1` acknowledges all of them, which is rarely what you mean.)", " There is deliberately no `dropped()` marker for a TABLE, unlike for a column: a", " dropped column leaves a slot worth documenting in the declaration, a dropped table", " leaves nothing the marker would be a dead entry you must remember to delete.", " Soft-drop: set `VOLTRO_SOFT_DROP=1` alongside DESTRUCTIVE_OK to RENAME instead of DROP", " (data survives as `<name>__dropped_<ts>` for ~7d; restorable via `voltro db restore-snapshot`)."), i > 0 && c.push(`${i} required column(s) need a backfill strategy before adding to a populated table.`, " → Annotate the column: `.backfill(sql`<expr>`)` or `.backfill(row => <fn>)` or `.default(<value>)`.", " Existing rows get the backfill value; the column then lands as NOT NULL."), a > 0) {
2510
+ let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2511
+ for (let r of e.plan.operations) {
2512
+ let e = "table" in r.op ? r.op.table : void 0;
2513
+ if (e === void 0) continue;
2514
+ let i = "column" in r.op ? String(r.op.column) : void 0;
2515
+ if (i === void 0) continue;
2516
+ let a = r.op.kind === "drop-column" ? t : r.op.kind === "add-column" ? n : void 0;
2517
+ a !== void 0 && a.set(e, [...a.get(e) ?? [], i]);
2518
+ }
2519
+ let r = [...t.entries()].filter(([e]) => (n.get(e)?.length ?? 0) > 0).map(([e, t]) => `${e}: ${t.join(", ")} gone, ${n.get(e).join(", ")} new`);
2520
+ c.push(`${a} column(s) are missing from your declared schema.`), r.length > 0 && c.push(" → DID YOU RENAME ONE? This plan drops AND adds columns on the same table:", ...r.map((e) => ` ${e}`), " If so, add `.renamedFrom('<oldName>')` to the NEW column — the planner then emits a", " RENAME and the data moves with it. Dropping and re-adding loses every value."), c.push(" → If intentional: give the field the `dropped()` marker as its VALUE —", " `<column>: dropped()` (import it from `@voltro/database`). It is not a method", " chained onto the column; the slot stays, documenting the hole.", " → If a typo: restore the field. Data survives until you drop it.");
2521
+ }
2522
+ return o > 0 && c.push(`${o} column(s) look like renames (one column gone + a new one of same shape appeared).`, " → On the NEW column add `.renamedFrom('<oldName>')` so the planner emits RENAME instead of DROP+ADD."), c.push("", "See `voltro db plan` for the full machine-readable diff."), s + "\n" + c.join("\n");
2494
2523
  }
2495
2524
  }
2496
- }, vr = /* @__PURE__ */ new Set([
2525
+ }, br = /* @__PURE__ */ new Set([
2497
2526
  "node_modules",
2498
2527
  "dist",
2499
2528
  "build",
@@ -2502,11 +2531,11 @@ BEGIN
2502
2531
  ".next",
2503
2532
  ".git",
2504
2533
  ".framework"
2505
- ]), yr = async (e) => {
2534
+ ]), xr = async (e) => {
2506
2535
  let t = [], n = async (e) => {
2507
2536
  let r = await h.readdir(e, { withFileTypes: !0 }).catch(() => []);
2508
2537
  for (let i of r) {
2509
- if (vr.has(i.name)) continue;
2538
+ if (br.has(i.name)) continue;
2510
2539
  let r = g(e, i.name);
2511
2540
  i.isDirectory() ? await n(r) : i.isFile() && l.test(i.name) && t.push(r);
2512
2541
  }
@@ -2515,7 +2544,7 @@ BEGIN
2515
2544
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
2516
2545
  return n.localeCompare(r);
2517
2546
  });
2518
- }, br = async (e) => {
2547
+ }, Sr = async (e) => {
2519
2548
  let t = [];
2520
2549
  for (let n of e) {
2521
2550
  let e = (await import(ee(n).href)).default;
@@ -2529,11 +2558,11 @@ BEGIN
2529
2558
  });
2530
2559
  }
2531
2560
  return t;
2532
- }, xr = (e) => e`
2561
+ }, Cr = (e) => e`
2533
2562
  SELECT ${e("id")}
2534
2563
  FROM ${e("_voltro_migration_plans")}
2535
2564
  WHERE ${e("source")} = 'file'
2536
- `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), Sr = (e, t, n, r) => d.gen(function* () {
2565
+ `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), wr = (e, t, n, r) => d.gen(function* () {
2537
2566
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
2538
2567
  sql: e,
2539
2568
  log: {
@@ -2566,9 +2595,9 @@ BEGIN
2566
2595
  ${r}, ${n}, ${"file"},
2567
2596
  ${c}, ${a}, ${t.migration.description})
2568
2597
  `, { durationMs: c };
2569
- }), Cr = (e, t) => d.gen(function* () {
2598
+ }), Tr = (e, t) => d.gen(function* () {
2570
2599
  let n = yield* d.tryPromise({
2571
- try: () => yr(g(t, "migrations")),
2600
+ try: () => xr(g(t, "migrations")),
2572
2601
  catch: (e) => e
2573
2602
  });
2574
2603
  if (n.length === 0) return {
@@ -2576,25 +2605,25 @@ BEGIN
2576
2605
  skipped: []
2577
2606
  };
2578
2607
  let r = yield* d.tryPromise({
2579
- try: () => br(n),
2608
+ try: () => Sr(n),
2580
2609
  catch: (e) => e
2581
2610
  });
2582
2611
  if (r.length === 0) return {
2583
2612
  pending: [],
2584
2613
  skipped: []
2585
2614
  };
2586
- let i = new Set(yield* xr(e));
2615
+ let i = new Set(yield* Cr(e));
2587
2616
  return {
2588
2617
  pending: r.filter((e) => !i.has(e.migration.id)),
2589
2618
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
2590
2619
  };
2591
- }), wr = (e, t) => Cr(e, t).pipe(d.map((e) => e.pending.map((e) => e.migration.id))), Tr = (e, t) => d.gen(function* () {
2592
- let { pending: n, skipped: r } = yield* Cr(e, t.projectRoot);
2620
+ }), Er = (e, t) => Tr(e, t).pipe(d.map((e) => e.pending.map((e) => e.migration.id))), Dr = (e, t) => d.gen(function* () {
2621
+ let { pending: n, skipped: r } = yield* Tr(e, t.projectRoot);
2593
2622
  if (n.length === 0) return {
2594
2623
  applied: [],
2595
2624
  skipped: r
2596
2625
  };
2597
- yield* T(e);
2626
+ yield* C(e);
2598
2627
  let i = [];
2599
2628
  try {
2600
2629
  for (let r of n) {
@@ -2603,7 +2632,7 @@ BEGIN
2603
2632
  id: r.migration.id,
2604
2633
  file: r.file
2605
2634
  }));
2606
- let { durationMs: n } = yield* Sr(e, r, t.env, t.appliedBy);
2635
+ let { durationMs: n } = yield* wr(e, r, t.env, t.appliedBy);
2607
2636
  i.push({
2608
2637
  id: r.migration.id,
2609
2638
  durationMs: n
@@ -2614,28 +2643,28 @@ BEGIN
2614
2643
  }));
2615
2644
  }
2616
2645
  } finally {
2617
- yield* E(e).pipe(d.orDie);
2646
+ yield* w(e).pipe(d.orDie);
2618
2647
  }
2619
2648
  return {
2620
2649
  applied: i,
2621
2650
  skipped: r
2622
2651
  };
2623
- }), Er = (e, t) => e`
2652
+ }), Or = (e, t) => e`
2624
2653
  SELECT ${e("id")}
2625
2654
  FROM ${e("_voltro_migration_plans")}
2626
2655
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
2627
2656
  LIMIT 1
2628
- `, Dr = (e, t) => d.gen(function* () {
2629
- if (!(yield* Er(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2657
+ `, kr = (e, t) => d.gen(function* () {
2658
+ if (!(yield* Or(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2630
2659
  let n = yield* d.tryPromise({
2631
- try: () => yr(g(t.projectRoot, "migrations")),
2660
+ try: () => xr(g(t.projectRoot, "migrations")),
2632
2661
  catch: (e) => e
2633
2662
  }), r = (yield* d.tryPromise({
2634
- try: () => br(n),
2663
+ try: () => Sr(n),
2635
2664
  catch: (e) => e
2636
2665
  })).find((e) => e.migration.id === t.id);
2637
2666
  if (!r) return yield* d.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
2638
- yield* T(e);
2667
+ yield* C(e);
2639
2668
  let i = Date.now();
2640
2669
  try {
2641
2670
  let n = {
@@ -2662,9 +2691,9 @@ BEGIN
2662
2691
  durationMs: o
2663
2692
  };
2664
2693
  } finally {
2665
- yield* E(e).pipe(d.orDie);
2694
+ yield* w(e).pipe(d.orDie);
2666
2695
  }
2667
- }), Or = (e) => d.gen(function* () {
2696
+ }), Ar = (e) => d.gen(function* () {
2668
2697
  let t = yield* p.SqlClient, n = yield* t`
2669
2698
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
2670
2699
  WHERE source = 'auto-diff'
@@ -2709,10 +2738,10 @@ BEGIN
2709
2738
  snapshotFingerprint: e.fingerprint,
2710
2739
  snapshotId: i
2711
2740
  };
2712
- }), kr = (e, ...t) => ({
2741
+ }), jr = (e, ...t) => ({
2713
2742
  _tag: "RawSqlFragment",
2714
2743
  strings: [...e],
2715
2744
  values: [...t]
2716
- }), Ar = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2745
+ }), Mr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2717
2746
  //#endregion
2718
- export { l as FILE_MIGRATION_PATTERN, it as REACTIVE_TRIGGER_PREFIX, te as VOLTRO_MIGRATION_LOCK_KEY, ft as _internalCmp, T as acquireMigrationLock, Ke as applyNamespacedSchema, ir as applyPlan, Be as applySchema, zt as chunkTables, F as declaredSnapshot, ve as defaultArrayClause, _e as defaultClause, k as defaultJsonClause, _r as describeOutcome, at as detectReactiveTriggerDrift, tn as emitDropColumnDdl, nn as emitDropColumnDdlMysql, ze as emitFrameworkBootstrapSql, Le as emitNamespaceProvisionDdl, Re as emitNamespacedSchemaSql, M as emitSchemaSql, N as fingerprintSchema, ot as formatReactiveTriggerDrift, fr as ignoreTablesFromEnv, Yt as introspectSchema, o as isFileMigration, Ar as isRawSqlFragment, Pt as mapPgType, s as migration, A as numericIdSql, Nt as parseEnumCheck, wr as pendingFileMigrationIds, Mt as planMigrations, qe as provisionTenantNamespace, E as releaseMigrationLock, gn as renderColumnMysql, pn as renderColumnPg, Dr as rollbackFileBasedMigration, Tr as runFileBasedMigrations, Je as runFrameworkBootstrap, Ge as runMigrate, gr as runPlannedMigrations, P as shortFingerprint, et as snapshotColumn, kr as sql, O as sqlType, Or as squashMigrationPlans, pr as unblockLossy, he as withMigrationLock };
2747
+ export { l as FILE_MIGRATION_PATTERN, ot as REACTIVE_TRIGGER_PREFIX, re as VOLTRO_MIGRATION_LOCK_KEY, mt as _internalCmp, C as acquireMigrationLock, Je as applyNamespacedSchema, ir as applyPlan, He as applySchema, Vt as chunkTables, N as declaredSnapshot, be as defaultArrayClause, ye as defaultClause, D as defaultJsonClause, yr as describeOutcome, pr as destructiveScope, st as detectReactiveTriggerDrift, $t as emitDropColumnDdl, en as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, ct as formatReactiveTriggerDrift, fr as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, Mr as isRawSqlFragment, It as mapPgType, s as migration, O as numericIdSql, Ft as parseEnumCheck, Er as pendingFileMigrationIds, Pt as planMigrations, Ye as provisionTenantNamespace, w as releaseMigrationLock, gn as renderColumnMysql, dn as renderColumnPg, kr as rollbackFileBasedMigration, Dr as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, vr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, jr as sql, E as sqlType, Ar as squashMigrationPlans, hr as unblockLossy, _e as withMigrationLock };