@voltro/database 0.42.0 → 0.43.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
@@ -833,17 +833,17 @@ BEGIN
833
833
  }
834
834
  return t;
835
835
  }, Bt = (e) => {
836
- if (!e.idScheme && !e.sensitive && !e.safe) return e;
837
- let { idScheme: t, sensitive: n, safe: r, ...i } = e;
838
- return i;
836
+ if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs) return e;
837
+ let { idScheme: t, sensitive: n, safe: r, generatedAs: i, ...a } = e;
838
+ return a;
839
839
  }, Vt = (e) => [...e].map(Bt).sort((e, t) => e.name.localeCompare(t.name)), Ht = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), Ut = (e) => [...e].map((e) => ({
840
840
  name: e.name,
841
841
  columns: Vt(e.columns),
842
842
  indexes: Ht(e.indexes)
843
- })).sort((e, t) => e.name.localeCompare(t.name)), F = (e) => {
843
+ })).sort((e, t) => e.name.localeCompare(t.name)), Wt = (e) => {
844
844
  let t = { tables: Ut(e.tables) }, n = JSON.stringify(zt(t));
845
845
  return te("sha256").update(n).digest("hex");
846
- }, I = (e) => e.slice(0, 16), Wt = (e, t) => {
846
+ }, F = (e) => e.slice(0, 16), Gt = (e, t) => {
847
847
  let n = t.references ? {
848
848
  table: t.references().tableName,
849
849
  column: "id",
@@ -882,7 +882,7 @@ BEGIN
882
882
  ...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
883
883
  ...t.spatial === void 0 ? {} : { spatial: t.spatial }
884
884
  };
885
- }, Gt = (e) => {
885
+ }, Kt = (e) => {
886
886
  let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
887
887
  n.has(e.name) || (n.add(e.name), t.push(e));
888
888
  }, i = e.appliedPrimaryKey ?? [];
@@ -930,11 +930,11 @@ BEGIN
930
930
  });
931
931
  }
932
932
  return t;
933
- }, Kt = (e) => {
933
+ }, qt = (e) => {
934
934
  let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
935
935
  for (let [r, i] of Object.entries(e.fields)) {
936
936
  if (i.dropped) continue;
937
- let e = Wt(r, i);
937
+ let e = Gt(r, i);
938
938
  n.push(t.has(r) ? {
939
939
  ...e,
940
940
  unique: !0
@@ -944,21 +944,21 @@ BEGIN
944
944
  return {
945
945
  name: e.tableName,
946
946
  columns: n,
947
- indexes: Gt(e),
947
+ indexes: Kt(e),
948
948
  ...r.length > 0 ? { primaryKey: [...r] } : {},
949
949
  ...i === void 0 ? {} : { renamedFrom: i }
950
950
  };
951
- }, qt = (e) => {
951
+ }, Jt = (e) => {
952
952
  let t = /* @__PURE__ */ new Map();
953
953
  for (let n of e) for (let e of n.indexes) {
954
954
  let r = t.get(e.name);
955
955
  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}').`);
956
956
  t.set(e.name, n.name);
957
957
  }
958
- }, L = (e, t) => {
959
- let n = e.map((e) => Kt(de(e, t)));
960
- return qt(n), { tables: n };
961
- }, Jt = (e, t, n = k) => x.gen(function* () {
958
+ }, I = (e, t) => {
959
+ let n = e.map((e) => qt(de(e, t)));
960
+ return Jt(n), { tables: n };
961
+ }, Yt = (e, t, n = k) => x.gen(function* () {
962
962
  let r = (yield* e`
963
963
  SELECT p.prosrc
964
964
  FROM pg_proc p
@@ -989,7 +989,7 @@ BEGIN
989
989
  stale: l.sort(),
990
990
  functionOutdated: i
991
991
  };
992
- }), Yt = (e) => {
992
+ }), Xt = (e) => {
993
993
  let t = [];
994
994
  if (e.missing.length > 0) {
995
995
  let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
@@ -1000,19 +1000,19 @@ BEGIN
1000
1000
  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.`);
1001
1001
  }
1002
1002
  return e.functionOutdated && t.push("The change-notify function in this database is OLDER than the framework installed here. Its triggers fire, so nothing looks wrong — but a row too large for a NOTIFY payload (postgres caps it at 8000 bytes) is emitted without its primary key, and a change that carries no key cannot be re-read: it reaches subscriptions as a re-query and reaches every TAP — search index, analytics mirror, cdc-out, row history — as nothing at all. Run `voltro db apply` to replace it."), t.length > 0 ? t.join("\n") : void 0;
1003
- }, Xt = {
1003
+ }, Zt = {
1004
1004
  postgres: !0,
1005
1005
  mysql: !0,
1006
1006
  mariadb: !0,
1007
1007
  mssql: !0,
1008
1008
  sqlite: !0
1009
- }, Zt = {
1009
+ }, Qt = {
1010
1010
  postgres: !0,
1011
1011
  mysql: !1,
1012
1012
  mariadb: !1,
1013
1013
  mssql: !0,
1014
1014
  sqlite: !0
1015
- }, Qt = (e) => {
1015
+ }, $t = (e) => {
1016
1016
  switch (e) {
1017
1017
  case "add-column":
1018
1018
  case "drop-column":
@@ -1022,47 +1022,47 @@ BEGIN
1022
1022
  case "add-foreign-key":
1023
1023
  case "add-unique":
1024
1024
  case "add-unique-composite":
1025
- case "add-check": return Zt;
1026
- default: return Xt;
1025
+ case "add-check": return Qt;
1026
+ default: return Zt;
1027
1027
  }
1028
- }, $t = (e, t) => {
1028
+ }, en = (e, t) => {
1029
1029
  let n = new Map(t.tables.map((e) => [e.name, e]));
1030
1030
  return new Map(e.map((e) => [e.tableName, {
1031
1031
  table: e,
1032
1032
  snapshot: n.get(e.tableName),
1033
1033
  columnDefs: e.fields
1034
1034
  }]));
1035
- }, R = (e) => {
1035
+ }, L = (e) => {
1036
1036
  if (typeof e != "object" || !e) return JSON.stringify(e);
1037
- if (Array.isArray(e)) return `[${e.map(R).join(",")}]`;
1037
+ if (Array.isArray(e)) return `[${e.map(L).join(",")}]`;
1038
1038
  let t = e;
1039
- return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${R(t[e])}`).join(",")}}`;
1040
- }, en = (e) => {
1039
+ return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`;
1040
+ }, tn = (e) => {
1041
1041
  if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
1042
1042
  let t = e.defaultValue;
1043
1043
  if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
1044
1044
  if (typeof t == "number") return String(t);
1045
- if (typeof t != "string") return R(t);
1045
+ if (typeof t != "string") return L(t);
1046
1046
  let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
1047
1047
  if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
1048
1048
  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);
1049
1049
  if (o) try {
1050
- return R(JSON.parse(o[1]));
1050
+ return L(JSON.parse(o[1]));
1051
1051
  } catch {}
1052
1052
  let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
1053
1053
  if (s) try {
1054
- return R(JSON.parse(s[1]));
1054
+ return L(JSON.parse(s[1]));
1055
1055
  } catch {}
1056
1056
  if (a.startsWith("{") || a.startsWith("[")) try {
1057
- return R(JSON.parse(a));
1057
+ return L(JSON.parse(a));
1058
1058
  } catch {}
1059
1059
  return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
1060
- }, tn = (e, t) => {
1061
- let n = en(e), r = en(t);
1060
+ }, nn = (e, t) => {
1061
+ let n = tn(e), r = tn(t);
1062
1062
  if (n === r) return !0;
1063
1063
  let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
1064
1064
  return i(n) === i(r);
1065
- }, nn = (e) => {
1065
+ }, rn = (e) => {
1066
1066
  if (!e) return null;
1067
1067
  let t = (e) => e === "restrict" ? "noAction" : e;
1068
1068
  return {
@@ -1071,25 +1071,25 @@ BEGIN
1071
1071
  onDelete: t(e.onDelete),
1072
1072
  onUpdate: t(e.onUpdate)
1073
1073
  };
1074
- }, rn = (e, t) => {
1074
+ }, an = (e, t) => {
1075
1075
  let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
1076
1076
  if (!n && !r) return !0;
1077
1077
  if (!n || !r || n.length !== r.length) return !1;
1078
1078
  let i = [...n].sort(), a = [...r].sort();
1079
1079
  return i.every((e, t) => e === a[t]);
1080
- }, an = (e, t) => {
1080
+ }, on = (e, t) => {
1081
1081
  try {
1082
1082
  let n = /\((\d+)\)/.exec(j(e, t));
1083
1083
  return n ? Number(n[1]) : void 0;
1084
1084
  } catch {
1085
1085
  return;
1086
1086
  }
1087
- }, on = (e, t, n) => n === void 0 || o(n) ? !0 : e.type !== "text" || t.type !== "text" || an(e, n) === t.maxLength, sn = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && tn(e, t) && on(e, t, n) && JSON.stringify(nn(e.references)) === JSON.stringify(nn(t.references)) && rn(e.oneOf, t.oneOf), cn = (e, t) => t.oneOf && t.oneOf.length > 0 ? z({
1087
+ }, sn = (e, t, n) => n === void 0 || o(n) ? !0 : e.type !== "text" || t.type !== "text" || on(e, n) === t.maxLength, cn = (e, t, n) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && nn(e, t) && sn(e, t, n) && JSON.stringify(rn(e.references)) === JSON.stringify(rn(t.references)) && an(e.oneOf, t.oneOf), ln = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
1088
1088
  kind: "add-check",
1089
1089
  table: e,
1090
1090
  column: t.name,
1091
1091
  values: t.oneOf
1092
- }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, ln = (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])), un = (e, t, n) => {
1092
+ }, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, un = (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])), dn = (e, t, n) => {
1093
1093
  let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [];
1094
1094
  for (let t of e.columns) {
1095
1095
  let e = r.get(t.name);
@@ -1097,7 +1097,7 @@ BEGIN
1097
1097
  a.push(t);
1098
1098
  continue;
1099
1099
  }
1100
- sn(t, e, n) || s.push({
1100
+ cn(t, e, n) || s.push({
1101
1101
  declared: t,
1102
1102
  live: e
1103
1103
  });
@@ -1108,47 +1108,47 @@ BEGIN
1108
1108
  removed: o,
1109
1109
  changed: s
1110
1110
  };
1111
- }, dn = (e, t) => {
1111
+ }, fn = (e, t) => {
1112
1112
  let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
1113
1113
  for (let t of e.indexes) {
1114
1114
  let e = n.get(t.name);
1115
- (!e || !ln(t, e)) && i.push(t);
1115
+ (!e || !un(t, e)) && i.push(t);
1116
1116
  }
1117
1117
  for (let e of t.indexes) r.has(e.name) || a.push(e);
1118
1118
  return {
1119
1119
  added: i,
1120
1120
  removed: a
1121
1121
  };
1122
- }, z = (e, t, n, r) => ({
1122
+ }, R = (e, t, n, r) => ({
1123
1123
  op: e,
1124
1124
  classification: t,
1125
- atomicByDialect: Qt(e.kind),
1125
+ atomicByDialect: $t(e.kind),
1126
1126
  ...n ? { reason: n } : {},
1127
1127
  ...r ? { blocked: r } : {}
1128
- }), fn = (e, t, n) => {
1128
+ }), pn = (e, t, n) => {
1129
1129
  let r = {
1130
1130
  kind: "add-column",
1131
1131
  table: e,
1132
1132
  column: t
1133
1133
  };
1134
- return t.nullable ? z(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? z(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? z(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : z(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
1135
- }, pn = (e, t, n) => {
1134
+ 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` });
1135
+ }, mn = (e, t, n) => {
1136
1136
  let r = {
1137
1137
  kind: "drop-column",
1138
1138
  table: e,
1139
1139
  column: t.name
1140
1140
  };
1141
- return n?.dropped ? z(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : z(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
1142
- }, mn = (e, t, n, r, i) => z({
1141
+ 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` });
1142
+ }, hn = (e, t, n, r, i) => R({
1143
1143
  kind: "create-table",
1144
1144
  table: e,
1145
1145
  columns: t,
1146
1146
  indexes: n,
1147
1147
  ...r && r.length > 0 ? { primaryKey: r } : {}
1148
- }, "safe", i ?? "new table — no data to preserve"), hn = (e) => z({
1148
+ }, "safe", i ?? "new table — no data to preserve"), gn = (e) => R({
1149
1149
  kind: "drop-table",
1150
1150
  table: e
1151
- }, "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" }), gn = 5e4, _n = (e, t, n, r) => {
1151
+ }, "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" }), _n = 5e4, vn = (e, t, n, r) => {
1152
1152
  let i = (n ?? 0) >= r, a;
1153
1153
  return a = t.unique ? t.columns.length === 1 ? {
1154
1154
  kind: "add-unique",
@@ -1163,16 +1163,16 @@ BEGIN
1163
1163
  kind: "add-index",
1164
1164
  table: e,
1165
1165
  index: t
1166
- }, i ? z(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
1167
- }, vn = (e, t) => t.unique && t.columns.length > 1 ? z({
1166
+ }, 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");
1167
+ }, yn = (e, t) => t.unique && t.columns.length > 1 ? R({
1168
1168
  kind: "drop-unique-composite",
1169
1169
  table: e,
1170
1170
  name: t.name
1171
- }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : z({
1171
+ }, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
1172
1172
  kind: "drop-index",
1173
1173
  table: e,
1174
1174
  index: t.name
1175
- }, "safe", "drop index (no data loss — index is derived data)"), yn = (e, t) => {
1175
+ }, "safe", "drop index (no data loss — index is derived data)"), bn = (e, t) => {
1176
1176
  if (e === "reference") return "text";
1177
1177
  switch (t) {
1178
1178
  case "sqlite":
@@ -1180,7 +1180,10 @@ BEGIN
1180
1180
  case "mssql": return e === "json" ? "text" : e;
1181
1181
  default: return e;
1182
1182
  }
1183
- }, bn = (e, t, n, r, i, a) => {
1183
+ }, xn = (e, t, n) => {
1184
+ let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
1185
+ return n === "postgres" ? `${r} — add \`{ using: '${t.name}::${t.type}' }\` when the cast is not implicit, or use a file-based migration` : `${r} — ${n === void 0 ? "this dialect" : n} converts in place (\`using\` is postgres-only and is ignored here), so verify the conversion is value-preserving for your data, or use a file-based migration`;
1186
+ }, Sn = (e, t, n, r, i, a) => {
1184
1187
  let s = [];
1185
1188
  if (t.nullable !== n.nullable) {
1186
1189
  let n = {
@@ -1189,7 +1192,7 @@ BEGIN
1189
1192
  column: t.name,
1190
1193
  toNullable: t.nullable
1191
1194
  };
1192
- s.push(t.nullable ? z(n, "safe", `loosen ${e}.${t.name} to nullable`) : z(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1195
+ s.push(t.nullable ? R(n, "safe", `loosen ${e}.${t.name} to nullable`) : R(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
1193
1196
  }
1194
1197
  if (t.unique !== n.unique) {
1195
1198
  if (t.unique) {
@@ -1198,39 +1201,39 @@ BEGIN
1198
1201
  table: e,
1199
1202
  column: t.name
1200
1203
  }, r = (i ?? 0) >= a;
1201
- s.push(r ? z(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : z(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1202
- } else s.push(z({
1204
+ s.push(r ? R(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
1205
+ } else s.push(R({
1203
1206
  kind: "drop-unique",
1204
1207
  table: e,
1205
1208
  column: t.name
1206
1209
  }, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
1207
1210
  }
1208
- if (yn(t.type, r) !== yn(n.type, r)) {
1209
- let r = t.narrowedFrom;
1210
- if (r && r.from === n.type) {
1211
- let i = {
1211
+ if (bn(t.type, r) !== bn(n.type, r)) {
1212
+ let i = t.narrowedFrom;
1213
+ if (i && i.from === n.type) {
1214
+ let r = {
1212
1215
  kind: "alter-column-type",
1213
1216
  table: e,
1214
1217
  column: t.name,
1215
1218
  from: n.type,
1216
1219
  to: t.type,
1217
- ...r.using === void 0 ? {} : { using: r.using }
1220
+ ...i.using === void 0 ? {} : { using: i.using }
1218
1221
  };
1219
- s.push(z(i, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${r.from}') declared` + (r.using ? ` with USING ${r.using}` : " (implicit cast)")));
1222
+ s.push(R(r, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${i.from}') declared` + (i.using ? ` with USING ${i.using}` : " (implicit cast)")));
1220
1223
  } else {
1221
- let r = {
1224
+ let i = {
1222
1225
  kind: "alter-column-type",
1223
1226
  table: e,
1224
1227
  column: t.name,
1225
1228
  from: n.type,
1226
1229
  to: t.type
1227
1230
  };
1228
- s.push(z(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
1231
+ s.push(R(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: xn(n.type, t, r) }));
1229
1232
  }
1230
1233
  }
1231
1234
  if (t.type === "text" && n.type === "text" && !o(r ?? "postgres") && t.maxLength !== n.maxLength) {
1232
1235
  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})`;
1233
- s.push(z({
1236
+ s.push(R({
1234
1237
  kind: "alter-column-type",
1235
1238
  table: e,
1236
1239
  column: t.name,
@@ -1238,7 +1241,7 @@ BEGIN
1238
1241
  to: "text"
1239
1242
  }, 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)}`));
1240
1243
  }
1241
- if (!tn(t, n)) {
1244
+ if (!nn(t, n)) {
1242
1245
  let n = {
1243
1246
  kind: "alter-column-default",
1244
1247
  table: e,
@@ -1246,23 +1249,23 @@ BEGIN
1246
1249
  hasDefault: t.hasDefault,
1247
1250
  ...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
1248
1251
  };
1249
- s.push(z(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1252
+ s.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
1250
1253
  }
1251
- if (!rn(t.oneOf, n.oneOf)) {
1252
- n.oneOf && n.oneOf.length > 0 && s.push(z({
1254
+ if (!an(t.oneOf, n.oneOf)) {
1255
+ n.oneOf && n.oneOf.length > 0 && s.push(R({
1253
1256
  kind: "drop-check",
1254
1257
  table: e,
1255
1258
  column: t.name
1256
1259
  }, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
1257
- let r = cn(e, t);
1260
+ let r = ln(e, t);
1258
1261
  r && s.push(r);
1259
1262
  }
1260
- return JSON.stringify(nn(t.references)) !== JSON.stringify(nn(n.references)) && (n.references && s.push(z({
1263
+ return JSON.stringify(rn(t.references)) !== JSON.stringify(rn(n.references)) && (n.references && s.push(R({
1261
1264
  kind: "drop-foreign-key",
1262
1265
  table: e,
1263
1266
  column: t.name
1264
- }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), s.push(...xn(e, t))), s;
1265
- }, xn = (e, t) => {
1267
+ }, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), s.push(...Cn(e, t))), s;
1268
+ }, Cn = (e, t) => {
1266
1269
  let n = [];
1267
1270
  if (!t.references) return n;
1268
1271
  let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
@@ -1274,15 +1277,15 @@ BEGIN
1274
1277
  ...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
1275
1278
  ...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
1276
1279
  };
1277
- return i === "null" && !t.nullable ? n.push(z(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(z({
1280
+ return i === "null" && !t.nullable ? n.push(R(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(R({
1278
1281
  ...a,
1279
1282
  orphanPolicy: i
1280
- }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(z(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1281
- }, Sn = (e, t, n) => {
1283
+ }, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(R(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
1284
+ }, wn = (e, t, n) => {
1282
1285
  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));
1283
1286
  for (let [n, c] of Object.entries(t)) {
1284
1287
  let t = c.renamedFrom;
1285
- t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(z({
1288
+ t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
1286
1289
  kind: "rename-column",
1287
1290
  table: e.tableName,
1288
1291
  from: t,
@@ -1294,26 +1297,26 @@ BEGIN
1294
1297
  consumedAddedNames: i,
1295
1298
  consumedRemovedNames: a
1296
1299
  };
1297
- }, Cn = /* @__PURE__ */ new Set([
1300
+ }, Tn = /* @__PURE__ */ new Set([
1298
1301
  "postgres",
1299
1302
  "mysql",
1300
1303
  "mariadb",
1301
1304
  "mssql"
1302
- ]), wn = {
1305
+ ]), En = {
1303
1306
  ops: [],
1304
1307
  consumedAddedNames: /* @__PURE__ */ new Set(),
1305
1308
  consumedRemovedNames: /* @__PURE__ */ new Set()
1306
- }, Tn = (e) => !e.unique && !e.expression, En = (e, t, n, r, i) => {
1307
- if (i === void 0 || !Cn.has(i)) return wn;
1308
- let a = t.added.filter((e) => Tn(e) && !r.has(e.name));
1309
- if (a.length === 0) return wn;
1309
+ }, Dn = (e) => !e.unique && !e.expression, On = (e, t, n, r, i) => {
1310
+ if (i === void 0 || !Tn.has(i)) return En;
1311
+ let a = t.added.filter((e) => Dn(e) && !r.has(e.name));
1312
+ if (a.length === 0) return En;
1310
1313
  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();
1311
1314
  for (let n of t.removed) {
1312
- if (!Tn(n)) continue;
1315
+ if (!Dn(n)) continue;
1313
1316
  let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
1314
1317
  if (r.length !== 1) continue;
1315
1318
  let i = r[0];
1316
- i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(z({
1319
+ i.name !== n.name && (l.add(i.name), u.add(n.name), c.push(R({
1317
1320
  kind: "rename-index",
1318
1321
  table: e,
1319
1322
  from: n.name,
@@ -1325,7 +1328,7 @@ BEGIN
1325
1328
  consumedAddedNames: l,
1326
1329
  consumedRemovedNames: u
1327
1330
  };
1328
- }, Dn = (e, t, n) => {
1331
+ }, kn = (e, t, n) => {
1329
1332
  let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
1330
1333
  for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
1331
1334
  for (let c of e.tables) {
@@ -1336,7 +1339,7 @@ BEGIN
1336
1339
  continue;
1337
1340
  }
1338
1341
  if (t.has(c.name)) {
1339
- r.push(z({
1342
+ r.push(R({
1340
1343
  kind: "rename-table",
1341
1344
  from: e,
1342
1345
  to: c.name
@@ -1344,14 +1347,14 @@ BEGIN
1344
1347
  continue;
1345
1348
  }
1346
1349
  if ((s.get(e) ?? 0) !== 1) {
1347
- r.push(z({
1350
+ r.push(R({
1348
1351
  kind: "rename-table",
1349
1352
  from: e,
1350
1353
  to: c.name
1351
1354
  }, "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.` }));
1352
1355
  continue;
1353
1356
  }
1354
- i.set(c.name, e), a.add(e), r.push(z({
1357
+ i.set(c.name, e), a.add(e), r.push(R({
1355
1358
  kind: "rename-table",
1356
1359
  from: e,
1357
1360
  to: c.name
@@ -1365,19 +1368,19 @@ BEGIN
1365
1368
  claimedOldNames: c,
1366
1369
  refusals: o
1367
1370
  };
1368
- }, On = (e, t, n, r) => {
1371
+ }, An = (e, t, n, r) => {
1369
1372
  if (t === void 0) return {
1370
1373
  live: e,
1371
1374
  ops: []
1372
1375
  };
1373
- let i = r !== void 0 && Cn.has(r), a = [], o = e.indexes.map((e) => {
1376
+ let i = r !== void 0 && Tn.has(r), a = [], o = e.indexes.map((e) => {
1374
1377
  if (!e.name.startsWith(t)) return e;
1375
1378
  let r = `${n}${e.name.slice(t.length)}`;
1376
1379
  return r === e.name ? e : e.name === `${t}_pkey` ? {
1377
1380
  ...e,
1378
1381
  name: r,
1379
1382
  table: n
1380
- } : i ? (a.push(z({
1383
+ } : i ? (a.push(R({
1381
1384
  kind: "rename-index",
1382
1385
  table: n,
1383
1386
  from: e.name,
@@ -1396,7 +1399,7 @@ BEGIN
1396
1399
  },
1397
1400
  ops: a
1398
1401
  };
1399
- }, kn = (e) => {
1402
+ }, jn = (e) => {
1400
1403
  let t = {
1401
1404
  safe: 0,
1402
1405
  needsDefault: 0,
@@ -1429,42 +1432,42 @@ BEGIN
1429
1432
  case "multi-step": t.multiStep++;
1430
1433
  }
1431
1434
  return t;
1432
- }, An = (e) => {
1433
- let t = L(e.declared, e.dialect), n = $t(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? gn, a = [], o = Dn(t, r, n);
1435
+ }, Mn = (e) => {
1436
+ let t = I(e.declared, e.dialect), n = en(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? _n, a = [], o = kn(t, r, n);
1434
1437
  a.push(...o.ops);
1435
1438
  for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
1436
- a.push(mn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1439
+ a.push(hn(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
1437
1440
  for (let t of e.columns) {
1438
- let n = cn(e.name, t);
1441
+ let n = ln(e.name, t);
1439
1442
  n && a.push(n);
1440
1443
  }
1441
1444
  }
1442
1445
  let s = new Set(e.ignoreTables ?? []);
1443
- for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || m(t.name) || v(t.name) || s.has(t.name) || a.push(hn(t.name));
1446
+ for (let t of e.live.tables) n.has(t.name) || o.claimedOldNames.has(t.name) || m(t.name) || v(t.name) || s.has(t.name) || a.push(gn(t.name));
1444
1447
  for (let s of t.tables) {
1445
1448
  let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
1446
1449
  if (!c) continue;
1447
- let l = On(c, t, s.name, e.dialect);
1450
+ let l = An(c, t, s.name, e.dialect);
1448
1451
  a.push(...l.ops);
1449
- let u = l.live, d = n.get(s.name), f = un(s, u, e.dialect), p = dn(s, u), m = Sn(d.table, d.columnDefs, f);
1452
+ let u = l.live, d = n.get(s.name), f = dn(s, u, e.dialect), p = fn(s, u), m = wn(d.table, d.columnDefs, f);
1450
1453
  a.push(...m.ops);
1451
1454
  for (let e of f.removed) {
1452
1455
  if (m.consumedRemovedNames.has(e.name) || v(e.name)) continue;
1453
1456
  let t = d.columnDefs[e.name];
1454
- a.push(pn(s.name, e, t));
1457
+ a.push(mn(s.name, e, t));
1455
1458
  }
1456
1459
  for (let e of f.added) {
1457
1460
  if (m.consumedAddedNames.has(e.name)) continue;
1458
1461
  let t = d.columnDefs[e.name];
1459
- a.push(fn(s.name, e, t));
1460
- let n = cn(s.name, e);
1461
- n && a.push(n), a.push(...xn(s.name, e));
1462
+ a.push(pn(s.name, e, t));
1463
+ let n = ln(s.name, e);
1464
+ n && a.push(n), a.push(...Cn(s.name, e));
1462
1465
  }
1463
- let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = En(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1466
+ let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = On(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
1464
1467
  a.push(...g.ops);
1465
- for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(_n(s.name, e, u.rowCount, i));
1466
- for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(vn(s.name, e));
1467
- for (let { declared: t, live: n } of f.changed) a.push(...bn(s.name, t, n, e.dialect, u.rowCount, i));
1468
+ for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(vn(s.name, e, u.rowCount, i));
1469
+ for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(yn(s.name, e));
1470
+ for (let { declared: t, live: n } of f.changed) a.push(...Sn(s.name, t, n, e.dialect, u.rowCount, i));
1468
1471
  }
1469
1472
  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) => {
1470
1473
  let t = l.get(e);
@@ -1473,7 +1476,7 @@ BEGIN
1473
1476
  target: e.references.table
1474
1477
  }] : []) : [];
1475
1478
  }, d = fe([...c], u), f = [];
1476
- for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(z({
1479
+ for (let e of t.tables) if (c.has(e.name)) for (let t of e.columns) !t.references || !d.has(w(e.name, t.name)) || f.push(R({
1477
1480
  kind: "add-foreign-key",
1478
1481
  table: e.name,
1479
1482
  column: t.name,
@@ -1545,11 +1548,11 @@ BEGIN
1545
1548
  });
1546
1549
  return {
1547
1550
  operations: S,
1548
- fromFingerprint: F(e.live),
1549
- toFingerprint: F(t),
1550
- summary: kn(S)
1551
+ fromFingerprint: Wt(e.live),
1552
+ toFingerprint: Wt(t),
1553
+ summary: jn(S)
1551
1554
  };
1552
- }, jn = (e) => {
1555
+ }, Nn = (e) => {
1553
1556
  let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
1554
1557
  if (!t) return null;
1555
1558
  let n = [...e.replace(/\\'/g, "''").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
@@ -1557,7 +1560,7 @@ BEGIN
1557
1560
  column: t[1],
1558
1561
  values: n
1559
1562
  };
1560
- }, Mn = (e, t) => {
1563
+ }, Pn = (e, t) => {
1561
1564
  if (t === "vector") return "vector";
1562
1565
  switch (e) {
1563
1566
  case "text":
@@ -1584,7 +1587,10 @@ BEGIN
1584
1587
  case "USER-DEFINED": return "text";
1585
1588
  default: return "text";
1586
1589
  }
1587
- }, B = (e) => {
1590
+ }, Fn = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
1591
+ expr: e,
1592
+ stored: t
1593
+ } }, z = (e) => {
1588
1594
  switch (e.toUpperCase()) {
1589
1595
  case "CASCADE": return "cascade";
1590
1596
  case "RESTRICT": return "restrict";
@@ -1592,25 +1598,25 @@ BEGIN
1592
1598
  case "SET DEFAULT": return "noAction";
1593
1599
  default: return "noAction";
1594
1600
  }
1595
- }, Nn = (e, t) => {
1601
+ }, In = (e, t) => {
1596
1602
  let n = e !== void 0 && e !== "" ? Number(e) : NaN;
1597
1603
  return Number.isInteger(n) && n > 0 ? n : t;
1598
- }, Pn = () => Nn(process.env.VOLTRO_INTROSPECT_BATCH, 20), Fn = 300, In = () => {
1604
+ }, Ln = () => In(process.env.VOLTRO_INTROSPECT_BATCH, 20), Rn = 300, zn = () => {
1599
1605
  let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
1600
- return e !== void 0 && e.trim() === "0" ? 0 : Nn(e, 3e4);
1601
- }, Ln = (e, t) => {
1606
+ return e !== void 0 && e.trim() === "0" ? 0 : In(e, 3e4);
1607
+ }, Bn = (e, t) => {
1602
1608
  let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
1603
1609
  for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
1604
1610
  return r;
1605
- }, Rn = (e) => {
1606
- let t = In(), n = x.gen(function* () {
1611
+ }, Vn = (e) => {
1612
+ let t = zn(), n = x.gen(function* () {
1607
1613
  t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
1608
- let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Pn(), a = (e, t) => x.gen(function* () {
1614
+ let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Ln(), a = (e, t) => x.gen(function* () {
1609
1615
  let r = [];
1610
- for (let a of Ln(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1616
+ for (let a of Bn(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
1611
1617
  return r;
1612
1618
  }), o = [];
1613
- for (let t = 0;; t += Fn) {
1619
+ for (let t = 0;; t += Rn) {
1614
1620
  let n = yield* e`
1615
1621
  SELECT c.relname AS table_name,
1616
1622
  COALESCE(c.reltuples::bigint, 0) AS row_count
@@ -1618,15 +1624,15 @@ BEGIN
1618
1624
  JOIN pg_namespace n ON n.oid = c.relnamespace
1619
1625
  WHERE n.nspname = current_schema() AND c.relkind = 'r'
1620
1626
  ORDER BY c.relname
1621
- LIMIT ${r(Fn)} OFFSET ${r(t)}
1627
+ LIMIT ${r(Rn)} OFFSET ${r(t)}
1622
1628
  `;
1623
- if (o.push(...n), n.length < Fn) break;
1629
+ if (o.push(...n), n.length < Rn) break;
1624
1630
  }
1625
1631
  let s = /* @__PURE__ */ new Set(), c = [];
1626
1632
  for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
1627
1633
  let l = c.map((e) => e.table_name), u = yield* a(l, (t) => e`
1628
1634
  SELECT table_name, column_name, data_type, udt_name, is_nullable, column_default,
1629
- character_maximum_length
1635
+ character_maximum_length, is_generated, generation_expression
1630
1636
  FROM information_schema.columns
1631
1637
  WHERE table_schema = current_schema() AND table_name IN ${t}
1632
1638
  ORDER BY table_name, ordinal_position
@@ -1754,22 +1760,23 @@ BEGIN
1754
1760
  let te = [];
1755
1761
  for (let e of c) {
1756
1762
  let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = 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) => {
1757
- 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" : Mn(t.data_type, t.udt_name), c = a ? {
1763
+ 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" : Pn(t.data_type, t.udt_name), c = a ? {
1758
1764
  table: a.target_table,
1759
1765
  column: a.target_column,
1760
- onDelete: B(a.delete_rule),
1761
- onUpdate: B(a.update_rule)
1766
+ onDelete: z(a.delete_rule),
1767
+ onUpdate: z(a.update_rule)
1762
1768
  } : void 0, l = m.get(`${e.table_name}.${t.column_name}`);
1763
1769
  return {
1764
1770
  name: t.column_name,
1765
1771
  type: s,
1766
- ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
1772
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1767
1773
  nullable: t.is_nullable === "YES",
1768
1774
  unique: i.has(t.column_name) || n && t.column_name === "id",
1769
1775
  hasDefault: t.column_default !== null,
1770
1776
  ...t.column_default === null ? {} : { defaultValue: t.column_default },
1771
1777
  ...c ? { references: c } : {},
1772
- ...l ? { oneOf: l } : {}
1778
+ ...l ? { oneOf: l } : {},
1779
+ ...Fn(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
1773
1780
  };
1774
1781
  }), l = [], u = ee.get(e.table_name);
1775
1782
  if (u) for (let [t, n] of u) {
@@ -1808,7 +1815,7 @@ BEGIN
1808
1815
  let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
1809
1816
  return n.includes("statement timeout") || n.includes("57014") ? x.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.`)) : x.fail(e);
1810
1817
  }));
1811
- }, zn = (e, t) => {
1818
+ }, Hn = (e, t) => {
1812
1819
  switch (e.toLowerCase()) {
1813
1820
  case "varchar":
1814
1821
  case "char":
@@ -1840,21 +1847,21 @@ BEGIN
1840
1847
  case "json": return "json";
1841
1848
  default: return "text";
1842
1849
  }
1843
- }, V = (e) => e.map((e) => {
1850
+ }, B = (e) => e.map((e) => {
1844
1851
  let t = e, n = {};
1845
1852
  for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
1846
1853
  return n;
1847
- }), Bn = (e) => x.gen(function* () {
1848
- let t = V(yield* e`
1854
+ }), Un = (e) => x.gen(function* () {
1855
+ let t = B(yield* e`
1849
1856
  SELECT table_name, COALESCE(table_rows, 0) AS table_rows
1850
1857
  FROM information_schema.tables
1851
1858
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
1852
- ORDER BY table_name`), n = V(yield* e`
1859
+ ORDER BY table_name`), n = B(yield* e`
1853
1860
  SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
1854
- character_maximum_length
1861
+ character_maximum_length, generation_expression, extra
1855
1862
  FROM information_schema.columns
1856
1863
  WHERE table_schema = DATABASE()
1857
- ORDER BY table_name, ordinal_position`), r = V(yield* e`
1864
+ ORDER BY table_name, ordinal_position`), r = B(yield* e`
1858
1865
  SELECT k.table_name AS source_table,
1859
1866
  k.column_name AS source_column,
1860
1867
  k.referenced_table_name AS target_table,
@@ -1864,11 +1871,11 @@ BEGIN
1864
1871
  JOIN information_schema.referential_constraints r
1865
1872
  ON k.constraint_name = r.constraint_name
1866
1873
  AND k.table_schema = r.constraint_schema
1867
- WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = V(yield* e`
1874
+ WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = B(yield* e`
1868
1875
  SELECT table_name, index_name, non_unique, column_name, seq_in_index
1869
1876
  FROM information_schema.statistics
1870
1877
  WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
1871
- ORDER BY table_name, index_name, seq_in_index`), a = V(yield* e`
1878
+ ORDER BY table_name, index_name, seq_in_index`), a = B(yield* e`
1872
1879
  SELECT tc.table_name AS table_name, cc.check_clause AS check_clause
1873
1880
  FROM information_schema.check_constraints cc
1874
1881
  JOIN information_schema.table_constraints tc
@@ -1881,7 +1888,7 @@ BEGIN
1881
1888
  o.add(`${e.table_name}.${t[1]}`);
1882
1889
  continue;
1883
1890
  }
1884
- let n = jn(e.check_clause);
1891
+ let n = Nn(e.check_clause);
1885
1892
  n && s.set(`${e.table_name}.${n.column}`, n.values);
1886
1893
  }
1887
1894
  let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -1904,22 +1911,23 @@ BEGIN
1904
1911
  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);
1905
1912
  if (f) for (let e of f.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
1906
1913
  let p = t.map((t) => {
1907
- 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" : zn(t.data_type, t.column_type), u = c ? {
1914
+ 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" : Hn(t.data_type, t.column_type), u = c ? {
1908
1915
  table: c.target_table,
1909
1916
  column: c.target_column,
1910
- onDelete: B(c.delete_rule),
1911
- onUpdate: B(c.update_rule)
1917
+ onDelete: z(c.delete_rule),
1918
+ onUpdate: z(c.update_rule)
1912
1919
  } : 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}`);
1913
1920
  return {
1914
1921
  name: t.column_name,
1915
1922
  type: l,
1916
1923
  nullable: t.is_nullable === "YES",
1917
- ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
1924
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
1918
1925
  unique: d,
1919
1926
  hasDefault: f !== null,
1920
1927
  ...f === null ? {} : { defaultValue: f },
1921
1928
  ...u ? { references: u } : {},
1922
- ...p ? { oneOf: p } : {}
1929
+ ...p ? { oneOf: p } : {},
1930
+ ...Fn(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {}
1923
1931
  };
1924
1932
  }), m = new Set(n.map((e) => e.source_column)), h = [];
1925
1933
  if (f) for (let [t, n] of f) {
@@ -1946,10 +1954,10 @@ BEGIN
1946
1954
  });
1947
1955
  }
1948
1956
  return { tables: d };
1949
- }), Vn = (e) => {
1957
+ }), Wn = (e) => {
1950
1958
  let t = e.toUpperCase();
1951
1959
  return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
1952
- }, Hn = (e) => x.gen(function* () {
1960
+ }, Gn = (e) => x.gen(function* () {
1953
1961
  let t = yield* e`
1954
1962
  SELECT name, sql FROM sqlite_master
1955
1963
  WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
@@ -1960,17 +1968,17 @@ BEGIN
1960
1968
  let n = [...e[2].matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
1961
1969
  n.length > 0 && t.set(e[1], n);
1962
1970
  }
1963
- let o = yield* e.unsafe(`PRAGMA table_info(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set();
1971
+ let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Set();
1964
1972
  for (let t of c) {
1965
1973
  let r = (yield* e.unsafe(`PRAGMA index_info(${n(t.name)})`)).map((e) => e.name).filter((e) => e !== null);
1966
1974
  d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
1967
1975
  }
1968
1976
  let p = o.map((e) => {
1969
- let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Vn(e.type), a = r ? {
1977
+ let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Wn(e.type), a = r ? {
1970
1978
  table: r.table,
1971
1979
  column: r.to,
1972
- onDelete: B(r.on_delete),
1973
- onUpdate: B(r.on_update)
1980
+ onDelete: z(r.on_delete),
1981
+ onUpdate: z(r.on_update)
1974
1982
  } : void 0, o = t.get(e.name);
1975
1983
  return {
1976
1984
  name: e.name,
@@ -1980,7 +1988,8 @@ BEGIN
1980
1988
  hasDefault: e.dflt_value !== null,
1981
1989
  ...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
1982
1990
  ...a ? { references: a } : {},
1983
- ...o ? { oneOf: o } : {}
1991
+ ...o ? { oneOf: o } : {},
1992
+ ...Fn(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
1984
1993
  };
1985
1994
  }), m = new Set(s.map((e) => e.from)), h = [];
1986
1995
  for (let e of c) {
@@ -2005,7 +2014,7 @@ BEGIN
2005
2014
  });
2006
2015
  }
2007
2016
  return { tables: r };
2008
- }), Un = (e) => {
2017
+ }), Kn = (e) => {
2009
2018
  switch (e.toLowerCase()) {
2010
2019
  case "int":
2011
2020
  case "smallint":
@@ -2027,14 +2036,19 @@ BEGIN
2027
2036
  case "image": return "bytes";
2028
2037
  default: return "text";
2029
2038
  }
2030
- }, H = (e) => e === !0 || e === 1, Wn = (e) => x.gen(function* () {
2039
+ }, V = (e) => e === !0 || e === 1, qn = (e) => x.gen(function* () {
2031
2040
  let t = yield* e`
2032
2041
  SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
2033
2042
  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
2034
2043
  SELECT TABLE_NAME AS table_name, COLUMN_NAME AS column_name, DATA_TYPE AS data_type,
2035
2044
  IS_NULLABLE AS is_nullable, COLUMN_DEFAULT AS column_default,
2036
2045
  CHARACTER_MAXIMUM_LENGTH AS character_maximum_length
2037
- FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* e`
2046
+ FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, ORDINAL_POSITION`, r = yield* x.orElseSucceed(e`
2047
+ SELECT t.name AS table_name, c.name AS column_name, cc.definition AS definition,
2048
+ cc.is_persisted AS is_persisted
2049
+ FROM sys.computed_columns cc
2050
+ JOIN sys.columns c ON c.object_id = cc.object_id AND c.column_id = cc.column_id
2051
+ JOIN sys.tables t ON t.object_id = cc.object_id`, () => []), i = new Map(r.map((e) => [`${e.table_name}.${e.column_name}`, e])), a = yield* e`
2038
2052
  SELECT st.name AS source_table, sc.name AS source_column,
2039
2053
  tt.name AS target_table, tc.name AS target_column,
2040
2054
  fk.delete_referential_action_desc AS delete_rule,
@@ -2044,7 +2058,7 @@ BEGIN
2044
2058
  JOIN sys.tables st ON st.object_id = fkc.parent_object_id
2045
2059
  JOIN sys.columns sc ON sc.object_id = fkc.parent_object_id AND sc.column_id = fkc.parent_column_id
2046
2060
  JOIN sys.tables tt ON tt.object_id = fkc.referenced_object_id
2047
- JOIN sys.columns tc ON tc.object_id = fkc.referenced_object_id AND tc.column_id = fkc.referenced_column_id`, i = yield* e`
2061
+ JOIN sys.columns tc ON tc.object_id = fkc.referenced_object_id AND tc.column_id = fkc.referenced_column_id`, o = yield* e`
2048
2062
  SELECT t.name AS table_name, i.name AS index_name, i.is_unique AS is_unique,
2049
2063
  i.is_primary_key AS is_primary, c.name AS column_name, ic.key_ordinal AS key_ordinal
2050
2064
  FROM sys.indexes i
@@ -2052,162 +2066,163 @@ BEGIN
2052
2066
  JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
2053
2067
  JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
2054
2068
  WHERE i.type > 0 AND ic.is_included_column = 0
2055
- ORDER BY t.name, i.name, ic.key_ordinal`, a = yield* e`
2069
+ ORDER BY t.name, i.name, ic.key_ordinal`, s = yield* e`
2056
2070
  SELECT t.name AS table_name, c.name AS column_name, cc.definition AS def
2057
2071
  FROM sys.check_constraints cc
2058
2072
  JOIN sys.tables t ON t.object_id = cc.parent_object_id
2059
2073
  JOIN sys.columns c ON c.object_id = cc.parent_object_id AND c.column_id = cc.parent_column_id
2060
- WHERE cc.parent_column_id <> 0`, o = /* @__PURE__ */ new Map();
2061
- for (let e of a) {
2074
+ WHERE cc.parent_column_id <> 0`, c = /* @__PURE__ */ new Map();
2075
+ for (let e of s) {
2062
2076
  let t = [...e.def.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
2063
- t.length > 0 && o.set(`${e.table_name}.${e.column_name}`, t);
2077
+ t.length > 0 && c.set(`${e.table_name}.${e.column_name}`, t);
2064
2078
  }
2065
- let s = /* @__PURE__ */ new Map();
2079
+ let l = /* @__PURE__ */ new Map();
2066
2080
  for (let e of n) {
2067
- let t = s.get(e.table_name) ?? [];
2068
- t.push(e), s.set(e.table_name, t);
2081
+ let t = l.get(e.table_name) ?? [];
2082
+ t.push(e), l.set(e.table_name, t);
2069
2083
  }
2070
- let c = /* @__PURE__ */ new Map();
2071
- for (let e of r) {
2072
- let t = c.get(e.source_table) ?? [];
2073
- t.push(e), c.set(e.source_table, t);
2084
+ let u = /* @__PURE__ */ new Map();
2085
+ for (let e of a) {
2086
+ let t = u.get(e.source_table) ?? [];
2087
+ t.push(e), u.set(e.source_table, t);
2074
2088
  }
2075
- let l = /* @__PURE__ */ new Map();
2076
- for (let e of i) {
2077
- let t = l.get(e.table_name);
2078
- t || (t = /* @__PURE__ */ new Map(), l.set(e.table_name, t));
2089
+ let d = /* @__PURE__ */ new Map();
2090
+ for (let e of o) {
2091
+ let t = d.get(e.table_name);
2092
+ t || (t = /* @__PURE__ */ new Map(), d.set(e.table_name, t));
2079
2093
  let n = t.get(e.index_name) ?? [];
2080
2094
  n.push(e), t.set(e.index_name, n);
2081
2095
  }
2082
- let u = [];
2096
+ let f = [];
2083
2097
  for (let { table_name: e } of t) {
2084
- 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();
2085
- if (a) for (let [, e] of a) {
2098
+ let t = l.get(e) ?? [], n = u.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), a = new Set(n.map((e) => e.source_column)), o = d.get(e), s = [], p = /* @__PURE__ */ new Set();
2099
+ if (o) for (let [, e] of o) {
2086
2100
  let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
2087
- if (H(t[0].is_primary)) for (let e of t) d.push(e.column_name);
2088
- else H(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
2101
+ if (V(t[0].is_primary)) for (let e of t) s.push(e.column_name);
2102
+ else V(t[0].is_unique) && t.length === 1 && p.add(t[0].column_name);
2089
2103
  }
2090
- let p = t.map((t) => {
2091
- 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" : Un(t.data_type), s = i ? {
2092
- table: i.target_table,
2093
- column: i.target_column,
2094
- onDelete: Gn(i.delete_rule),
2095
- onUpdate: Gn(i.update_rule)
2096
- } : void 0, c = t.column_default === null ? null : Kn(t.column_default), l = o.get(`${e}.${t.column_name}`);
2104
+ let m = t.map((t) => {
2105
+ let n = s.length === 1 && s[0] === t.column_name, a = r.get(t.column_name), o = a ? "reference" : n && t.column_name === "id" ? "id" : Kn(t.data_type), l = a ? {
2106
+ table: a.target_table,
2107
+ column: a.target_column,
2108
+ onDelete: Jn(a.delete_rule),
2109
+ onUpdate: Jn(a.update_rule)
2110
+ } : void 0, u = t.column_default === null ? null : Yn(t.column_default), d = c.get(`${e}.${t.column_name}`);
2097
2111
  return {
2098
2112
  name: t.column_name,
2099
- type: a,
2113
+ type: o,
2100
2114
  nullable: t.is_nullable === "YES",
2101
- ...U(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: U(t.data_type, t.character_maximum_length) },
2102
- unique: f.has(t.column_name) || n && t.column_name === "id",
2103
- hasDefault: c !== null,
2104
- ...c === null ? {} : { defaultValue: c },
2105
- ...s ? { references: s } : {},
2106
- ...l ? { oneOf: l } : {}
2115
+ ...H(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: H(t.data_type, t.character_maximum_length) },
2116
+ unique: p.has(t.column_name) || n && t.column_name === "id",
2117
+ hasDefault: u !== null,
2118
+ ...u === null ? {} : { defaultValue: u },
2119
+ ...l ? { references: l } : {},
2120
+ ...d ? { oneOf: d } : {},
2121
+ ...Fn(i.get(`${e}.${t.column_name}`)?.definition ?? null, V(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
2107
2122
  };
2108
- }), m = [];
2109
- if (a) for (let [t, n] of a) {
2123
+ }), h = [];
2124
+ if (o) for (let [t, n] of o) {
2110
2125
  let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
2111
- H(r[0].is_primary) || r.length === 1 && H(r[0].is_unique) || r.length === 1 && !H(r[0].is_unique) && i.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || m.push({
2126
+ V(r[0].is_primary) || r.length === 1 && V(r[0].is_unique) || r.length === 1 && !V(r[0].is_unique) && a.has(r[0].column_name) && t !== `${e}_${r[0].column_name}_idx` || h.push({
2112
2127
  name: t,
2113
2128
  table: e,
2114
2129
  columns: r.map((e) => e.column_name),
2115
- unique: H(r[0].is_unique)
2130
+ unique: V(r[0].is_unique)
2116
2131
  });
2117
2132
  }
2118
- d.length > 0 && m.push({
2133
+ s.length > 0 && h.push({
2119
2134
  name: `${e}_pkey`,
2120
2135
  table: e,
2121
- columns: d,
2136
+ columns: s,
2122
2137
  unique: !0
2123
- }), u.push({
2138
+ }), f.push({
2124
2139
  name: e,
2125
- columns: p,
2126
- indexes: m
2140
+ columns: m,
2141
+ indexes: h
2127
2142
  });
2128
2143
  }
2129
- return { tables: u };
2130
- }), Gn = (e) => {
2144
+ return { tables: f };
2145
+ }), Jn = (e) => {
2131
2146
  switch (e.toUpperCase().replace(/_/g, " ")) {
2132
2147
  case "CASCADE": return "cascade";
2133
2148
  case "SET NULL": return "setNull";
2134
2149
  case "SET DEFAULT": return "noAction";
2135
2150
  default: return "noAction";
2136
2151
  }
2137
- }, Kn = (e) => {
2152
+ }, Yn = (e) => {
2138
2153
  let t = e.trim();
2139
2154
  for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
2140
2155
  return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
2141
- }, qn = /* @__PURE__ */ new Set([
2156
+ }, Xn = /* @__PURE__ */ new Set([
2142
2157
  "character varying",
2143
2158
  "varchar",
2144
2159
  "nvarchar",
2145
2160
  "char",
2146
2161
  "character",
2147
2162
  "nchar"
2148
- ]), U = (e, t) => {
2149
- if (!qn.has(e.toLowerCase())) return;
2163
+ ]), H = (e, t) => {
2164
+ if (!Xn.has(e.toLowerCase())) return;
2150
2165
  let n = Number(t);
2151
2166
  if (!(!Number.isFinite(n) || n <= 0)) return n;
2152
- }, Jn = /* @__PURE__ */ new Set([O]), Yn = (e) => e.onDialectOrElse({
2153
- mysql: () => Bn(e),
2154
- mssql: () => Wn(e),
2155
- sqlite: () => Hn(e),
2156
- orElse: () => Rn(e)
2167
+ }, Zn = /* @__PURE__ */ new Set([O]), Qn = (e) => e.onDialectOrElse({
2168
+ mysql: () => Un(e),
2169
+ mssql: () => qn(e),
2170
+ sqlite: () => Gn(e),
2171
+ orElse: () => Vn(e)
2157
2172
  }).pipe(x.map((e) => ({
2158
2173
  ...e,
2159
- tables: e.tables.filter((e) => !Jn.has(e.name))
2160
- }))), Xn = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", Zn = /* @__PURE__ */ new WeakMap(), W = (e) => x.suspend(() => {
2161
- let t = Zn.get(e);
2162
- return t === void 0 ? Qn(e).pipe(x.tap((t) => x.sync(() => Zn.set(e, t)))) : x.succeed(t);
2163
- }), Qn = (e) => e.unsafe("SELECT VERSION() AS v").pipe(x.map((e) => {
2174
+ tables: e.tables.filter((e) => !Zn.has(e.name))
2175
+ }))), $n = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", er = /* @__PURE__ */ new WeakMap(), U = (e) => x.suspend(() => {
2176
+ let t = er.get(e);
2177
+ return t === void 0 ? tr(e).pipe(x.tap((t) => x.sync(() => er.set(e, t)))) : x.succeed(t);
2178
+ }), tr = (e) => e.unsafe("SELECT VERSION() AS v").pipe(x.map((e) => {
2164
2179
  let t = e[0]?.v;
2165
- return typeof t == "string" ? Xn(t) : "mysql";
2166
- }), x.catchAll(() => x.succeed("mysql"))), $n = (e) => {
2180
+ return typeof t == "string" ? $n(t) : "mysql";
2181
+ }), x.catchAll(() => x.succeed("mysql"))), nr = (e) => {
2167
2182
  let t = e;
2168
2183
  for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
2169
2184
  let e = t;
2170
2185
  if (typeof e.errno == "number") return e.errno;
2171
2186
  t = e.cause;
2172
2187
  }
2173
- }, er = (e) => {
2188
+ }, rr = (e) => {
2174
2189
  let t = [], n = e;
2175
2190
  for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
2176
2191
  let e = n;
2177
2192
  typeof e.message == "string" && t.push(e.message), n = e.cause;
2178
2193
  }
2179
2194
  return t.join(" | ");
2180
- }, tr = (e, t) => {
2195
+ }, ir = (e, t) => {
2181
2196
  if (t.length === 0) return !1;
2182
- let n = $n(e), r = er(e);
2197
+ let n = nr(e), r = rr(e);
2183
2198
  return t.some((e) => e.errno !== void 0 && n !== void 0 && e.errno.includes(n) || e.messageIncludes !== void 0 && e.messageIncludes.some((e) => r.includes(e)));
2184
- }, nr = {
2199
+ }, ar = {
2185
2200
  why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
2186
2201
  errno: [1061]
2187
- }, rr = {
2202
+ }, or = {
2188
2203
  why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
2189
2204
  errno: [1091]
2190
- }, ir = {
2205
+ }, sr = {
2191
2206
  why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
2192
2207
  messageIncludes: ["no such column"]
2193
- }, G = (e, t) => e.onDialectOrElse({
2208
+ }, W = (e, t) => e.onDialectOrElse({
2194
2209
  mysql: () => x.succeed(t.replace("T", " ").replace("Z", "")),
2195
2210
  orElse: () => x.succeed(t)
2196
- }), ar = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, or = (e, t) => {
2211
+ }), cr = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, lr = (e, t) => {
2197
2212
  if ((e.type !== "text" || e.maxLength === void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
2198
2213
  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;
2199
2214
  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.`);
2200
2215
  return j(e, t);
2201
- }, sr = (e) => {
2202
- let t = or(e, "postgres");
2203
- return t === void 0 ? cr(e) : t;
2204
- }, cr = (e) => {
2216
+ }, ur = (e) => {
2217
+ let t = lr(e, "postgres");
2218
+ return t === void 0 ? dr(e) : t;
2219
+ }, dr = (e) => {
2205
2220
  switch (e.type) {
2206
2221
  case "id": return "text";
2207
2222
  case "text": return "text";
2208
2223
  case "integer": return "integer";
2209
2224
  case "real": return "double precision";
2210
- case "decimal": return ar(e, "NUMERIC");
2225
+ case "decimal": return cr(e, "NUMERIC");
2211
2226
  case "bigint": return "bigint";
2212
2227
  case "boolean": return "boolean";
2213
2228
  case "timestamp": return "timestamptz";
@@ -2221,15 +2236,15 @@ BEGIN
2221
2236
  case "interval": return "interval";
2222
2237
  case "raw": return e.rawDdl ?? "text";
2223
2238
  }
2224
- }, lr = (e) => {
2225
- let t = or(e, "mariadb");
2239
+ }, fr = (e) => {
2240
+ let t = lr(e, "mariadb");
2226
2241
  if (t !== void 0) return t;
2227
2242
  switch (e.type) {
2228
2243
  case "id": return "VARCHAR(64)";
2229
2244
  case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
2230
2245
  case "integer": return "INT";
2231
2246
  case "real": return "DOUBLE";
2232
- case "decimal": return ar(e, "DECIMAL");
2247
+ case "decimal": return cr(e, "DECIMAL");
2233
2248
  case "bigint": return "BIGINT";
2234
2249
  case "boolean": return "TINYINT(1)";
2235
2250
  case "timestamp": return "DATETIME(6)";
@@ -2243,58 +2258,58 @@ BEGIN
2243
2258
  case "interval": return "BIGINT";
2244
2259
  case "raw": return e.rawDdl ?? "LONGTEXT";
2245
2260
  }
2246
- }, K = (e) => `"${e}"`, q = (e) => `\`${e.replace(/`/g, "``")}\``, ur = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", dr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, fr = (e, t = "mariadb") => `ALTER TABLE ${q(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${q(e.column)}, ALGORITHM=COPY;`, pr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, mr = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Ur(t)}`)};`, hr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${gr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, gr = (e, t) => {
2261
+ }, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, pr = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", mr = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, hr = (e, t = "mariadb") => `ALTER TABLE ${K(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${K(e.column)}, ALGORITHM=COPY;`, gr = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, _r = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Gr(t)}`)};`, vr = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${yr(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, yr = (e, t) => {
2247
2262
  let n = t(e.defaultValue);
2248
2263
  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.`);
2249
2264
  return n;
2250
- }, _r = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], vr = (e, t, n) => {
2251
- let r = _r(e, t, n);
2252
- return r ? Wt(n, r) : void 0;
2253
- }, yr = (e, t, n) => {
2265
+ }, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], br = (e, t, n) => {
2266
+ let r = q(e, t, n);
2267
+ return r ? Gt(n, r) : void 0;
2268
+ }, xr = (e, t, n) => {
2254
2269
  let r = n ?? e.nullable, i = Qe(e, "mariadb");
2255
2270
  return [
2256
- q(t),
2271
+ K(t),
2257
2272
  j(e, "mariadb"),
2258
2273
  r ? null : "NOT NULL",
2259
2274
  i
2260
2275
  ].filter(Boolean).join(" ");
2261
- }, br = (e, t) => e == null ? null : Array.isArray(e) ? xr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, xr = (e, t, n) => $e(e, t ?? { type: "json" }, n), Sr = (e, t) => e == null ? null : Array.isArray(e) ? xr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, Cr = (e, t) => {
2276
+ }, Sr = (e, t) => e == null ? null : Array.isArray(e) ? Cr(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "mariadb") : null, Cr = (e, t, n) => $e(e, t ?? { type: "json" }, n), wr = (e, t) => e == null ? null : Array.isArray(e) ? Cr(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "postgres") : null, Tr = (e, t) => {
2262
2277
  if (!e.generatedAs) return null;
2263
2278
  let { expr: n, stored: r } = e.generatedAs;
2264
2279
  return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
2265
- }, wr = (e) => {
2280
+ }, Er = (e) => {
2266
2281
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
2267
- let t = Cr(e, "postgres");
2268
- if (t) return `${K(e.name)} ${sr(e)} ${t}`;
2269
- let n = [K(e.name), sr(e)];
2282
+ let t = Tr(e, "postgres");
2283
+ if (t) return `${G(e.name)} ${ur(e)} ${t}`;
2284
+ let n = [G(e.name), ur(e)];
2270
2285
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2271
- let t = Sr(e.defaultValue, e);
2286
+ let t = wr(e.defaultValue, e);
2272
2287
  t && n.push(t);
2273
2288
  }
2274
- return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2289
+ return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
2275
2290
  cascade: "CASCADE",
2276
2291
  restrict: "RESTRICT",
2277
2292
  setNull: "SET NULL",
2278
2293
  noAction: "NO ACTION"
2279
2294
  }[e.references.onDelete]}`)), n.join(" ");
2280
- }, Tr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Er = (e) => {
2281
- let t = e.columns.map((e) => ` ${wr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${t}${Tr(e, K)}\n)`];
2282
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(Jr).join(", ")})`);
2295
+ }, Dr = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Or = (e) => {
2296
+ let t = e.columns.map((e) => ` ${Er(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Dr(e, G)}\n)`];
2297
+ 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(Xr).join(", ")})`);
2283
2298
  return n;
2284
- }, Dr = 191, Or = (e) => {
2285
- let t = lr(e).toUpperCase();
2299
+ }, kr = 191, Ar = (e) => {
2300
+ let t = fr(e).toUpperCase();
2286
2301
  return t.endsWith("TEXT") || t.endsWith("BLOB");
2287
- }, kr = (e) => {
2302
+ }, jr = (e) => {
2288
2303
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
2289
- let t = Cr(e, "mariadb");
2290
- if (t) return `${q(e.name)} ${lr(e)} ${t}`;
2291
- let n = [q(e.name), lr(e)];
2292
- if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Or(e) && n.push("UNIQUE"), e.hasDefault) {
2293
- let t = br(e.defaultValue, e);
2304
+ let t = Tr(e, "mariadb");
2305
+ if (t) return `${K(e.name)} ${fr(e)} ${t}`;
2306
+ let n = [K(e.name), fr(e)];
2307
+ if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Ar(e) && n.push("UNIQUE"), e.hasDefault) {
2308
+ let t = Sr(e.defaultValue, e);
2294
2309
  t && n.push(t);
2295
2310
  }
2296
2311
  return n.join(" ");
2297
- }, Ar = (e) => e.columns.flatMap((t) => {
2312
+ }, Mr = (e) => e.columns.flatMap((t) => {
2298
2313
  if (!t.references) return [];
2299
2314
  let n = t.references.onDelete ? ` ON DELETE ${{
2300
2315
  cascade: "CASCADE",
@@ -2302,27 +2317,27 @@ BEGIN
2302
2317
  setNull: "SET NULL",
2303
2318
  noAction: "NO ACTION"
2304
2319
  }[t.references.onDelete]}` : "";
2305
- return [` CONSTRAINT ${q(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${q(t.name)}) REFERENCES ${q(t.references.table)} (${q(t.references.column)})${n}`];
2306
- }), jr = (e, t = "mariadb") => {
2320
+ return [` CONSTRAINT ${K(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${K(t.name)}) REFERENCES ${K(t.references.table)} (${K(t.references.column)})${n}`];
2321
+ }), Nr = (e, t = "mariadb") => {
2307
2322
  let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
2308
- let t = Kr(n.get(e));
2309
- return t === void 0 ? q(e) : `${q(e)}(${t})`;
2310
- }, i = e.columns.map((e) => ` ${kr(e)}`).join(",\n"), a = Ar(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${q(e.table)} (\n${o}${Tr(e, r)}\n)`];
2311
- for (let n of e.columns) n.unique && n.type !== "id" && Or(n) && s.push(`CREATE UNIQUE INDEX ${ur(t)}${q(`${e.table}_${n.name}_key`)} ON ${q(e.table)} (${r(n.name)})`);
2312
- for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${ur(t)}${q(n.name)} ON ${q(e.table)} (${n.columns.map(r).join(", ")})`);
2323
+ let t = Jr(n.get(e));
2324
+ return t === void 0 ? K(e) : `${K(e)}(${t})`;
2325
+ }, i = e.columns.map((e) => ` ${jr(e)}`).join(",\n"), a = Mr(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${o}${Dr(e, r)}\n)`];
2326
+ for (let n of e.columns) n.unique && n.type !== "id" && Ar(n) && s.push(`CREATE UNIQUE INDEX ${pr(t)}${K(`${e.table}_${n.name}_key`)} ON ${K(e.table)} (${r(n.name)})`);
2327
+ for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${pr(t)}${K(n.name)} ON ${K(e.table)} (${n.columns.map(r).join(", ")})`);
2313
2328
  return s;
2314
- }, Mr = {
2329
+ }, Pr = {
2315
2330
  cascade: "CASCADE",
2316
2331
  restrict: "RESTRICT",
2317
2332
  setNull: "SET NULL",
2318
2333
  noAction: "NO ACTION"
2319
- }, Nr = {
2334
+ }, Fr = {
2320
2335
  cascade: "CASCADE",
2321
2336
  restrict: "NO ACTION",
2322
2337
  setNull: "SET NULL",
2323
2338
  noAction: "NO ACTION"
2324
- }, Pr = (e) => {
2325
- let t = or(e, "sqlite");
2339
+ }, Ir = (e) => {
2340
+ let t = lr(e, "sqlite");
2326
2341
  if (t !== void 0) return t;
2327
2342
  switch (e.type) {
2328
2343
  case "integer":
@@ -2333,60 +2348,60 @@ BEGIN
2333
2348
  case "bytes": return "BLOB";
2334
2349
  default: return "TEXT";
2335
2350
  }
2336
- }, Fr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Ir = (e) => {
2351
+ }, Lr = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Rr = (e) => {
2337
2352
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
2338
- let t = Cr(e, "sqlite");
2339
- if (t) return `${K(e.name)} ${Pr(e)} ${t}`;
2340
- let n = [K(e.name), Pr(e)];
2353
+ let t = Tr(e, "sqlite");
2354
+ if (t) return `${G(e.name)} ${Ir(e)} ${t}`;
2355
+ let n = [G(e.name), Ir(e)];
2341
2356
  if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
2342
- let t = Fr(e.defaultValue, "CURRENT_TIMESTAMP");
2357
+ let t = Lr(e.defaultValue, "CURRENT_TIMESTAMP");
2343
2358
  t && n.push(t);
2344
2359
  }
2345
- if (e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Mr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2360
+ if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Pr[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
2346
2361
  let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2347
- n.push(`CHECK (${K(e.name)} IN (${t}))`);
2362
+ n.push(`CHECK (${G(e.name)} IN (${t}))`);
2348
2363
  }
2349
2364
  return n.join(" ");
2350
- }, Lr = (e) => {
2351
- let t = e.columns.map((e) => ` ${Ir(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${t}${Tr(e, K)}\n)`];
2352
- for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(K).join(", ")})`);
2365
+ }, zr = (e) => {
2366
+ let t = e.columns.map((e) => ` ${Rr(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${Dr(e, G)}\n)`];
2367
+ 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(", ")})`);
2353
2368
  return n;
2354
2369
  }, J = (e, t) => {
2355
2370
  let n = t.find((t) => t.tableName === e);
2356
2371
  if (!n) return [];
2357
- let r = L([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => K(e.name)).join(", "), o = [
2358
- ...Lr({
2372
+ let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
2373
+ ...zr({
2359
2374
  kind: "create-table",
2360
2375
  table: i,
2361
2376
  columns: r.columns,
2362
2377
  indexes: [],
2363
2378
  ...r.primaryKey ? { primaryKey: r.primaryKey } : {}
2364
2379
  }),
2365
- `INSERT INTO ${K(i)} (${a}) SELECT ${a} FROM ${K(e)}`,
2366
- `DROP TABLE ${K(e)}`,
2367
- `ALTER TABLE ${K(i)} RENAME TO ${K(e)}`
2380
+ `INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
2381
+ `DROP TABLE ${G(e)}`,
2382
+ `ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
2368
2383
  ];
2369
- for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e)} (${t.columns.map(K).join(", ")})`);
2384
+ 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(", ")})`);
2370
2385
  return o;
2371
- }, Rr = (e, t, n, r) => {
2386
+ }, Br = (e, t, n, r) => {
2372
2387
  let i = r ?? e.nullable;
2373
2388
  return `ALTER TABLE ${Y(n)} ALTER COLUMN ${Y(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
2374
- }, zr = (e) => {
2389
+ }, Vr = (e) => {
2375
2390
  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 ${Y(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
2376
2391
  if (!e.hasDefault) return t;
2377
- let n = Fr(e.defaultValue, "SYSUTCDATETIME()");
2392
+ let n = Lr(e.defaultValue, "SYSUTCDATETIME()");
2378
2393
  if (!n) return t;
2379
2394
  let r = n.replace(/^DEFAULT\s+/i, "");
2380
2395
  return `${t} ALTER TABLE ${Y(e.table)} ADD DEFAULT ${r} FOR ${Y(e.column)};`;
2381
- }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Br = (e) => {
2382
- let t = or(e, "mssql");
2396
+ }, Y = (e) => `[${e.replace(/]/g, "]]")}]`, Hr = (e) => {
2397
+ let t = lr(e, "mssql");
2383
2398
  if (t !== void 0) return t;
2384
2399
  switch (e.type) {
2385
2400
  case "id":
2386
2401
  case "reference": return "NVARCHAR(64)";
2387
2402
  case "integer": return "INT";
2388
2403
  case "real": return "FLOAT";
2389
- case "decimal": return ar(e, "DECIMAL");
2404
+ case "decimal": return cr(e, "DECIMAL");
2390
2405
  case "bigint": return "BIGINT";
2391
2406
  case "boolean": return "BIT";
2392
2407
  case "timestamp": return "DATETIME2(6)";
@@ -2394,44 +2409,44 @@ BEGIN
2394
2409
  case "bytes": return "VARBINARY(MAX)";
2395
2410
  default: return "NVARCHAR(MAX)";
2396
2411
  }
2397
- }, Vr = (e, t) => {
2412
+ }, Ur = (e, t) => {
2398
2413
  if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
2399
- let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Br(e), r = Cr(e, "mssql");
2414
+ let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Hr(e), r = Tr(e, "mssql");
2400
2415
  if (r) return `${Y(e.name)} ${r}`;
2401
2416
  let i = [Y(e.name), n];
2402
2417
  if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
2403
- let t = Fr(e.defaultValue, "SYSUTCDATETIME()");
2418
+ let t = Lr(e.defaultValue, "SYSUTCDATETIME()");
2404
2419
  t && i.push(t);
2405
2420
  }
2406
- return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Nr[e.references.onDelete]}`)), i.join(" ");
2407
- }, Hr = (e) => {
2408
- let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Vr(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Tr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2421
+ return e.references && (i.push(`REFERENCES ${Y(e.references.table)} (${Y(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${Fr[e.references.onDelete]}`)), i.join(" ");
2422
+ }, Wr = (e) => {
2423
+ let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Ur(e, n)}`).join(",\n"), i = `CREATE TABLE ${Y(e.table)} (\n${r}${Dr(e, Y)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
2409
2424
  for (let n of e.indexes) {
2410
2425
  if (n.name === `${e.table}_pkey`) continue;
2411
2426
  let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Y(n.name)} ON ${Y(e.table)} (${n.columns.map(Y).join(", ")})`;
2412
2427
  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)}')`);
2413
2428
  }
2414
2429
  return a;
2415
- }, Ur = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Wr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Gr = (e, t, n) => {
2416
- let r = `${e.table}${Ur(t)}`;
2430
+ }, Gr = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Kr = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, qr = (e, t, n) => {
2431
+ let r = `${e.table}${Gr(t)}`;
2417
2432
  return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
2418
- }, Kr = (e) => {
2419
- if (e === void 0 || !Or(e)) return;
2433
+ }, Jr = (e) => {
2434
+ if (e === void 0 || !Ar(e)) return;
2420
2435
  let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
2421
- return t === void 0 ? Dr : Math.min(Dr, t);
2422
- }, qr = (e, t, n) => {
2423
- let r = Kr(vr(e, t, n));
2424
- return r === void 0 ? q(n) : `${q(n)}(${r})`;
2425
- }, Jr = (e) => e.startsWith("(") ? e : K(e), Yr = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map(Jr).join(", ")});`, Xr = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${ur(n)}${q(e.index.name)} ON ${q(e.table)} (${e.index.columns.map((n) => qr(t, e.table, n)).join(", ")});`, Zr = (e) => `DROP INDEX IF EXISTS ${K(e.index)};`, Qr = (e) => `DROP INDEX ${q(e.index)} ON ${q(e.table)};`, $r = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ei = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, ti = (e) => {
2436
+ return t === void 0 ? kr : Math.min(kr, t);
2437
+ }, Yr = (e, t, n) => {
2438
+ let r = Jr(br(e, t, n));
2439
+ return r === void 0 ? K(n) : `${K(n)}(${r})`;
2440
+ }, Xr = (e) => e.startsWith("(") ? e : G(e), Zr = (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(Xr).join(", ")});`, Qr = (e, t, n = "mariadb") => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${pr(n)}${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Yr(t, e.table, n)).join(", ")});`, $r = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, ei = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, ti = (e) => `DROP INDEX IF EXISTS ${Y(e.index)} ON ${Y(e.table)};`, ni = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, ri = (e) => {
2426
2441
  let t = (e) => e.replace(/'/g, "''");
2427
2442
  return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
2428
- }, ni = (e) => `ALTER INDEX ${K(e.from)} RENAME TO ${K(e.to)};`, ri = (e) => `ALTER TABLE ${q(e.table)} RENAME INDEX ${q(e.from)} TO ${q(e.to)};`, ii = (e) => {
2443
+ }, ii = (e) => `ALTER INDEX ${G(e.from)} RENAME TO ${G(e.to)};`, ai = (e) => `ALTER TABLE ${K(e.table)} RENAME INDEX ${K(e.from)} TO ${K(e.to)};`, oi = (e) => {
2429
2444
  let t = (e) => e.replace(/'/g, "''");
2430
2445
  return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
2431
- }, ai = (e) => {
2446
+ }, si = (e) => {
2432
2447
  let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Y(e.index.name)} ON ${Y(e.table)} (${e.index.columns.map(Y).join(", ")})`;
2433
2448
  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)}');`;
2434
- }, oi = (e, t, n) => {
2449
+ }, ci = (e, t, n) => {
2435
2450
  let r = n.find((t) => t.tableName === e);
2436
2451
  if (!r) return [];
2437
2452
  let i = [];
@@ -2440,13 +2455,13 @@ BEGIN
2440
2455
  t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Y(e)} ALTER COLUMN ${Y(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
2441
2456
  }
2442
2457
  return i;
2443
- }, si = (e) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${K(e.column)});`, ci = (e, t) => `ALTER TABLE ${q(e.table)} ADD CONSTRAINT ${q(`${e.table}_${e.column}_key`)} UNIQUE (${qr(t, e.table, e.column)});`, li = (e) => {
2444
- let t = e.fields.map((e) => K(e)).join(", ");
2445
- return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${t});`;
2446
- }, ui = (e, t) => {
2447
- let n = e.fields.map((n) => qr(t, e.table, n)).join(", ");
2448
- return `ALTER TABLE ${q(e.table)} ADD CONSTRAINT ${q(e.name)} UNIQUE (${n});`;
2449
- }, di = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(e.name)};`, fi = (e) => `ALTER TABLE ${q(e.table)} DROP INDEX ${q(e.name)};`, pi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_key`)};`, mi = (e) => `ALTER TABLE ${q(e.table)} DROP INDEX ${q(`${e.table}_${e.column}_key`)};`, hi = (e, t) => {
2458
+ }, li = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, ui = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Yr(t, e.table, e.column)});`, di = (e) => {
2459
+ let t = e.fields.map((e) => G(e)).join(", ");
2460
+ return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
2461
+ }, fi = (e, t) => {
2462
+ let n = e.fields.map((n) => Yr(t, e.table, n)).join(", ");
2463
+ return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
2464
+ }, pi = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, mi = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, hi = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, gi = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, _i = (e, t) => {
2450
2465
  let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
2451
2466
  if (e.orphanPolicy) {
2452
2467
  let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
@@ -2464,11 +2479,11 @@ BEGIN
2464
2479
  setNull: "SET NULL",
2465
2480
  noAction: "NO ACTION"
2466
2481
  }[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
2467
- }, gi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_fkey`)};`, _i = (e) => `ALTER TABLE ${q(e.table)} DROP FOREIGN KEY ${q(`${e.table}_${e.column}_fkey`)};`, vi = (e, t) => {
2482
+ }, vi = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, yi = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, bi = (e, t) => {
2468
2483
  let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
2469
2484
  return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
2470
- }, yi = (e) => `ALTER TABLE ${K(e.table)} DROP CONSTRAINT IF EXISTS ${K(`${e.table}_${e.column}_check`)};`, bi = (e) => `ALTER TABLE ${q(e.table)} DROP CHECK ${q(`${e.table}_${e.column}_check`)};`, xi = (e, t, n, r) => {
2471
- let i = e.column, a = r === "mariadb", o = a ? q : r === "mssql" ? Y : K, s = a ? lr(i) : r === "mssql" ? Br(i) : r === "sqlite" ? Pr(i) : sr(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? br(e, i) : r === "mssql" ? Fr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Fr(e, "CURRENT_TIMESTAMP") : Sr(e, i), u = Cr(i, r);
2485
+ }, xi = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, Si = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, Ci = (e, t, n, r) => {
2486
+ let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Y : G, s = a ? fr(i) : r === "mssql" ? Hr(i) : r === "sqlite" ? Ir(i) : ur(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Sr(e, i) : r === "mssql" ? Lr(e, "SYSUTCDATETIME()") : r === "sqlite" ? Lr(e, "CURRENT_TIMESTAMP") : wr(e, i), u = Tr(i, r);
2472
2487
  if (u) {
2473
2488
  let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
2474
2489
  return {
@@ -2496,7 +2511,7 @@ BEGIN
2496
2511
  post: f ? [f] : []
2497
2512
  };
2498
2513
  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;
2499
- }, Si = (e) => {
2514
+ }, wi = (e) => {
2500
2515
  let t = new Map(e.map((e) => [e.tableName, e]));
2501
2516
  return (e, n) => {
2502
2517
  let r = t.get(e);
@@ -2516,13 +2531,13 @@ BEGIN
2516
2531
  ...o
2517
2532
  };
2518
2533
  };
2519
- }, X = (e, t, n, r = []) => e.unsafe(t).pipe(x.catchIf((e) => tr(e, r), () => x.void), x.tapError((e) => x.sync(() => {
2534
+ }, X = (e, t, n, r = []) => e.unsafe(t).pipe(x.catchIf((e) => ir(e, r), () => x.void), x.tapError((e) => x.sync(() => {
2520
2535
  process.stderr.write(ae(`applier: statement failed (op=${n})`, t, e, 400));
2521
2536
  })), x.mapError((e) => {
2522
2537
  let r = ae(`applier: statement failed (op=${n})`, t, e, 400).trim();
2523
2538
  return Object.assign(e, { message: r });
2524
- }), x.map(() => void 0)), Z = (e, t, n) => x.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, r, i) => e.unsafe(`SELECT ${i === void 0 ? "*" : n(i, t)} FROM ${n(r, t)} WHERE 1=0`).pipe(x.as(!0), x.catchAll(() => x.succeed(!1))), Ci = (e, t) => x.gen(function* () {
2525
- let n = L([Ie], t).tables[0];
2539
+ }), x.map(() => void 0)), Z = (e, t, n) => x.forEach(t, (t) => X(e, t, n), { discard: !0 }), Q = (e, t) => e.literal(`LIMIT ${Math.max(1, Math.floor(Number.isFinite(t) ? t : 1))}`), $ = (e, t, r, i) => e.unsafe(`SELECT ${i === void 0 ? "*" : n(i, t)} FROM ${n(r, t)} WHERE 1=0`).pipe(x.as(!0), x.catchAll(() => x.succeed(!1))), Ti = (e, t) => x.gen(function* () {
2540
+ let n = I([Ie], t).tables[0];
2526
2541
  if (!n) return yield* x.die(/* @__PURE__ */ Error("migration applier: the resume-ledger table descriptor produced no snapshot. This is a framework bug."));
2527
2542
  let r = {
2528
2543
  kind: "create-table",
@@ -2530,18 +2545,18 @@ BEGIN
2530
2545
  columns: n.columns,
2531
2546
  indexes: []
2532
2547
  }, i = yield* e.onDialectOrElse({
2533
- mysql: () => W(e).pipe(x.map((e) => jr(r, e))),
2534
- mssql: () => x.succeed(Hr(r)),
2535
- sqlite: () => x.succeed(Lr(r)),
2536
- orElse: () => x.succeed(Er(r))
2548
+ mysql: () => U(e).pipe(x.map((e) => Nr(r, e))),
2549
+ mssql: () => x.succeed(Wr(r)),
2550
+ sqlite: () => x.succeed(zr(r)),
2551
+ orElse: () => x.succeed(Or(r))
2537
2552
  });
2538
2553
  yield* x.forEach(i, (t) => X(e, t, "resume-ledger-bootstrap"), { discard: !0 });
2539
- }), wi = (e) => e`
2554
+ }), Ei = (e) => e`
2540
2555
  SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
2541
2556
  ${e("status")}, ${e("payload")}
2542
2557
  FROM ${e(O)}
2543
- `, Ti = (e, t, n, r) => x.gen(function* () {
2544
- let i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2558
+ `, Di = (e, t, n, r) => x.gen(function* () {
2559
+ let i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2545
2560
  yield* x.forEach(r, ({ index: r, planned: a }) => e`
2546
2561
  INSERT INTO ${e(O)}
2547
2562
  (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
@@ -2552,8 +2567,8 @@ BEGIN
2552
2567
  ${a.op.kind}, ${Re(a.op)}, ${"pending"},
2553
2568
  ${JSON.stringify(a)}, ${i})
2554
2569
  `, { discard: !0 });
2555
- }), Ei = (e, t, n, r, i) => x.gen(function* () {
2556
- let a = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2570
+ }), Oi = (e, t, n, r, i) => x.gen(function* () {
2571
+ let a = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2557
2572
  if (r === "applied") {
2558
2573
  yield* e`
2559
2574
  UPDATE ${e(O)}
@@ -2568,8 +2583,8 @@ BEGIN
2568
2583
  SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
2569
2584
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
2570
2585
  `;
2571
- }), Di = (e, t, n, r) => x.gen(function* () {
2572
- let i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2586
+ }), ki = (e, t, n, r) => x.gen(function* () {
2587
+ let i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2573
2588
  r.length > 0 && (yield* e`
2574
2589
  UPDATE ${e(O)}
2575
2590
  SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
@@ -2579,7 +2594,7 @@ BEGIN
2579
2594
  SET ${e("status")} = ${"pending"}
2580
2595
  WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
2581
2596
  `);
2582
- }), Oi = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(x.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(x.asVoid), ki = (e, t, r) => x.gen(function* () {
2597
+ }), Ai = (e, t) => t === void 0 ? e`DELETE FROM ${e(O)}`.pipe(x.asVoid) : e`DELETE FROM ${e(O)} WHERE ${e("runId")} = ${t}`.pipe(x.asVoid), ji = (e, t, r) => x.gen(function* () {
2583
2598
  if (Ke(r.op, r.classification, t) !== "artefact-repair") return "clean";
2584
2599
  let i = r.op, a = (e) => n(e, t);
2585
2600
  if (t === "sqlite" || t === "turso") {
@@ -2590,113 +2605,113 @@ BEGIN
2590
2605
  if (i.kind !== "alter-column-type") return "clean";
2591
2606
  let o = `${i.column}${He}`, s = `${i.column}${Ue}`, c = yield* $(e, t, i.table, i.column), l = yield* $(e, t, i.table, o), u = yield* $(e, t, i.table, s), d = (e) => x.logWarning(`migration resume: ${e}`).pipe(x.annotateLogs({ scope: "voltro:migrate" }));
2592
2607
  return !l && !u ? "clean" : c && l && !u ? (yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(o)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${i.table}.${o}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* X(e, `ALTER TABLE ${a(i.table)} RENAME COLUMN ${a(o)} TO ${a(i.column)}`, "resume-repair"), yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${i.table}.${i.column}'`), "applied") : c && !l && u ? (yield* X(e, `ALTER TABLE ${a(i.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${i.table}.${s}'`), "applied") : yield* x.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${i.table}.${i.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${o}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
2593
- }), Ai = (e, t, n, r = "fresh") => x.gen(function* () {
2594
- let i = process.hrtime.bigint(), a = Si(n.declared), o = t.op;
2608
+ }), Mi = (e, t, n, r = "fresh") => x.gen(function* () {
2609
+ let i = process.hrtime.bigint(), a = wi(n.declared), o = t.op;
2595
2610
  switch (o.kind) {
2596
2611
  case "create-table": {
2597
2612
  let t = yield* e.onDialectOrElse({
2598
- mysql: () => W(e).pipe(x.map((e) => jr(o, e))),
2599
- mssql: () => x.succeed(Hr(o)),
2600
- sqlite: () => x.succeed(Lr(o)),
2601
- orElse: () => x.succeed(Er(o))
2613
+ mysql: () => U(e).pipe(x.map((e) => Nr(o, e))),
2614
+ mssql: () => x.succeed(Wr(o)),
2615
+ sqlite: () => x.succeed(zr(o)),
2616
+ orElse: () => x.succeed(Or(o))
2602
2617
  }), n = yield* e.onDialectOrElse({
2603
- mysql: () => x.succeed([nr]),
2618
+ mysql: () => x.succeed([ar]),
2604
2619
  orElse: () => x.succeed([])
2605
2620
  });
2606
2621
  for (let r of t) yield* X(e, r, o.kind, n);
2607
2622
  break;
2608
2623
  }
2609
2624
  case "drop-table": {
2610
- let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Gr(o, n, e) : Wr(o, e);
2625
+ let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? qr(o, n, e) : Kr(o, e);
2611
2626
  yield* e.onDialectOrElse({
2612
- mysql: () => X(e, r(q), o.kind),
2613
- orElse: () => X(e, r(K), o.kind)
2627
+ mysql: () => X(e, r(K), o.kind),
2628
+ orElse: () => X(e, r(G), o.kind)
2614
2629
  });
2615
2630
  break;
2616
2631
  }
2617
2632
  case "drop-column": {
2618
2633
  let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
2619
2634
  yield* e.onDialectOrElse({
2620
- mysql: () => W(e).pipe(x.flatMap((r) => X(e, t ? mr(o, n, q) : fr(o, r), o.kind, t ? [] : [rr]))),
2621
- sqlite: () => X(e, t ? mr(o, n, K) : dr(o, K, !1), o.kind, t ? [] : [ir]),
2622
- orElse: () => X(e, t ? mr(o, n, K) : dr(o, K), o.kind)
2635
+ mysql: () => U(e).pipe(x.flatMap((r) => X(e, t ? _r(o, n, K) : hr(o, r), o.kind, t ? [] : [or]))),
2636
+ sqlite: () => X(e, t ? _r(o, n, G) : mr(o, G, !1), o.kind, t ? [] : [sr]),
2637
+ orElse: () => X(e, t ? _r(o, n, G) : mr(o, G), o.kind)
2623
2638
  });
2624
2639
  break;
2625
2640
  }
2626
2641
  case "rename-column":
2627
2642
  yield* e.onDialectOrElse({
2628
- mysql: () => X(e, pr(o, q), o.kind),
2643
+ mysql: () => X(e, gr(o, K), o.kind),
2629
2644
  mssql: () => X(e, `EXEC sp_rename N'${o.table.replace(/'/g, "''")}.${o.from.replace(/'/g, "''")}', N'${o.to.replace(/'/g, "''")}', 'COLUMN';`, o.kind),
2630
- orElse: () => X(e, pr(o, K), o.kind)
2645
+ orElse: () => X(e, gr(o, G), o.kind)
2631
2646
  });
2632
2647
  break;
2633
2648
  case "add-index":
2634
2649
  yield* e.onDialectOrElse({
2635
- mysql: () => W(e).pipe(x.flatMap((t) => X(e, Xr(o, n.declared, t), o.kind, [nr]))),
2636
- mssql: () => Z(e, [...oi(o.table, o.index.columns, n.declared), ai(o)], o.kind),
2637
- orElse: () => X(e, Yr(o, t.classification === "online-required"), o.kind)
2650
+ mysql: () => U(e).pipe(x.flatMap((t) => X(e, Qr(o, n.declared, t), o.kind, [ar]))),
2651
+ mssql: () => Z(e, [...ci(o.table, o.index.columns, n.declared), si(o)], o.kind),
2652
+ orElse: () => X(e, Zr(o, t.classification === "online-required"), o.kind)
2638
2653
  });
2639
2654
  break;
2640
2655
  case "drop-index":
2641
2656
  yield* e.onDialectOrElse({
2642
- mysql: () => X(e, Qr(o), o.kind),
2643
- mssql: () => X(e, $r(o), o.kind),
2644
- orElse: () => X(e, Zr(o), o.kind)
2657
+ mysql: () => X(e, ei(o), o.kind),
2658
+ mssql: () => X(e, ti(o), o.kind),
2659
+ orElse: () => X(e, $r(o), o.kind)
2645
2660
  });
2646
2661
  break;
2647
2662
  case "rename-table":
2648
2663
  yield* e.onDialectOrElse({
2649
- mysql: () => X(e, ei(o, q), o.kind),
2650
- mssql: () => X(e, ti(o), o.kind),
2651
- orElse: () => X(e, ei(o, K), o.kind)
2664
+ mysql: () => X(e, ni(o, K), o.kind),
2665
+ mssql: () => X(e, ri(o), o.kind),
2666
+ orElse: () => X(e, ni(o, G), o.kind)
2652
2667
  });
2653
2668
  break;
2654
2669
  case "rename-index":
2655
2670
  yield* e.onDialectOrElse({
2656
- mysql: () => X(e, ri(o), o.kind),
2657
- mssql: () => X(e, ii(o), o.kind),
2658
- orElse: () => X(e, ni(o), o.kind)
2671
+ mysql: () => X(e, ai(o), o.kind),
2672
+ mssql: () => X(e, oi(o), o.kind),
2673
+ orElse: () => X(e, ii(o), o.kind)
2659
2674
  });
2660
2675
  break;
2661
2676
  case "add-unique":
2662
2677
  yield* e.onDialectOrElse({
2663
- mysql: () => X(e, ci(o, n.declared), o.kind),
2678
+ mysql: () => X(e, ui(o, n.declared), o.kind),
2664
2679
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2665
- mssql: () => Z(e, [...oi(o.table, [o.column], n.declared), si(o)], o.kind),
2666
- orElse: () => X(e, si(o), o.kind)
2680
+ mssql: () => Z(e, [...ci(o.table, [o.column], n.declared), li(o)], o.kind),
2681
+ orElse: () => X(e, li(o), o.kind)
2667
2682
  });
2668
2683
  break;
2669
2684
  case "drop-unique":
2670
2685
  yield* e.onDialectOrElse({
2671
- mysql: () => X(e, mi(o), o.kind),
2686
+ mysql: () => X(e, gi(o), o.kind),
2672
2687
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2673
- orElse: () => X(e, pi(o), o.kind)
2688
+ orElse: () => X(e, hi(o), o.kind)
2674
2689
  });
2675
2690
  break;
2676
2691
  case "add-unique-composite":
2677
2692
  yield* e.onDialectOrElse({
2678
- mysql: () => X(e, ui(o, n.declared), o.kind),
2693
+ mysql: () => X(e, fi(o, n.declared), o.kind),
2679
2694
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2680
- mssql: () => Z(e, [...oi(o.table, o.fields, n.declared), li(o)], o.kind),
2681
- orElse: () => X(e, li(o), o.kind)
2695
+ mssql: () => Z(e, [...ci(o.table, o.fields, n.declared), di(o)], o.kind),
2696
+ orElse: () => X(e, di(o), o.kind)
2682
2697
  });
2683
2698
  break;
2684
2699
  case "drop-unique-composite":
2685
2700
  yield* e.onDialectOrElse({
2686
- mysql: () => X(e, fi(o), o.kind),
2701
+ mysql: () => X(e, mi(o), o.kind),
2687
2702
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2688
- orElse: () => X(e, di(o), o.kind)
2703
+ orElse: () => X(e, pi(o), o.kind)
2689
2704
  });
2690
2705
  break;
2691
2706
  case "add-foreign-key":
2692
2707
  yield* e.onDialectOrElse({
2693
- mysql: () => Z(e, hi(o, q), o.kind),
2708
+ mysql: () => Z(e, _i(o, K), o.kind),
2694
2709
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2695
- orElse: () => Z(e, hi(o, K), o.kind)
2710
+ orElse: () => Z(e, _i(o, G), o.kind)
2696
2711
  });
2697
2712
  break;
2698
2713
  case "add-column": {
2699
- let n = xi(o, t, a, yield* e.onDialectOrElse({
2714
+ let n = Ci(o, t, a, yield* e.onDialectOrElse({
2700
2715
  mysql: () => x.succeed("mariadb"),
2701
2716
  mssql: () => x.succeed("mssql"),
2702
2717
  sqlite: () => x.succeed("sqlite"),
@@ -2742,41 +2757,41 @@ BEGIN
2742
2757
  case "alter-column-nullability":
2743
2758
  yield* e.onDialectOrElse({
2744
2759
  mysql: () => {
2745
- let t = _r(n.declared, o.table, o.column);
2746
- return t ? X(e, `ALTER TABLE ${q(o.table)} MODIFY COLUMN ${yr(t, o.column, o.toNullable)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2760
+ let t = q(n.declared, o.table, o.column);
2761
+ return t ? X(e, `ALTER TABLE ${K(o.table)} MODIFY COLUMN ${xr(t, o.column, o.toNullable)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2747
2762
  },
2748
2763
  mssql: () => {
2749
- let t = _r(n.declared, o.table, o.column);
2750
- return t ? X(e, Rr(t, o.column, o.table, o.toNullable), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2764
+ let t = q(n.declared, o.table, o.column);
2765
+ return t ? X(e, Br(t, o.column, o.table, o.toNullable), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${o.table}.${o.column}'.`));
2751
2766
  },
2752
2767
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2753
- orElse: () => X(e, `ALTER TABLE ${K(o.table)} ALTER COLUMN ${K(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2768
+ orElse: () => X(e, `ALTER TABLE ${G(o.table)} ALTER COLUMN ${G(o.column)} ${o.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, o.kind)
2754
2769
  });
2755
2770
  break;
2756
2771
  case "alter-column-default": {
2757
- let t = vr(n.declared, o.table, o.column);
2772
+ let t = br(n.declared, o.table, o.column);
2758
2773
  yield* e.onDialectOrElse({
2759
- mysql: () => X(e, hr(o, q, (e) => br(e, t)), o.kind),
2760
- mssql: () => X(e, zr(o), o.kind),
2774
+ mysql: () => X(e, vr(o, K, (e) => Sr(e, t)), o.kind),
2775
+ mssql: () => X(e, Vr(o), o.kind),
2761
2776
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2762
- orElse: () => X(e, hr(o, K, (e) => Sr(e, t)), o.kind)
2777
+ orElse: () => X(e, vr(o, G, (e) => wr(e, t)), o.kind)
2763
2778
  });
2764
2779
  break;
2765
2780
  }
2766
2781
  case "alter-column-type": {
2767
- let r = sr(vr(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2782
+ let r = ur(br(n.declared, o.table, o.column) ?? { type: o.to }), i = o.using ? ` USING ${o.using}` : "";
2768
2783
  if (t.classification !== "online-required") {
2769
2784
  yield* e.onDialectOrElse({
2770
2785
  mysql: () => {
2771
- let t = _r(n.declared, o.table, o.column);
2772
- return t ? X(e, `ALTER TABLE ${q(o.table)} MODIFY COLUMN ${yr(t, o.column)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2786
+ let t = q(n.declared, o.table, o.column);
2787
+ return t ? X(e, `ALTER TABLE ${K(o.table)} MODIFY COLUMN ${xr(t, o.column)};`, o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${o.table}.${o.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
2773
2788
  },
2774
2789
  mssql: () => {
2775
- let t = _r(n.declared, o.table, o.column);
2776
- return t ? X(e, Rr(t, o.column, o.table), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2790
+ let t = q(n.declared, o.table, o.column);
2791
+ return t ? X(e, Br(t, o.column, o.table), o.kind) : x.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${o.table}.${o.column}'.`));
2777
2792
  },
2778
2793
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2779
- orElse: () => X(e, `ALTER TABLE ${K(o.table)} ALTER COLUMN ${K(o.column)} TYPE ${r}${i};`, o.kind)
2794
+ orElse: () => X(e, `ALTER TABLE ${G(o.table)} ALTER COLUMN ${G(o.column)} TYPE ${r}${i};`, o.kind)
2780
2795
  });
2781
2796
  break;
2782
2797
  }
@@ -2785,34 +2800,34 @@ BEGIN
2785
2800
  orElse: () => x.void
2786
2801
  });
2787
2802
  let a = `${o.column}__shadow`, s = `${o.column}__old`;
2788
- yield* e.unsafe(`ALTER TABLE ${K(o.table)} ADD COLUMN ${K(a)} ${r}`);
2789
- let c = o.using ?? K(o.column), l;
2803
+ yield* e.unsafe(`ALTER TABLE ${G(o.table)} ADD COLUMN ${G(a)} ${r}`);
2804
+ let c = o.using ?? G(o.column), l;
2790
2805
  for (;;) {
2791
2806
  let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${Q(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(o.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${Q(e, 5e3)}`;
2792
2807
  if (t.length === 0) break;
2793
- yield* e.unsafe(`UPDATE ${K(o.table)} SET ${K(a)} = ${c} WHERE ${K(o.column)} IS NOT NULL AND ${K(a)} IS NULL AND ${K("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2808
+ yield* e.unsafe(`UPDATE ${G(o.table)} SET ${G(a)} = ${c} WHERE ${G(o.column)} IS NOT NULL AND ${G(a)} IS NULL AND ${G("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
2794
2809
  }
2795
- yield* x.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${K(o.table)} RENAME COLUMN ${K(o.column)} TO ${K(s)}`), yield* e.unsafe(`ALTER TABLE ${K(o.table)} RENAME COLUMN ${K(a)} TO ${K(o.column)}`), yield* e.unsafe(`ALTER TABLE ${K(o.table)} DROP COLUMN ${K(s)}`);
2810
+ yield* x.logInfo(`alter-column-type shadow ${o.table}.${o.column}: shadow populated`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${G(o.table)} RENAME COLUMN ${G(o.column)} TO ${G(s)}`), yield* e.unsafe(`ALTER TABLE ${G(o.table)} RENAME COLUMN ${G(a)} TO ${G(o.column)}`), yield* e.unsafe(`ALTER TABLE ${G(o.table)} DROP COLUMN ${G(s)}`);
2796
2811
  break;
2797
2812
  }
2798
2813
  case "drop-foreign-key":
2799
2814
  yield* e.onDialectOrElse({
2800
- mysql: () => X(e, _i(o), o.kind),
2815
+ mysql: () => X(e, yi(o), o.kind),
2801
2816
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2802
- orElse: () => X(e, gi(o), o.kind)
2817
+ orElse: () => X(e, vi(o), o.kind)
2803
2818
  });
2804
2819
  break;
2805
2820
  case "add-check":
2806
2821
  yield* e.onDialectOrElse({
2807
- mysql: () => X(e, vi(o, q), o.kind),
2822
+ mysql: () => X(e, bi(o, K), o.kind),
2808
2823
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2809
- orElse: () => X(e, vi(o, K), o.kind)
2824
+ orElse: () => X(e, bi(o, G), o.kind)
2810
2825
  });
2811
2826
  break;
2812
2827
  case "drop-check": yield* e.onDialectOrElse({
2813
- mysql: () => X(e, bi(o), o.kind),
2828
+ mysql: () => X(e, Si(o), o.kind),
2814
2829
  sqlite: () => Z(e, J(o.table, n.declared), o.kind),
2815
- orElse: () => X(e, yi(o), o.kind)
2830
+ orElse: () => X(e, xi(o), o.kind)
2816
2831
  });
2817
2832
  }
2818
2833
  return {
@@ -2820,7 +2835,7 @@ BEGIN
2820
2835
  status: "applied",
2821
2836
  durationMs: Number((process.hrtime.bigint() - i) / 1000000n)
2822
2837
  };
2823
- }), ji = (e, t, n, r) => x.gen(function* () {
2838
+ }), Ni = (e, t, n, r) => x.gen(function* () {
2824
2839
  let i = [...new Set(r.map((e) => e.runId))];
2825
2840
  if (i.length > 1) return yield* x.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${O}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
2826
2841
  let a = i[0], o = [...r].map((e) => ({
@@ -2834,7 +2849,7 @@ BEGIN
2834
2849
  runId: a,
2835
2850
  why: "no operation had started — no DDL ran"
2836
2851
  };
2837
- let l = s ? yield* ki(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2852
+ let l = s ? yield* ji(e, t, s.planned) : "clean", u = r[0].planFingerprint;
2838
2853
  if (u !== n.toFingerprint) return {
2839
2854
  kind: "discard",
2840
2855
  runId: a,
@@ -2845,7 +2860,7 @@ BEGIN
2845
2860
  kind: "discard",
2846
2861
  runId: a,
2847
2862
  why: "every recorded operation had already taken effect"
2848
- } : (yield* Di(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* x.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), {
2863
+ } : (yield* ki(e, a, f.map((e) => e.index), p.map((e) => e.index)), yield* x.logWarning(`migration resume: continuing run ${a} — replaying ${f.length} operation(s), ${o.length - f.length} already applied`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), {
2849
2864
  kind: "resume",
2850
2865
  runId: a,
2851
2866
  ops: f.map((e) => ({
@@ -2853,7 +2868,7 @@ BEGIN
2853
2868
  planned: e.planned
2854
2869
  }))
2855
2870
  });
2856
- }), Mi = (e, t, n) => x.gen(function* () {
2871
+ }), Pi = (e, t, n) => x.gen(function* () {
2857
2872
  let r = t.operations.filter((e) => e.blocked);
2858
2873
  if (r.length > 0) return yield* x.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
2859
2874
  yield* E(e, { schema: n.lockSchema });
@@ -2862,20 +2877,20 @@ BEGIN
2862
2877
  planned: e
2863
2878
  })), p = "fresh";
2864
2879
  try {
2865
- yield* Ci(e, o);
2866
- let r = yield* wi(e);
2880
+ yield* Ti(e, o);
2881
+ let r = yield* Ei(e);
2867
2882
  if (r.length > 0) {
2868
- let n = yield* ji(e, o, t, r);
2869
- n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* x.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* Oi(e, n.runId));
2883
+ let n = yield* Ni(e, o, t, r);
2884
+ n.kind === "resume" ? (d = n.runId, f = n.ops, p = "resume") : (yield* x.logWarning(`migration resume: discarding the ledger of run ${n.runId} — ${n.why}`).pipe(x.annotateLogs({ scope: "voltro:migrate" })), yield* Ai(e, n.runId));
2870
2885
  }
2871
- p === "fresh" && f.length > 0 && (yield* Ti(e, d, t.toFingerprint, f)), c.length > 0 && (yield* e.withTransaction(x.gen(function* () {
2886
+ p === "fresh" && f.length > 0 && (yield* Di(e, d, t.toFingerprint, f)), c.length > 0 && (yield* e.withTransaction(x.gen(function* () {
2872
2887
  let e = yield* C.SqlClient;
2873
- for (let t of c) a.push(yield* Ai(e, t, n));
2888
+ for (let t of c) a.push(yield* Mi(e, t, n));
2874
2889
  })));
2875
2890
  for (let { index: t, planned: r } of f) {
2876
- yield* Ei(e, d, t, "started");
2877
- let i = yield* Ai(e, r, n, p);
2878
- a.push(i), yield* Ei(e, d, t, "applied", i.durationMs);
2891
+ yield* Oi(e, d, t, "started");
2892
+ let i = yield* Mi(e, r, n, p);
2893
+ a.push(i), yield* Oi(e, d, t, "applied", i.durationMs);
2879
2894
  }
2880
2895
  } finally {
2881
2896
  yield* D(e, { schema: n.lockSchema }).pipe(x.orDie);
@@ -2885,7 +2900,7 @@ BEGIN
2885
2900
  let e = m.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");
2886
2901
  return yield* x.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 ${m.operations.length}:\n${e}${m.operations.length > 10 ? `\n … and ${m.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.`));
2887
2902
  }
2888
- let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* G(e, v), b = [...c, ...f.map((e) => e.planned)];
2903
+ let h = a.filter((e) => e.status === "applied").length, g = Date.now() - i, _ = d, v = (/* @__PURE__ */ new Date()).toISOString(), y = yield* W(e, v), b = [...c, ...f.map((e) => e.planned)];
2889
2904
  yield* e`
2890
2905
  INSERT INTO ${e("_voltro_migration_plans")}
2891
2906
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -2895,7 +2910,7 @@ BEGIN
2895
2910
  (${_}, ${t.toFingerprint}, ${m.fromFingerprint}, ${JSON.stringify(b)},
2896
2911
  ${n.appliedBy}, ${n.environment}, ${n.source},
2897
2912
  ${g}, ${y}, ${n.notes ?? null})
2898
- `, yield* Oi(e, d);
2913
+ `, yield* Ai(e, d);
2899
2914
  let S = [...new Set(b.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
2900
2915
  return yield* x.promise(() => l({ changedTables: S }).catch(() => {})), {
2901
2916
  id: _,
@@ -2909,14 +2924,14 @@ BEGIN
2909
2924
  source: n.source,
2910
2925
  ...n.notes ? { notes: n.notes } : {}
2911
2926
  };
2912
- }), Ni = (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"), Pi = (e) => e`
2927
+ }), Fi = (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"), Ii = (e) => e`
2913
2928
  SELECT fingerprint
2914
2929
  FROM _voltro_migration_plans
2915
2930
  ORDER BY ${e("appliedAt")} DESC
2916
2931
  LIMIT 1
2917
- `.pipe(x.map((e) => e.length > 0 ? e[0].fingerprint : void 0), x.catchAll(() => x.succeed(void 0))), Fi = (e, t, n) => x.gen(function* () {
2918
- if ((yield* Pi(e)) === t.toFingerprint) return "already-current";
2919
- let r = `plan_${Date.now().toString(36)}`, i = yield* G(e, (/* @__PURE__ */ new Date()).toISOString());
2932
+ `.pipe(x.map((e) => e.length > 0 ? e[0].fingerprint : void 0), x.catchAll(() => x.succeed(void 0))), Li = (e, t, n) => x.gen(function* () {
2933
+ if ((yield* Ii(e)) === t.toFingerprint) return "already-current";
2934
+ let r = `plan_${Date.now().toString(36)}`, i = yield* W(e, (/* @__PURE__ */ new Date()).toISOString());
2920
2935
  return yield* e`
2921
2936
  INSERT INTO ${e("_voltro_migration_plans")}
2922
2937
  (${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
@@ -2927,8 +2942,8 @@ BEGIN
2927
2942
  ${n.appliedBy}, ${n.environment}, ${n.source},
2928
2943
  ${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
2929
2944
  `, "recorded";
2930
- }).pipe(x.catchAll(() => x.succeed("already-current"))), Ii = (e, t) => x.gen(function* () {
2931
- let n = F(L(t, Ne(e))), r = yield* Pi(e);
2945
+ }).pipe(x.catchAll(() => x.succeed("already-current"))), Ri = (e, t) => x.gen(function* () {
2946
+ let n = Wt(I(t, Ne(e))), r = yield* Ii(e);
2932
2947
  return r === n ? {
2933
2948
  kind: "up-to-date",
2934
2949
  fingerprint: n
@@ -2937,23 +2952,23 @@ BEGIN
2937
2952
  expected: n,
2938
2953
  ...r === void 0 ? {} : { actual: r }
2939
2954
  };
2940
- }), Li = [
2955
+ }), zi = [
2941
2956
  "pgeagertest_",
2942
2957
  "mig_e2e_",
2943
2958
  "mig_test_",
2944
2959
  "mysqleagertest_",
2945
2960
  "mssqleagertest_",
2946
2961
  "sqliteeagertest_"
2947
- ], Ri = (e) => Li.some((t) => e.startsWith(t)), zi = (e, t) => x.gen(function* () {
2962
+ ], Bi = (e) => zi.some((t) => e.startsWith(t)), Vi = (e, t) => x.gen(function* () {
2948
2963
  if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
2949
- let n = t.filter((e) => Ri(e.name)).map((e) => e.name);
2964
+ let n = t.filter((e) => Bi(e.name)).map((e) => e.name);
2950
2965
  if (n.length === 0) return [];
2951
2966
  for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(x.catchAll(() => x.void));
2952
2967
  return n;
2953
- }), Bi = () => {
2968
+ }), Hi = () => {
2954
2969
  let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
2955
2970
  return e.length > 0 ? { ignoreTables: e } : {};
2956
- }, Vi = (e) => {
2971
+ }, Ui = (e) => {
2957
2972
  if (e === void 0) return;
2958
2973
  let t = e.trim();
2959
2974
  if (t === "") return;
@@ -2963,48 +2978,48 @@ BEGIN
2963
2978
  kind: "tables",
2964
2979
  tables: new Set(n)
2965
2980
  } : void 0;
2966
- }, Hi = (e) => typeof e.table == "string" ? e.table : void 0, Ui = (e, t = { kind: "all" }) => ({
2981
+ }, Wi = (e) => typeof e.table == "string" ? e.table : void 0, Gi = (e, t = { kind: "all" }) => ({
2967
2982
  ...e,
2968
2983
  operations: e.operations.map((e) => {
2969
2984
  if (!e.blocked || e.classification !== "lossy") return e;
2970
2985
  if (t?.kind === "tables") {
2971
- let n = Hi(e.op);
2986
+ let n = Wi(e.op);
2972
2987
  if (n === void 0 || !t.tables.has(n)) return e;
2973
2988
  }
2974
2989
  let { blocked: n, ...r } = e;
2975
2990
  return r;
2976
2991
  })
2977
- }), Wi = (e, t, n) => t === "postgres" ? Jt(e, n).pipe(x.flatMap((e) => {
2978
- let t = Yt(e);
2992
+ }), Ki = (e, t, n) => t === "postgres" ? Yt(e, n).pipe(x.flatMap((e) => {
2993
+ let t = Xt(e);
2979
2994
  return t === void 0 ? x.void : x.logWarning(`auto-migrate: ${t}`).pipe(x.annotateLogs({ scope: "voltro:migrate" }));
2980
- }), x.catchAll(() => x.void)) : x.void, Gi = (e, t, n) => x.gen(function* () {
2995
+ }), x.catchAll(() => x.void)) : x.void, qi = (e, t, n) => x.gen(function* () {
2981
2996
  let r = Ne(e), i = t;
2982
2997
  if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
2983
- let t = F(L(i, r));
2984
- if ((yield* Pi(e)) === t) return yield* Wi(e, r, i), {
2998
+ let t = Wt(I(i, r));
2999
+ if ((yield* Ii(e)) === t) return yield* Ki(e, r, i), {
2985
3000
  kind: "up-to-date",
2986
3001
  fingerprint: t
2987
3002
  };
2988
3003
  }
2989
- let a = yield* Yn(e), o = yield* zi(e, a.tables);
3004
+ let a = yield* Qn(e), o = yield* Vi(e, a.tables);
2990
3005
  o.length > 0 && (yield* x.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(x.annotateLogs({
2991
3006
  scope: "voltro:migrate",
2992
3007
  count: o.length
2993
- })), a = yield* Yn(e));
2994
- let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !m(e.name) || s.has(e.name)), l = An({
3008
+ })), a = yield* Qn(e));
3009
+ let s = new Set(t.map((e) => e.tableName)), c = (e) => e.filter((e) => !m(e.name) || s.has(e.name)), l = Mn({
2995
3010
  declared: i,
2996
3011
  live: { tables: c(a.tables) },
2997
3012
  dialect: r,
2998
- ...Bi()
3013
+ ...Hi()
2999
3014
  });
3000
3015
  if (l.summary.blocked > 0) {
3001
- let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Vi(process.env.VOLTRO_DESTRUCTIVE_OK);
3002
- if (t === void 0 || !e || (l = Ui(l, t), l.operations.some((e) => e.blocked))) return {
3016
+ let e = l.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Ui(process.env.VOLTRO_DESTRUCTIVE_OK);
3017
+ if (t === void 0 || !e || (l = Gi(l, t), l.operations.some((e) => e.blocked))) return {
3003
3018
  kind: "refused-blocked",
3004
3019
  plan: l
3005
3020
  };
3006
3021
  }
3007
- return l.operations.length === 0 ? (yield* Fi(e, l, {
3022
+ return l.operations.length === 0 ? (yield* Li(e, l, {
3008
3023
  appliedBy: n.appliedBy,
3009
3024
  environment: n.environment === "prod" ? "dev" : n.environment,
3010
3025
  source: "auto-diff"
@@ -3013,37 +3028,37 @@ BEGIN
3013
3028
  fingerprint: l.toFingerprint
3014
3029
  }) : {
3015
3030
  kind: "applied",
3016
- applied: yield* Mi(e, l, {
3031
+ applied: yield* Pi(e, l, {
3017
3032
  declared: t,
3018
3033
  appliedBy: n.appliedBy,
3019
3034
  environment: n.environment === "prod" ? "dev" : n.environment,
3020
3035
  source: "auto-diff",
3021
3036
  replan: (e) => x.gen(function* () {
3022
- let t = yield* Yn(e);
3023
- return An({
3037
+ let t = yield* Qn(e);
3038
+ return Mn({
3024
3039
  declared: i,
3025
3040
  live: { tables: c(t.tables) },
3026
3041
  dialect: r,
3027
- ...Bi()
3042
+ ...Hi()
3028
3043
  });
3029
3044
  })
3030
3045
  }),
3031
3046
  plan: l
3032
3047
  };
3033
- }), Ki = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? x.succeed({
3048
+ }), Ji = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? x.succeed({
3034
3049
  kind: "skipped",
3035
3050
  reason: "VOLTRO_AUTO_MIGRATE=0"
3036
- }) : n.environment === "prod" ? Ii(e, t) : Gi(e, t, n), qi = (e, t) => {
3051
+ }) : n.environment === "prod" ? Ri(e, t) : qi(e, t, n), Yi = (e, t) => {
3037
3052
  switch (e.kind) {
3038
3053
  case "skipped": return `auto-migrate: skipped (${e.reason})`;
3039
- case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${I(e.fingerprint)})`;
3054
+ case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${F(e.fingerprint)})`;
3040
3055
  case "applied": {
3041
3056
  let t = e.plan.summary;
3042
- 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=${I(e.applied.fingerprint)}`;
3057
+ 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=${F(e.applied.fingerprint)}`;
3043
3058
  }
3044
- case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${I(e.expected)}` + (e.actual ? ` live=${I(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3059
+ case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${F(e.expected)}` + (e.actual ? ` live=${F(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
3045
3060
  case "refused-blocked": {
3046
- 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` + Ni(e.plan), c = [""];
3061
+ 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` + Fi(e.plan), c = [""];
3047
3062
  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) {
3048
3063
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
3049
3064
  for (let r of e.plan.operations) {
@@ -3060,7 +3075,7 @@ BEGIN
3060
3075
  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");
3061
3076
  }
3062
3077
  }
3063
- }, Ji = /* @__PURE__ */ new Set([
3078
+ }, Xi = /* @__PURE__ */ new Set([
3064
3079
  "node_modules",
3065
3080
  "dist",
3066
3081
  "build",
@@ -3069,11 +3084,11 @@ BEGIN
3069
3084
  ".next",
3070
3085
  ".git",
3071
3086
  ".framework"
3072
- ]), Yi = async (e) => {
3087
+ ]), Zi = async (e) => {
3073
3088
  let t = [], n = async (e) => {
3074
3089
  let r = await ne.readdir(e, { withFileTypes: !0 }).catch(() => []);
3075
3090
  for (let i of r) {
3076
- if (Ji.has(i.name)) continue;
3091
+ if (Xi.has(i.name)) continue;
3077
3092
  let r = re(e, i.name);
3078
3093
  i.isDirectory() ? await n(r) : i.isFile() && d.test(i.name) && t.push(r);
3079
3094
  }
@@ -3082,7 +3097,7 @@ BEGIN
3082
3097
  let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
3083
3098
  return n.localeCompare(r);
3084
3099
  });
3085
- }, Xi = async (e) => {
3100
+ }, Qi = async (e) => {
3086
3101
  let t = [];
3087
3102
  for (let n of e) {
3088
3103
  let e = (await import(ie(n).href)).default;
@@ -3096,11 +3111,11 @@ BEGIN
3096
3111
  });
3097
3112
  }
3098
3113
  return t;
3099
- }, Zi = (e) => e`
3114
+ }, $i = (e) => e`
3100
3115
  SELECT ${e("id")}
3101
3116
  FROM ${e("_voltro_migration_plans")}
3102
3117
  WHERE ${e("source")} = 'file'
3103
- `.pipe(x.map((e) => e.map((e) => e.id)), x.catchAll(() => x.succeed([]))), Qi = class extends Error {
3118
+ `.pipe(x.map((e) => e.map((e) => e.id)), x.catchAll(() => x.succeed([]))), ea = class extends Error {
3104
3119
  migrationId;
3105
3120
  file;
3106
3121
  cause;
@@ -3108,7 +3123,7 @@ BEGIN
3108
3123
  constructor(e, t, n) {
3109
3124
  super(`migration ${e}: up() SUCCEEDED but the ledger row could not be written.\n The change IS in the database. It is NOT recorded, so the next run would apply it AGAIN.\n Do not re-run ${t} until this is resolved.\n Cause: ${n instanceof Error ? n.message : String(n)}`), this.migrationId = e, this.file = t, this.cause = n, this.name = "FileMigrationLedgerError";
3110
3125
  }
3111
- }, $i = (e, t, n, r) => x.gen(function* () {
3126
+ }, ta = (e, t, n, r) => x.gen(function* () {
3112
3127
  let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
3113
3128
  sql: e,
3114
3129
  log: {
@@ -3129,7 +3144,7 @@ BEGIN
3129
3144
  });
3130
3145
  let c = Date.now() - i;
3131
3146
  !x.isEffect(s) && c < 2 && (yield* x.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(x.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
3132
- let l = yield* G(e, a);
3147
+ let l = yield* W(e, a);
3133
3148
  return yield* e`
3134
3149
  INSERT INTO ${e("_voltro_migration_plans")}
3135
3150
  (${e("id")}, ${e("fingerprint")}, ${e("operations")},
@@ -3142,10 +3157,10 @@ BEGIN
3142
3157
  }])},
3143
3158
  ${r}, ${n}, ${"file"},
3144
3159
  ${c}, ${l}, ${t.migration.description})
3145
- `.pipe(x.mapError((e) => new Qi(t.migration.id, t.file, e))), { durationMs: c };
3146
- }), ea = (e, t) => x.gen(function* () {
3160
+ `.pipe(x.mapError((e) => new ea(t.migration.id, t.file, e))), { durationMs: c };
3161
+ }), na = (e, t) => x.gen(function* () {
3147
3162
  let n = yield* x.tryPromise({
3148
- try: () => Yi(re(t, "migrations")),
3163
+ try: () => Zi(re(t, "migrations")),
3149
3164
  catch: (e) => e
3150
3165
  });
3151
3166
  if (n.length === 0) return {
@@ -3153,20 +3168,20 @@ BEGIN
3153
3168
  skipped: []
3154
3169
  };
3155
3170
  let r = yield* x.tryPromise({
3156
- try: () => Xi(n),
3171
+ try: () => Qi(n),
3157
3172
  catch: (e) => e
3158
3173
  });
3159
3174
  if (r.length === 0) return {
3160
3175
  pending: [],
3161
3176
  skipped: []
3162
3177
  };
3163
- let i = new Set(yield* Zi(e));
3178
+ let i = new Set(yield* $i(e));
3164
3179
  return {
3165
3180
  pending: r.filter((e) => !i.has(e.migration.id)),
3166
3181
  skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
3167
3182
  };
3168
- }), ta = (e, t) => ea(e, t).pipe(x.map((e) => e.pending.map((e) => e.migration.id))), na = (e, t) => x.gen(function* () {
3169
- let { pending: n, skipped: r } = yield* ea(e, t.projectRoot);
3183
+ }), ra = (e, t) => na(e, t).pipe(x.map((e) => e.pending.map((e) => e.migration.id))), ia = (e, t) => x.gen(function* () {
3184
+ let { pending: n, skipped: r } = yield* na(e, t.projectRoot);
3170
3185
  if (n.length === 0) return {
3171
3186
  applied: [],
3172
3187
  skipped: r
@@ -3180,7 +3195,7 @@ BEGIN
3180
3195
  id: r.migration.id,
3181
3196
  file: r.file
3182
3197
  }));
3183
- let { durationMs: n } = yield* $i(e, r, t.env, t.appliedBy);
3198
+ let { durationMs: n } = yield* ta(e, r, t.env, t.appliedBy);
3184
3199
  i.push({
3185
3200
  id: r.migration.id,
3186
3201
  durationMs: n
@@ -3197,18 +3212,18 @@ BEGIN
3197
3212
  applied: i,
3198
3213
  skipped: r
3199
3214
  };
3200
- }), ra = (e, t) => e`
3215
+ }), aa = (e, t) => e`
3201
3216
  SELECT ${e("id")}
3202
3217
  FROM ${e("_voltro_migration_plans")}
3203
3218
  WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
3204
3219
  LIMIT 1
3205
- `, ia = (e, t) => x.gen(function* () {
3206
- if (!(yield* ra(e, t.id))[0]) return yield* x.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3220
+ `, oa = (e, t) => x.gen(function* () {
3221
+ if (!(yield* aa(e, t.id))[0]) return yield* x.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
3207
3222
  let n = yield* x.tryPromise({
3208
- try: () => Yi(re(t.projectRoot, "migrations")),
3223
+ try: () => Zi(re(t.projectRoot, "migrations")),
3209
3224
  catch: (e) => e
3210
3225
  }), r = (yield* x.tryPromise({
3211
- try: () => Xi(n),
3226
+ try: () => Qi(n),
3212
3227
  catch: (e) => e
3213
3228
  })).find((e) => e.migration.id === t.id);
3214
3229
  if (!r) return yield* x.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
@@ -3241,7 +3256,7 @@ BEGIN
3241
3256
  } finally {
3242
3257
  yield* D(e, { schema: t.lockSchema }).pipe(x.orDie);
3243
3258
  }
3244
- }), aa = (e) => x.gen(function* () {
3259
+ }), sa = (e) => x.gen(function* () {
3245
3260
  let t = yield* C.SqlClient, n = yield* t`
3246
3261
  SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
3247
3262
  WHERE source = 'auto-diff'
@@ -3286,7 +3301,7 @@ BEGIN
3286
3301
  snapshotFingerprint: e.fingerprint,
3287
3302
  snapshotId: i
3288
3303
  };
3289
- }), oa = { safe: !0 }, sa = (e) => {
3304
+ }), ca = { safe: !0 }, la = (e) => {
3290
3305
  switch (e.kind) {
3291
3306
  case "drop-column": return {
3292
3307
  safe: !1,
@@ -3313,7 +3328,7 @@ BEGIN
3313
3328
  reason: `old instances read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
3314
3329
  remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
3315
3330
  };
3316
- case "alter-column-nullability": return e.toNullable ? oa : {
3331
+ case "alter-column-nullability": return e.toNullable ? ca : {
3317
3332
  safe: !1,
3318
3333
  reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
3319
3334
  remedy: `make code always write "${e.column}" and deploy that first; add NOT NULL in a LATER deploy (with a default to cover the gap)`
@@ -3343,12 +3358,12 @@ BEGIN
3343
3358
  case "drop-unique":
3344
3359
  case "drop-unique-composite":
3345
3360
  case "drop-foreign-key":
3346
- case "drop-check": return oa;
3361
+ case "drop-check": return ca;
3347
3362
  }
3348
- }, ca = (e) => {
3363
+ }, ua = (e) => {
3349
3364
  let t = [];
3350
3365
  for (let n of e) {
3351
- let e = sa(n.op);
3366
+ let e = la(n.op);
3352
3367
  e.safe || t.push({
3353
3368
  op: n,
3354
3369
  reason: e.reason,
@@ -3356,7 +3371,7 @@ BEGIN
3356
3371
  });
3357
3372
  }
3358
3373
  return t;
3359
- }, la = (e) => {
3374
+ }, da = (e) => {
3360
3375
  if (!e.enabled || e.unsafeCount === 0) return {
3361
3376
  refuse: !1,
3362
3377
  warnForced: !1,
@@ -3372,18 +3387,18 @@ BEGIN
3372
3387
  warnForced: !1,
3373
3388
  message: `${t}. Old instances would break against the new schema mid-rollout. Split into expand → deploy → contract (see the ⚠ list above), deploy with no overlap (maintenance window / scale-to-zero), or pass --force to override.`
3374
3389
  };
3375
- }, ua = (e) => {
3390
+ }, fa = (e) => {
3376
3391
  let t = e.table;
3377
3392
  if (typeof t == "string") return t;
3378
3393
  let n = e.from;
3379
3394
  return typeof n == "string" ? n : void 0;
3380
- }, da = (e) => ({
3395
+ }, pa = (e) => ({
3381
3396
  kind: e.op.kind,
3382
- table: ua(e.op),
3397
+ table: fa(e.op),
3383
3398
  classification: e.classification,
3384
3399
  reason: e.reason,
3385
3400
  blockedFix: e.blocked?.fix
3386
- }), fa = (e) => e.operations.map(da), pa = async (e) => {
3401
+ }), ma = (e) => e.operations.map(pa), ha = async (e) => {
3387
3402
  let t = e.log ?? (() => {}), n = {
3388
3403
  branchId: e.branchId,
3389
3404
  mechanism: e.mechanism,
@@ -3402,10 +3417,10 @@ BEGIN
3402
3417
  applied: !1,
3403
3418
  converged: !1,
3404
3419
  residual: r,
3405
- infidelity: fa(o)
3420
+ infidelity: ma(o)
3406
3421
  };
3407
3422
  else {
3408
- let i = await e.plan(), o = fa(i), s = o.filter((e) => e.classification === "lossy"), c = Ui(i), l = c.operations.filter((e) => e.blocked !== void 0).map(da);
3423
+ let i = await e.plan(), o = ma(i), s = o.filter((e) => e.classification === "lossy"), c = Gi(i), l = c.operations.filter((e) => e.blocked !== void 0).map(pa);
3409
3424
  if (l.length > 0) a = {
3410
3425
  ...n,
3411
3426
  outcome: "blocked",
@@ -3430,7 +3445,7 @@ BEGIN
3430
3445
  };
3431
3446
  else {
3432
3447
  await e.apply(c), t(`branch ${e.branchId}: applied ${o.length} operation(s)`);
3433
- let i = fa(await e.replan());
3448
+ let i = ma(await e.replan());
3434
3449
  a = {
3435
3450
  ...n,
3436
3451
  outcome: i.length > 0 ? "diverged" : s.length > 0 ? "lossy" : "clean",
@@ -3468,7 +3483,7 @@ BEGIN
3468
3483
  ...a,
3469
3484
  tornDown: o
3470
3485
  };
3471
- }, ma = (e) => {
3486
+ }, ga = (e) => {
3472
3487
  switch (e.outcome) {
3473
3488
  case "clean": return 0;
3474
3489
  case "lossy": return 2;
@@ -3477,22 +3492,22 @@ BEGIN
3477
3492
  case "infidelity": return 1;
3478
3493
  case "failed": return 1;
3479
3494
  }
3480
- }, ha = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, ga = (e) => {
3495
+ }, _a = (e) => ` ${e.classification === "lossy" ? "✗" : "•"} ${e.kind}${e.table ? ` ${e.table}` : ""} [${e.classification}]${e.reason ? ` — ${e.reason}` : ""}${e.blockedFix ? `\n ! ${e.blockedFix}` : ""}`, va = (e) => {
3481
3496
  let t = [];
3482
3497
  if (t.push(`branch rehearsal · ${e.branchId} · mechanism ${e.mechanism}`), t.push(` branched ${e.branchedTables} table(s), replayed ${e.replayedForeignKeys} foreign key(s)`), e.outcome === "failed") t.push(` FAILED: ${e.error ?? "unknown error"}`);
3483
3498
  else if (e.outcome === "infidelity") {
3484
3499
  t.push(" BRANCH IS NOT A FAITHFUL COPY of the parent — the rehearsal proves nothing about your migration."), t.push(" The parent's own schema still differs from the branch by:");
3485
- for (let n of e.infidelity) t.push(ha(n));
3500
+ for (let n of e.infidelity) t.push(_a(n));
3486
3501
  } else {
3487
3502
  t.push(` plan: ${e.operations.length} operation(s), ${e.lossy.length} lossy, ${e.blocked.length} refused`);
3488
- for (let n of e.operations) t.push(ha(n));
3489
- if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(ha(n));
3503
+ for (let n of e.operations) t.push(_a(n));
3504
+ if (e.lossy.length > 0 && (t.push(""), t.push(` ⚠ ${e.lossy.length} operation(s) DESTROY DATA. They were executed on the branch (it is`), t.push(" disposable) so they are rehearsed, but production refuses them until you set"), t.push(" VOLTRO_DESTRUCTIVE_OK — naming the tables, not `1`.")), e.blocked.length > 0 && (t.push(""), t.push(` ${e.blocked.length} operation(s) the planner will not auto-apply anywhere — the plan was NOT executed.`)), e.applied && (t.push(""), t.push(e.converged ? " ✓ applied on the branch, and the re-plan is EMPTY (the migration converges)." : ` ✗ applied, but the re-plan STILL proposes ${e.residual.length} operation(s) — this migration does not converge:`), !e.converged)) for (let n of e.residual) t.push(_a(n));
3490
3505
  }
3491
3506
  return t.push(e.tornDown ? ` branch ${e.branchId} torn down.` : ` branch ${e.branchId} KEPT — drop it when you are done.`), t.join("\n");
3492
- }, _a = (e, ...t) => ({
3507
+ }, ya = (e, ...t) => ({
3493
3508
  _tag: "RawSqlFragment",
3494
3509
  strings: [...e],
3495
3510
  values: [...t]
3496
- }), va = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3511
+ }), ba = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
3497
3512
  //#endregion
3498
- export { k as DEFAULT_CDC_CHANNEL, d as FILE_MIGRATION_PATTERN, Qi as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, pe as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, G as appliedAtValue, It as applyNamespacedSchema, Mi as applyPlan, Et as applySchema, la as assessRollingDeployGate, ma as branchRehearsalExitCode, Ln as chunkTables, sa as classifyRollingDeploySafety, L as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, M as defaultJsonClause, qi as describeOutcome, Vi as destructiveScope, Jt as detectReactiveTriggerDrift, Xr as emitAddIndexMysql, jr as emitCreateTableMysql, dr as emitDropColumnDdl, fr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, Xn as engineFromVersion, F as fingerprintSchema, ye as fnv1a64, ga as formatBranchRehearsal, Yt as formatReactiveTriggerDrift, Bi as ignoreTablesFromEnv, Yn as introspectSchema, tr as isAlreadySatisfied, c as isFileMigration, va as isRawSqlFragment, Ot as isReRunSafeDdl, Mn as mapPgType, g as migration, be as migrationLockKeyForSchema, T as migrationLockNameForSchema, Kr as mysqlIndexPrefixFor, Ye as notifyFunctionName, N as numericIdSql, jn as parseEnumCheck, ta as pendingFileMigrationIds, An as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Fi as recordUpToDate, pa as rehearseMigrationOnBranch, da as rehearsedOperation, D as releaseMigrationLock, kr as renderColumnMysql, wr as renderColumnPg, he as resolveMigrationLockSchema, W as resolveMysqlEngine, ia as rollbackFileBasedMigration, ca as rollingDeployUnsafeOps, na as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, Ki as runPlannedMigrations, I as shortFingerprint, Wt as snapshotColumn, _a as sql, j as sqlType, aa as squashMigrationPlans, Ui as unblockLossy, Me as withMigrationLock };
3513
+ export { k as DEFAULT_CDC_CHANNEL, d as FILE_MIGRATION_PATTERN, ea as FileMigrationLedgerError, qe as REACTIVE_TRIGGER_PREFIX, pe as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, W as appliedAtValue, It as applyNamespacedSchema, Pi as applyPlan, Et as applySchema, da as assessRollingDeployGate, ga as branchRehearsalExitCode, Bn as chunkTables, la as classifyRollingDeploySafety, I as declaredSnapshot, $e as defaultArrayClause, Qe as defaultClause, M as defaultJsonClause, Yi as describeOutcome, Ui as destructiveScope, Yt as detectReactiveTriggerDrift, Qr as emitAddIndexMysql, Nr as emitCreateTableMysql, mr as emitDropColumnDdl, hr as emitDropColumnDdlMysql, Tt as emitFrameworkBootstrapSql, Ct as emitNamespaceProvisionDdl, wt as emitNamespacedSchemaSql, St as emitSchemaSql, $n as engineFromVersion, Wt as fingerprintSchema, ye as fnv1a64, va as formatBranchRehearsal, Xt as formatReactiveTriggerDrift, Hi as ignoreTablesFromEnv, Qn as introspectSchema, ir as isAlreadySatisfied, c as isFileMigration, ba as isRawSqlFragment, Ot as isReRunSafeDdl, Pn as mapPgType, g as migration, be as migrationLockKeyForSchema, T as migrationLockNameForSchema, Jr as mysqlIndexPrefixFor, Ye as notifyFunctionName, N as numericIdSql, Nn as parseEnumCheck, ra as pendingFileMigrationIds, Mn as planMigrations, Lt as provisionTenantNamespace, Je as reactiveTriggerName, pt as reactiveTriggerRepairSql, Li as recordUpToDate, ha as rehearseMigrationOnBranch, pa as rehearsedOperation, D as releaseMigrationLock, jr as renderColumnMysql, Er as renderColumnPg, he as resolveMigrationLockSchema, U as resolveMysqlEngine, oa as rollbackFileBasedMigration, ua as rollingDeployUnsafeOps, ia as runFileBasedMigrations, Rt as runFrameworkBootstrap, Ft as runMigrate, Ji as runPlannedMigrations, F as shortFingerprint, Gt as snapshotColumn, ya as sql, j as sqlType, sa as squashMigrationPlans, Gi as unblockLossy, Me as withMigrationLock };