@voltro/database 0.22.1 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sql.js CHANGED
@@ -1,13 +1,13 @@
1
- import { B as e, W as t, a as n, c as r, i, lt as a, n as o, r as s, rt as c, t as l, z as u } from "./fileBased-CDnutVVk.js";
2
- import { Effect as d } from "effect";
3
- import { createLogger as f } from "@voltro/logger";
4
- import { SqlClient as p } from "@effect/sql";
5
- import { createHash as m } from "node:crypto";
6
- import { promises as h } from "node:fs";
7
- import { join as g } from "node:path";
8
- import { pathToFileURL as ee } from "node:url";
1
+ import { H as e, U as t, a as n, c as r, d as i, ft as a, i as o, n as s, o as c, ot as l, q as u, r as d, s as f } from "./frameworkLiveTables-BvPIm2cD.js";
2
+ import { Effect as p } from "effect";
3
+ import { createLogger as m } from "@voltro/logger";
4
+ import { SqlClient as h } from "@effect/sql";
5
+ import { createHash as g } from "node:crypto";
6
+ import { promises as _ } from "node:fs";
7
+ import { join as v } from "node:path";
8
+ import { pathToFileURL as y } from "node:url";
9
9
  //#region src/migrations/ddlError.ts
10
- var _ = (e, t, n, r = 400) => {
10
+ var b = (e, t, n, r = 400) => {
11
11
  let i = n, a = i.cause ?? {}, o = (e) => {
12
12
  let t = a[e];
13
13
  return t == null || t === "" ? void 0 : String(t);
@@ -39,17 +39,17 @@ 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), te = (e, t) => `_ua_${t}_${e}`.slice(0, 64), x = (e, t) => {
43
- if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(v)) return e;
42
+ }, x = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, S = (e) => e.replace(/"/g, "`"), ee = (e) => typeof e == "string" ? e : e.name ?? String(e), te = (e, t) => `_ua_${t}_${e}`.slice(0, 64), ne = (e, t) => {
43
+ if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(x)) return e;
44
44
  let n = { ...e.fields }, r = [], i = [];
45
45
  for (let t of e.appliedIndexes) {
46
- if (!v(t)) {
46
+ if (!x(t)) {
47
47
  r.push(t);
48
48
  continue;
49
49
  }
50
- let a = y(t.where), o = [];
50
+ let a = S(t.where), o = [];
51
51
  for (let r of t.fields) {
52
- let i = b(r);
52
+ let i = ee(r);
53
53
  if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
54
54
  let s = te(t.name, i);
55
55
  o.push(s), n[s] = {
@@ -74,101 +74,101 @@ var _ = (e, t, n, r = 400) => {
74
74
  appliedIndexes: r,
75
75
  appliedUniques: [...e.appliedUniques ?? [], ...i]
76
76
  };
77
- }, S = (e, t) => `${e}::${t}`, ne = (e, t) => {
77
+ }, C = (e, t) => `${e}::${t}`, re = (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(S(e, t.column)) : r.has(t.target) || a(t.target);
81
+ for (let t of o) n.has(t.target) ? i.add(C(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
- }, re = 6322741009312437n, ie = 250, ae = () => {
86
+ }, ie = 6322741009312437n, ae = 250, oe = () => {
87
87
  let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
88
88
  return Number.isFinite(e) && e > 0 ? e : 3e4;
89
- }, oe = (e) => d.gen(function* () {
90
- let t = ae(), n = Date.now();
89
+ }, se = (e) => p.gen(function* () {
90
+ let t = oe(), 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(`${ie} millis`);
94
+ Date.now() - n >= t && (yield* p.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* p.sleep(`${ae} millis`);
95
95
  }
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* () {
96
+ }), ce = (e) => p.gen(function* () {
97
+ yield* e`SELECT pg_advisory_unlock(${ie.toString()}::bigint)`;
98
+ }), le = `voltro_migration_${ie.toString(36)}`, ue = 30, de = (e) => p.gen(function* () {
99
99
  (yield* e`
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* () {
100
+ SELECT GET_LOCK(${le}, ${ue}) AS got`)[0]?.got !== 1 && (yield* p.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${le}' within ${ue}s (another migration is in progress, or a prior one left it held).`)));
101
+ }), fe = (e) => p.gen(function* () {
102
+ yield* e`SELECT RELEASE_LOCK(${le})`;
103
+ }), pe = `voltro_migration_${ie.toString(36)}`, me = 3e4, he = (e) => p.gen(function* () {
104
104
  let t = yield* e`
105
105
  DECLARE @res int;
106
- EXEC @res = sp_getapplock @Resource = ${fe}, @LockMode = 'Exclusive',
107
- @LockOwner = 'Session', @LockTimeout = ${pe};
106
+ EXEC @res = sp_getapplock @Resource = ${pe}, @LockMode = 'Exclusive',
107
+ @LockOwner = 'Session', @LockTimeout = ${me};
108
108
  SELECT @res AS res`;
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({
109
+ (t[0]?.res ?? -999) < 0 && (yield* p.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${pe}' (sp_getapplock returned ${t[0]?.res ?? "no row"}; another migration is in progress).`)));
110
+ }), ge = (e) => p.gen(function* () {
111
+ yield* e`EXEC sp_releaseapplock @Resource = ${pe}, @LockOwner = 'Session'`;
112
+ }), _e = p.void, w = (e) => e.onDialectOrElse({
118
113
  mysql: () => de(e),
119
114
  mssql: () => he(e),
120
- sqlite: () => ge,
115
+ sqlite: () => _e,
121
116
  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
- let n = e.type;
126
- if (e.spatial) {
127
- if (t === "postgres") return `${e.spatial.kind}(${e.spatial.geomKind},${e.spatial.srid})`;
128
- throw Error(`@voltro/plugin-postgis: ${e.spatial.kind}('${e.spatial.geomKind}', ${e.spatial.srid}) is postgres-only — the active dialect is '${t}'. PostGIS has no portable equivalent; use store: 'postgres' (or DB_DIALECT=postgres) for spatial columns, or model the value as plain text/json.`);
129
- }
130
- if (n === "raw") {
131
- if (e.rawDdl === void 0) throw Error("raw() column is missing its DDL fragment — this is a framework bug.");
132
- return e.rawDdl;
133
- }
134
- if (n === "array" && e.arrayElement) {
135
- if (t === "postgres") return `${E({
136
- ...e,
137
- type: e.arrayElement,
117
+ }), T = (e) => e.onDialectOrElse({
118
+ mysql: () => fe(e),
119
+ mssql: () => ge(e),
120
+ sqlite: () => _e,
121
+ orElse: () => ce(e)
122
+ }), ve = (e, t) => p.acquireUseRelease(w(e), () => t, () => T(e).pipe(p.orDie)), ye = m({ scope: "voltro:migrate" }), E = (e) => {
123
+ ye.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
124
+ }, D = (t, n) => {
125
+ let r = t.type;
126
+ if (t.spatial) {
127
+ if (n === "postgres") return `${t.spatial.kind}(${t.spatial.geomKind},${t.spatial.srid})`;
128
+ throw Error(`@voltro/plugin-postgis: ${t.spatial.kind}('${t.spatial.geomKind}', ${t.spatial.srid}) is postgres-only — the active dialect is '${n}'. PostGIS has no portable equivalent; use store: 'postgres' (or DB_DIALECT=postgres) for spatial columns, or model the value as plain text/json.`);
129
+ }
130
+ if (r === "raw") {
131
+ if (t.rawDdl === void 0) throw Error("raw() column is missing its DDL fragment — this is a framework bug.");
132
+ return t.rawDdl;
133
+ }
134
+ if (r === "array" && t.arrayElement) {
135
+ if (n === "postgres") return `${D({
136
+ ...t,
137
+ type: t.arrayElement,
138
138
  arrayElement: void 0
139
- }, t)}[]`;
140
- if (t === "mysql" || t === "mariadb") return "JSON";
141
- if (t === "mssql") return "NVARCHAR(MAX)";
142
- if (u(t)) return "TEXT";
143
- }
144
- if (n === "vector") {
145
- let n = e.vectorDim;
146
- if (n === void 0) throw Error("vector column is missing its dimension — this is a framework bug.");
147
- let r = e.vectorPrecision === "half";
148
- if (t === "postgres") return r ? `HALFVEC(${n})` : `VECTOR(${n})`;
149
- if (t === "mysql" || t === "mariadb") return `VECTOR(${n})`;
150
- if (t === "mssql") return "VARBINARY(MAX)";
151
- if (u(t)) return "BLOB";
152
- }
153
- if (n === "interval") {
154
- if (t === "postgres") return "INTERVAL";
155
- if (t === "mysql" || t === "mariadb" || t === "mssql") return "BIGINT";
156
- if (u(t)) return "INTEGER";
157
- }
158
- if (n === "decimal") {
159
- let n = e.precision, r = e.scale ?? 0;
160
- if (n === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
161
- return u(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
162
- }
163
- if (n === "bigint") return u(t) ? "INTEGER" : "BIGINT";
164
- if (n === "enum") {
165
- if (t === "postgres") return e.enumName ?? "TEXT";
166
- if (t === "mysql" || t === "mariadb") return `ENUM(${(e.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
167
- if (t === "mssql") return "NVARCHAR(255)";
168
- if (u(t)) return "TEXT";
169
- }
170
- if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : u(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
171
- if (u(t)) switch (n) {
139
+ }, n)}[]`;
140
+ if (n === "mysql" || n === "mariadb") return "JSON";
141
+ if (n === "mssql") return "NVARCHAR(MAX)";
142
+ if (e(n)) return "TEXT";
143
+ }
144
+ if (r === "vector") {
145
+ let r = t.vectorDim;
146
+ if (r === void 0) throw Error("vector column is missing its dimension — this is a framework bug.");
147
+ let i = t.vectorPrecision === "half";
148
+ if (n === "postgres") return i ? `HALFVEC(${r})` : `VECTOR(${r})`;
149
+ if (n === "mysql" || n === "mariadb") return `VECTOR(${r})`;
150
+ if (n === "mssql") return "VARBINARY(MAX)";
151
+ if (e(n)) return "BLOB";
152
+ }
153
+ if (r === "interval") {
154
+ if (n === "postgres") return "INTERVAL";
155
+ if (n === "mysql" || n === "mariadb" || n === "mssql") return "BIGINT";
156
+ if (e(n)) return "INTEGER";
157
+ }
158
+ if (r === "decimal") {
159
+ let r = t.precision, i = t.scale ?? 0;
160
+ if (r === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
161
+ return e(n) ? "NUMERIC" : n === "postgres" ? `NUMERIC(${r}, ${i})` : `DECIMAL(${r}, ${i})`;
162
+ }
163
+ if (r === "bigint") return e(n) ? "INTEGER" : "BIGINT";
164
+ if (r === "enum") {
165
+ if (n === "postgres") return t.enumName ?? "TEXT";
166
+ if (n === "mysql" || n === "mariadb") return `ENUM(${(t.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
167
+ if (n === "mssql") return "NVARCHAR(255)";
168
+ if (e(n)) return "TEXT";
169
+ }
170
+ if (r === "text" && t.maxLength !== void 0 && t.generatedAs === void 0) return n === "mssql" ? `NVARCHAR(${t.maxLength})` : e(n) ? "TEXT" : `VARCHAR(${t.maxLength})`;
171
+ if (e(n)) switch (r) {
172
172
  case "id": return "TEXT";
173
173
  case "text": return "TEXT";
174
174
  case "integer": return "INTEGER";
@@ -184,9 +184,9 @@ var _ = (e, t, n, r = 400) => {
184
184
  case "array": return "TEXT";
185
185
  case "interval": return "INTEGER";
186
186
  }
187
- if (t === "mysql" || t === "mariadb") switch (n) {
187
+ if (n === "mysql" || n === "mariadb") switch (r) {
188
188
  case "id": return "VARCHAR(64)";
189
- case "text": return e.hasDefault && e.defaultFactory === void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : e.generatedAs ? "TEXT" : "LONGTEXT";
189
+ case "text": return t.hasDefault && t.defaultFactory === void 0 || t.oneOf && t.oneOf.length > 0 ? "VARCHAR(255)" : t.generatedAs ? "TEXT" : "LONGTEXT";
190
190
  case "integer": return "INT";
191
191
  case "real": return "DOUBLE";
192
192
  case "boolean": return "TINYINT(1)";
@@ -200,9 +200,9 @@ var _ = (e, t, n, r = 400) => {
200
200
  case "array": return "JSON";
201
201
  case "interval": return "BIGINT";
202
202
  }
203
- if (t === "mssql") switch (n) {
203
+ if (n === "mssql") switch (r) {
204
204
  case "id": return "NVARCHAR(64)";
205
- case "text": return e.hasDefault && e.defaultFactory === void 0 || e.oneOf && e.oneOf.length > 0 ? "NVARCHAR(450)" : "NVARCHAR(MAX)";
205
+ case "text": return t.hasDefault && t.defaultFactory === void 0 || t.oneOf && t.oneOf.length > 0 ? "NVARCHAR(450)" : "NVARCHAR(MAX)";
206
206
  case "integer": return "INT";
207
207
  case "real": return "FLOAT";
208
208
  case "boolean": return "BIT";
@@ -216,7 +216,7 @@ var _ = (e, t, n, r = 400) => {
216
216
  case "array": return "NVARCHAR(MAX)";
217
217
  case "interval": return "BIGINT";
218
218
  }
219
- switch (n) {
219
+ switch (r) {
220
220
  case "id": return "TEXT";
221
221
  case "text": return "TEXT";
222
222
  case "integer": return "INTEGER";
@@ -228,26 +228,26 @@ var _ = (e, t, n, r = 400) => {
228
228
  case "bytes": return "BYTEA";
229
229
  case "reference": return "TEXT";
230
230
  case "vector": return "VECTOR";
231
- case "enum": return e.enumName ?? "TEXT";
231
+ case "enum": return t.enumName ?? "TEXT";
232
232
  case "array": return "TEXT[]";
233
233
  case "interval": return "INTERVAL";
234
234
  }
235
- }, ye = (e, t) => {
236
- if (!e.hasDefault || e.defaultFactory !== void 0) return null;
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) ? 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({
235
+ }, be = (t, n) => {
236
+ if (!t.hasDefault || t.defaultFactory !== void 0) return null;
237
+ let r = t.defaultValue;
238
+ return r === "now" ? e(n) ? "DEFAULT CURRENT_TIMESTAMP" : n === "mssql" ? "DEFAULT SYSUTCDATETIME()" : n === "mysql" || n === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof r == "boolean" ? n === "postgres" ? `DEFAULT ${r}` : `DEFAULT ${+!!r}` : typeof r == "number" ? `DEFAULT ${r}` : typeof r == "string" ? `DEFAULT '${r.replace(/'/g, "''")}'` : Array.isArray(r) ? xe(r, t, n) : typeof r == "object" && r ? O(r, n) : null;
239
+ }, xe = (e, t, n) => {
240
+ if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return O(e, n);
241
+ let r = D({
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
- }, D = (e, t) => {
247
+ }, O = (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
- }, O = (e, t) => {
250
+ }, k = (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
- }, k = (e, t) => {
259
+ }, A = (e, t) => {
260
260
  if (e === "restrict" && t === "mssql") return "NO ACTION";
261
261
  switch (e) {
262
262
  case "cascade": return "CASCADE";
@@ -264,174 +264,216 @@ var _ = (e, t, n, r = 400) => {
264
264
  case "setNull": return "SET NULL";
265
265
  case "noAction": return "NO ACTION";
266
266
  }
267
- }, xe = (t, n, r) => r === null ? e(t, n) : `${e(r, n)}.${e(t, n)}`, Se = 191, Ce = (t, n, r) => {
268
- let i = e(t, r);
267
+ }, Se = (e, n, r) => r === null ? t(e, n) : `${t(r, n)}.${t(e, n)}`, Ce = 191, we = (e, n, r) => {
268
+ let i = t(e, r);
269
269
  if (r !== "mysql" && r !== "mariadb") return i;
270
- let a = n[t];
270
+ let a = n[e];
271
271
  if (!a) return i;
272
- let o = E(a, r).toUpperCase();
273
- return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${Se})` : i;
274
- }, we = (e, t) => {
272
+ let o = D(a, r).toUpperCase();
273
+ return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${i}(${Ce})` : i;
274
+ }, Te = (e, t) => {
275
275
  if (!e.generatedAs) return null;
276
276
  let { expr: n, stored: r } = e.generatedAs;
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`;
277
+ if (t === "postgres") return r || E("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
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
- }, 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
- n.type === "id" && !o && c.push("PRIMARY KEY");
286
- let l = we(n, r);
287
- if (l) c.push(l);
282
+ }, Ee = (n, r, i, a, o = !1, s = !1) => {
283
+ if (r.type === "id" && r.idScheme?.kind === "numeric") return k(n, i);
284
+ let c = i === "mssql" && r.type === "text" && !r.generatedAs && r.maxLength === void 0 && a?.has(n) ? "NVARCHAR(450)" : D(r, i), l = [t(n, i), c];
285
+ r.type === "id" && !s && l.push("PRIMARY KEY");
286
+ let u = Te(r, i);
287
+ if (u) l.push(u);
288
288
  else {
289
- n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && c.push("UNIQUE");
290
- let e = ye(n, r);
291
- e && c.push(e);
292
- }
293
- if (n.type === "reference" && n.references && !a) {
294
- let t = n.references();
295
- c.push(`REFERENCES ${e(t.tableName, r)} (${e("id", r)})`);
296
- let i = k(n.onDelete ?? "restrict", r);
297
- c.push(`ON DELETE ${i}`);
298
- let a = k(n.refOnUpdate ?? "noAction", r);
299
- a !== "NO ACTION" && c.push(`ON UPDATE ${a}`);
300
- }
301
- if (n.oneOf && n.oneOf.length > 0) {
302
- let i = n.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
303
- c.push(`CHECK (${e(t, r)} IN (${i}))`);
304
- }
305
- if (n.checks && n.checks.length > 0) for (let e of n.checks) c.push(`CHECK (${e})`);
306
- if (n.type === "enum" && n.enumValues && n.enumValues.length > 0 && (r === "mssql" || u(r))) {
307
- let i = n.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
308
- c.push(`CHECK (${e(t, r)} IN (${i}))`);
309
- }
310
- if (n.type === "json" || n.type === "array") {
311
- let n = e(t, r);
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
- }
314
- return c.join(" ");
315
- }, Ee = (t, n, r = null, i) => {
289
+ r.nullable || l.push("NOT NULL"), r.unique && r.type !== "id" && l.push("UNIQUE");
290
+ let e = be(r, i);
291
+ e && l.push(e);
292
+ }
293
+ if (r.type === "reference" && r.references && !o) {
294
+ let e = r.references();
295
+ l.push(`REFERENCES ${t(e.tableName, i)} (${t("id", i)})`);
296
+ let n = A(r.onDelete ?? "restrict", i);
297
+ l.push(`ON DELETE ${n}`);
298
+ let a = A(r.refOnUpdate ?? "noAction", i);
299
+ a !== "NO ACTION" && l.push(`ON UPDATE ${a}`);
300
+ }
301
+ if (r.oneOf && r.oneOf.length > 0) {
302
+ let e = r.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
303
+ l.push(`CHECK (${t(n, i)} IN (${e}))`);
304
+ }
305
+ if (r.checks && r.checks.length > 0) for (let e of r.checks) l.push(`CHECK (${e})`);
306
+ if (r.type === "enum" && r.enumValues && r.enumValues.length > 0 && (i === "mssql" || e(i))) {
307
+ let e = r.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
308
+ l.push(`CHECK (${t(n, i)} IN (${e}))`);
309
+ }
310
+ if (r.type === "json" || r.type === "array") {
311
+ let r = t(n, i);
312
+ e(i) ? l.push(`CHECK (${r} IS NULL OR json_valid(${r}))`) : i === "mssql" && l.push(`CHECK (${r} IS NULL OR ISJSON(${r}) = 1)`);
313
+ }
314
+ return l.join(" ");
315
+ }, De = (e, n, r = null, i) => {
316
316
  let a = /* @__PURE__ */ new Set();
317
- for (let e of t.appliedIndexes ?? []) for (let t of e.fields) typeof t == "string" && a.add(t);
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]) => ` ${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
- return ` CONSTRAINT ${e(r.name, n)} UNIQUE (${i})`;
322
- }), u = (t.appliedChecks ?? []).map((t) => ` CONSTRAINT ${e(t.name, n)} CHECK (${t.expr})`), d = [
323
- ...s ? [` PRIMARY KEY (${o.map((e) => Ce(e, t.fields, n)).join(", ")})`] : [],
317
+ for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
318
+ for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && a.add(e);
319
+ let o = e.appliedPrimaryKey ?? [], s = o.length > 0, c = Object.entries(e.fields).map(([e, t]) => ` ${Ee(e, t, n, a, i?.has(e) ?? !1, s)}`).join(",\n"), l = (e.appliedUniques ?? []).map((r) => {
320
+ let i = r.fields.map((t) => we(t, e.fields, n)).join(", ");
321
+ return ` CONSTRAINT ${t(r.name, n)} UNIQUE (${i})`;
322
+ }), u = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${t(e.name, n)} CHECK (${e.expr})`), d = [
323
+ ...s ? [` PRIMARY KEY (${o.map((t) => we(t, e.fields, n)).join(", ")})`] : [],
324
324
  ...l,
325
325
  ...u
326
- ], f = d.length > 0 ? `${c},\n${d.join(",\n")}` : c, p = xe(t.tableName, n, r);
326
+ ], f = d.length > 0 ? `${c},\n${d.join(",\n")}` : c, p = Se(e.tableName, n, r);
327
327
  if (n === "mssql") {
328
- let e = r === null ? t.tableName : `${r}.${t.tableName}`, n = `CREATE TABLE ${p} (\n${f}\n)`;
329
- return `IF OBJECT_ID('${e.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
328
+ let t = r === null ? e.tableName : `${r}.${e.tableName}`, n = `CREATE TABLE ${p} (\n${f}\n)`;
329
+ return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${n.replace(/'/g, "''")}');`;
330
330
  }
331
331
  return [
332
332
  `CREATE TABLE IF NOT EXISTS ${p} (`,
333
333
  f,
334
334
  ");"
335
335
  ].join("\n");
336
- }, De = (t, n, r) => {
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
- 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
- }, Oe = (n, r, a = null) => {
340
- let o = [], s = /* @__PURE__ */ new Set(), c = (e) => e.join("\0"), l = (e, n, i, a) => {
341
- let o = {
336
+ }, Oe = (e, n, r) => {
337
+ let i = `${e}_${n.name}_fts`, a = (e) => t(e, r), o = n.columns.map(a).join(", "), s = n.columns.map((e) => `new.${a(e)}`).join(", "), c = [];
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(e)} 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(e)} 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(e)} 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
+ }, ke = (e, n, r = null) => {
340
+ let i = [], a = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, t, r, i) => {
341
+ let a = {
342
342
  using: "",
343
343
  withSuffix: "",
344
344
  skip: !1
345
345
  };
346
- if (i === void 0 || i === "btree") return o;
347
- if (i === "gist") return r === "postgres" ? {
346
+ if (r === void 0 || r === "btree") return a;
347
+ if (r === "gist") return n === "postgres" ? {
348
348
  using: " USING GIST",
349
349
  withSuffix: "",
350
350
  skip: !1
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
- if (i === "gin") return r === "postgres" ? {
351
+ } : (E(`[voltro:migrate] index '${e}' on '${t}': ${n} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), a);
352
+ if (r === "gin") return n === "postgres" ? {
353
353
  using: " USING GIN",
354
354
  withSuffix: "",
355
355
  skip: !1
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(...).`), {
356
+ } : n === "mysql" || n === "mariadb" ? (E(`[voltro:migrate] gin index '${e}' on '${t}': ${n} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
357
357
  using: "",
358
358
  withSuffix: "",
359
359
  skip: !0
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
- if (i === "brin") return r === "postgres" ? {
360
+ }) : (E(`[voltro:migrate] gin index '${e}' on '${t}': ${n} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), a);
361
+ if (r === "brin") return n === "postgres" ? {
362
362
  using: " USING BRIN",
363
363
  withSuffix: "",
364
364
  skip: !1
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
- if (i === "hnsw") {
367
- if (r === "postgres") {
368
- let e = a?.hnsw?.m ?? 16, n = a?.hnsw?.efConstruction ?? 64, r = a?.hnsw?.opclass ?? t(a?.hnsw?.distance);
365
+ } : (E(`[voltro:migrate] brin index '${e}' on '${t}': ${n} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), a);
366
+ if (r === "hnsw") {
367
+ if (n === "postgres") {
368
+ let e = i?.hnsw?.m ?? 16, t = i?.hnsw?.efConstruction ?? 64, n = i?.hnsw?.opclass ?? u(i?.hnsw?.distance);
369
369
  return {
370
370
  using: " USING hnsw",
371
- withSuffix: ` WITH (m = ${e}, ef_construction = ${n})`,
372
- opclass: r,
371
+ withSuffix: ` WITH (m = ${e}, ef_construction = ${t})`,
372
+ opclass: n,
373
373
  skip: !1
374
374
  };
375
375
  }
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.`), {
376
+ return E(`[voltro:migrate] hnsw index '${e}' on '${t}': ${n} 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
380
380
  };
381
381
  }
382
- return o;
383
- }, u = (e, t) => {
384
- let a = e.map((e) => {
385
- if (typeof e == "string") return Ce(e, n.fields, r);
386
- if ("jsonPath" in e) {
387
- let { column: t, path: n, numeric: a } = e.jsonPath;
388
- return `(${i(t, n, r, { numeric: a })})`;
382
+ return a;
383
+ }, c = (t, r) => {
384
+ let i = t.map((t) => {
385
+ if (typeof t == "string") return we(t, e.fields, n);
386
+ if ("jsonPath" in t) {
387
+ let { column: e, path: r, numeric: i } = t.jsonPath;
388
+ return `(${f(e, r, n, { numeric: i })})`;
389
389
  }
390
- return `(${e.expr})`;
390
+ return `(${t.expr})`;
391
391
  });
392
- return t !== void 0 && a.length === 1 ? `${a[0]} ${t}` : a.join(", ");
393
- }, d = (t, n, i, o, s, c = "", d = !1) => {
394
- let f = l(t, n, o, s);
392
+ return r !== void 0 && i.length === 1 ? `${i[0]} ${r}` : i.join(", ");
393
+ }, l = (e, i, a, o, l, u = "", d = !1) => {
394
+ let f = s(e, i, o, l);
395
395
  if (f.skip) return "";
396
- let p = u(i, f.opclass), m = `${f.withSuffix}${c}`, h = xe(n, r, a), g = d ? "UNIQUE " : "";
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};`;
396
+ let p = c(a, f.opclass), m = `${f.withSuffix}${u}`, h = Se(i, n, r), g = d ? "UNIQUE " : "";
397
+ return n === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${t(e, n)} ON ${h}${f.using} (${p})${m};` : n === "mysql" ? `CREATE ${g}INDEX ${t(e, n)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${t(e, n)} ON ${h}${f.using} (${p})${m};`;
398
398
  };
399
- for (let t of n.appliedFullText ?? []) if (r === "postgres") {
400
- let i = t.config ?? "english", a = `${t.name}_tsv`, s = t.columns.map((n) => {
401
- let a = t.weights?.[n] ?? "A";
402
- return `setweight(to_tsvector('${i}', coalesce(${e(n, r)}, '')), '${a}')`;
399
+ for (let r of e.appliedFullText ?? []) if (n === "postgres") {
400
+ let a = r.config ?? "english", o = `${r.name}_tsv`, s = r.columns.map((e) => {
401
+ let i = r.weights?.[e] ?? "A";
402
+ return `setweight(to_tsvector('${a}', coalesce(${t(e, n)}, '')), '${i}')`;
403
403
  }).join(" || ");
404
- o.push(`ALTER TABLE ${e(n.tableName, r)} ADD COLUMN IF NOT EXISTS ${e(a, r)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), o.push(`CREATE INDEX IF NOT EXISTS ${e(t.name, r)} ON ${e(n.tableName, r)} USING GIN (${e(a, r)});`);
405
- } else if (r === "mysql" || r === "mariadb") {
406
- let i = t.columns.map((t) => e(t, r)).join(", ");
407
- o.push(`CREATE FULLTEXT INDEX ${e(t.name, r)} ON ${e(n.tableName, r)} (${i});`);
408
- } else if (r === "turso") throw Error(`@voltro/sql-turso: full-text index '${t.name}' on '${n.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
409
- else r === "sqlite" ? o.push(...De(n.tableName, t, r)) : 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
- for (let e of n.appliedIndexes) {
411
- if ((r === "mariadb" || r === "mssql") && e.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
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(...).`);
404
+ i.push(`ALTER TABLE ${t(e.tableName, n)} ADD COLUMN IF NOT EXISTS ${t(o, n)} tsvector GENERATED ALWAYS AS (${s}) STORED;`), i.push(`CREATE INDEX IF NOT EXISTS ${t(r.name, n)} ON ${t(e.tableName, n)} USING GIN (${t(o, n)});`);
405
+ } else if (n === "mysql" || n === "mariadb") {
406
+ let a = r.columns.map((e) => t(e, n)).join(", ");
407
+ i.push(`CREATE FULLTEXT INDEX ${t(r.name, n)} ON ${t(e.tableName, n)} (${a});`);
408
+ } else if (n === "turso") throw Error(`@voltro/sql-turso: full-text index '${r.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
409
+ else n === "sqlite" ? i.push(...Oe(e.tableName, r, n)) : E(`[voltro:migrate] full-text index '${r.name}' on '${e.tableName}': ${n} uses a ranked LIKE search at query time (no native FTS catalog required).`);
410
+ for (let t of e.appliedIndexes) {
411
+ if ((n === "mariadb" || n === "mssql") && t.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
412
+ E(`[voltro:migrate] json-path index '${t.name}' on '${e.tableName}': ${n} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${n}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
413
413
  continue;
414
414
  }
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
- let t = "";
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
- let i = d(e.name, n.tableName, e.fields, e.kind, e.kindOptions, t, e.unique === !0);
419
- i !== "" && o.push(i), e.fields.every((e) => typeof e == "string") && s.add(c(e.fields));
420
- }
421
- for (let [e, t] of Object.entries(n.fields)) {
422
- if (t.type !== "reference" || t.fkAutoIndex === !1 || s.has(c([e]))) continue;
423
- let r = `${n.tableName}_${e}_idx`;
424
- o.push(d(r, n.tableName, [e])), s.add(c([e]));
425
- }
426
- return o.join("\n");
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) => `
415
+ if (t.unique && t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${t.name}' on '${e.tableName}' cannot be expressed on ${n} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${n}, or move this table to postgres/sqlite/mssql.`);
416
+ let r = "";
417
+ t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb" ? E(`[voltro:migrate] partial index '${t.name}' on '${e.tableName}': ${n} does not support WHERE clauses on indexes — emitting a full index`) : r = ` WHERE ${t.where}`);
418
+ let s = l(t.name, e.tableName, t.fields, t.kind, t.kindOptions, r, t.unique === !0);
419
+ s !== "" && i.push(s), t.fields.every((e) => typeof e == "string") && a.add(o(t.fields));
420
+ }
421
+ for (let [t, n] of Object.entries(e.fields)) {
422
+ if (n.type !== "reference" || n.fkAutoIndex === !1 || a.has(o([t]))) continue;
423
+ let r = `${e.tableName}_${t}_idx`;
424
+ i.push(l(r, e.tableName, [t])), a.add(o([t]));
425
+ }
426
+ return i.join("\n");
427
+ }, j = "framework_changes", Ae = (e, t, n = j) => {
428
+ if (t !== "postgres") return [];
429
+ let r = e.filter((e) => e.isReactive !== !1);
430
+ return r.length === 0 ? [] : [Me(n), ...r.map((e) => Ne(e, n))];
431
+ }, je = (e) => e === "framework_changes" ? "framework_notify_change" : `framework_notify_change_${e}`, Me = (e) => `
432
+ CREATE OR REPLACE FUNCTION ${je(e)}() RETURNS trigger AS $$
433
+ DECLARE
434
+ payload TEXT;
435
+ BEGIN
436
+ payload := json_build_object(
437
+ 'table', TG_TABLE_NAME,
438
+ -- The schema the write landed in. Under namespace isolation this is
439
+ -- the tenant schema (tenant_<id>); the CDC consumer uses it so a
440
+ -- write in tenant A namespace does not spuriously wake tenant B
441
+ -- subscriptions on the same-named table. public/absent = shared.
442
+ 'schema', TG_TABLE_SCHEMA,
443
+ 'op', lower(TG_OP),
444
+ 'old', CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE row_to_json(OLD) END,
445
+ 'new', CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE row_to_json(NEW) END
446
+ )::text;
447
+ -- pg_notify hard-caps the payload at 8000 bytes; a wide reactive row
448
+ -- (big text / json column) would otherwise abort the write itself.
449
+ -- Fall back to a body-less notice — the CDC consumer treats absent
450
+ -- old/new as "all columns changed" and re-queries, so correctness is
451
+ -- preserved; only the delta-diff fast path is skipped for that write.
452
+ IF octet_length(payload) >= 7999 THEN
453
+ payload := json_build_object(
454
+ 'table', TG_TABLE_NAME,
455
+ 'schema', TG_TABLE_SCHEMA,
456
+ 'op', lower(TG_OP),
457
+ 'old', NULL,
458
+ 'new', NULL,
459
+ 'oversized', true
460
+ )::text;
461
+ END IF;
462
+ PERFORM pg_notify('${e}', payload);
463
+ RETURN COALESCE(NEW, OLD);
464
+ END;
465
+ $$ LANGUAGE plpgsql;
466
+ `.trim(), Ne = (e, t) => {
467
+ let n = t === "framework_changes" ? `framework_changes_${e.tableName}` : `framework_changes_${t}_${e.tableName}`;
468
+ return `
428
469
  ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL;
429
- DROP TRIGGER IF EXISTS framework_changes_${e.tableName} ON "${e.tableName}";
430
- CREATE TRIGGER framework_changes_${e.tableName}
470
+ DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}";
471
+ CREATE TRIGGER ${n}
431
472
  AFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"
432
- FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
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) => {
473
+ FOR EACH ROW EXECUTE FUNCTION ${je(t)}();
474
+ `.trim();
475
+ }, Pe = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), Fe = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), Ie = (e) => {
476
+ let t = new Map(e.map((e) => [e.tableName, e])), n = re(e.map((e) => e.tableName), (e) => {
435
477
  let n = t.get(e);
436
478
  return n ? Object.entries(n.fields).flatMap(([e, n]) => {
437
479
  if (n.type !== "reference" || !n.references) return [];
@@ -442,7 +484,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
442
484
  }] : [];
443
485
  }) : [];
444
486
  }), r = [];
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({
487
+ 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({
446
488
  table: t.tableName,
447
489
  column: e,
448
490
  targetTable: i.references().tableName,
@@ -453,7 +495,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
453
495
  if (!(i.has(e.tableName) || a.has(e.tableName))) {
454
496
  a.add(e.tableName);
455
497
  for (let [r, i] of Object.entries(e.fields)) {
456
- if (i.type !== "reference" || !i.references || n.has(S(e.tableName, r))) continue;
498
+ if (i.type !== "reference" || !i.references || n.has(C(e.tableName, r))) continue;
457
499
  let a = i.references();
458
500
  if (a.tableName === e.tableName) continue;
459
501
  let o = t.get(a.tableName);
@@ -467,30 +509,30 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
467
509
  sorted: o,
468
510
  cyclic: r
469
511
  };
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}`;
512
+ }, Le = (e, n, r = null) => {
513
+ let i = (e) => r ? `${t(r, n)}.${t(e, n)}` : t(e, n), a = `${e.table}_${e.column}_fkey`, o = A(e.onDelete, n), s = A(e.onUpdate, n), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (r) => `ADD CONSTRAINT ${t(a, n)} FOREIGN KEY ${r ? "IF NOT EXISTS " : ""}(${t(e.column, n)}) REFERENCES ${i(e.targetTable)} (${t("id", n)})${c}`;
472
514
  switch (n) {
473
515
  case "postgres": return [
474
516
  "DO $$ BEGIN",
475
517
  " IF NOT EXISTS (SELECT 1 FROM pg_constraint",
476
- ` WHERE conname = '${a}' AND conrelid = '${r ? `${r}.` : ""}${t.table}'::regclass) THEN`,
477
- ` ALTER TABLE ${i(t.table)} ${l(!1)};`,
518
+ ` WHERE conname = '${a}' AND conrelid = '${r ? `${r}.` : ""}${e.table}'::regclass) THEN`,
519
+ ` ALTER TABLE ${i(e.table)} ${l(!1)};`,
478
520
  " END IF;",
479
521
  "END $$;"
480
522
  ].join("\n");
481
- case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${a}') ALTER TABLE ${i(t.table)} ${l(!1)};`;
482
- case "mariadb": return `ALTER TABLE ${i(t.table)} ${l(!0)};`;
483
- default: return `ALTER TABLE ${i(t.table)} ${l(!1)};`;
523
+ case "mssql": return `IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = '${a}') ALTER TABLE ${i(e.table)} ${l(!1)};`;
524
+ case "mariadb": return `ALTER TABLE ${i(e.table)} ${l(!0)};`;
525
+ default: return `ALTER TABLE ${i(e.table)} ${l(!1)};`;
484
526
  }
485
- }, Fe = (e, t) => {
486
- let n = /* @__PURE__ */ new Map();
487
- if (u(t)) return n;
488
- for (let t of e) {
489
- let e = n.get(t.table) ?? /* @__PURE__ */ new Set();
490
- e.add(t.column), n.set(t.table, e);
527
+ }, Re = (t, n) => {
528
+ let r = /* @__PURE__ */ new Map();
529
+ if (e(n)) return r;
530
+ for (let e of t) {
531
+ let t = r.get(e.table) ?? /* @__PURE__ */ new Set();
532
+ t.add(e.column), r.set(e.table, t);
491
533
  }
492
- return n;
493
- }, Ie = (e, t) => {
534
+ return r;
535
+ }, ze = (e, t) => {
494
536
  if (t !== "postgres") return "";
495
537
  let n = /* @__PURE__ */ new Map();
496
538
  for (let t of e) for (let e of Object.values(t.fields)) {
@@ -506,7 +548,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
506
548
  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
549
  }
508
550
  return r.join("\n\n");
509
- }, Le = (e, t) => {
551
+ }, Be = (e, t) => {
510
552
  if (t !== "postgres") return "";
511
553
  let n = /* @__PURE__ */ new Set();
512
554
  for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
@@ -520,80 +562,71 @@ BEGIN
520
562
  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
563
  }
522
564
  return r.join("\n\n");
523
- }, Re = (e) => {
524
- let t = [], r = [];
525
- for (let i of e) n(i) ? r.push(i) : t.push(i);
565
+ }, Ve = (e) => {
566
+ let t = [], n = [];
567
+ for (let i of e) r(i) ? n.push(i) : t.push(i);
526
568
  return {
527
569
  tables: t,
528
- views: r
570
+ views: n
529
571
  };
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
- l && c.push(l);
535
- let d = Ie(a, t);
536
- d && c.push(d);
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
- for (let e of a) {
540
- let n = Oe(e, t);
541
- n && c.push(n);
542
- }
543
- let f = a.filter((e) => e.isReactive !== !1);
544
- if (f.length > 0 && t === "postgres") {
545
- c.push(ke);
546
- for (let e of f) c.push(Ae(e));
547
- }
548
- for (let e of i) c.push(r(e, t));
549
- return c.join("\n\n") + "\n";
550
- }, ze = (t, n, r) => {
551
- let i = e(t, n);
572
+ }, M = (t, n, r = j) => {
573
+ let { tables: a, views: o } = Ve(t), { sorted: s, cyclic: c } = Ie(a.map((e) => ne(e, n))), l = Re(c, n), u = [];
574
+ n === "postgres" && Pe(s) && u.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && Fe(s) && u.push("CREATE EXTENSION IF NOT EXISTS postgis;");
575
+ let d = Be(s, n);
576
+ d && u.push(d);
577
+ let f = ze(s, n);
578
+ f && u.push(f);
579
+ for (let e of s) u.push(De(e, n, null, l.get(e.tableName)));
580
+ if (!e(n)) for (let e of c) u.push(Le(e, n));
581
+ for (let e of s) {
582
+ let t = ke(e, n);
583
+ t && u.push(t);
584
+ }
585
+ u.push(...Ae(s, n, r));
586
+ for (let e of o) u.push(i(e, n));
587
+ return u.join("\n\n") + "\n";
588
+ }, He = (e, n, r) => {
589
+ let i = t(e, n);
552
590
  switch (n) {
553
591
  case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${i};`;
554
592
  case "mysql":
555
593
  case "mariadb": return `CREATE DATABASE IF NOT EXISTS ${i};`;
556
- case "mssql": return `IF SCHEMA_ID('${t.replace(/'/g, "''")}') IS NULL EXEC(N'CREATE SCHEMA ${i.replace(/'/g, "''")}');`;
594
+ case "mssql": return `IF SCHEMA_ID('${e.replace(/'/g, "''")}') IS NULL EXEC(N'CREATE SCHEMA ${i.replace(/'/g, "''")}');`;
557
595
  case "turso":
558
- case "sqlite": return `ATTACH DATABASE '${(r ?? `${t}.db`).replace(/'/g, "''")}' AS ${i};`;
559
- }
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
- for (let e of s) {
568
- let t = Oe(e, n, r);
596
+ case "sqlite": return `ATTACH DATABASE '${(r ?? `${e}.db`).replace(/'/g, "''")}' AS ${i};`;
597
+ }
598
+ }, Ue = (n, r, i, a) => {
599
+ let o = He(i, r, a), s = t(i, r);
600
+ if (r === "postgres") return `${o}\n\nSET search_path TO ${s};\n\n${M(n, r)}`;
601
+ if (r === "mysql" || r === "mariadb") return `${o}\n\nUSE ${s};\n\n${M(n, r)}`;
602
+ let { sorted: c, cyclic: l } = Ie(n), u = Re(l, r), d = [o];
603
+ for (let e of c) d.push(De(e, r, i, u.get(e.tableName)));
604
+ if (!e(r)) for (let e of l) d.push(Le(e, r, i));
605
+ for (let e of c) {
606
+ let t = ke(e, r, i);
569
607
  t && d.push(t);
570
608
  }
571
609
  return d.join("\n\n") + "\n";
572
- }, Ve = (e, t) => {
573
- let { sorted: n, cyclic: r } = Ne(e), i = Fe(r, t), a = [], o = Le(n, t);
574
- o && a.push(o);
575
- let s = Ie(n, t);
576
- s && a.push(s);
577
- for (let e of n) a.push(Ee(e, t, null, i.get(e.tableName)));
578
- for (let e of r) a.push(Pe(e, t));
579
- let c = n.filter((e) => e.isReactive);
580
- if (c.length > 0) {
581
- a.push(ke);
582
- for (let e of c) a.push(Ae(e));
583
- }
584
- return a.join("\n\n") + "\n";
585
- }, He = (e, t = "postgres") => d.gen(function* () {
586
- let n = yield* p.SqlClient;
587
- yield* _e(n, Ge(n, A(e, t), t)).pipe(d.orDie);
588
- }), Ue = (e, t) => {
610
+ }, We = (e, t, n = j) => {
611
+ let { sorted: r, cyclic: i } = Ie(e), a = Re(i, t), o = [], s = Be(r, t);
612
+ s && o.push(s);
613
+ let c = ze(r, t);
614
+ c && o.push(c);
615
+ for (let e of r) o.push(De(e, t, null, a.get(e.tableName)));
616
+ for (let e of i) o.push(Le(e, t));
617
+ return o.push(...Ae(r, t, n)), o.join("\n\n") + "\n";
618
+ }, Ge = (e, t = "postgres", n = j) => p.gen(function* () {
619
+ let r = yield* h.SqlClient;
620
+ yield* ve(r, Je(r, M(e, t, n), t)).pipe(p.orDie);
621
+ }), Ke = (e, t) => {
589
622
  let n = t.cause ?? {};
590
623
  return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
591
- }, We = (e) => d.gen(function* () {
592
- let t = yield* p.SqlClient;
593
- for (let n of Ke(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && ve.debug(`EXEC: ${n.replace(/\s+/g, " ").slice(0, 180)}`), yield* t.unsafe(n).pipe(d.catchIf((e) => Ue(n, e), () => d.void), d.tapError((e) => d.sync(() => {
594
- ve.error(_("migrate: statement failed", n, e, 200));
595
- })), d.orDieWith((e) => Error(_("migrate: statement failed", n, e, 400).trim())));
596
- }), Ge = (e, t, n) => (n === "turso" ? We(t) : e.withTransaction(We(t))).pipe(d.orDie), Ke = (e) => {
624
+ }, qe = (e) => p.gen(function* () {
625
+ let t = yield* h.SqlClient;
626
+ for (let n of Ye(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && ye.debug(`EXEC: ${n.replace(/\s+/g, " ").slice(0, 180)}`), yield* t.unsafe(n).pipe(p.catchIf((e) => Ke(n, e), () => p.void), p.tapError((e) => p.sync(() => {
627
+ ye.error(b("migrate: statement failed", n, e, 200));
628
+ })), p.orDieWith((e) => Error(b("migrate: statement failed", n, e, 400).trim())));
629
+ }), Je = (e, t, n) => (n === "turso" ? qe(t) : e.withTransaction(qe(t))).pipe(p.orDie), Ye = (e) => {
597
630
  let t = [], n = "", r = !1;
598
631
  for (let i = 0; i < e.length; i++) {
599
632
  if (e.slice(i, i + 2) === "$$") {
@@ -608,40 +641,40 @@ BEGIN
608
641
  }
609
642
  let i = n.trim();
610
643
  return i.length > 0 && t.push(i), t;
611
- }, qe = async (e, t, n = "postgres") => {
612
- await d.runPromise(He(e, n).pipe(d.provide(t)));
613
- }, Je = (e, t, n = "postgres") => d.gen(function* () {
614
- let r = Be(e, n, t), i = yield* p.SqlClient;
615
- yield* _e(i, Ge(i, r, n)).pipe(d.orDie);
616
- }), Ye = async (e, t, n, r = "postgres") => {
617
- await d.runPromise(Je(e, t, r).pipe(d.provide(n)));
618
644
  }, Xe = async (e, t, n = "postgres") => {
619
- await d.runPromise(d.gen(function* () {
620
- let t = Ve(e, n), r = yield* p.SqlClient;
621
- yield* _e(r, Ge(r, t, n)).pipe(d.orDie);
622
- }).pipe(d.provide(t)));
623
- }, Ze = (e) => {
645
+ await p.runPromise(Ge(e, n).pipe(p.provide(t)));
646
+ }, Ze = (e, t, n = "postgres") => p.gen(function* () {
647
+ let r = Ue(e, n, t), i = yield* h.SqlClient;
648
+ yield* ve(i, Je(i, r, n)).pipe(p.orDie);
649
+ }), Qe = async (e, t, n, r = "postgres") => {
650
+ await p.runPromise(Ze(e, t, r).pipe(p.provide(n)));
651
+ }, $e = async (e, t, n = "postgres") => {
652
+ await p.runPromise(p.gen(function* () {
653
+ let t = We(e, n), r = yield* h.SqlClient;
654
+ yield* ve(r, Je(r, t, n)).pipe(p.orDie);
655
+ }).pipe(p.provide(t)));
656
+ }, et = (e) => {
624
657
  if (e == null) return e;
625
- if (Array.isArray(e)) return e.map(Ze);
658
+ if (Array.isArray(e)) return e.map(et);
626
659
  if (typeof e != "object") return e;
627
660
  let t = {};
628
661
  for (let n of Object.keys(e).sort()) {
629
662
  let r = e[n];
630
- r !== void 0 && (t[n] = Ze(r));
663
+ r !== void 0 && (t[n] = et(r));
631
664
  }
632
665
  return t;
633
- }, Qe = (e) => {
666
+ }, tt = (e) => {
634
667
  if (!e.idScheme && !e.sensitive && !e.safe) return e;
635
668
  let { idScheme: t, sensitive: n, safe: r, ...i } = e;
636
669
  return i;
637
- }, $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) => ({
670
+ }, nt = (e) => [...e].map(tt).sort((e, t) => e.name.localeCompare(t.name)), rt = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), it = (e) => [...e].map((e) => ({
638
671
  name: e.name,
639
- columns: $e(e.columns),
640
- indexes: et(e.indexes)
641
- })).sort((e, t) => e.name.localeCompare(t.name)), j = (e) => {
642
- let t = { tables: tt(e.tables) }, n = JSON.stringify(Ze(t));
643
- return m("sha256").update(n).digest("hex");
644
- }, M = (e) => e.slice(0, 16), nt = (e, t) => {
672
+ columns: nt(e.columns),
673
+ indexes: rt(e.indexes)
674
+ })).sort((e, t) => e.name.localeCompare(t.name)), N = (e) => {
675
+ let t = { tables: it(e.tables) }, n = JSON.stringify(et(t));
676
+ return g("sha256").update(n).digest("hex");
677
+ }, P = (e) => e.slice(0, 16), at = (e, t) => {
645
678
  let n = t.references ? {
646
679
  table: t.references().tableName,
647
680
  column: "id",
@@ -680,7 +713,7 @@ BEGIN
680
713
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
681
714
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
682
715
  };
683
- }, rt = (e) => {
716
+ }, ot = (e) => {
684
717
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
685
718
  n.has(e.name) || (n.add(e.name), t.push(e));
686
719
  }, i = e.appliedPrimaryKey ?? [];
@@ -720,7 +753,7 @@ BEGIN
720
753
  let i = n;
721
754
  if (i.dropped || !i.references || i.fkAutoIndex === !1 || s.has(t)) continue;
722
755
  let a = `${e.tableName}_${t}_idx`;
723
- c(e.tableName, a, !0, [t]), r({
756
+ l(e.tableName, a, !0, [t]), r({
724
757
  name: a,
725
758
  table: e.tableName,
726
759
  columns: [t],
@@ -728,11 +761,11 @@ BEGIN
728
761
  });
729
762
  }
730
763
  return t;
731
- }, it = (e) => {
764
+ }, st = (e) => {
732
765
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
733
766
  for (let [r, i] of Object.entries(e.fields)) {
734
767
  if (i.dropped) continue;
735
- let e = nt(r, i);
768
+ let e = at(r, i);
736
769
  n.push(t.has(r) ? {
737
770
  ...e,
738
771
  unique: !0
@@ -742,21 +775,21 @@ BEGIN
742
775
  return {
743
776
  name: e.tableName,
744
777
  columns: n,
745
- indexes: rt(e),
778
+ indexes: ot(e),
746
779
  ...r.length > 0 ? { primaryKey: [...r] } : {},
747
780
  ...i === void 0 ? {} : { renamedFrom: i }
748
781
  };
749
- }, at = (e) => {
782
+ }, ct = (e) => {
750
783
  let t = /* @__PURE__ */ new Map();
751
784
  for (let n of e) for (let e of n.indexes) {
752
785
  let r = t.get(e.name);
753
786
  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}').`);
754
787
  t.set(e.name, n.name);
755
788
  }
756
- }, N = (e, t) => {
757
- let n = e.map((e) => it(x(e, t)));
758
- return at(n), { tables: n };
759
- }, ot = "framework_changes_", st = (e, t) => d.gen(function* () {
789
+ }, F = (e, t) => {
790
+ let n = e.map((e) => st(ne(e, t)));
791
+ return ct(n), { tables: n };
792
+ }, lt = "framework_changes_", ut = (e, t) => p.gen(function* () {
760
793
  let n = t.filter((e) => !e.tableName.startsWith("_voltro_"));
761
794
  if (n.length === 0) return {
762
795
  missing: [],
@@ -769,17 +802,17 @@ BEGIN
769
802
  JOIN pg_namespace n ON n.oid = c.relnamespace
770
803
  WHERE NOT t.tgisinternal
771
804
  AND n.nspname = current_schema()
772
- AND t.tgname LIKE ${`${ot}%`}
805
+ AND t.tgname LIKE ${`${lt}%`}
773
806
  `, i = new Set(r.map((e) => e.tgname)), a = [], o = [];
774
807
  for (let e of n) {
775
- let t = i.has(`${ot}${e.tableName}`), n = e.isReactive !== !1;
808
+ let t = i.has(`${lt}${e.tableName}`), n = e.isReactive !== !1;
776
809
  n && !t && a.push(e.tableName), !n && t && o.push(e.tableName);
777
810
  }
778
811
  return {
779
812
  missing: a.sort(),
780
813
  stale: o.sort()
781
814
  };
782
- }), ct = (e) => {
815
+ }), dt = (e) => {
783
816
  let t = [];
784
817
  if (e.missing.length > 0) {
785
818
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -790,19 +823,19 @@ BEGIN
790
823
  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.`);
791
824
  }
792
825
  return t.length > 0 ? t.join("\n") : void 0;
793
- }, lt = /* @__PURE__ */ new Set(["voltro_isr_cache"]), ut = (e) => lt.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), dt = /__dropped_\d{14}$/, ft = (e) => dt.test(e), pt = {
826
+ }, ft = {
794
827
  postgres: !0,
795
828
  mysql: !0,
796
829
  mariadb: !0,
797
830
  mssql: !0,
798
831
  sqlite: !0
799
- }, mt = {
832
+ }, pt = {
800
833
  postgres: !0,
801
834
  mysql: !1,
802
835
  mariadb: !1,
803
836
  mssql: !0,
804
837
  sqlite: !0
805
- }, ht = (e) => {
838
+ }, mt = (e) => {
806
839
  switch (e) {
807
840
  case "add-column":
808
841
  case "drop-column":
@@ -812,43 +845,43 @@ BEGIN
812
845
  case "add-foreign-key":
813
846
  case "add-unique":
814
847
  case "add-unique-composite":
815
- case "add-check": return mt;
816
- default: return pt;
848
+ case "add-check": return pt;
849
+ default: return ft;
817
850
  }
818
- }, gt = (e, t) => {
851
+ }, ht = (e, t) => {
819
852
  let n = new Map(t.tables.map((e) => [e.name, e]));
820
853
  return new Map(e.map((e) => [e.tableName, {
821
854
  table: e,
822
855
  snapshot: n.get(e.tableName),
823
856
  columnDefs: e.fields
824
857
  }]));
825
- }, P = (e) => {
858
+ }, I = (e) => {
826
859
  if (typeof e != "object" || !e) return JSON.stringify(e);
827
- if (Array.isArray(e)) return `[${e.map(P).join(",")}]`;
860
+ if (Array.isArray(e)) return `[${e.map(I).join(",")}]`;
828
861
  let t = e;
829
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${P(t[e])}`).join(",")}}`;
830
- }, _t = (e) => {
862
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${I(t[e])}`).join(",")}}`;
863
+ }, gt = (e) => {
831
864
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
832
865
  let t = e.defaultValue;
833
866
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
834
867
  if (typeof t == "number") return String(t);
835
- if (typeof t != "string") return P(t);
868
+ if (typeof t != "string") return I(t);
836
869
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
837
870
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
838
871
  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);
839
872
  if (o) try {
840
- return P(JSON.parse(o[1]));
873
+ return I(JSON.parse(o[1]));
841
874
  } catch {}
842
875
  if (a.startsWith("{") || a.startsWith("[")) try {
843
- return P(JSON.parse(a));
876
+ return I(JSON.parse(a));
844
877
  } catch {}
845
878
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
846
- }, vt = (e, t) => {
847
- let n = _t(e), r = _t(t);
879
+ }, _t = (e, t) => {
880
+ let n = gt(e), r = gt(t);
848
881
  if (n === r) return !0;
849
882
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
850
883
  return i(n) === i(r);
851
- }, F = (e) => {
884
+ }, L = (e) => {
852
885
  if (!e) return null;
853
886
  let t = (e) => e === "restrict" ? "noAction" : e;
854
887
  return {
@@ -857,25 +890,25 @@ BEGIN
857
890
  onDelete: t(e.onDelete),
858
891
  onUpdate: t(e.onUpdate)
859
892
  };
860
- }, yt = (e, t) => {
893
+ }, vt = (e, t) => {
861
894
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
862
895
  if (!n && !r) return !0;
863
896
  if (!n || !r || n.length !== r.length) return !1;
864
897
  let i = [...n].sort(), a = [...r].sort();
865
898
  return i.every((e, t) => e === a[t]);
866
- }, bt = (e, t) => {
899
+ }, yt = (e, t) => {
867
900
  try {
868
- let n = /\((\d+)\)/.exec(E(e, t));
901
+ let n = /\((\d+)\)/.exec(D(e, t));
869
902
  return n ? Number(n[1]) : void 0;
870
903
  } catch {
871
904
  return;
872
905
  }
873
- }, xt = (e, t, n) => n === void 0 || u(n) ? !0 : e.type !== "text" || t.type !== "text" || bt(e, n) === t.maxLength, St = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && vt(e, t) && xt(e, t, n) && JSON.stringify(F(e.references)) === JSON.stringify(F(t.references)) && yt(e.oneOf, t.oneOf), Ct = (e, t) => t.oneOf && t.oneOf.length > 0 ? I({
906
+ }, bt = (t, n, r) => r === void 0 || e(r) ? !0 : t.type !== "text" || n.type !== "text" || yt(t, r) === n.maxLength, xt = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && _t(e, t) && bt(e, t, n) && JSON.stringify(L(e.references)) === JSON.stringify(L(t.references)) && vt(e.oneOf, t.oneOf), St = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
874
907
  kind: "add-check",
875
908
  table: e,
876
909
  column: t.name,
877
910
  values: t.oneOf
878
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, wt = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), Tt = (e, t, n) => {
911
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, Ct = (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])), wt = (e, t, n) => {
879
912
  let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [];
880
913
  for (let t of e.columns) {
881
914
  let e = r.get(t.name);
@@ -883,7 +916,7 @@ BEGIN
883
916
  a.push(t);
884
917
  continue;
885
918
  }
886
- St(t, e, n) || s.push({
919
+ xt(t, e, n) || s.push({
887
920
  declared: t,
888
921
  live: e
889
922
  });
@@ -894,47 +927,47 @@ BEGIN
894
927
  removed: o,
895
928
  changed: s
896
929
  };
897
- }, Et = (e, t) => {
930
+ }, Tt = (e, t) => {
898
931
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
899
932
  for (let t of e.indexes) {
900
933
  let e = n.get(t.name);
901
- (!e || !wt(t, e)) && i.push(t);
934
+ (!e || !Ct(t, e)) && i.push(t);
902
935
  }
903
936
  for (let e of t.indexes) r.has(e.name) || a.push(e);
904
937
  return {
905
938
  added: i,
906
939
  removed: a
907
940
  };
908
- }, I = (e, t, n, r) => ({
941
+ }, R = (e, t, n, r) => ({
909
942
  op: e,
910
943
  classification: t,
911
- atomicByDialect: ht(e.kind),
944
+ atomicByDialect: mt(e.kind),
912
945
  ...n ? { reason: n } : {},
913
946
  ...r ? { blocked: r } : {}
914
- }), Dt = (e, t, n) => {
947
+ }), Et = (e, t, n) => {
915
948
  let r = {
916
949
  kind: "add-column",
917
950
  table: e,
918
951
  column: t
919
952
  };
920
- return t.nullable ? I(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? I(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? I(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : I(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
921
- }, Ot = (e, t, n) => {
953
+ return t.nullable ? R(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? R(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? R(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : R(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
954
+ }, Dt = (e, t, n) => {
922
955
  let r = {
923
956
  kind: "drop-column",
924
957
  table: e,
925
958
  column: t.name
926
959
  };
927
- return n?.dropped ? I(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : I(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
928
- }, kt = (e, t, n, r, i) => I({
960
+ return n?.dropped ? R(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : R(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
961
+ }, Ot = (e, t, n, r, i) => R({
929
962
  kind: "create-table",
930
963
  table: e,
931
964
  columns: t,
932
965
  indexes: n,
933
966
  ...r && r.length > 0 ? { primaryKey: r } : {}
934
- }, "safe", i ?? "new table — no data to preserve"), At = (e) => I({
967
+ }, "safe", i ?? "new table — no data to preserve"), kt = (e) => R({
935
968
  kind: "drop-table",
936
969
  table: e
937
- }, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), jt = 5e4, Mt = (e, t, n, r) => {
970
+ }, "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" }), At = 5e4, jt = (e, t, n, r) => {
938
971
  let i = (n ?? 0) >= r, a;
939
972
  return a = t.unique ? t.columns.length === 1 ? {
940
973
  kind: "add-unique",
@@ -949,16 +982,16 @@ BEGIN
949
982
  kind: "add-index",
950
983
  table: e,
951
984
  index: t
952
- }, i ? I(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : I(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
953
- }, Nt = (e, t) => t.unique && t.columns.length > 1 ? I({
985
+ }, i ? R(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
986
+ }, Mt = (e, t) => t.unique && t.columns.length > 1 ? R({
954
987
  kind: "drop-unique-composite",
955
988
  table: e,
956
989
  name: t.name
957
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : I({
990
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
958
991
  kind: "drop-index",
959
992
  table: e,
960
993
  index: t.name
961
- }, "safe", "drop index (no data loss — index is derived data)"), Pt = (e, t) => {
994
+ }, "safe", "drop index (no data loss — index is derived data)"), Nt = (e, t) => {
962
995
  if (e === "reference") return "text";
963
996
  switch (t) {
964
997
  case "sqlite":
@@ -966,106 +999,106 @@ BEGIN
966
999
  case "mssql": return e === "json" ? "text" : e;
967
1000
  default: return e;
968
1001
  }
969
- }, Ft = (e, t, n, r, i, a) => {
970
- let o = [];
971
- if (t.nullable !== n.nullable) {
972
- let n = {
1002
+ }, Pt = (t, n, r, i, a, o) => {
1003
+ let s = [];
1004
+ if (n.nullable !== r.nullable) {
1005
+ let e = {
973
1006
  kind: "alter-column-nullability",
974
- table: e,
975
- column: t.name,
976
- toNullable: t.nullable
1007
+ table: t,
1008
+ column: n.name,
1009
+ toNullable: n.nullable
977
1010
  };
978
- o.push(t.nullable ? I(n, "safe", `loosen ${e}.${t.name} to nullable`) : I(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1011
+ s.push(n.nullable ? R(e, "safe", `loosen ${t}.${n.name} to nullable`) : R(e, "needs-backfill", `tighten ${t}.${n.name} to NOT NULL — existing rows must already be non-null`));
979
1012
  }
980
- if (t.unique !== n.unique) if (t.unique) {
981
- let n = {
1013
+ if (n.unique !== r.unique) if (n.unique) {
1014
+ let e = {
982
1015
  kind: "add-unique",
983
- table: e,
984
- column: t.name
985
- }, r = (i ?? 0) >= a;
986
- o.push(r ? I(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : I(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
987
- } else o.push(I({
1016
+ table: t,
1017
+ column: n.name
1018
+ }, r = (a ?? 0) >= o;
1019
+ s.push(r ? R(e, "online-required", `online unique build on ${a} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(e, "safe", `add unique constraint on ${t}.${n.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1020
+ } else s.push(R({
988
1021
  kind: "drop-unique",
989
- table: e,
990
- column: t.name
991
- }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
992
- if (Pt(t.type, r) !== Pt(n.type, r)) {
993
- let r = t.narrowedFrom;
994
- if (r && r.from === n.type) {
1022
+ table: t,
1023
+ column: n.name
1024
+ }, "safe", `drop unique constraint on ${t}.${n.name} — constraint is derived metadata, no data loss`));
1025
+ if (Nt(n.type, i) !== Nt(r.type, i)) {
1026
+ let e = n.narrowedFrom;
1027
+ if (e && e.from === r.type) {
995
1028
  let i = {
996
1029
  kind: "alter-column-type",
997
- table: e,
998
- column: t.name,
999
- from: n.type,
1000
- to: t.type,
1001
- ...r.using === void 0 ? {} : { using: r.using }
1030
+ table: t,
1031
+ column: n.name,
1032
+ from: r.type,
1033
+ to: n.type,
1034
+ ...e.using === void 0 ? {} : { using: e.using }
1002
1035
  };
1003
- o.push(I(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1036
+ s.push(R(i, "needs-backfill", `type change ${r.type} → ${n.type} on ${t}.${n.name} — narrowedFrom('${e.from}') declared` + (e.using ? ` with USING ${e.using}` : " (implicit cast)")));
1004
1037
  } else {
1005
- let r = {
1038
+ let e = {
1006
1039
  kind: "alter-column-type",
1007
- table: e,
1008
- column: t.name,
1009
- from: n.type,
1010
- to: t.type
1040
+ table: t,
1041
+ column: n.name,
1042
+ from: r.type,
1043
+ to: n.type
1011
1044
  };
1012
- o.push(I(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1045
+ s.push(R(e, "lossy", `type change ${r.type} → ${n.type} on ${t}.${n.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${r.type}', { using: '${n.name}::${n.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1013
1046
  }
1014
1047
  }
1015
- if (t.type === "text" && n.type === "text" && !u(r ?? "postgres") && t.maxLength !== n.maxLength) {
1016
- let r = t.maxLength === void 0 || n.maxLength !== void 0 && t.maxLength > n.maxLength, i = n.maxLength === void 0 ? "unbounded" : `varchar(${n.maxLength})`, a = t.maxLength === void 0 ? "unbounded" : `varchar(${t.maxLength})`;
1017
- o.push(I({
1048
+ if (n.type === "text" && r.type === "text" && !e(i ?? "postgres") && n.maxLength !== r.maxLength) {
1049
+ let e = n.maxLength === void 0 || r.maxLength !== void 0 && n.maxLength > r.maxLength, i = r.maxLength === void 0 ? "unbounded" : `varchar(${r.maxLength})`, a = n.maxLength === void 0 ? "unbounded" : `varchar(${n.maxLength})`;
1050
+ s.push(R({
1018
1051
  kind: "alter-column-type",
1019
- table: e,
1020
- column: t.name,
1052
+ table: t,
1053
+ column: n.name,
1021
1054
  from: "text",
1022
1055
  to: "text"
1023
- }, r ? "safe" : "needs-backfill", r ? `text length ${i} → ${a} on ${e}.${t.name} — widening, no data can be lost` : `text length ${i} → ${a} on ${e}.${t.name} — NARROWING; the ALTER fails if any existing value is longer than ${String(t.maxLength)}. Check first: SELECT COUNT(*) FROM ${e} WHERE LENGTH(${t.name}) > ${String(t.maxLength)}`));
1056
+ }, e ? "safe" : "needs-backfill", e ? `text length ${i} → ${a} on ${t}.${n.name} — widening, no data can be lost` : `text length ${i} → ${a} on ${t}.${n.name} — NARROWING; the ALTER fails if any existing value is longer than ${String(n.maxLength)}. Check first: SELECT COUNT(*) FROM ${t} WHERE LENGTH(${n.name}) > ${String(n.maxLength)}`));
1024
1057
  }
1025
- if (!vt(t, n)) {
1026
- let n = {
1058
+ if (!_t(n, r)) {
1059
+ let e = {
1027
1060
  kind: "alter-column-default",
1028
- table: e,
1029
- column: t.name,
1030
- hasDefault: t.hasDefault,
1031
- ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1061
+ table: t,
1062
+ column: n.name,
1063
+ hasDefault: n.hasDefault,
1064
+ ...n.defaultValue === void 0 ? {} : { defaultValue: n.defaultValue }
1032
1065
  };
1033
- o.push(I(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1066
+ s.push(R(e, "safe", `default change on ${t}.${n.name} affects only future inserts`));
1034
1067
  }
1035
- if (!yt(t.oneOf, n.oneOf)) {
1036
- n.oneOf && n.oneOf.length > 0 && o.push(I({
1068
+ if (!vt(n.oneOf, r.oneOf)) {
1069
+ r.oneOf && r.oneOf.length > 0 && s.push(R({
1037
1070
  kind: "drop-check",
1038
- table: e,
1039
- column: t.name
1040
- }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1041
- let r = Ct(e, t);
1042
- r && o.push(r);
1071
+ table: t,
1072
+ column: n.name
1073
+ }, "safe", `drop stale enum CHECK on ${t}.${n.name}`));
1074
+ let e = St(t, n);
1075
+ e && s.push(e);
1043
1076
  }
1044
- if (JSON.stringify(F(t.references)) !== JSON.stringify(F(n.references)) && (n.references && o.push(I({
1077
+ if (JSON.stringify(L(n.references)) !== JSON.stringify(L(r.references)) && (r.references && s.push(R({
1045
1078
  kind: "drop-foreign-key",
1046
- table: e,
1047
- column: t.name
1048
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), t.references)) {
1049
- let n = t.references.table, r = t.references.orphanPolicy ?? "fail", i = {
1079
+ table: t,
1080
+ column: n.name
1081
+ }, "safe", `drop FK on ${t}.${n.name} (→ ${r.references.table})`)), n.references)) {
1082
+ let e = n.references.table, r = n.references.orphanPolicy ?? "fail", i = {
1050
1083
  kind: "add-foreign-key",
1051
- table: e,
1052
- column: t.name,
1053
- targetTable: n,
1054
- targetColumn: t.references.column,
1055
- ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1056
- ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1084
+ table: t,
1085
+ column: n.name,
1086
+ targetTable: e,
1087
+ targetColumn: n.references.column,
1088
+ ...n.references.onDelete ? { onDelete: n.references.onDelete } : {},
1089
+ ...n.references.onUpdate ? { onUpdate: n.references.onUpdate } : {}
1057
1090
  };
1058
- r === "null" && !t.nullable ? o.push(I(i, "lossy", `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : r === "null" || r === "delete" ? o.push(I({
1091
+ r === "null" && !n.nullable ? s.push(R(i, "lossy", `add FK ${t}.${n.name} → ${e}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${n.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : r === "null" || r === "delete" ? s.push(R({
1059
1092
  ...i,
1060
1093
  orphanPolicy: r
1061
- }, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(I(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
1094
+ }, "lossy", r === "delete" ? `add FK ${t}.${n.name} → ${e}: orphanPolicy 'delete' first DELETES rows whose ${n.name} points at a missing ${e}` : `add FK ${t}.${n.name} → ${e}: orphanPolicy 'null' first NULLs ${n.name} where it points at a missing ${e}`)) : s.push(R(i, "needs-backfill", `add FK ${t}.${n.name} → ${e} — existing rows must already reference a valid ${e} (else set orphanPolicy:'null'/'delete')`));
1062
1095
  }
1063
- return o;
1064
- }, It = (e, t, n) => {
1096
+ return s;
1097
+ }, Ft = (e, t, n) => {
1065
1098
  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));
1066
1099
  for (let [n, c] of Object.entries(t)) {
1067
1100
  let t = c.renamedFrom;
1068
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(I({
1101
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1069
1102
  kind: "rename-column",
1070
1103
  table: e.tableName,
1071
1104
  from: t,
@@ -1077,26 +1110,26 @@ BEGIN
1077
1110
  consumedAddedNames: i,
1078
1111
  consumedRemovedNames: a
1079
1112
  };
1080
- }, Lt = /* @__PURE__ */ new Set([
1113
+ }, It = /* @__PURE__ */ new Set([
1081
1114
  "postgres",
1082
1115
  "mysql",
1083
1116
  "mariadb",
1084
1117
  "mssql"
1085
- ]), Rt = {
1118
+ ]), Lt = {
1086
1119
  ops: [],
1087
1120
  consumedAddedNames: /* @__PURE__ */ new Set(),
1088
1121
  consumedRemovedNames: /* @__PURE__ */ new Set()
1089
- }, zt = (e) => !e.unique && !e.expression, Bt = (e, t, n, r, i) => {
1090
- if (i === void 0 || !Lt.has(i)) return Rt;
1091
- let a = t.added.filter((e) => zt(e) && !r.has(e.name));
1092
- if (a.length === 0) return Rt;
1122
+ }, Rt = (e) => !e.unique && !e.expression, zt = (e, t, n, r, i) => {
1123
+ if (i === void 0 || !It.has(i)) return Lt;
1124
+ let a = t.added.filter((e) => Rt(e) && !r.has(e.name));
1125
+ if (a.length === 0) return Lt;
1093
1126
  let o = (e) => e.columns.map((e) => n.get(e) ?? e).join("\0"), s = (e) => e.columns.join("\0"), c = [], l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Set();
1094
1127
  for (let n of t.removed) {
1095
- if (!zt(n)) continue;
1128
+ if (!Rt(n)) continue;
1096
1129
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1097
1130
  if (r.length !== 1) continue;
1098
1131
  let i = r[0];
1099
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(I({
1132
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1100
1133
  kind: "rename-index",
1101
1134
  table: e,
1102
1135
  from: n.name,
@@ -1108,33 +1141,33 @@ BEGIN
1108
1141
  consumedAddedNames: l,
1109
1142
  consumedRemovedNames: u
1110
1143
  };
1111
- }, Vt = (e, t, n) => {
1144
+ }, Bt = (e, t, n) => {
1112
1145
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1113
1146
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1114
1147
  for (let c of e.tables) {
1115
1148
  let e = c.renamedFrom;
1116
1149
  if (e !== void 0 && e !== c.name && t.has(e)) {
1150
+ if (n.has(e)) {
1151
+ o.set(c.name, `.renamedFrom('${e}') NOT applied — '${e}' is still declared by this schema, so it belongs to that declaration. This table is created empty; that is the intended outcome when an app owns a table of the same name.`);
1152
+ continue;
1153
+ }
1117
1154
  if (t.has(c.name)) {
1118
- r.push(I({
1155
+ r.push(R({
1119
1156
  kind: "rename-table",
1120
1157
  from: e,
1121
1158
  to: c.name
1122
1159
  }, "needs-rename-annotation", `.renamedFrom('${e}') cannot be applied — both '${e}' and '${c.name}' exist in the database`, { fix: `decide which holds the real rows: move them into '${c.name}' and drop '${e}', or drop the empty '${c.name}' so the rename can run. '${e}' is left untouched until you do.` }));
1123
1160
  continue;
1124
1161
  }
1125
- if (n.has(e)) {
1126
- o.set(c.name, `.renamedFrom('${e}') NOT applied — '${e}' is still declared by this schema, so it belongs to that declaration. This table is created empty; that is the intended outcome when an app owns a table of the same name.`);
1127
- continue;
1128
- }
1129
1162
  if ((s.get(e) ?? 0) !== 1) {
1130
- r.push(I({
1163
+ r.push(R({
1131
1164
  kind: "rename-table",
1132
1165
  from: e,
1133
1166
  to: c.name
1134
1167
  }, "needs-rename-annotation", `.renamedFrom('${e}') is claimed by ${s.get(e)} tables — nothing says which receives its rows`, { fix: `remove the \`.renamedFrom('${e}')\` marker from all but one of them.` }));
1135
1168
  continue;
1136
1169
  }
1137
- i.set(c.name, e), a.add(e), r.push(I({
1170
+ i.set(c.name, e), a.add(e), r.push(R({
1138
1171
  kind: "rename-table",
1139
1172
  from: e,
1140
1173
  to: c.name
@@ -1148,19 +1181,19 @@ BEGIN
1148
1181
  claimedOldNames: c,
1149
1182
  refusals: o
1150
1183
  };
1151
- }, Ht = (e, t, n, r) => {
1184
+ }, Vt = (e, t, n, r) => {
1152
1185
  if (t === void 0) return {
1153
1186
  live: e,
1154
1187
  ops: []
1155
1188
  };
1156
- let i = r !== void 0 && Lt.has(r), a = [], o = e.indexes.map((e) => {
1189
+ let i = r !== void 0 && It.has(r), a = [], o = e.indexes.map((e) => {
1157
1190
  if (!e.name.startsWith(t)) return e;
1158
1191
  let r = `${n}${e.name.slice(t.length)}`;
1159
1192
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1160
1193
  ...e,
1161
1194
  name: r,
1162
1195
  table: n
1163
- } : i ? (a.push(I({
1196
+ } : i ? (a.push(R({
1164
1197
  kind: "rename-index",
1165
1198
  table: n,
1166
1199
  from: e.name,
@@ -1179,7 +1212,7 @@ BEGIN
1179
1212
  },
1180
1213
  ops: a
1181
1214
  };
1182
- }, Ut = (e) => {
1215
+ }, Ht = (e) => {
1183
1216
  let t = {
1184
1217
  safe: 0,
1185
1218
  needsDefault: 0,
@@ -1214,51 +1247,51 @@ BEGIN
1214
1247
  break;
1215
1248
  }
1216
1249
  return t;
1217
- }, Wt = (e) => {
1218
- let t = N(e.declared, e.dialect), n = gt(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? jt, a = [], o = Vt(t, r, n);
1250
+ }, Ut = (e) => {
1251
+ let t = F(e.declared, e.dialect), n = ht(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? At, a = [], o = Bt(t, r, n);
1219
1252
  a.push(...o.ops);
1220
1253
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1221
- a.push(kt(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1254
+ a.push(Ot(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1222
1255
  for (let t of e.columns) {
1223
- let n = Ct(e.name, t);
1256
+ let n = St(e.name, t);
1224
1257
  n && a.push(n);
1225
1258
  }
1226
1259
  }
1227
- let s = new Set(e.ignoreTables ?? []);
1228
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || ut(t.name) || ft(t.name) || s.has(t.name) || a.push(At(t.name));
1260
+ let c = new Set(e.ignoreTables ?? []);
1261
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || s(t.name) || d(t.name) || c.has(t.name) || a.push(kt(t.name));
1229
1262
  for (let s of t.tables) {
1230
1263
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1231
1264
  if (!c) continue;
1232
- let l = Ht(c, t, s.name, e.dialect);
1265
+ let l = Vt(c, t, s.name, e.dialect);
1233
1266
  a.push(...l.ops);
1234
- let u = l.live, d = n.get(s.name), f = Tt(s, u, e.dialect), p = Et(s, u), m = It(d.table, d.columnDefs, f);
1235
- a.push(...m.ops);
1236
- for (let e of f.removed) {
1237
- if (m.consumedRemovedNames.has(e.name) || ft(e.name)) continue;
1238
- let t = d.columnDefs[e.name];
1239
- a.push(Ot(s.name, e, t));
1240
- }
1241
- for (let e of f.added) {
1242
- if (m.consumedAddedNames.has(e.name)) continue;
1243
- let t = d.columnDefs[e.name];
1267
+ let u = l.live, f = n.get(s.name), p = wt(s, u, e.dialect), m = Tt(s, u), h = Ft(f.table, f.columnDefs, p);
1268
+ a.push(...h.ops);
1269
+ for (let e of p.removed) {
1270
+ if (h.consumedRemovedNames.has(e.name) || d(e.name)) continue;
1271
+ let t = f.columnDefs[e.name];
1244
1272
  a.push(Dt(s.name, e, t));
1245
- let n = Ct(s.name, e);
1273
+ }
1274
+ for (let e of p.added) {
1275
+ if (h.consumedAddedNames.has(e.name)) continue;
1276
+ let t = f.columnDefs[e.name];
1277
+ a.push(Et(s.name, e, t));
1278
+ let n = St(s.name, e);
1246
1279
  n && a.push(n);
1247
1280
  }
1248
- let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = Bt(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1249
- a.push(...g.ops);
1250
- for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(Mt(s.name, e, u.rowCount, i));
1251
- for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(Nt(s.name, e));
1252
- for (let { declared: t, live: n } of f.changed) a.push(...Ft(s.name, t, n, e.dialect, u.rowCount, i));
1253
- }
1254
- let c = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), l = new Map(t.tables.map((e) => [e.name, e])), u = (e) => {
1255
- let t = l.get(e);
1256
- return t ? t.columns.flatMap((e) => e.references && c.has(e.references.table) ? [{
1281
+ let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = zt(s.name, m, g, new Set(u.indexes.map((e) => e.name)), e.dialect);
1282
+ a.push(..._.ops);
1283
+ for (let e of m.added) _.consumedAddedNames.has(e.name) || a.push(jt(s.name, e, u.rowCount, i));
1284
+ for (let e of m.removed) _.consumedRemovedNames.has(e.name) || a.push(Mt(s.name, e));
1285
+ for (let { declared: t, live: n } of p.changed) a.push(...Pt(s.name, t, n, e.dialect, u.rowCount, i));
1286
+ }
1287
+ let l = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), u = new Map(t.tables.map((e) => [e.name, e])), f = (e) => {
1288
+ let t = u.get(e);
1289
+ return t ? t.columns.flatMap((e) => e.references && l.has(e.references.table) ? [{
1257
1290
  column: e.name,
1258
1291
  target: e.references.table
1259
1292
  }] : []) : [];
1260
- }, d = ne([...c], u), f = [];
1261
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(S(e.name, t.name)) || f.push(I({
1293
+ }, p = re([...l], f), m = [];
1294
+ for (let e of t.tables) if (l.has(e.name)) for (let t of e.columns) !t.references || !p.has(C(e.name, t.name)) || m.push(R({
1262
1295
  kind: "add-foreign-key",
1263
1296
  table: e.name,
1264
1297
  column: t.name,
@@ -1267,14 +1300,14 @@ BEGIN
1267
1300
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1268
1301
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1269
1302
  }, "safe", `deferred FK ${e.name}.${t.name} → ${t.references.table} — breaks a create-time table cycle`));
1270
- if (d.size > 0) {
1303
+ if (p.size > 0) {
1271
1304
  let e = (e) => e.references ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "references")) : e;
1272
1305
  for (let t = 0; t < a.length; t += 1) {
1273
1306
  let n = a[t];
1274
1307
  if (n.op.kind !== "create-table") continue;
1275
1308
  let r = n.op;
1276
- if (!r.columns.some((e) => d.has(S(r.table, e.name)))) continue;
1277
- let i = r.columns.map((t) => d.has(S(r.table, t.name)) ? e(t) : t);
1309
+ if (!r.columns.some((e) => p.has(C(r.table, e.name)))) continue;
1310
+ let i = r.columns.map((t) => p.has(C(r.table, t.name)) ? e(t) : t);
1278
1311
  a[t] = {
1279
1312
  ...n,
1280
1313
  op: {
@@ -1283,24 +1316,24 @@ BEGIN
1283
1316
  }
1284
1317
  };
1285
1318
  }
1286
- a.push(...f);
1319
+ a.push(...m);
1287
1320
  }
1288
- let p = new Map(t.tables.map((e) => [e.name, e])), m = /* @__PURE__ */ new Map(), h = (e, t = /* @__PURE__ */ new Set()) => {
1289
- let n = m.get(e);
1321
+ let h = new Map(t.tables.map((e) => [e.name, e])), g = /* @__PURE__ */ new Map(), _ = (e, t = /* @__PURE__ */ new Set()) => {
1322
+ let n = g.get(e);
1290
1323
  if (n !== void 0) return n;
1291
1324
  if (t.has(e)) return 0;
1292
- let r = p.get(e);
1325
+ let r = h.get(e);
1293
1326
  if (!r) return 0;
1294
1327
  let i = new Set(t).add(e), a = 0;
1295
1328
  for (let t of r.columns) {
1296
1329
  let n = t.references?.table;
1297
- n && n !== e && !d.has(S(e, t.name)) && (a = Math.max(a, h(n, i) + 1));
1330
+ n && n !== e && !p.has(C(e, t.name)) && (a = Math.max(a, _(n, i) + 1));
1298
1331
  }
1299
- return m.set(e, a), a;
1300
- }, g = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, ee = (e) => {
1332
+ return g.set(e, a), a;
1333
+ }, v = (e) => e === "rename-table" ? -1 : e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, y = (e) => {
1301
1334
  let t = "table" in e ? e.table : "";
1302
- return e.kind === "create-table" ? h(t) : e.kind === "drop-table" ? -h(t) : 0;
1303
- }, _ = {
1335
+ return e.kind === "create-table" ? _(t) : e.kind === "drop-table" ? -_(t) : 0;
1336
+ }, b = {
1304
1337
  "add-column": 0,
1305
1338
  "rename-column": 1,
1306
1339
  "rename-index": 1,
@@ -1318,23 +1351,23 @@ BEGIN
1318
1351
  "add-unique-composite": 5,
1319
1352
  "add-foreign-key": 5,
1320
1353
  "add-check": 5
1321
- }, v = (e) => _[e] ?? 9, y = [...a].sort((e, t) => {
1322
- let n = g(e.op.kind), r = g(t.op.kind);
1354
+ }, x = (e) => b[e] ?? 9, S = [...a].sort((e, t) => {
1355
+ let n = v(e.op.kind), r = v(t.op.kind);
1323
1356
  if (n !== r) return n - r;
1324
- let i = ee(e.op), a = ee(t.op);
1357
+ let i = y(e.op), a = y(t.op);
1325
1358
  if (i !== a) return i - a;
1326
1359
  let o = "table" in e.op ? e.op.table : "", s = "table" in t.op ? t.op.table : "";
1327
1360
  if (o !== s) return o.localeCompare(s);
1328
- let c = v(e.op.kind), l = v(t.op.kind);
1361
+ let c = x(e.op.kind), l = x(t.op.kind);
1329
1362
  return c === l ? e.op.kind.localeCompare(t.op.kind) : c - l;
1330
1363
  });
1331
1364
  return {
1332
- operations: y,
1333
- fromFingerprint: j(e.live),
1334
- toFingerprint: j(t),
1335
- summary: Ut(y)
1365
+ operations: S,
1366
+ fromFingerprint: N(e.live),
1367
+ toFingerprint: N(t),
1368
+ summary: Ht(S)
1336
1369
  };
1337
- }, Gt = (e) => {
1370
+ }, Wt = (e) => {
1338
1371
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1339
1372
  if (!t) return null;
1340
1373
  let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
@@ -1342,7 +1375,7 @@ BEGIN
1342
1375
  column: t[1],
1343
1376
  values: n
1344
1377
  };
1345
- }, Kt = (e, t) => {
1378
+ }, Gt = (e, t) => {
1346
1379
  if (t === "vector") return "vector";
1347
1380
  switch (e) {
1348
1381
  case "text":
@@ -1369,7 +1402,7 @@ BEGIN
1369
1402
  case "USER-DEFINED": return "text";
1370
1403
  default: return "text";
1371
1404
  }
1372
- }, L = (e) => {
1405
+ }, z = (e) => {
1373
1406
  switch (e.toUpperCase()) {
1374
1407
  case "CASCADE": return "cascade";
1375
1408
  case "RESTRICT": return "restrict";
@@ -1377,25 +1410,25 @@ BEGIN
1377
1410
  case "SET DEFAULT": return "noAction";
1378
1411
  default: return "noAction";
1379
1412
  }
1380
- }, qt = (e, t) => {
1413
+ }, Kt = (e, t) => {
1381
1414
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1382
1415
  return Number.isInteger(n) && n > 0 ? n : t;
1383
- }, Jt = () => qt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Yt = 300, Xt = () => {
1416
+ }, qt = () => Kt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Jt = 300, Yt = () => {
1384
1417
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1385
- return e !== void 0 && e.trim() === "0" ? 0 : qt(e, 3e4);
1386
- }, Zt = (e, t) => {
1418
+ return e !== void 0 && e.trim() === "0" ? 0 : Kt(e, 3e4);
1419
+ }, Xt = (e, t) => {
1387
1420
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1388
1421
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1389
1422
  return r;
1390
- }, Qt = (e) => {
1391
- let t = Xt(), n = d.gen(function* () {
1423
+ }, Zt = (e) => {
1424
+ let t = Yt(), n = p.gen(function* () {
1392
1425
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1393
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Jt(), a = (e, t) => d.gen(function* () {
1426
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = qt(), a = (e, t) => p.gen(function* () {
1394
1427
  let r = [];
1395
- for (let a of Zt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1428
+ for (let a of Xt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1396
1429
  return r;
1397
1430
  }), o = [];
1398
- for (let t = 0;; t += Yt) {
1431
+ for (let t = 0;; t += Jt) {
1399
1432
  let n = yield* e`
1400
1433
  SELECT c.relname AS table_name,
1401
1434
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1403,9 +1436,9 @@ BEGIN
1403
1436
  JOIN pg_namespace n ON n.oid = c.relnamespace
1404
1437
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1405
1438
  ORDER BY c.relname
1406
- LIMIT ${r(Yt)} OFFSET ${r(t)}
1439
+ LIMIT ${r(Jt)} OFFSET ${r(t)}
1407
1440
  `;
1408
- if (o.push(...n), n.length < Yt) break;
1441
+ if (o.push(...n), n.length < Jt) break;
1409
1442
  }
1410
1443
  let s = /* @__PURE__ */ new Set(), c = [];
1411
1444
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
@@ -1415,7 +1448,7 @@ BEGIN
1415
1448
  FROM information_schema.columns
1416
1449
  WHERE table_schema = current_schema() AND table_name IN ${t}
1417
1450
  ORDER BY table_name, ordinal_position
1418
- `), f = yield* a(l, (t) => e`
1451
+ `), d = yield* a(l, (t) => e`
1419
1452
  SELECT rel.relname AS table_name, att.attname AS column_name
1420
1453
  FROM pg_constraint con
1421
1454
  JOIN pg_class rel ON rel.oid = con.conrelid
@@ -1424,7 +1457,7 @@ BEGIN
1424
1457
  WHERE con.contype = 'p' AND nsp.nspname = current_schema()
1425
1458
  AND rel.relname IN ${t}
1426
1459
  ORDER BY rel.relname, array_position(con.conkey, att.attnum)
1427
- `), p = yield* a(l, (t) => e`
1460
+ `), f = yield* a(l, (t) => e`
1428
1461
  SELECT rel.relname AS table_name, con.conname AS constraint_name,
1429
1462
  att.attname AS column_name, array_position(con.conkey, att.attnum) AS position
1430
1463
  FROM pg_constraint con
@@ -1470,7 +1503,7 @@ BEGIN
1470
1503
  WHERE con.contype = 'f' AND nsp.nspname = current_schema()
1471
1504
  AND rel.relname IN ${t}
1472
1505
  ORDER BY rel.relname, con.conname, ck.ord
1473
- `), ee = yield* a(l, (t) => e`
1506
+ `), _ = yield* a(l, (t) => e`
1474
1507
  WITH ix AS (
1475
1508
  SELECT
1476
1509
  c.relname AS table_name,
@@ -1491,34 +1524,34 @@ BEGIN
1491
1524
  AND c.relname IN ${t}
1492
1525
  )
1493
1526
  SELECT * FROM ix ORDER BY table_name, index_name, position
1494
- `), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
1527
+ `), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), ee = /* @__PURE__ */ new Map();
1495
1528
  for (let e of u) {
1496
- let t = _.get(e.table_name);
1497
- t || (t = [], _.set(e.table_name, t)), t.push(e);
1498
- }
1499
- for (let e of f) {
1500
1529
  let t = v.get(e.table_name);
1501
- t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
1530
+ t || (t = [], v.set(e.table_name, t)), t.push(e);
1531
+ }
1532
+ for (let e of d) {
1533
+ let t = y.get(e.table_name);
1534
+ t || (t = /* @__PURE__ */ new Set(), y.set(e.table_name, t)), t.add(e.column_name);
1502
1535
  }
1503
- let S = /* @__PURE__ */ new Map();
1504
- for (let e of p) {
1505
- let t = `${e.table_name}\u0000${e.constraint_name}`, n = S.get(t);
1536
+ let te = /* @__PURE__ */ new Map();
1537
+ for (let e of f) {
1538
+ let t = `${e.table_name}\u0000${e.constraint_name}`, n = te.get(t);
1506
1539
  n || (n = {
1507
1540
  table: e.table_name,
1508
1541
  columns: []
1509
- }, S.set(t, n)), n.columns.push({
1542
+ }, te.set(t, n)), n.columns.push({
1510
1543
  name: e.column_name,
1511
1544
  position: e.position
1512
1545
  });
1513
1546
  }
1514
- for (let [e, t] of S) {
1547
+ for (let [e, t] of te) {
1515
1548
  let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
1516
1549
  if (n.length === 1) {
1517
- let e = y.get(t.table);
1518
- e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
1550
+ let e = b.get(t.table);
1551
+ e || (e = /* @__PURE__ */ new Set(), b.set(t.table, e)), e.add(n[0]);
1519
1552
  } else {
1520
- let r = b.get(t.table);
1521
- r || (r = [], b.set(t.table, r)), r.push({
1553
+ let r = x.get(t.table);
1554
+ r || (r = [], x.set(t.table, r)), r.push({
1522
1555
  name: e.slice(e.indexOf("\0") + 1),
1523
1556
  table: t.table,
1524
1557
  columns: n,
@@ -1527,28 +1560,28 @@ BEGIN
1527
1560
  }
1528
1561
  }
1529
1562
  for (let e of g) {
1530
- let t = te.get(e.source_table);
1531
- t || (t = [], te.set(e.source_table, t)), t.push(e);
1563
+ let t = S.get(e.source_table);
1564
+ t || (t = [], S.set(e.source_table, t)), t.push(e);
1532
1565
  }
1533
- for (let e of ee) {
1534
- let t = x.get(e.table_name);
1535
- t || (t = /* @__PURE__ */ new Map(), x.set(e.table_name, t));
1566
+ for (let e of _) {
1567
+ let t = ee.get(e.table_name);
1568
+ t || (t = /* @__PURE__ */ new Map(), ee.set(e.table_name, t));
1536
1569
  let n = t.get(e.index_name);
1537
1570
  n || (n = [], t.set(e.index_name, n)), n.push(e);
1538
1571
  }
1539
1572
  let ne = [];
1540
1573
  for (let e of c) {
1541
- let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = te.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
1542
- let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Kt(t.data_type, t.udt_name), c = a ? {
1574
+ let t = /* @__PURE__ */ new Set(), n = (v.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = b.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = S.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) => {
1575
+ 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" : Gt(t.data_type, t.udt_name), c = a ? {
1543
1576
  table: a.target_table,
1544
1577
  column: a.target_column,
1545
- onDelete: L(a.delete_rule),
1546
- onUpdate: L(a.update_rule)
1578
+ onDelete: z(a.delete_rule),
1579
+ onUpdate: z(a.update_rule)
1547
1580
  } : void 0, l = h.get(`${e.table_name}.${t.column_name}`);
1548
1581
  return {
1549
1582
  name: t.column_name,
1550
1583
  type: s,
1551
- ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1584
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1552
1585
  nullable: t.is_nullable === "YES",
1553
1586
  unique: i.has(t.column_name) || n && t.column_name === "id",
1554
1587
  hasDefault: t.column_default !== null,
@@ -1556,7 +1589,7 @@ BEGIN
1556
1589
  ...c ? { references: c } : {},
1557
1590
  ...l ? { oneOf: l } : {}
1558
1591
  };
1559
- }), l = [], u = x.get(e.table_name);
1592
+ }), l = [], u = ee.get(e.table_name);
1560
1593
  if (u) for (let [t, n] of u) {
1561
1594
  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) => {
1562
1595
  let t = e.position;
@@ -1572,7 +1605,7 @@ BEGIN
1572
1605
  ...a ? { expression: !0 } : {}
1573
1606
  });
1574
1607
  }
1575
- for (let t of b.get(e.table_name) ?? []) l.push(t);
1608
+ for (let t of x.get(e.table_name) ?? []) l.push(t);
1576
1609
  r.size > 0 && l.push({
1577
1610
  name: `${e.table_name}_pkey`,
1578
1611
  table: e.table_name,
@@ -1589,11 +1622,11 @@ BEGIN
1589
1622
  }
1590
1623
  return { tables: ne };
1591
1624
  });
1592
- return (t > 0 ? e.withTransaction(n) : n).pipe(d.catchAll((e) => {
1625
+ return (t > 0 ? e.withTransaction(n) : n).pipe(p.catchAll((e) => {
1593
1626
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1594
- return n.includes("statement timeout") || n.includes("57014") ? d.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : d.fail(e);
1627
+ return n.includes("statement timeout") || n.includes("57014") ? p.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.`)) : p.fail(e);
1595
1628
  }));
1596
- }, $t = (e, t) => {
1629
+ }, Qt = (e, t) => {
1597
1630
  switch (e.toLowerCase()) {
1598
1631
  case "varchar":
1599
1632
  case "char":
@@ -1625,21 +1658,21 @@ BEGIN
1625
1658
  case "json": return "json";
1626
1659
  default: return "text";
1627
1660
  }
1628
- }, R = (e) => e.map((e) => {
1661
+ }, B = (e) => e.map((e) => {
1629
1662
  let t = e, n = {};
1630
1663
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1631
1664
  return n;
1632
- }), en = (e) => d.gen(function* () {
1633
- let t = R(yield* e`
1665
+ }), $t = (e) => p.gen(function* () {
1666
+ let t = B(yield* e`
1634
1667
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1635
1668
  FROM information_schema.tables
1636
1669
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1637
- ORDER BY table_name`), n = R(yield* e`
1670
+ ORDER BY table_name`), n = B(yield* e`
1638
1671
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1639
1672
  character_maximum_length
1640
1673
  FROM information_schema.columns
1641
1674
  WHERE table_schema = DATABASE()
1642
- ORDER BY table_name, ordinal_position`), r = R(yield* e`
1675
+ ORDER BY table_name, ordinal_position`), r = B(yield* e`
1643
1676
  SELECT k.table_name AS source_table,
1644
1677
  k.column_name AS source_column,
1645
1678
  k.referenced_table_name AS target_table,
@@ -1649,21 +1682,21 @@ BEGIN
1649
1682
  JOIN information_schema.referential_constraints r
1650
1683
  ON k.constraint_name = r.constraint_name
1651
1684
  AND k.table_schema = r.constraint_schema
1652
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = R(yield* e`
1685
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = B(yield* e`
1653
1686
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1654
1687
  FROM information_schema.statistics
1655
1688
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1656
- ORDER BY table_name, index_name, seq_in_index`), a = R(yield* e`
1689
+ ORDER BY table_name, index_name, seq_in_index`), a = B(yield* e`
1657
1690
  SELECT table_name, check_clause
1658
1691
  FROM information_schema.check_constraints
1659
- WHERE constraint_schema = DATABASE()`.unprepared.pipe(d.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
1692
+ WHERE constraint_schema = DATABASE()`.unprepared.pipe(p.orElseSucceed(() => []))), o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
1660
1693
  for (let e of a) {
1661
1694
  let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
1662
1695
  if (t) {
1663
1696
  o.add(`${e.table_name}.${t[1]}`);
1664
1697
  continue;
1665
1698
  }
1666
- let n = Gt(e.check_clause);
1699
+ let n = Wt(e.check_clause);
1667
1700
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1668
1701
  }
1669
1702
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1681,22 +1714,22 @@ BEGIN
1681
1714
  let n = t.get(e.index_name) ?? [];
1682
1715
  n.push(e), t.set(e.index_name, n);
1683
1716
  }
1684
- let f = [];
1717
+ let d = [];
1685
1718
  for (let e of t) {
1686
- let t = c.get(e.table_name) ?? [], n = l.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), d = u.get(e.table_name);
1687
- if (d) for (let e of d.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1719
+ 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(), f = u.get(e.table_name);
1720
+ if (f) for (let e of f.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1688
1721
  let p = t.map((t) => {
1689
- let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : $t(t.data_type, t.column_type), u = c ? {
1722
+ 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" : Qt(t.data_type, t.column_type), u = c ? {
1690
1723
  table: c.target_table,
1691
1724
  column: c.target_column,
1692
- onDelete: L(c.delete_rule),
1693
- onUpdate: L(c.update_rule)
1725
+ onDelete: z(c.delete_rule),
1726
+ onUpdate: z(c.update_rule)
1694
1727
  } : 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}`);
1695
1728
  return {
1696
1729
  name: t.column_name,
1697
1730
  type: l,
1698
1731
  nullable: t.is_nullable === "YES",
1699
- ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1732
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1700
1733
  unique: d,
1701
1734
  hasDefault: f !== null,
1702
1735
  ...f === null ? {} : { defaultValue: f },
@@ -1704,7 +1737,7 @@ BEGIN
1704
1737
  ...p ? { oneOf: p } : {}
1705
1738
  };
1706
1739
  }), m = new Set(n.map((e) => e.source_column)), h = [];
1707
- if (d) for (let [t, n] of d) {
1740
+ if (f) for (let [t, n] of f) {
1708
1741
  let r = [...n].sort((e, t) => e.seq_in_index - t.seq_in_index);
1709
1742
  r.length === 1 && r[0].non_unique === 0 || r.length === 1 && r[0].non_unique !== 0 && m.has(r[0].column_name) && t !== `${e.table_name}_${r[0].column_name}_idx` || h.push({
1710
1743
  name: t,
@@ -1720,18 +1753,18 @@ BEGIN
1720
1753
  unique: !0
1721
1754
  });
1722
1755
  let g = Number(e.table_rows ?? 0);
1723
- f.push({
1756
+ d.push({
1724
1757
  name: e.table_name,
1725
1758
  columns: p,
1726
1759
  indexes: h,
1727
1760
  ...g > 0 ? { rowCount: g } : {}
1728
1761
  });
1729
1762
  }
1730
- return { tables: f };
1731
- }), tn = (e) => {
1763
+ return { tables: d };
1764
+ }), en = (e) => {
1732
1765
  let t = e.toUpperCase();
1733
1766
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1734
- }, nn = (e) => d.gen(function* () {
1767
+ }, tn = (e) => p.gen(function* () {
1735
1768
  let t = yield* e`
1736
1769
  SELECT name, sql FROM sqlite_master
1737
1770
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1748,11 +1781,11 @@ BEGIN
1748
1781
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1749
1782
  }
1750
1783
  let p = o.map((e) => {
1751
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : tn(e.type), a = r ? {
1784
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : en(e.type), a = r ? {
1752
1785
  table: r.table,
1753
1786
  column: r.to,
1754
- onDelete: L(r.on_delete),
1755
- onUpdate: L(r.on_update)
1787
+ onDelete: z(r.on_delete),
1788
+ onUpdate: z(r.on_update)
1756
1789
  } : void 0, o = t.get(e.name);
1757
1790
  return {
1758
1791
  name: e.name,
@@ -1787,7 +1820,7 @@ BEGIN
1787
1820
  });
1788
1821
  }
1789
1822
  return { tables: r };
1790
- }), rn = (e) => {
1823
+ }), nn = (e) => {
1791
1824
  switch (e.toLowerCase()) {
1792
1825
  case "int":
1793
1826
  case "smallint":
@@ -1809,7 +1842,7 @@ BEGIN
1809
1842
  case "image": return "bytes";
1810
1843
  default: return "text";
1811
1844
  }
1812
- }, z = (e) => e === !0 || e === 1, an = (e) => d.gen(function* () {
1845
+ }, V = (e) => e === !0 || e === 1, rn = (e) => p.gen(function* () {
1813
1846
  let t = yield* e`
1814
1847
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
1815
1848
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
@@ -1866,21 +1899,21 @@ BEGIN
1866
1899
  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();
1867
1900
  if (a) for (let [, e] of a) {
1868
1901
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
1869
- if (z(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1870
- else z(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1902
+ if (V(t[0].is_primary)) for (let e of t) d.push(e.column_name);
1903
+ else V(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
1871
1904
  }
1872
1905
  let p = t.map((t) => {
1873
- let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : rn(t.data_type), s = i ? {
1906
+ 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" : nn(t.data_type), s = i ? {
1874
1907
  table: i.target_table,
1875
1908
  column: i.target_column,
1876
- onDelete: on(i.delete_rule),
1877
- onUpdate: on(i.update_rule)
1878
- } : void 0, c = t.column_default === null ? null : sn(t.column_default), l = o.get(`${e}.${t.column_name}`);
1909
+ onDelete: an(i.delete_rule),
1910
+ onUpdate: an(i.update_rule)
1911
+ } : void 0, c = t.column_default === null ? null : on(t.column_default), l = o.get(`${e}.${t.column_name}`);
1879
1912
  return {
1880
1913
  name: t.column_name,
1881
1914
  type: a,
1882
1915
  nullable: t.is_nullable === "YES",
1883
- ...B(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: B(t.data_type, t.character_maximum_length) },
1916
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1884
1917
  unique: f.has(t.column_name) || n && t.column_name === "id",
1885
1918
  hasDefault: c !== null,
1886
1919
  ...c === null ? {} : { defaultValue: c },
@@ -1890,11 +1923,11 @@ BEGIN
1890
1923
  }), m = [];
1891
1924
  if (a) for (let [t, n] of a) {
1892
1925
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
1893
- z(r[0].is_primary) || r.length === 1 && z(r[0].is_unique) || r.length === 1 && !z(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1926
+ V(r[0].is_primary) || r.length === 1 && V(r[0].is_unique) || r.length === 1 && !V(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
1894
1927
  name: t,
1895
1928
  table: e,
1896
1929
  columns: r.map((e) => e.column_name),
1897
- unique: z(r[0].is_unique)
1930
+ unique: V(r[0].is_unique)
1898
1931
  });
1899
1932
  }
1900
1933
  d.length > 0 && m.push({
@@ -1909,48 +1942,48 @@ BEGIN
1909
1942
  });
1910
1943
  }
1911
1944
  return { tables: u };
1912
- }), on = (e) => {
1945
+ }), an = (e) => {
1913
1946
  switch (e.toUpperCase().replace(/_/g, " ")) {
1914
1947
  case "CASCADE": return "cascade";
1915
1948
  case "SET NULL": return "setNull";
1916
1949
  case "SET DEFAULT": return "noAction";
1917
1950
  default: return "noAction";
1918
1951
  }
1919
- }, sn = (e) => {
1952
+ }, on = (e) => {
1920
1953
  let t = e.trim();
1921
1954
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
1922
1955
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
1923
- }, cn = /* @__PURE__ */ new Set([
1956
+ }, sn = /* @__PURE__ */ new Set([
1924
1957
  "character varying",
1925
1958
  "varchar",
1926
1959
  "nvarchar",
1927
1960
  "char",
1928
1961
  "character",
1929
1962
  "nchar"
1930
- ]), B = (e, t) => {
1931
- if (!cn.has(e.toLowerCase())) return;
1963
+ ]), H = (e, t) => {
1964
+ if (!sn.has(e.toLowerCase())) return;
1932
1965
  let n = Number(t);
1933
1966
  if (!(!Number.isFinite(n) || n <= 0)) return n;
1934
- }, V = (e) => e.onDialectOrElse({
1935
- mysql: () => en(e),
1936
- mssql: () => an(e),
1937
- sqlite: () => nn(e),
1938
- orElse: () => Qt(e)
1939
- }), ln = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
1967
+ }, U = (e) => e.onDialectOrElse({
1968
+ mysql: () => $t(e),
1969
+ mssql: () => rn(e),
1970
+ sqlite: () => tn(e),
1971
+ orElse: () => Zt(e)
1972
+ }), cn = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, ln = (e, t) => {
1940
1973
  if (!(e.type === "text" && e.maxLength !== void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
1941
1974
  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;
1942
1975
  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.`);
1943
- return E(e, t);
1944
- }, U = (e) => {
1945
- let t = H(e, "postgres");
1946
- return t === void 0 ? un(e) : t;
1976
+ return D(e, t);
1947
1977
  }, un = (e) => {
1978
+ let t = ln(e, "postgres");
1979
+ return t === void 0 ? dn(e) : t;
1980
+ }, dn = (e) => {
1948
1981
  switch (e.type) {
1949
1982
  case "id": return "text";
1950
1983
  case "text": return "text";
1951
1984
  case "integer": return "integer";
1952
1985
  case "real": return "double precision";
1953
- case "decimal": return ln(e, "NUMERIC");
1986
+ case "decimal": return cn(e, "NUMERIC");
1954
1987
  case "bigint": return "bigint";
1955
1988
  case "boolean": return "boolean";
1956
1989
  case "timestamp": return "timestamptz";
@@ -1964,15 +1997,15 @@ BEGIN
1964
1997
  case "interval": return "interval";
1965
1998
  case "raw": return e.rawDdl ?? "text";
1966
1999
  }
1967
- }, W = (e) => {
1968
- let t = H(e, "mariadb");
2000
+ }, fn = (e) => {
2001
+ let t = ln(e, "mariadb");
1969
2002
  if (t !== void 0) return t;
1970
2003
  switch (e.type) {
1971
2004
  case "id": return "VARCHAR(64)";
1972
2005
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
1973
2006
  case "integer": return "INT";
1974
2007
  case "real": return "DOUBLE";
1975
- case "decimal": return ln(e, "DECIMAL");
2008
+ case "decimal": return cn(e, "DECIMAL");
1976
2009
  case "bigint": return "BIGINT";
1977
2010
  case "boolean": return "TINYINT(1)";
1978
2011
  case "timestamp": return "DATETIME(6)";
@@ -1986,82 +2019,82 @@ BEGIN
1986
2019
  case "interval": return "BIGINT";
1987
2020
  case "raw": return e.rawDdl ?? "LONGTEXT";
1988
2021
  }
1989
- }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, dn = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, fn = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, pn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, mn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${zn(t)}`)};`, hn = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${gn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, gn = (e, t) => {
2022
+ }, W = (e) => `"${e}"`, G = (e) => `\`${e.replace(/`/g, "``")}\``, pn = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, mn = (e) => `ALTER TABLE ${G(e.table)} DROP COLUMN IF EXISTS ${G(e.column)}, ALGORITHM=COPY;`, hn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, gn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Bn(t)}`)};`, _n = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${vn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, vn = (e, t) => {
1990
2023
  let n = t(e.defaultValue);
1991
2024
  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.`);
1992
2025
  return n;
1993
- }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], _n = (e, t, n) => {
1994
- let r = q(e, t, n);
1995
- return r ? nt(n, r) : void 0;
1996
- }, vn = (e, t, n) => {
1997
- let r = n ?? e.nullable, i = ye(e, "mariadb");
2026
+ }, K = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], yn = (e, t, n) => {
2027
+ let r = K(e, t, n);
2028
+ return r ? at(n, r) : void 0;
2029
+ }, bn = (e, t, n) => {
2030
+ let r = n ?? e.nullable, i = be(e, "mariadb");
1998
2031
  return [
1999
- K(t),
2000
- E(e, "mariadb"),
2032
+ G(t),
2033
+ D(e, "mariadb"),
2001
2034
  r ? null : "NOT NULL",
2002
2035
  i
2003
2036
  ].filter(Boolean).join(" ");
2004
- }, yn = (e, t) => e == null ? null : Array.isArray(e) ? bn(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "mysql") : null, bn = (e, t, n) => be(e, t ?? { type: "json" }, n), xn = (e, t) => e == null ? null : Array.isArray(e) ? bn(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "postgres") : null, J = (e, t) => {
2037
+ }, xn = (e, t) => e == null ? null : Array.isArray(e) ? Sn(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? O(e, "mysql") : null, Sn = (e, t, n) => xe(e, t ?? { type: "json" }, n), Cn = (e, t) => e == null ? null : Array.isArray(e) ? Sn(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? O(e, "postgres") : null, q = (e, t) => {
2005
2038
  if (!e.generatedAs) return null;
2006
2039
  let { expr: n, stored: r } = e.generatedAs;
2007
2040
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2008
- }, Sn = (e) => {
2009
- if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "postgres");
2010
- let t = J(e, "postgres");
2011
- if (t) return `${G(e.name)} ${U(e)} ${t}`;
2012
- let n = [G(e.name), U(e)];
2041
+ }, wn = (e) => {
2042
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "postgres");
2043
+ let t = q(e, "postgres");
2044
+ if (t) return `${W(e.name)} ${un(e)} ${t}`;
2045
+ let n = [W(e.name), un(e)];
2013
2046
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2014
- let t = xn(e.defaultValue, e);
2047
+ let t = Cn(e.defaultValue, e);
2015
2048
  t && n.push(t);
2016
2049
  }
2017
- return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2050
+ return e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2018
2051
  cascade: "CASCADE",
2019
2052
  restrict: "RESTRICT",
2020
2053
  setNull: "SET NULL",
2021
2054
  noAction: "NO ACTION"
2022
2055
  }[e.references.onDelete]}`)), n.join(" ");
2023
- }, Cn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", wn = (e) => {
2024
- let t = e.columns.map((e) => ` ${Sn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Cn(e, G)}\n)`];
2025
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(Wn).join(", ")})`);
2056
+ }, Tn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", En = (e) => {
2057
+ let t = e.columns.map((e) => ` ${wn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Tn(e, W)}\n)`];
2058
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(Gn).join(", ")})`);
2026
2059
  return n;
2027
- }, Tn = 191, En = (e) => {
2028
- let t = W(e).toUpperCase();
2060
+ }, Dn = 191, J = (e) => {
2061
+ let t = fn(e).toUpperCase();
2029
2062
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2030
- }, Dn = (e) => {
2031
- if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mariadb");
2032
- let t = J(e, "mariadb");
2033
- if (t) return `${K(e.name)} ${W(e)} ${t}`;
2034
- let n = [K(e.name), W(e)];
2035
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !En(e) && n.push("UNIQUE"), e.hasDefault) {
2036
- let t = yn(e.defaultValue, e);
2063
+ }, On = (e) => {
2064
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mariadb");
2065
+ let t = q(e, "mariadb");
2066
+ if (t) return `${G(e.name)} ${fn(e)} ${t}`;
2067
+ let n = [G(e.name), fn(e)];
2068
+ 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) {
2069
+ let t = xn(e.defaultValue, e);
2037
2070
  t && n.push(t);
2038
2071
  }
2039
- return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2072
+ return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2040
2073
  cascade: "CASCADE",
2041
2074
  restrict: "RESTRICT",
2042
2075
  setNull: "SET NULL",
2043
2076
  noAction: "NO ACTION"
2044
2077
  }[e.references.onDelete]}`)), n.join(" ");
2045
- }, On = (e) => {
2078
+ }, kn = (e) => {
2046
2079
  let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
2047
2080
  let n = t.get(e);
2048
- return n && En(n) ? `${K(e)}(${Tn})` : K(e);
2049
- }, r = e.columns.map((e) => ` ${Dn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${Cn(e, n)}\n)`];
2050
- for (let t of e.columns) t.unique && t.type !== "id" && En(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
2051
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(n).join(", ")})`);
2081
+ return n && J(n) ? `${G(e)}(${Dn})` : G(e);
2082
+ }, r = e.columns.map((e) => ` ${On(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${r}${Tn(e, n)}\n)`];
2083
+ for (let t of e.columns) t.unique && t.type !== "id" && J(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${G(`${e.table}_${t.name}_key`)} ON ${G(e.table)} (${n(t.name)})`);
2084
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(n).join(", ")})`);
2052
2085
  return i;
2053
- }, kn = {
2086
+ }, An = {
2054
2087
  cascade: "CASCADE",
2055
2088
  restrict: "RESTRICT",
2056
2089
  setNull: "SET NULL",
2057
2090
  noAction: "NO ACTION"
2058
- }, An = {
2091
+ }, jn = {
2059
2092
  cascade: "CASCADE",
2060
2093
  restrict: "NO ACTION",
2061
2094
  setNull: "SET NULL",
2062
2095
  noAction: "NO ACTION"
2063
- }, jn = (e) => {
2064
- let t = H(e, "sqlite");
2096
+ }, Mn = (e) => {
2097
+ let t = ln(e, "sqlite");
2065
2098
  if (t !== void 0) return t;
2066
2099
  switch (e.type) {
2067
2100
  case "integer":
@@ -2072,60 +2105,60 @@ BEGIN
2072
2105
  case "bytes": return "BLOB";
2073
2106
  default: return "TEXT";
2074
2107
  }
2075
- }, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "sqlite") : null, Mn = (e) => {
2076
- if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "sqlite");
2077
- let t = J(e, "sqlite");
2078
- if (t) return `${G(e.name)} ${jn(e)} ${t}`;
2079
- let n = [G(e.name), jn(e)];
2108
+ }, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? O(e, "sqlite") : null, Nn = (e) => {
2109
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "sqlite");
2110
+ let t = q(e, "sqlite");
2111
+ if (t) return `${W(e.name)} ${Mn(e)} ${t}`;
2112
+ let n = [W(e.name), Mn(e)];
2080
2113
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2081
2114
  let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
2082
2115
  t && n.push(t);
2083
2116
  }
2084
- if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${kn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2117
+ if (e.references && (n.push(`REFERENCES ${W(e.references.table)} (${W(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${An[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2085
2118
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2086
- n.push(`CHECK (${G(e.name)} IN (${t}))`);
2119
+ n.push(`CHECK (${W(e.name)} IN (${t}))`);
2087
2120
  }
2088
2121
  return n.join(" ");
2089
- }, Nn = (e) => {
2090
- let t = e.columns.map((e) => ` ${Mn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Cn(e, G)}\n)`];
2091
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
2122
+ }, Pn = (e) => {
2123
+ let t = e.columns.map((e) => ` ${Nn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${t}${Tn(e, W)}\n)`];
2124
+ for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e.table)} (${t.columns.map(W).join(", ")})`);
2092
2125
  return n;
2093
2126
  }, X = (e, t) => {
2094
2127
  let n = t.find((t) => t.tableName === e);
2095
2128
  if (!n) return [];
2096
- let r = N([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
2097
- ...Nn({
2129
+ let r = F([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => W(e.name)).join(", "), o = [
2130
+ ...Pn({
2098
2131
  kind: "create-table",
2099
2132
  table: i,
2100
2133
  columns: r.columns,
2101
2134
  indexes: [],
2102
2135
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
2103
2136
  }),
2104
- `INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
2105
- `DROP TABLE ${G(e)}`,
2106
- `ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
2137
+ `INSERT INTO ${W(i)} (${a}) SELECT ${a} FROM ${W(e)}`,
2138
+ `DROP TABLE ${W(e)}`,
2139
+ `ALTER TABLE ${W(i)} RENAME TO ${W(e)}`
2107
2140
  ];
2108
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
2141
+ for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${W(t.name)} ON ${W(e)} (${t.columns.map(W).join(", ")})`);
2109
2142
  return o;
2110
- }, Pn = (e, t, n, r) => {
2143
+ }, Fn = (e, t, n, r) => {
2111
2144
  let i = r ?? e.nullable;
2112
- return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${E(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2113
- }, Fn = (e) => {
2145
+ return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${D(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2146
+ }, In = (e) => {
2114
2147
  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 + ']');`;
2115
2148
  if (!e.hasDefault) return t;
2116
2149
  let n = Y(e.defaultValue, "SYSUTCDATETIME()");
2117
2150
  if (!n) return t;
2118
2151
  let r = n.replace(/^DEFAULT\s+/i, "");
2119
2152
  return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
2120
- }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, In = (e) => {
2121
- let t = H(e, "mssql");
2153
+ }, Z = (e) => `[${e.replace(/]/g, "]]")}]`, Ln = (e) => {
2154
+ let t = ln(e, "mssql");
2122
2155
  if (t !== void 0) return t;
2123
2156
  switch (e.type) {
2124
2157
  case "id":
2125
2158
  case "reference": return "NVARCHAR(64)";
2126
2159
  case "integer": return "INT";
2127
2160
  case "real": return "FLOAT";
2128
- case "decimal": return ln(e, "DECIMAL");
2161
+ case "decimal": return cn(e, "DECIMAL");
2129
2162
  case "bigint": return "BIGINT";
2130
2163
  case "boolean": return "BIT";
2131
2164
  case "timestamp": return "DATETIME2(6)";
@@ -2133,40 +2166,40 @@ BEGIN
2133
2166
  case "bytes": return "VARBINARY(MAX)";
2134
2167
  default: return "NVARCHAR(MAX)";
2135
2168
  }
2136
- }, Ln = (e, t) => {
2137
- if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mssql");
2138
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : In(e), r = J(e, "mssql");
2169
+ }, Rn = (e, t) => {
2170
+ if (e.type === "id" && e.idScheme?.kind === "numeric") return k(e.name, "mssql");
2171
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Ln(e), r = q(e, "mssql");
2139
2172
  if (r) return `${Z(e.name)} ${r}`;
2140
2173
  let i = [Z(e.name), n];
2141
2174
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2142
2175
  let t = Y(e.defaultValue, "SYSUTCDATETIME()");
2143
2176
  t && i.push(t);
2144
2177
  }
2145
- return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${An[e.references.onDelete]}`)), i.join(" ");
2146
- }, Rn = (e) => {
2147
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Ln(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${Cn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2178
+ return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${jn[e.references.onDelete]}`)), i.join(" ");
2179
+ }, zn = (e) => {
2180
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Rn(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${Tn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2148
2181
  for (let n of e.indexes) {
2149
2182
  if (n.name === `${e.table}_pkey`) continue;
2150
2183
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
2151
2184
  a.push(`IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(n.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(r)}')`);
2152
2185
  }
2153
2186
  return a;
2154
- }, zn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Bn = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Vn = (e, t, n) => {
2155
- let r = `${e.table}${zn(t)}`;
2187
+ }, Bn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Vn = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Hn = (e, t, n) => {
2188
+ let r = `${e.table}${Bn(t)}`;
2156
2189
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2157
- }, Hn = (e, t, n) => {
2158
- let r = q(e, t, n);
2159
- return r ? En({ type: r.type }) : !1;
2160
- }, Un = (e, t, n) => Hn(e, t, n) ? `${K(n)}(${Tn})` : K(n), Wn = (e) => e.startsWith("(") ? e : G(e), Gn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(Wn).join(", ")});`, Kn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Un(t, e.table, n)).join(", ")});`, qn = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Jn = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, Yn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, Xn = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Zn = (e) => {
2190
+ }, Un = (e, t, n) => {
2191
+ let r = K(e, t, n);
2192
+ return r ? J({ type: r.type }) : !1;
2193
+ }, Wn = (e, t, n) => Un(e, t, n) ? `${G(n)}(${Dn})` : G(n), Gn = (e) => e.startsWith("(") ? e : W(e), Kn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map(Gn).join(", ")});`, qn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map((n) => Wn(t, e.table, n)).join(", ")});`, Jn = (e) => `DROP INDEX IF EXISTS ${W(e.index)};`, Yn = (e) => `DROP INDEX ${G(e.index)} ON ${G(e.table)};`, Xn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, Zn = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, Qn = (e) => {
2161
2194
  let t = (e) => e.replace(/'/g, "''");
2162
2195
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2163
- }, Qn = (e) => `ALTER INDEX ${G(e.from)} RENAME TO ${G(e.to)};`, $n = (e) => `ALTER TABLE ${K(e.table)} RENAME INDEX ${K(e.from)} TO ${K(e.to)};`, er = (e) => {
2196
+ }, $n = (e) => `ALTER INDEX ${W(e.from)} RENAME TO ${W(e.to)};`, er = (e) => `ALTER TABLE ${G(e.table)} RENAME INDEX ${G(e.from)} TO ${G(e.to)};`, tr = (e) => {
2164
2197
  let t = (e) => e.replace(/'/g, "''");
2165
2198
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2166
- }, tr = (e) => {
2199
+ }, nr = (e) => {
2167
2200
  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(", ")})`;
2168
2201
  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)}');`;
2169
- }, nr = (e, t, n) => {
2202
+ }, rr = (e, t, n) => {
2170
2203
  let r = n.find((t) => t.tableName === e);
2171
2204
  if (!r) return [];
2172
2205
  let i = [];
@@ -2175,13 +2208,13 @@ BEGIN
2175
2208
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2176
2209
  }
2177
2210
  return i;
2178
- }, rr = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, ir = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Un(t, e.table, e.column)});`, ar = (e) => {
2179
- let t = e.fields.map((e) => G(e)).join(", ");
2180
- return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2181
- }, or = (e, t) => {
2182
- let n = e.fields.map((n) => Un(t, e.table, n)).join(", ");
2183
- return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2184
- }, sr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, cr = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, lr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, ur = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, dr = (e, t) => {
2211
+ }, ir = (e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${W(e.column)});`, ar = (e, t) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${Wn(t, e.table, e.column)});`, or = (e) => {
2212
+ let t = e.fields.map((e) => W(e)).join(", ");
2213
+ return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${t});`;
2214
+ }, sr = (e, t) => {
2215
+ let n = e.fields.map((n) => Wn(t, e.table, n)).join(", ");
2216
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${n});`;
2217
+ }, cr = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(e.name)};`, lr = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(e.name)};`, ur = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_key`)};`, dr = (e) => `ALTER TABLE ${G(e.table)} DROP INDEX ${G(`${e.table}_${e.column}_key`)};`, fr = (e, t) => {
2185
2218
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2186
2219
  if (e.orphanPolicy) {
2187
2220
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2199,11 +2232,11 @@ BEGIN
2199
2232
  setNull: "SET NULL",
2200
2233
  noAction: "NO ACTION"
2201
2234
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2202
- }, fr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, pr = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, mr = (e, t) => {
2235
+ }, pr = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_fkey`)};`, mr = (e) => `ALTER TABLE ${G(e.table)} DROP FOREIGN KEY ${G(`${e.table}_${e.column}_fkey`)};`, hr = (e, t) => {
2203
2236
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2204
2237
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2205
- }, hr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, gr = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, _r = (e, t, n, r) => {
2206
- let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? In(i) : r === "sqlite" ? jn(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? yn(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : xn(e, i), u = J(i, r);
2238
+ }, gr = (e) => `ALTER TABLE ${W(e.table)} DROP CONSTRAINT IF EXISTS ${W(`${e.table}_${e.column}_check`)};`, _r = (e) => `ALTER TABLE ${G(e.table)} DROP CHECK ${G(`${e.table}_${e.column}_check`)};`, vr = (e, t, n, r) => {
2239
+ let i = e.column, a = r === "mariadb", o = a ? G : r === "mssql" ? Z : W, s = a ? fn(i) : r === "mssql" ? Ln(i) : r === "sqlite" ? Mn(i) : un(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? xn(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : Cn(e, i), u = q(i, r);
2207
2240
  if (u) {
2208
2241
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2209
2242
  return {
@@ -2231,7 +2264,7 @@ BEGIN
2231
2264
  post: f ? [f] : []
2232
2265
  };
2233
2266
  return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
2234
- }, vr = (e) => {
2267
+ }, yr = (e) => {
2235
2268
  let t = new Map(e.map((e) => [e.tableName, e]));
2236
2269
  return (e, n) => {
2237
2270
  let r = t.get(e);
@@ -2251,118 +2284,118 @@ BEGIN
2251
2284
  ...o
2252
2285
  };
2253
2286
  };
2254
- }, Q = (e, t, n) => e.unsafe(t).pipe(d.tapError((e) => d.sync(() => {
2255
- process.stderr.write(_(`applier: statement failed (op=${n})`, t, e, 400));
2256
- })), d.mapError((e) => {
2257
- let r = _(`applier: statement failed (op=${n})`, t, e, 400).trim();
2287
+ }, Q = (e, t, n) => e.unsafe(t).pipe(p.tapError((e) => p.sync(() => {
2288
+ process.stderr.write(b(`applier: statement failed (op=${n})`, t, e, 400));
2289
+ })), p.mapError((e) => {
2290
+ let r = b(`applier: statement failed (op=${n})`, t, e, 400).trim();
2258
2291
  return Object.assign(e, { message: r });
2259
- }), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), yr = (e, t, n) => d.gen(function* () {
2260
- let r = process.hrtime.bigint(), i = vr(n.declared), a = t.op;
2292
+ }), p.map(() => void 0)), $ = (e, t, n) => p.forEach(t, (t) => Q(e, t, n), { discard: !0 }), br = (e, t, n) => p.gen(function* () {
2293
+ let r = process.hrtime.bigint(), i = yr(n.declared), a = t.op;
2261
2294
  switch (a.kind) {
2262
2295
  case "create-table": {
2263
2296
  let t = yield* e.onDialectOrElse({
2264
- mysql: () => d.succeed(On(a)),
2265
- mssql: () => d.succeed(Rn(a)),
2266
- sqlite: () => d.succeed(Nn(a)),
2267
- orElse: () => d.succeed(wn(a))
2297
+ mysql: () => p.succeed(kn(a)),
2298
+ mssql: () => p.succeed(zn(a)),
2299
+ sqlite: () => p.succeed(Pn(a)),
2300
+ orElse: () => p.succeed(En(a))
2268
2301
  });
2269
2302
  for (let n of t) yield* Q(e, n, a.kind);
2270
2303
  break;
2271
2304
  }
2272
2305
  case "drop-table": {
2273
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Vn(a, n, e) : Bn(a, e);
2306
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Hn(a, n, e) : Vn(a, e);
2274
2307
  yield* e.onDialectOrElse({
2275
- mysql: () => Q(e, r(K), a.kind),
2276
- orElse: () => Q(e, r(G), a.kind)
2308
+ mysql: () => Q(e, r(G), a.kind),
2309
+ orElse: () => Q(e, r(W), a.kind)
2277
2310
  });
2278
2311
  break;
2279
2312
  }
2280
2313
  case "drop-column": {
2281
2314
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2282
2315
  yield* e.onDialectOrElse({
2283
- mysql: () => Q(e, t ? mn(a, n, K) : fn(a), a.kind),
2284
- orElse: () => Q(e, t ? mn(a, n, G) : dn(a, G), a.kind)
2316
+ mysql: () => Q(e, t ? gn(a, n, G) : mn(a), a.kind),
2317
+ orElse: () => Q(e, t ? gn(a, n, W) : pn(a, W), a.kind)
2285
2318
  });
2286
2319
  break;
2287
2320
  }
2288
2321
  case "rename-column":
2289
2322
  yield* e.onDialectOrElse({
2290
- mysql: () => Q(e, pn(a, K), a.kind),
2323
+ mysql: () => Q(e, hn(a, G), a.kind),
2291
2324
  mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
2292
- orElse: () => Q(e, pn(a, G), a.kind)
2325
+ orElse: () => Q(e, hn(a, W), a.kind)
2293
2326
  });
2294
2327
  break;
2295
2328
  case "add-index":
2296
2329
  yield* e.onDialectOrElse({
2297
- mysql: () => Q(e, Kn(a, n.declared), a.kind),
2298
- mssql: () => $(e, [...nr(a.table, a.index.columns, n.declared), tr(a)], a.kind),
2299
- orElse: () => Q(e, Gn(a, t.classification === "online-required"), a.kind)
2330
+ mysql: () => Q(e, qn(a, n.declared), a.kind),
2331
+ mssql: () => $(e, [...rr(a.table, a.index.columns, n.declared), nr(a)], a.kind),
2332
+ orElse: () => Q(e, Kn(a, t.classification === "online-required"), a.kind)
2300
2333
  });
2301
2334
  break;
2302
2335
  case "drop-index":
2303
2336
  yield* e.onDialectOrElse({
2304
- mysql: () => Q(e, Jn(a), a.kind),
2305
- mssql: () => Q(e, Yn(a), a.kind),
2306
- orElse: () => Q(e, qn(a), a.kind)
2337
+ mysql: () => Q(e, Yn(a), a.kind),
2338
+ mssql: () => Q(e, Xn(a), a.kind),
2339
+ orElse: () => Q(e, Jn(a), a.kind)
2307
2340
  });
2308
2341
  break;
2309
2342
  case "rename-table":
2310
2343
  yield* e.onDialectOrElse({
2311
- mysql: () => Q(e, Xn(a, K), a.kind),
2312
- mssql: () => Q(e, Zn(a), a.kind),
2313
- orElse: () => Q(e, Xn(a, G), a.kind)
2344
+ mysql: () => Q(e, Zn(a, G), a.kind),
2345
+ mssql: () => Q(e, Qn(a), a.kind),
2346
+ orElse: () => Q(e, Zn(a, W), a.kind)
2314
2347
  });
2315
2348
  break;
2316
2349
  case "rename-index":
2317
2350
  yield* e.onDialectOrElse({
2318
- mysql: () => Q(e, $n(a), a.kind),
2319
- mssql: () => Q(e, er(a), a.kind),
2320
- orElse: () => Q(e, Qn(a), a.kind)
2351
+ mysql: () => Q(e, er(a), a.kind),
2352
+ mssql: () => Q(e, tr(a), a.kind),
2353
+ orElse: () => Q(e, $n(a), a.kind)
2321
2354
  });
2322
2355
  break;
2323
2356
  case "add-unique":
2324
2357
  yield* e.onDialectOrElse({
2325
- mysql: () => Q(e, ir(a, n.declared), a.kind),
2358
+ mysql: () => Q(e, ar(a, n.declared), a.kind),
2326
2359
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2327
- mssql: () => $(e, [...nr(a.table, [a.column], n.declared), rr(a)], a.kind),
2328
- orElse: () => Q(e, rr(a), a.kind)
2360
+ mssql: () => $(e, [...rr(a.table, [a.column], n.declared), ir(a)], a.kind),
2361
+ orElse: () => Q(e, ir(a), a.kind)
2329
2362
  });
2330
2363
  break;
2331
2364
  case "drop-unique":
2332
2365
  yield* e.onDialectOrElse({
2333
- mysql: () => Q(e, ur(a), a.kind),
2366
+ mysql: () => Q(e, dr(a), a.kind),
2334
2367
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2335
- orElse: () => Q(e, lr(a), a.kind)
2368
+ orElse: () => Q(e, ur(a), a.kind)
2336
2369
  });
2337
2370
  break;
2338
2371
  case "add-unique-composite":
2339
2372
  yield* e.onDialectOrElse({
2340
- mysql: () => Q(e, or(a, n.declared), a.kind),
2373
+ mysql: () => Q(e, sr(a, n.declared), a.kind),
2341
2374
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2342
- mssql: () => $(e, [...nr(a.table, a.fields, n.declared), ar(a)], a.kind),
2343
- orElse: () => Q(e, ar(a), a.kind)
2375
+ mssql: () => $(e, [...rr(a.table, a.fields, n.declared), or(a)], a.kind),
2376
+ orElse: () => Q(e, or(a), a.kind)
2344
2377
  });
2345
2378
  break;
2346
2379
  case "drop-unique-composite":
2347
2380
  yield* e.onDialectOrElse({
2348
- mysql: () => Q(e, cr(a), a.kind),
2381
+ mysql: () => Q(e, lr(a), a.kind),
2349
2382
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2350
- orElse: () => Q(e, sr(a), a.kind)
2383
+ orElse: () => Q(e, cr(a), a.kind)
2351
2384
  });
2352
2385
  break;
2353
2386
  case "add-foreign-key":
2354
2387
  yield* e.onDialectOrElse({
2355
- mysql: () => $(e, dr(a, K), a.kind),
2388
+ mysql: () => $(e, fr(a, G), a.kind),
2356
2389
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2357
- orElse: () => $(e, dr(a, G), a.kind)
2390
+ orElse: () => $(e, fr(a, W), a.kind)
2358
2391
  });
2359
2392
  break;
2360
2393
  case "add-column": {
2361
- let n = _r(a, t, i, yield* e.onDialectOrElse({
2362
- mysql: () => d.succeed("mariadb"),
2363
- mssql: () => d.succeed("mssql"),
2364
- sqlite: () => d.succeed("sqlite"),
2365
- orElse: () => d.succeed("postgres")
2394
+ let n = vr(a, t, i, yield* e.onDialectOrElse({
2395
+ mysql: () => p.succeed("mariadb"),
2396
+ mssql: () => p.succeed("mssql"),
2397
+ sqlite: () => p.succeed("sqlite"),
2398
+ orElse: () => p.succeed("postgres")
2366
2399
  }));
2367
2400
  for (let t of n.pre) yield* Q(e, t, a.kind);
2368
2401
  if (n.backfillKind === "sql" && n.backfillSql) if (!(t.classification === "online-required" || n.batchSize !== void 0)) yield* e`UPDATE ${e(a.table)} SET ${e(a.column.name)} = ${n.backfillSql}`;
@@ -2372,10 +2405,10 @@ BEGIN
2372
2405
  let s = i === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(a.column.name)} IS NULL ORDER BY ${e("id")} LIMIT ${t}` : yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(a.column.name)} IS NULL AND ${e("id")} > ${i} ORDER BY ${e("id")} LIMIT ${t}`;
2373
2406
  if (s.length === 0) break;
2374
2407
  let c = s.map((e) => e.id);
2375
- yield* e`UPDATE ${e(a.table)} SET ${e(a.column.name)} = ${n.backfillSql} WHERE ${e("id")} IN ${e.in(c)}`, o += s.length, yield* d.logInfo(`backfill ${a.table}.${a.column.name}: ${o} rows`).pipe(d.annotateLogs({
2408
+ yield* e`UPDATE ${e(a.table)} SET ${e(a.column.name)} = ${n.backfillSql} WHERE ${e("id")} IN ${e.in(c)}`, o += s.length, yield* p.logInfo(`backfill ${a.table}.${a.column.name}: ${o} rows`).pipe(p.annotateLogs({
2376
2409
  scope: "voltro:migrate",
2377
2410
  mode: "sql-batched"
2378
- })), i = s[s.length - 1].id, r > 0 && (yield* d.sleep(`${r} millis`));
2411
+ })), i = s[s.length - 1].id, r > 0 && (yield* p.sleep(`${r} millis`));
2379
2412
  }
2380
2413
  }
2381
2414
  else if (n.backfillKind === "js" && n.backfillJs) {
@@ -2384,17 +2417,17 @@ BEGIN
2384
2417
  let s = i === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(a.column.name)} IS NULL ORDER BY ${e("id")} LIMIT ${t}` : yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(a.column.name)} IS NULL AND ${e("id")} > ${i} ORDER BY ${e("id")} LIMIT ${t}`;
2385
2418
  if (s.length === 0) break;
2386
2419
  for (let t of s) {
2387
- let r = yield* d.tryPromise({
2420
+ let r = yield* p.tryPromise({
2388
2421
  try: () => Promise.resolve(n.backfillJs({ id: t.id })),
2389
2422
  catch: (e) => e
2390
- }).pipe(d.orDie);
2423
+ }).pipe(p.orDie);
2391
2424
  yield* e`UPDATE ${e(a.table)} SET ${e(a.column.name)} = ${r} WHERE ${e("id")} = ${t.id}`;
2392
2425
  }
2393
- o += s.length, yield* d.logInfo(`backfill ${a.table}.${a.column.name}: ${o} rows processed`).pipe(d.annotateLogs({
2426
+ o += s.length, yield* p.logInfo(`backfill ${a.table}.${a.column.name}: ${o} rows processed`).pipe(p.annotateLogs({
2394
2427
  scope: "voltro:migrate",
2395
2428
  table: a.table,
2396
2429
  column: a.column.name
2397
- })), i = s[s.length - 1].id, r > 0 && (yield* d.sleep(`${r} millis`));
2430
+ })), i = s[s.length - 1].id, r > 0 && (yield* p.sleep(`${r} millis`));
2398
2431
  }
2399
2432
  }
2400
2433
  for (let t of n.post) yield* Q(e, t, a.kind);
@@ -2403,78 +2436,78 @@ BEGIN
2403
2436
  case "alter-column-nullability":
2404
2437
  yield* e.onDialectOrElse({
2405
2438
  mysql: () => {
2406
- let t = q(n.declared, a.table, a.column);
2407
- return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${vn(t, a.column, a.toNullable)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2439
+ let t = K(n.declared, a.table, a.column);
2440
+ return t ? Q(e, `ALTER TABLE ${G(a.table)} MODIFY COLUMN ${bn(t, a.column, a.toNullable)};`, a.kind) : p.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.`));
2408
2441
  },
2409
2442
  mssql: () => {
2410
- let t = q(n.declared, a.table, a.column);
2411
- return t ? Q(e, Pn(t, a.column, a.table, a.toNullable), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
2443
+ let t = K(n.declared, a.table, a.column);
2444
+ return t ? Q(e, Fn(t, a.column, a.table, a.toNullable), a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
2412
2445
  },
2413
2446
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2414
- orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2447
+ orElse: () => Q(e, `ALTER TABLE ${W(a.table)} ALTER COLUMN ${W(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
2415
2448
  });
2416
2449
  break;
2417
2450
  case "alter-column-default": {
2418
- let t = _n(n.declared, a.table, a.column);
2451
+ let t = yn(n.declared, a.table, a.column);
2419
2452
  yield* e.onDialectOrElse({
2420
- mysql: () => Q(e, hn(a, K, (e) => yn(e, t)), a.kind),
2421
- mssql: () => Q(e, Fn(a), a.kind),
2453
+ mysql: () => Q(e, _n(a, G, (e) => xn(e, t)), a.kind),
2454
+ mssql: () => Q(e, In(a), a.kind),
2422
2455
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2423
- orElse: () => Q(e, hn(a, G, (e) => xn(e, t)), a.kind)
2456
+ orElse: () => Q(e, _n(a, W, (e) => Cn(e, t)), a.kind)
2424
2457
  });
2425
2458
  break;
2426
2459
  }
2427
2460
  case "alter-column-type": {
2428
- let r = U(_n(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2461
+ let r = un(yn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
2429
2462
  if (t.classification !== "online-required") {
2430
2463
  yield* e.onDialectOrElse({
2431
2464
  mysql: () => {
2432
- let t = q(n.declared, a.table, a.column);
2433
- return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${vn(t, a.column)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2465
+ let t = K(n.declared, a.table, a.column);
2466
+ return t ? Q(e, `ALTER TABLE ${G(a.table)} MODIFY COLUMN ${bn(t, a.column)};`, a.kind) : p.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.`));
2434
2467
  },
2435
2468
  mssql: () => {
2436
- let t = q(n.declared, a.table, a.column);
2437
- return t ? Q(e, Pn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2469
+ let t = K(n.declared, a.table, a.column);
2470
+ return t ? Q(e, Fn(t, a.column, a.table), a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
2438
2471
  },
2439
2472
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2440
- orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
2473
+ orElse: () => Q(e, `ALTER TABLE ${W(a.table)} ALTER COLUMN ${W(a.column)} TYPE ${r}${i};`, a.kind)
2441
2474
  });
2442
2475
  break;
2443
2476
  }
2444
2477
  yield* e.onDialectOrElse({
2445
- mysql: () => d.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${a.table}.${a.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
2446
- orElse: () => d.void
2478
+ mysql: () => p.die(/* @__PURE__ */ Error(`online-required alter-column-type on ${a.table}.${a.column} is not supported on mariadb (the shadow-swap path is postgres-only). Use a smaller-table window or an external online-DDL tool.`)),
2479
+ orElse: () => p.void
2447
2480
  });
2448
2481
  let o = `${a.column}__shadow`, s = `${a.column}__old`;
2449
- yield* e.unsafe(`ALTER TABLE ${G(a.table)} ADD COLUMN ${G(o)} ${r}`);
2450
- let c = a.using ?? G(a.column), l;
2482
+ yield* e.unsafe(`ALTER TABLE ${W(a.table)} ADD COLUMN ${W(o)} ${r}`);
2483
+ let c = a.using ?? W(a.column), l;
2451
2484
  for (;;) {
2452
2485
  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`;
2453
2486
  if (t.length === 0) break;
2454
- 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;
2487
+ yield* e.unsafe(`UPDATE ${W(a.table)} SET ${W(o)} = ${c} WHERE ${W(a.column)} IS NOT NULL AND ${W(o)} IS NULL AND ${W("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2455
2488
  }
2456
- 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)}`);
2489
+ yield* p.logInfo(`alter-column-type shadow ${a.table}.${a.column}: shadow populated`).pipe(p.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${W(a.table)} RENAME COLUMN ${W(a.column)} TO ${W(s)}`), yield* e.unsafe(`ALTER TABLE ${W(a.table)} RENAME COLUMN ${W(o)} TO ${W(a.column)}`), yield* e.unsafe(`ALTER TABLE ${W(a.table)} DROP COLUMN ${W(s)}`);
2457
2490
  break;
2458
2491
  }
2459
2492
  case "drop-foreign-key":
2460
2493
  yield* e.onDialectOrElse({
2461
- mysql: () => Q(e, pr(a), a.kind),
2494
+ mysql: () => Q(e, mr(a), a.kind),
2462
2495
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2463
- orElse: () => Q(e, fr(a), a.kind)
2496
+ orElse: () => Q(e, pr(a), a.kind)
2464
2497
  });
2465
2498
  break;
2466
2499
  case "add-check":
2467
2500
  yield* e.onDialectOrElse({
2468
- mysql: () => Q(e, mr(a, K), a.kind),
2501
+ mysql: () => Q(e, hr(a, G), a.kind),
2469
2502
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2470
- orElse: () => Q(e, mr(a, G), a.kind)
2503
+ orElse: () => Q(e, hr(a, W), a.kind)
2471
2504
  });
2472
2505
  break;
2473
2506
  case "drop-check":
2474
2507
  yield* e.onDialectOrElse({
2475
- mysql: () => Q(e, gr(a), a.kind),
2508
+ mysql: () => Q(e, _r(a), a.kind),
2476
2509
  sqlite: () => $(e, X(a.table, n.declared), a.kind),
2477
- orElse: () => Q(e, hr(a), a.kind)
2510
+ orElse: () => Q(e, gr(a), a.kind)
2478
2511
  });
2479
2512
  break;
2480
2513
  }
@@ -2483,33 +2516,33 @@ BEGIN
2483
2516
  status: "applied",
2484
2517
  durationMs: Number((process.hrtime.bigint() - r) / 1000000n)
2485
2518
  };
2486
- }), br = (e, t, n) => d.gen(function* () {
2519
+ }), xr = (e, t, n) => p.gen(function* () {
2487
2520
  let r = t.operations.filter((e) => e.blocked);
2488
- if (r.length > 0) return yield* d.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2489
- yield* C(e);
2521
+ if (r.length > 0) return yield* p.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2522
+ yield* w(e);
2490
2523
  let i = Date.now(), a = [];
2491
2524
  try {
2492
2525
  let r = yield* e.onDialectOrElse({
2493
- pg: () => d.succeed(!0),
2494
- mssql: () => d.succeed(!0),
2495
- orElse: () => d.succeed(!1)
2526
+ pg: () => p.succeed(!0),
2527
+ mssql: () => p.succeed(!0),
2528
+ orElse: () => p.succeed(!1)
2496
2529
  }), i = r ? t.operations.filter((e) => e.classification !== "online-required") : [], o = r ? t.operations.filter((e) => e.classification === "online-required") : t.operations;
2497
- i.length > 0 && (yield* e.withTransaction(d.gen(function* () {
2498
- let e = yield* p.SqlClient;
2499
- for (let t of i) a.push(yield* yr(e, t, n));
2530
+ i.length > 0 && (yield* e.withTransaction(p.gen(function* () {
2531
+ let e = yield* h.SqlClient;
2532
+ for (let t of i) a.push(yield* br(e, t, n));
2500
2533
  })));
2501
- for (let t of o) a.push(yield* yr(e, t, n));
2534
+ for (let t of o) a.push(yield* br(e, t, n));
2502
2535
  } finally {
2503
- yield* w(e).pipe(d.orDie);
2536
+ yield* T(e).pipe(p.orDie);
2504
2537
  }
2505
2538
  let o = yield* n.replan(e);
2506
2539
  if (o.operations.length > 0) {
2507
2540
  let e = o.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
2508
- return yield* d.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${o.operations.length}:\n${e}${o.operations.length > 10 ? `\n … and ${o.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2541
+ return yield* p.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${o.operations.length}:\n${e}${o.operations.length > 10 ? `\n … and ${o.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved.`));
2509
2542
  }
2510
- let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), f = yield* e.onDialectOrElse({
2511
- mysql: () => d.succeed(u.replace("T", " ").replace("Z", "")),
2512
- orElse: () => d.succeed(u)
2543
+ let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), d = yield* e.onDialectOrElse({
2544
+ mysql: () => p.succeed(u.replace("T", " ").replace("Z", "")),
2545
+ orElse: () => p.succeed(u)
2513
2546
  });
2514
2547
  return yield* e`
2515
2548
  INSERT INTO ${e("_voltro_migration_plans")}
@@ -2519,7 +2552,7 @@ BEGIN
2519
2552
  VALUES
2520
2553
  (${l}, ${t.toFingerprint}, ${o.fromFingerprint}, ${JSON.stringify(t.operations)},
2521
2554
  ${n.appliedBy}, ${n.environment}, ${n.source},
2522
- ${c}, ${f}, ${n.notes ?? null})
2555
+ ${c}, ${d}, ${n.notes ?? null})
2523
2556
  `, {
2524
2557
  id: l,
2525
2558
  appliedAt: u,
@@ -2532,19 +2565,19 @@ BEGIN
2532
2565
  source: n.source,
2533
2566
  ...n.notes ? { notes: n.notes } : {}
2534
2567
  };
2535
- }), xr = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Sr = (e) => e`
2568
+ }), Sr = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), Cr = (e) => e`
2536
2569
  SELECT fingerprint
2537
2570
  FROM _voltro_migration_plans
2538
2571
  ORDER BY ${e("appliedAt")} DESC
2539
2572
  LIMIT 1
2540
- `.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), Cr = (e) => e.onDialectOrElse({
2573
+ `.pipe(p.map((e) => e.length > 0 ? e[0].fingerprint : void 0), p.catchAll(() => p.succeed(void 0))), wr = (e) => e.onDialectOrElse({
2541
2574
  pg: () => "postgres",
2542
2575
  mysql: () => "mysql",
2543
2576
  mssql: () => "mssql",
2544
2577
  sqlite: () => "sqlite",
2545
2578
  orElse: () => "sqlite"
2546
- }), wr = (e, t) => d.gen(function* () {
2547
- let n = j(N(t, Cr(e))), r = yield* Sr(e);
2579
+ }), Tr = (e, t) => p.gen(function* () {
2580
+ let n = N(F(t, wr(e))), r = yield* Cr(e);
2548
2581
  return r === n ? {
2549
2582
  kind: "up-to-date",
2550
2583
  fingerprint: n
@@ -2553,23 +2586,23 @@ BEGIN
2553
2586
  expected: n,
2554
2587
  ...r === void 0 ? {} : { actual: r }
2555
2588
  };
2556
- }), Tr = [
2589
+ }), Er = [
2557
2590
  "pgeagertest_",
2558
2591
  "mig_e2e_",
2559
2592
  "mig_test_",
2560
2593
  "mysqleagertest_",
2561
2594
  "mssqleagertest_",
2562
2595
  "sqliteeagertest_"
2563
- ], Er = (e) => Tr.some((t) => e.startsWith(t)), Dr = (e, t) => d.gen(function* () {
2596
+ ], Dr = (e) => Er.some((t) => e.startsWith(t)), Or = (e, t) => p.gen(function* () {
2564
2597
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2565
- let n = t.filter((e) => Er(e.name)).map((e) => e.name);
2598
+ let n = t.filter((e) => Dr(e.name)).map((e) => e.name);
2566
2599
  if (n.length === 0) return [];
2567
- for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(d.catchAll(() => d.void));
2600
+ for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(p.catchAll(() => p.void));
2568
2601
  return n;
2569
- }), Or = () => {
2602
+ }), kr = () => {
2570
2603
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2571
2604
  return e.length > 0 ? { ignoreTables: e } : {};
2572
- }, kr = (e) => {
2605
+ }, Ar = (e) => {
2573
2606
  if (e === void 0) return;
2574
2607
  let t = e.trim();
2575
2608
  if (t === "") return;
@@ -2579,83 +2612,83 @@ BEGIN
2579
2612
  kind: "tables",
2580
2613
  tables: new Set(n)
2581
2614
  } : void 0;
2582
- }, Ar = (e) => typeof e.table == "string" ? e.table : void 0, jr = (e, t = { kind: "all" }) => ({
2615
+ }, jr = (e) => typeof e.table == "string" ? e.table : void 0, Mr = (e, t = { kind: "all" }) => ({
2583
2616
  ...e,
2584
2617
  operations: e.operations.map((e) => {
2585
2618
  if (!e.blocked || e.classification !== "lossy") return e;
2586
2619
  if (t?.kind === "tables") {
2587
- let n = Ar(e.op);
2620
+ let n = jr(e.op);
2588
2621
  if (n === void 0 || !t.tables.has(n)) return e;
2589
2622
  }
2590
2623
  let { blocked: n, ...r } = e;
2591
2624
  return r;
2592
2625
  })
2593
- }), Mr = (e, t, n) => t === "postgres" ? st(e, n).pipe(d.flatMap((e) => {
2594
- let t = ct(e);
2595
- return t === void 0 ? d.void : d.logWarning(`auto-migrate: ${t}`).pipe(d.annotateLogs({ scope: "voltro:migrate" }));
2596
- }), d.catchAll(() => d.void)) : d.void, Nr = (e, t, n) => d.gen(function* () {
2597
- let r = Cr(e), i = t;
2626
+ }), Nr = (e, t, n) => t === "postgres" ? ut(e, n).pipe(p.flatMap((e) => {
2627
+ let t = dt(e);
2628
+ return t === void 0 ? p.void : p.logWarning(`auto-migrate: ${t}`).pipe(p.annotateLogs({ scope: "voltro:migrate" }));
2629
+ }), p.catchAll(() => p.void)) : p.void, Pr = (e, t, n) => p.gen(function* () {
2630
+ let r = wr(e), i = t;
2598
2631
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2599
- let t = j(N(i, r));
2600
- if ((yield* Sr(e)) === t) return yield* Mr(e, r, i), {
2632
+ let t = N(F(i, r));
2633
+ if ((yield* Cr(e)) === t) return yield* Nr(e, r, i), {
2601
2634
  kind: "up-to-date",
2602
2635
  fingerprint: t
2603
2636
  };
2604
2637
  }
2605
- let a = yield* V(e), o = yield* Dr(e, a.tables);
2606
- o.length > 0 && (yield* d.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(d.annotateLogs({
2638
+ let a = yield* U(e), o = yield* Or(e, a.tables);
2639
+ o.length > 0 && (yield* p.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(p.annotateLogs({
2607
2640
  scope: "voltro:migrate",
2608
2641
  count: o.length
2609
- })), a = yield* V(e));
2610
- let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !ut(e.name) || s.has(e.name)), l = Wt({
2642
+ })), a = yield* U(e));
2643
+ let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !s(e.name) || c.has(e.name)), u = Ut({
2611
2644
  declared: i,
2612
- live: { tables: c(a.tables) },
2645
+ live: { tables: l(a.tables) },
2613
2646
  dialect: r,
2614
- ...Or()
2647
+ ...kr()
2615
2648
  });
2616
- if (l.summary.blocked > 0) {
2617
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = kr(process.env.VOLTRO_DESTRUCTIVE_OK);
2618
- if (t === void 0 || !e || (l = jr(l, t), l.operations.some((e) => e.blocked))) return {
2649
+ if (u.summary.blocked > 0) {
2650
+ let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Ar(process.env.VOLTRO_DESTRUCTIVE_OK);
2651
+ if (t === void 0 || !e || (u = Mr(u, t), u.operations.some((e) => e.blocked))) return {
2619
2652
  kind: "refused-blocked",
2620
- plan: l
2653
+ plan: u
2621
2654
  };
2622
2655
  }
2623
- return l.operations.length === 0 ? {
2656
+ return u.operations.length === 0 ? {
2624
2657
  kind: "up-to-date",
2625
- fingerprint: l.toFingerprint
2658
+ fingerprint: u.toFingerprint
2626
2659
  } : {
2627
2660
  kind: "applied",
2628
- applied: yield* br(e, l, {
2661
+ applied: yield* xr(e, u, {
2629
2662
  declared: t,
2630
2663
  appliedBy: n.appliedBy,
2631
2664
  environment: n.environment === "prod" ? "dev" : n.environment,
2632
2665
  source: "auto-diff",
2633
- replan: (e) => d.gen(function* () {
2634
- let t = yield* V(e);
2635
- return Wt({
2666
+ replan: (e) => p.gen(function* () {
2667
+ let t = yield* U(e);
2668
+ return Ut({
2636
2669
  declared: i,
2637
- live: { tables: c(t.tables) },
2670
+ live: { tables: l(t.tables) },
2638
2671
  dialect: r,
2639
- ...Or()
2672
+ ...kr()
2640
2673
  });
2641
2674
  })
2642
2675
  }),
2643
- plan: l
2676
+ plan: u
2644
2677
  };
2645
- }), Pr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
2678
+ }), Fr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? p.succeed({
2646
2679
  kind: "skipped",
2647
2680
  reason: "VOLTRO_AUTO_MIGRATE=0"
2648
- }) : n.environment === "prod" ? wr(e, t) : Nr(e, t, n), Fr = (e, t) => {
2681
+ }) : n.environment === "prod" ? Tr(e, t) : Pr(e, t, n), Ir = (e, t) => {
2649
2682
  switch (e.kind) {
2650
2683
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
2651
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${M(e.fingerprint)})`;
2684
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${P(e.fingerprint)})`;
2652
2685
  case "applied": {
2653
2686
  let t = e.plan.summary;
2654
- 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)}`;
2687
+ 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)}`;
2655
2688
  }
2656
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${M(e.expected)}` + (e.actual ? ` live=${M(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
2689
+ 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.";
2657
2690
  case "refused-blocked": {
2658
- let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + xr(e.plan), c = [""];
2691
+ 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` + Sr(e.plan), c = [""];
2659
2692
  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) {
2660
2693
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2661
2694
  for (let r of e.plan.operations) {
@@ -2672,7 +2705,7 @@ BEGIN
2672
2705
  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");
2673
2706
  }
2674
2707
  }
2675
- }, Ir = /* @__PURE__ */ new Set([
2708
+ }, Lr = /* @__PURE__ */ new Set([
2676
2709
  "node_modules",
2677
2710
  "dist",
2678
2711
  "build",
@@ -2681,58 +2714,58 @@ BEGIN
2681
2714
  ".next",
2682
2715
  ".git",
2683
2716
  ".framework"
2684
- ]), Lr = async (e) => {
2717
+ ]), Rr = async (e) => {
2685
2718
  let t = [], n = async (e) => {
2686
- let r = await h.readdir(e, { withFileTypes: !0 }).catch(() => []);
2719
+ let r = await _.readdir(e, { withFileTypes: !0 }).catch(() => []);
2687
2720
  for (let i of r) {
2688
- if (Ir.has(i.name)) continue;
2689
- let r = g(e, i.name);
2690
- i.isDirectory() ? await n(r) : i.isFile() && l.test(i.name) && t.push(r);
2721
+ if (Lr.has(i.name)) continue;
2722
+ let r = v(e, i.name);
2723
+ i.isDirectory() ? await n(r) : i.isFile() && o.test(i.name) && t.push(r);
2691
2724
  }
2692
2725
  };
2693
2726
  return await n(e), t.sort((e, t) => {
2694
2727
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
2695
2728
  return n.localeCompare(r);
2696
2729
  });
2697
- }, Rr = async (e) => {
2730
+ }, zr = async (e) => {
2698
2731
  let t = [];
2699
- for (let n of e) {
2700
- let e = (await import(ee(n).href)).default;
2701
- if (!o(e)) {
2702
- process.stderr.write(`[voltro:migrate] ${n} has no default-exported \`migration(...)\` — skipped\n`);
2732
+ for (let r of e) {
2733
+ let e = (await import(y(r).href)).default;
2734
+ if (!n(e)) {
2735
+ process.stderr.write(`[voltro:migrate] ${r} has no default-exported \`migration(...)\` — skipped\n`);
2703
2736
  continue;
2704
2737
  }
2705
2738
  t.push({
2706
- file: n,
2739
+ file: r,
2707
2740
  migration: e
2708
2741
  });
2709
2742
  }
2710
2743
  return t;
2711
- }, zr = (e) => e`
2744
+ }, Br = (e) => e`
2712
2745
  SELECT ${e("id")}
2713
2746
  FROM ${e("_voltro_migration_plans")}
2714
2747
  WHERE ${e("source")} = 'file'
2715
- `.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), Br = (e, t, n, r) => d.gen(function* () {
2748
+ `.pipe(p.map((e) => e.map((e) => e.id)), p.catchAll(() => p.succeed([]))), Vr = (e, t, n, r) => p.gen(function* () {
2716
2749
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
2717
2750
  sql: e,
2718
2751
  log: {
2719
- info: (e, n) => d.logInfo(e).pipe(d.annotateLogs({
2752
+ info: (e, n) => p.logInfo(e).pipe(p.annotateLogs({
2720
2753
  scope: `migrations:file:${t.migration.id}`,
2721
2754
  ...n ?? {}
2722
2755
  })),
2723
- warn: (e, n) => d.logWarning(e).pipe(d.annotateLogs({
2756
+ warn: (e, n) => p.logWarning(e).pipe(p.annotateLogs({
2724
2757
  scope: `migrations:file:${t.migration.id}`,
2725
2758
  ...n ?? {}
2726
2759
  }))
2727
2760
  },
2728
2761
  appliedAt: a
2729
2762
  }, s = t.migration.up(o);
2730
- d.isEffect(s) ? yield* s : yield* d.tryPromise({
2763
+ p.isEffect(s) ? yield* s : yield* p.tryPromise({
2731
2764
  try: () => s,
2732
2765
  catch: (e) => e
2733
2766
  });
2734
2767
  let c = Date.now() - i;
2735
- return !d.isEffect(s) && c < 2 && (yield* d.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(d.annotateLogs({ scope: `migrations:file:${t.migration.id}` }))), yield* e`
2768
+ return !p.isEffect(s) && c < 2 && (yield* p.logWarning(`migration ${t.migration.id}: up() resolved in ${c}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(p.annotateLogs({ scope: `migrations:file:${t.migration.id}` }))), yield* e`
2736
2769
  INSERT INTO ${e("_voltro_migration_plans")}
2737
2770
  (${e("id")}, ${e("fingerprint")}, ${e("operations")},
2738
2771
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
@@ -2745,93 +2778,93 @@ BEGIN
2745
2778
  ${r}, ${n}, ${"file"},
2746
2779
  ${c}, ${a}, ${t.migration.description})
2747
2780
  `, { durationMs: c };
2748
- }), Vr = (e, t) => d.gen(function* () {
2749
- let n = yield* d.tryPromise({
2750
- try: () => Lr(g(t, "migrations")),
2781
+ }), Hr = (e, t) => p.gen(function* () {
2782
+ let n = yield* p.tryPromise({
2783
+ try: () => Rr(v(t, "migrations")),
2751
2784
  catch: (e) => e
2752
2785
  });
2753
2786
  if (n.length === 0) return {
2754
2787
  pending: [],
2755
2788
  skipped: []
2756
2789
  };
2757
- let r = yield* d.tryPromise({
2758
- try: () => Rr(n),
2790
+ let r = yield* p.tryPromise({
2791
+ try: () => zr(n),
2759
2792
  catch: (e) => e
2760
2793
  });
2761
2794
  if (r.length === 0) return {
2762
2795
  pending: [],
2763
2796
  skipped: []
2764
2797
  };
2765
- let i = new Set(yield* zr(e));
2798
+ let i = new Set(yield* Br(e));
2766
2799
  return {
2767
2800
  pending: r.filter((e) => !i.has(e.migration.id)),
2768
2801
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
2769
2802
  };
2770
- }), Hr = (e, t) => Vr(e, t).pipe(d.map((e) => e.pending.map((e) => e.migration.id))), Ur = (e, t) => d.gen(function* () {
2771
- let { pending: n, skipped: r } = yield* Vr(e, t.projectRoot);
2803
+ }), Ur = (e, t) => Hr(e, t).pipe(p.map((e) => e.pending.map((e) => e.migration.id))), Wr = (e, t) => p.gen(function* () {
2804
+ let { pending: n, skipped: r } = yield* Hr(e, t.projectRoot);
2772
2805
  if (n.length === 0) return {
2773
2806
  applied: [],
2774
2807
  skipped: r
2775
2808
  };
2776
- yield* C(e);
2809
+ yield* w(e);
2777
2810
  let i = [];
2778
2811
  try {
2779
2812
  for (let r of n) {
2780
- yield* d.logInfo("file-based migration applying").pipe(d.annotateLogs({
2813
+ yield* p.logInfo("file-based migration applying").pipe(p.annotateLogs({
2781
2814
  scope: "voltro:migrate",
2782
2815
  id: r.migration.id,
2783
2816
  file: r.file
2784
2817
  }));
2785
- let { durationMs: n } = yield* Br(e, r, t.env, t.appliedBy);
2818
+ let { durationMs: n } = yield* Vr(e, r, t.env, t.appliedBy);
2786
2819
  i.push({
2787
2820
  id: r.migration.id,
2788
2821
  durationMs: n
2789
- }), yield* d.logInfo("file-based migration applied").pipe(d.annotateLogs({
2822
+ }), yield* p.logInfo("file-based migration applied").pipe(p.annotateLogs({
2790
2823
  scope: "voltro:migrate",
2791
2824
  id: r.migration.id,
2792
2825
  durationMs: n
2793
2826
  }));
2794
2827
  }
2795
2828
  } finally {
2796
- yield* w(e).pipe(d.orDie);
2829
+ yield* T(e).pipe(p.orDie);
2797
2830
  }
2798
2831
  return {
2799
2832
  applied: i,
2800
2833
  skipped: r
2801
2834
  };
2802
- }), Wr = (e, t) => e`
2835
+ }), Gr = (e, t) => e`
2803
2836
  SELECT ${e("id")}
2804
2837
  FROM ${e("_voltro_migration_plans")}
2805
2838
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
2806
2839
  LIMIT 1
2807
- `, Gr = (e, t) => d.gen(function* () {
2808
- if (!(yield* Wr(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2809
- let n = yield* d.tryPromise({
2810
- try: () => Lr(g(t.projectRoot, "migrations")),
2840
+ `, Kr = (e, t) => p.gen(function* () {
2841
+ if (!(yield* Gr(e, t.id))[0]) return yield* p.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
2842
+ let n = yield* p.tryPromise({
2843
+ try: () => Rr(v(t.projectRoot, "migrations")),
2811
2844
  catch: (e) => e
2812
- }), r = (yield* d.tryPromise({
2813
- try: () => Rr(n),
2845
+ }), r = (yield* p.tryPromise({
2846
+ try: () => zr(n),
2814
2847
  catch: (e) => e
2815
2848
  })).find((e) => e.migration.id === t.id);
2816
- if (!r) return yield* d.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
2817
- yield* C(e);
2849
+ if (!r) return yield* p.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
2850
+ yield* w(e);
2818
2851
  let i = Date.now();
2819
2852
  try {
2820
2853
  let n = {
2821
2854
  sql: e,
2822
2855
  log: {
2823
- info: (e, n) => d.logInfo(e).pipe(d.annotateLogs({
2856
+ info: (e, n) => p.logInfo(e).pipe(p.annotateLogs({
2824
2857
  scope: `migrations:file:${t.id}`,
2825
2858
  ...n ?? {}
2826
2859
  })),
2827
- warn: (e, n) => d.logWarning(e).pipe(d.annotateLogs({
2860
+ warn: (e, n) => p.logWarning(e).pipe(p.annotateLogs({
2828
2861
  scope: `migrations:file:${t.id}`,
2829
2862
  ...n ?? {}
2830
2863
  }))
2831
2864
  },
2832
2865
  appliedAt: (/* @__PURE__ */ new Date()).toISOString()
2833
2866
  }, a = r.migration.down(n);
2834
- d.isEffect(a) ? yield* a : yield* d.tryPromise({
2867
+ p.isEffect(a) ? yield* a : yield* p.tryPromise({
2835
2868
  try: () => a,
2836
2869
  catch: (e) => e
2837
2870
  });
@@ -2841,19 +2874,19 @@ BEGIN
2841
2874
  durationMs: o
2842
2875
  };
2843
2876
  } finally {
2844
- yield* w(e).pipe(d.orDie);
2877
+ yield* T(e).pipe(p.orDie);
2845
2878
  }
2846
- }), Kr = (e) => d.gen(function* () {
2847
- let t = yield* p.SqlClient, n = yield* t`
2879
+ }), qr = (e) => p.gen(function* () {
2880
+ let t = yield* h.SqlClient, n = yield* t`
2848
2881
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
2849
2882
  WHERE source = 'auto-diff'
2850
2883
  AND squashedAt IS NULL
2851
2884
  AND appliedAt < ${e.before}
2852
2885
  ORDER BY appliedAt DESC
2853
2886
  `;
2854
- if (n.length === 0) return yield* d.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
2887
+ if (n.length === 0) return yield* p.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
2855
2888
  let r = n[0];
2856
- if (r.fingerprint !== e.fingerprint) return yield* d.fail(/* @__PURE__ */ Error(`squash: latest pre-squash fingerprint (${r.fingerprint.slice(0, 12)}…) differs from current declared-schema fingerprint (${e.fingerprint.slice(0, 12)}…). This means the working tree carries un-applied changes — squashing now would lock the drift in.\n\nFix: run \`voltro db apply\` first to align the live schema with the working tree, then re-squash.`));
2889
+ if (r.fingerprint !== e.fingerprint) return yield* p.fail(/* @__PURE__ */ Error(`squash: latest pre-squash fingerprint (${r.fingerprint.slice(0, 12)}…) differs from current declared-schema fingerprint (${e.fingerprint.slice(0, 12)}…). This means the working tree carries un-applied changes — squashing now would lock the drift in.\n\nFix: run \`voltro db apply\` first to align the live schema with the working tree, then re-squash.`));
2857
2890
  yield* t`
2858
2891
  UPDATE _voltro_migration_plans
2859
2892
  SET squashedAt = CURRENT_TIMESTAMP
@@ -2888,10 +2921,10 @@ BEGIN
2888
2921
  snapshotFingerprint: e.fingerprint,
2889
2922
  snapshotId: i
2890
2923
  };
2891
- }), qr = (e, ...t) => ({
2924
+ }), Jr = (e, ...t) => ({
2892
2925
  _tag: "RawSqlFragment",
2893
2926
  strings: [...e],
2894
2927
  values: [...t]
2895
- }), Jr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2928
+ }), Yr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
2896
2929
  //#endregion
2897
- export { l as FILE_MIGRATION_PATTERN, ot as REACTIVE_TRIGGER_PREFIX, re as VOLTRO_MIGRATION_LOCK_KEY, C as acquireMigrationLock, Je as applyNamespacedSchema, br as applyPlan, He as applySchema, Zt as chunkTables, N as declaredSnapshot, be as defaultArrayClause, ye as defaultClause, D as defaultJsonClause, Fr as describeOutcome, kr as destructiveScope, st as detectReactiveTriggerDrift, dn as emitDropColumnDdl, fn as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, ct as formatReactiveTriggerDrift, Or as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, Jr as isRawSqlFragment, Kt as mapPgType, s as migration, O as numericIdSql, Gt as parseEnumCheck, Hr as pendingFileMigrationIds, Wt as planMigrations, Ye as provisionTenantNamespace, w as releaseMigrationLock, Dn as renderColumnMysql, Sn as renderColumnPg, Gr as rollbackFileBasedMigration, Ur as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, Pr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, qr as sql, E as sqlType, Kr as squashMigrationPlans, jr as unblockLossy, _e as withMigrationLock };
2930
+ export { j as DEFAULT_CDC_CHANNEL, o as FILE_MIGRATION_PATTERN, lt as REACTIVE_TRIGGER_PREFIX, ie as VOLTRO_MIGRATION_LOCK_KEY, w as acquireMigrationLock, Ze as applyNamespacedSchema, xr as applyPlan, Ge as applySchema, Xt as chunkTables, F as declaredSnapshot, xe as defaultArrayClause, be as defaultClause, O as defaultJsonClause, Ir as describeOutcome, Ar as destructiveScope, ut as detectReactiveTriggerDrift, pn as emitDropColumnDdl, mn as emitDropColumnDdlMysql, We as emitFrameworkBootstrapSql, He as emitNamespaceProvisionDdl, Ue as emitNamespacedSchemaSql, M as emitSchemaSql, N as fingerprintSchema, dt as formatReactiveTriggerDrift, kr as ignoreTablesFromEnv, U as introspectSchema, n as isFileMigration, Yr as isRawSqlFragment, Gt as mapPgType, c as migration, k as numericIdSql, Wt as parseEnumCheck, Ur as pendingFileMigrationIds, Ut as planMigrations, Qe as provisionTenantNamespace, T as releaseMigrationLock, On as renderColumnMysql, wn as renderColumnPg, Kr as rollbackFileBasedMigration, Wr as runFileBasedMigrations, $e as runFrameworkBootstrap, Xe as runMigrate, Fr as runPlannedMigrations, P as shortFingerprint, at as snapshotColumn, Jr as sql, D as sqlType, qr as squashMigrationPlans, Mr as unblockLossy, ve as withMigrationLock };