@voltro/data-transfer 0.49.0 → 0.50.1

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/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { Cause as e, Data as t, Effect as n, Exit as r, Metric as i, MetricBoundaries as a, Runtime as o, Schedule as s, Schema as c, Stream as l } from "effect";
2
2
  import { DATA_TRANSFERS_TABLE as u, REPLACE_IN_PROGRESS_TABLE as d, _voltroDataTransfersTable as f, classifyConstraintViolation as p, derivedRowId as m, ensureTableRegistered as h, eq as g, extractDbCause as _, getTable as v, inSet as y, isNotNull as b, or as x, recordsTable as S, registerTable as C, streamTable as w, suspendWriteRecorders as ee, suspendWriteRecordersEffect as te, unregisterTable as ne } from "@voltro/database";
3
3
  import { fingerprintSchema as re } from "@voltro/database/sql";
4
- import { createCipheriv as T, createDecipheriv as ie, createHash as E, createHmac as ae, randomBytes as D, scrypt as oe } from "node:crypto";
5
- import { STORAGE_REFS_TABLE as se, fromNodeReadable as ce, getObjectStream as le, putObjectStream as O, toNodeReadable as k } from "@voltro/plugin-storage";
6
- import * as A from "node:zlib";
7
- import { PassThrough as ue, Readable as j } from "node:stream";
8
- import { copyFile as de, createReadStream as fe, createWriteStream as M, existsSync as N, unlinkSync as pe } from "node:fs";
9
- import { SqlClient as P } from "@effect/sql";
10
- import { mkdir as F, readdir as me, stat as he } from "node:fs/promises";
11
- import { basename as ge, delimiter as I, dirname as _e, join as L, resolve as R, sep as ve } from "node:path";
12
- import { promisify as ye } from "node:util";
13
- import { spawn as be } from "node:child_process";
4
+ import { createCipheriv as T, createDecipheriv as E, createHash as D, createHmac as ie, randomBytes as ae, randomUUID as oe, scrypt as se } from "node:crypto";
5
+ import { copyFile as ce, createReadStream as le, createWriteStream as O, existsSync as ue, rename as de, statSync as fe, unlinkSync as k } from "node:fs";
6
+ import { STORAGE_REFS_TABLE as pe, fromNodeReadable as me, getObjectStream as A, putObjectStream as j, toNodeReadable as he } from "@voltro/plugin-storage";
7
+ import * as M from "node:zlib";
8
+ import { PassThrough as N, Readable as ge } from "node:stream";
9
+ import { SqlClient as _e } from "@effect/sql";
10
+ import { mkdir as P, readdir as F, stat as ve } from "node:fs/promises";
11
+ import { basename as I, delimiter as L, dirname as ye, join as R, resolve as be, sep as xe } from "node:path";
12
+ import { promisify as Se } from "node:util";
13
+ import { spawn as Ce } from "node:child_process";
14
14
  //#region src/consistency.ts
15
- var xe = (e) => {
15
+ var we = (e) => {
16
16
  switch (e) {
17
17
  case "postgres": return ["SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"];
18
18
  case "mysql":
@@ -22,7 +22,7 @@ var xe = (e) => {
22
22
  case "turso": return [];
23
23
  default: return [];
24
24
  }
25
- }, Se = {
25
+ }, Te = {
26
26
  email: { fake: "email" },
27
27
  fullName: { fake: "fullName" },
28
28
  firstName: { fake: "firstName" },
@@ -37,7 +37,7 @@ var xe = (e) => {
37
37
  date: "dateShift",
38
38
  secret: "null",
39
39
  freeText: "redact"
40
- }, Ce = (e) => {
40
+ }, Ee = (e) => {
41
41
  let t = {};
42
42
  for (let n of e.tables) {
43
43
  let e = {};
@@ -49,15 +49,15 @@ var xe = (e) => {
49
49
  t[n.name] = e;
50
50
  }
51
51
  return t;
52
- }, we = (e, t, n, r) => {
52
+ }, De = (e, t, n, r) => {
53
53
  let i = r.columns?.[`${e}.${t}`];
54
54
  if (i) return i;
55
55
  if (n?.sensitive) {
56
56
  let e = n.sensitive.class;
57
- return r.classes?.[e] ?? Se[e] ?? "redact";
57
+ return r.classes?.[e] ?? Te[e] ?? "redact";
58
58
  }
59
59
  return n?.safe ? r.onSafe ?? "keep" : n?.columnType === "id" || n?.columnType === "reference" ? "keep" : r.onUnclassified ?? "error";
60
- }, Te = (e, t) => ae("sha256", e).update(t == null ? "∅" : String(t)).digest(), z = (e, t) => e.readUInt32BE(t * 4 % (e.length - 4)), Ee = [
60
+ }, Oe = (e, t) => ie("sha256", e).update(t == null ? "∅" : String(t)).digest(), z = (e, t) => e.readUInt32BE(t * 4 % (e.length - 4)), ke = [
61
61
  "Ada",
62
62
  "Alan",
63
63
  "Grace",
@@ -70,7 +70,7 @@ var xe = (e) => {
70
70
  "Guido",
71
71
  "Margaret",
72
72
  "Bjarne"
73
- ], De = [
73
+ ], Ae = [
74
74
  "Lovelace",
75
75
  "Turing",
76
76
  "Hopper",
@@ -83,7 +83,7 @@ var xe = (e) => {
83
83
  "Rossum",
84
84
  "Hamilton",
85
85
  "Stroustrup"
86
- ], Oe = [
86
+ ], je = [
87
87
  "Maple",
88
88
  "Oak",
89
89
  "Cedar",
@@ -92,7 +92,7 @@ var xe = (e) => {
92
92
  "Birch",
93
93
  "Willow",
94
94
  "Ash"
95
- ], ke = [
95
+ ], Me = [
96
96
  "Initech",
97
97
  "Hooli",
98
98
  "Umbrella",
@@ -101,23 +101,23 @@ var xe = (e) => {
101
101
  "Soylent",
102
102
  "Stark",
103
103
  "Wayne"
104
- ], B = (e, t, n) => e[z(t, n) % e.length], Ae = (e, t, n) => {
105
- let r = Te(n, `${e}:${String(t)}`), i = z(r, 1) % 1e4;
104
+ ], B = (e, t, n) => e[z(t, n) % e.length], Ne = (e, t, n) => {
105
+ let r = Oe(n, `${e}:${String(t)}`), i = z(r, 1) % 1e4;
106
106
  switch (e) {
107
- case "email": return `${B(Ee, r, 0).toLowerCase()}.${B(De, r, 2).toLowerCase()}${i}@example.com`;
108
- case "fullName": return `${B(Ee, r, 0)} ${B(De, r, 1)}`;
109
- case "firstName": return B(Ee, r, 0);
110
- case "lastName": return B(De, r, 1);
111
- case "username": return `${B(Ee, r, 0).toLowerCase()}${i}`;
107
+ case "email": return `${B(ke, r, 0).toLowerCase()}.${B(Ae, r, 2).toLowerCase()}${i}@example.com`;
108
+ case "fullName": return `${B(ke, r, 0)} ${B(Ae, r, 1)}`;
109
+ case "firstName": return B(ke, r, 0);
110
+ case "lastName": return B(Ae, r, 1);
111
+ case "username": return `${B(ke, r, 0).toLowerCase()}${i}`;
112
112
  case "phone": return `+1${String(z(r, 0) % 1e10).padStart(10, "0")}`;
113
- case "address": return `${z(r, 0) % 9899 + 100} ${B(Oe, r, 1)} St`;
114
- case "company": return B(ke, r, 0);
113
+ case "address": return `${z(r, 0) % 9899 + 100} ${B(je, r, 1)} St`;
114
+ case "company": return B(Me, r, 0);
115
115
  case "url": return `https://example.com/${r.toString("hex").slice(0, 12)}`;
116
116
  case "ip": return `${z(r, 0) % 256}.${z(r, 1) % 256}.${z(r, 2) % 256}.${z(r, 3) % 254 + 1}`;
117
- case "creditCard": return je(`4${r.toString("hex").replace(/\D/g, "").padEnd(14, "0").slice(0, 14)}`);
117
+ case "creditCard": return Pe(`4${r.toString("hex").replace(/\D/g, "").padEnd(14, "0").slice(0, 14)}`);
118
118
  default: return `${e}_${r.toString("hex").slice(0, 8)}`;
119
119
  }
120
- }, je = (e) => {
120
+ }, Pe = (e) => {
121
121
  let t = e.slice(0, 15).split("").map(Number), n = 0;
122
122
  t.forEach((e, t) => {
123
123
  let r = e;
@@ -125,31 +125,31 @@ var xe = (e) => {
125
125
  });
126
126
  let r = (10 - n % 10) % 10;
127
127
  return e.slice(0, 15) + String(r);
128
- }, Me = 864e5, Ne = (e, t) => {
128
+ }, Fe = 864e5, Ie = (e, t) => {
129
129
  let n = e instanceof Date ? e.getTime() : Date.parse(String(e));
130
130
  if (Number.isNaN(n)) return e;
131
- let r = z(Te(t, "date-shift-offset"), 0) % 730 - 365, i = new Date(n + r * Me);
131
+ let r = z(Oe(t, "date-shift-offset"), 0) % 730 - 365, i = new Date(n + r * Fe);
132
132
  return e instanceof Date ? i : i.toISOString();
133
- }, Pe = (e, t) => {
133
+ }, Le = (e, t) => {
134
134
  if (t.value === null || t.value === void 0) return null;
135
135
  if (e === "error") throw Error(`masking: unresolved 'error' action for ${t.table}.${t.column}`);
136
136
  if (e === "keep") return t.value;
137
137
  if (e === "null") return null;
138
138
  if (e === "redact") return t.columnType === "text" || typeof t.value == "string" ? "[redacted]" : null;
139
- if (e === "hash") return Te(t.seed, t.value).toString("hex").slice(0, 16);
140
- if (e === "dateShift") return Ne(t.value, t.seed);
141
- if (typeof e == "object" && "fake" in e) return Ae(e.fake, t.value, t.seed);
139
+ if (e === "hash") return Oe(t.seed, t.value).toString("hex").slice(0, 16);
140
+ if (e === "dateShift") return Ie(t.value, t.seed);
141
+ if (typeof e == "object" && "fake" in e) return Ne(e.fake, t.value, t.seed);
142
142
  if (typeof e == "object" && "custom" in e) return e.custom(t);
143
143
  throw Error(`masking: '${t.table}.${t.column}' resolved to an action this build does not understand (${JSON.stringify(e)}). Refusing to copy the value through. Valid actions: 'keep' | 'null' | 'redact' | 'hash' | 'dateShift' | { fake: '<class>' } | { custom: fn }.`);
144
- }, Fe = (e) => typeof e == "string" ? e === "keep" || e === "null" || e === "redact" || e === "hash" || e === "dateShift" || e === "error" : typeof e != "object" || !e ? !1 : "fake" in e ? typeof e.fake == "string" : "custom" in e && typeof e.custom == "function", Ie = (e, t, n) => {
144
+ }, Re = (e) => typeof e == "string" ? e === "keep" || e === "null" || e === "redact" || e === "hash" || e === "dateShift" || e === "error" : typeof e != "object" || !e ? !1 : "fake" in e ? typeof e.fake == "string" : "custom" in e && typeof e.custom == "function", ze = (e, t, n) => {
145
145
  let r = {}, i = [], a = [];
146
146
  for (let o of e) for (let e of o.columns) {
147
- let s = `${o.name}.${e.name}`, c = we(o.name, e.name, t[o.name]?.[e.name], n);
147
+ let s = `${o.name}.${e.name}`, c = De(o.name, e.name, t[o.name]?.[e.name], n);
148
148
  if (c === "error") {
149
149
  i.push(s);
150
150
  continue;
151
151
  }
152
- if (!Fe(c)) {
152
+ if (!Re(c)) {
153
153
  a.push({
154
154
  column: s,
155
155
  action: c
@@ -163,7 +163,7 @@ var xe = (e) => {
163
163
  unclassified: i,
164
164
  invalid: a
165
165
  };
166
- }, Le = [
166
+ }, Be = [
167
167
  {
168
168
  name: "email",
169
169
  re: /[\w.+-]+@[\w-]+\.[\w.-]+/
@@ -180,7 +180,7 @@ var xe = (e) => {
180
180
  name: "creditCard",
181
181
  re: /\b(?:\d[ -]?){13,16}\b/
182
182
  }
183
- ], Re = (e, t, n) => {
183
+ ], Ve = (e, t, n) => {
184
184
  let r = [], i = /* @__PURE__ */ new Set();
185
185
  for (let [a, o] of Object.entries(n)) {
186
186
  if (!a.startsWith(`${t}.`) || o !== "keep") continue;
@@ -188,7 +188,7 @@ var xe = (e) => {
188
188
  for (let a of e) {
189
189
  let e = a[n];
190
190
  if (typeof e != "string" || e.length === 0) continue;
191
- let o = Le.find((t) => t.re.test(e));
191
+ let o = Be.find((t) => t.re.test(e));
192
192
  if (o && !i.has(n)) {
193
193
  i.add(n), r.push({
194
194
  table: t,
@@ -201,9 +201,9 @@ var xe = (e) => {
201
201
  }
202
202
  }
203
203
  return r;
204
- }, ze = (e, t, n, r, i) => {
204
+ }, He = (e, t, n, r, i) => {
205
205
  let a = {};
206
- for (let [o, s] of Object.entries(e)) a[o] = Pe(n[`${t}.${o}`] ?? "keep", {
206
+ for (let [o, s] of Object.entries(e)) a[o] = Le(n[`${t}.${o}`] ?? "keep", {
207
207
  value: s,
208
208
  table: t,
209
209
  column: o,
@@ -211,7 +211,7 @@ var xe = (e) => {
211
211
  ...i?.[o] ? { columnType: i[o] } : {}
212
212
  });
213
213
  return a;
214
- }, Be = /* @__PURE__ */ new Map([
214
+ }, Ue = /* @__PURE__ */ new Map([
215
215
  ["_voltro_migration_plans", "the schema fingerprint THIS deployment applied — a foreign row makes the next boot refuse"],
216
216
  ["_voltro_migrations", "which file-based migrations ran HERE — a foreign row marks unrun migrations as done"],
217
217
  ["_voltro_seeds", "which seeds ran HERE — a foreign row suppresses seeding the target still needs"],
@@ -243,7 +243,7 @@ var xe = (e) => {
243
243
  ["_voltro_notification_held", "notifications waiting to be SENT from here — a foreign row makes the target deliver something queued elsewhere"],
244
244
  ["_voltro_webhook_event_stats", "per-deployment delivery counters a backoff decision reads — foreign counts steer the target's retries"],
245
245
  ["_voltro_webhook_rate_windows", "the live rate-limit windows this deployment is inside — a foreign window throttles or releases wrongly"]
246
- ]), Ve = /* @__PURE__ */ new Map([
246
+ ]), We = /* @__PURE__ */ new Map([
247
247
  ["_voltro_agent_threads", "conversations the app's users had — app data"],
248
248
  ["_voltro_agent_messages", "the messages in those conversations — app data"],
249
249
  ["_voltro_prompts", "prompt definitions the app authored — app data"],
@@ -274,21 +274,21 @@ var xe = (e) => {
274
274
  ["_voltro_audit_log", "the app's audit trail — compliance data the app owns, not deployment bookkeeping"],
275
275
  ["_voltro_feature_flags", "the flags the app defined — app configuration"],
276
276
  ["_voltro_feature_flag_audit", "who changed which flag — belongs with the flags"]
277
- ]), V = (e) => Be.has(e), He = (e) => Be.get(e), Ue = (e, t) => {
277
+ ]), V = (e) => Ue.has(e), Ge = (e) => Ue.get(e), Ke = (e, t) => {
278
278
  if (e.length === 0) return;
279
- let n = e.map((e) => ` ${e} — ${He(e) ?? "describes this deployment"}`);
279
+ let n = e.map((e) => ` ${e} — ${Ge(e) ?? "describes this deployment"}`);
280
280
  return `${t} ${e.length} table(s) that describe a deployment rather than its data:\n${n.join("\n")}\n A row from another environment is not stale there, it is a false statement about this one.`;
281
281
  }, H = class extends c.TaggedError()("BundleError", {
282
282
  reason: c.String,
283
283
  path: c.optional(c.String)
284
- }) {}, We = class extends c.TaggedError()("CodecError", {
284
+ }) {}, qe = class extends c.TaggedError()("CodecError", {
285
285
  table: c.String,
286
286
  reason: c.String
287
- }) {}, Ge = class extends c.TaggedError()("IntegrityError", {
287
+ }) {}, Je = class extends c.TaggedError()("IntegrityError", {
288
288
  what: c.String,
289
289
  expected: c.String,
290
290
  actual: c.String
291
- }) {}, Ke = class extends t.TaggedError("CompressionError") {}, U = class extends c.TaggedError()("ScopeError", { reason: c.String }) {}, qe = class extends c.TaggedError()("RowsRefusedError", {
291
+ }) {}, Ye = class extends t.TaggedError("CompressionError") {}, U = class extends c.TaggedError()("ScopeError", { reason: c.String }) {}, Xe = class extends c.TaggedError()("RowsRefusedError", {
292
292
  rows: c.Array(c.Struct({
293
293
  table: c.String,
294
294
  id: c.String,
@@ -302,29 +302,29 @@ var xe = (e) => {
302
302
  refused: c.Number,
303
303
  primary: c.Number
304
304
  }))
305
- }) {}, Je = class extends c.TaggedError()("SchemaDriftError", {
305
+ }) {}, Ze = class extends c.TaggedError()("SchemaDriftError", {
306
306
  bundleFingerprint: c.String,
307
307
  targetFingerprint: c.String,
308
308
  diff: c.Array(c.String)
309
309
  }) {}, W = class extends t.TaggedError("NativeToolError") {
310
310
  get message() {
311
- let e = this.stderr?.trim();
312
- return `${this.tool}: ${this.reason}${e ? `\n${e}` : ""}`;
311
+ let e = this.stderr?.trim(), t = this.hint?.trim();
312
+ return `${this.tool}: ${this.reason}${e ? `\n${e}` : ""}${t ? `\n\nhint: ${t}` : ""}`;
313
313
  }
314
- }, Ye = class extends c.TaggedError()("MaskingError", {
314
+ }, Qe = class extends c.TaggedError()("MaskingError", {
315
315
  unclassified: c.Array(c.String),
316
316
  invalidActions: c.optional(c.Array(c.String))
317
- }) {}, Xe = class extends c.TaggedError()("ImportModeError", {
317
+ }) {}, $e = class extends c.TaggedError()("ImportModeError", {
318
318
  mode: c.String,
319
319
  reason: c.String
320
- }) {}, Ze = class extends c.TaggedError()("CrossDialectError", {
320
+ }) {}, et = class extends c.TaggedError()("CrossDialectError", {
321
321
  sourceDialect: c.String,
322
322
  targetDialect: c.String,
323
323
  blocking: c.Array(c.String)
324
- }) {}, G = (e, t) => e.tables.find((e) => e.name === t)?.columns.find((e) => e.type === "id")?.name ?? "id", Qe = (e, t) => (e.tables.find((e) => e.name === t)?.columns ?? []).filter((e) => e.references).map((e) => ({
324
+ }) {}, G = (e, t) => e.tables.find((e) => e.name === t)?.columns.find((e) => e.type === "id")?.name ?? "id", tt = (e, t) => (e.tables.find((e) => e.name === t)?.columns ?? []).filter((e) => e.references).map((e) => ({
325
325
  col: e.name,
326
326
  refTable: e.references.table
327
- })), $e = (e, t, r) => n.gen(function* () {
327
+ })), nt = (e, t, r) => n.gen(function* () {
328
328
  let i = r.maxDepth ?? 12, a = new Set(r.pinned ?? []), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), u = (e) => {
329
329
  let t = s.get(e) ?? /* @__PURE__ */ new Set();
330
330
  return s.set(e, t), t;
@@ -342,7 +342,7 @@ var xe = (e) => {
342
342
  for (let t of n) d(t.refTable, e[t.col]);
343
343
  };
344
344
  }, p = (r, i) => {
345
- let a = f(r, G(t, r), Qe(t, r));
345
+ let a = f(r, G(t, r), tt(t, r));
346
346
  return l.runForEach(w(e, {
347
347
  table: r,
348
348
  pk: G(t, r),
@@ -377,13 +377,13 @@ var xe = (e) => {
377
377
  }
378
378
  }
379
379
  return o;
380
- }), et = (e, t) => ({
380
+ }), rt = (e, t) => ({
381
381
  tables: [...e.keys()],
382
382
  predicateFor: (n) => {
383
383
  let r = e.get(n);
384
384
  return r ? y(G(t, n), [...r]) : void 0;
385
385
  }
386
- }), tt = "tenantId", nt = (e, t, r) => n.gen(function* () {
386
+ }), it = "tenantId", at = (e, t, r) => n.gen(function* () {
387
387
  let i = t.tables.map((e) => e.name), a = new Map(t.tables.map((e) => [e.name, e]));
388
388
  if (e.kind === "all") {
389
389
  let t = new Set(e.exclude ?? []);
@@ -403,29 +403,29 @@ var xe = (e) => {
403
403
  }
404
404
  let o = e.tenantId;
405
405
  if (o === void 0 || o === "") return yield* n.fail(new U({ reason: "scope { kind: 'tenant' } requires a tenantId — pass --tenant <id> (CLI) or scope.tenantId (API). Refusing to fall back to an unfiltered export." }));
406
- let s = r.tenantTables ? r.tenantTables.filter((e) => a.has(e)) : i.filter((e) => a.get(e)?.columns.some((e) => e.name === tt) ?? !1);
407
- if (s.length === 0) return yield* n.fail(new U({ reason: r.tenantTables ? "tenant scope: none of the provided tenantTables exist in the schema — nothing to filter." : `tenant scope: no table carries a '${tt}' column — nothing to filter. A tenant export of a schema without tenant-scoped tables would be the full database; refusing.` }));
408
- let c = yield* $e(r.store, t, {
409
- seeds: Object.fromEntries(s.map((e) => [e, g(tt, o)])),
406
+ let s = r.tenantTables ? r.tenantTables.filter((e) => a.has(e)) : i.filter((e) => a.get(e)?.columns.some((e) => e.name === it) ?? !1);
407
+ if (s.length === 0) return yield* n.fail(new U({ reason: r.tenantTables ? "tenant scope: none of the provided tenantTables exist in the schema — nothing to filter." : `tenant scope: no table carries a '${it}' column — nothing to filter. A tenant export of a schema without tenant-scoped tables would be the full database; refusing.` }));
408
+ let c = yield* nt(r.store, t, {
409
+ seeds: Object.fromEntries(s.map((e) => [e, g(it, o)])),
410
410
  pinned: s,
411
411
  children: { roots: s }
412
412
  }), l = [...c.entries()].filter(([, e]) => e.size > 0).map(([e]) => e), u = new Set(s);
413
413
  return {
414
414
  tables: [...s, ...l],
415
- predicateFor: (e) => u.has(e) ? g(tt, o) : c.has(e) ? y(G(t, e), [...c.get(e)]) : void 0
415
+ predicateFor: (e) => u.has(e) ? g(it, o) : c.has(e) ? y(G(t, e), [...c.get(e)]) : void 0
416
416
  };
417
- }), rt = (e, t) => ({
417
+ }), ot = (e, t) => ({
418
418
  list: t,
419
- open: (t) => le(e, t)
420
- }), it = (e) => ({
421
- write: (t, n, r) => O(e, t, n, r),
419
+ open: (t) => A(e, t)
420
+ }), st = (e) => ({
421
+ write: (t, n, r) => j(e, t, n, r),
422
422
  has: (t) => e.head(t).pipe(n.map((e) => e !== null))
423
- }), at = (e, t) => n.tryPromise({
423
+ }), ct = (e, t) => n.tryPromise({
424
424
  try: async () => {
425
425
  let { createWriteStream: n } = await import("node:fs"), r = await import("node:fs/promises"), { createHash: i, randomUUID: a } = await import("node:crypto"), { pipeline: o } = await import("node:stream/promises"), { Transform: s } = await import("node:stream"), c = await import("node:path"), l = c.join(t, `.tmp-${a()}`), u = i("sha256"), d = 0, f = new s({ transform(e, t, n) {
426
426
  u.update(e), d += e.length, n(null, e);
427
427
  } });
428
- await o(await k(e.stream), f, n(l));
428
+ await o(await he(e.stream), f, n(l));
429
429
  let p = u.digest("hex"), m = c.join(t, p);
430
430
  try {
431
431
  await r.access(m), await r.rm(l, { force: !0 });
@@ -442,19 +442,47 @@ var xe = (e) => {
442
442
  reason: `asset write failed: ${String(e?.message ?? e)}`,
443
443
  path: t
444
444
  })
445
- }), ot = (e, t, r) => n.gen(function* () {
446
- let i = yield* n.promise(() => import("node:path")), { createReadStream: a } = yield* n.promise(() => import("node:fs")), { createHash: o } = yield* n.promise(() => import("node:crypto")), s = i.join(t, r.sha256), c = o("sha256"), u = ce("bundle", () => a(s)).pipe(l.tap((e) => n.sync(() => c.update(e))));
445
+ }), lt = (e, t, r) => n.gen(function* () {
446
+ let i = yield* n.promise(() => import("node:path")), { createReadStream: a } = yield* n.promise(() => import("node:fs")), { createHash: o } = yield* n.promise(() => import("node:crypto")), s = i.join(t, r.sha256), c = o("sha256"), u = me("bundle", () => a(s)).pipe(l.tap((e) => n.sync(() => c.update(e))));
447
447
  yield* e.write(r.key, u, {
448
448
  contentType: r.contentType,
449
449
  totalSize: r.size
450
450
  });
451
451
  let d = c.digest("hex");
452
- if (d !== r.sha256) return yield* n.fail(new Ge({
452
+ if (d !== r.sha256) return yield* n.fail(new Je({
453
453
  what: `asset ${r.key}`,
454
454
  expected: r.sha256,
455
455
  actual: d
456
456
  }));
457
- }), st = () => typeof A.createZstdCompress == "function", ct = (e) => e === "none" ? "none" : e === "gzip" ? "gzip" : st() ? "zstd" : "gzip", lt = (e) => e === "zstd" ? ".zst" : e === "gzip" ? ".gz" : "", ut = (e) => e === "zstd" ? A.createZstdCompress() : e === "gzip" ? A.createGzip() : new ue(), dt = (e) => e === "zstd" ? A.createZstdDecompress() : e === "gzip" ? A.createGunzip() : new ue(), ft = 1, pt = c.Struct({
457
+ }), ut = {
458
+ done: () => !1,
459
+ mark: () => n.void
460
+ }, dt = (e) => typeof e == "object" && !!e && e.status === 404, ft = (e) => n.gen(function* () {
461
+ let t = e.progress ?? ut, r = 0, i = 0, a = [];
462
+ return yield* l.runForEach(e.source.list(), (o) => t.done(o.key) ? n.void : e.source.open(o.key).pipe(n.map((e) => e), n.catchIf(dt, () => n.sync(() => {
463
+ a.push(o.key);
464
+ })), n.flatMap((a) => a === void 0 ? n.void : ct(a, e.assetsDir).pipe(n.flatMap((e) => {
465
+ let n = {
466
+ key: o.key,
467
+ sha256: e.sha256,
468
+ size: e.size,
469
+ contentType: e.contentType
470
+ };
471
+ return r++, i += e.size, t.mark(o.key, n);
472
+ }))))).pipe(n.mapError((e) => e instanceof H ? e : new H({ reason: `asset export failed: ${String(e)}` }))), {
473
+ count: r,
474
+ totalBytes: i,
475
+ missing: a
476
+ };
477
+ }), pt = (e) => me("bundle", () => le(e)).pipe(l.decodeText(), l.splitLines, l.filter((e) => e.trim().length > 0), l.map((e) => JSON.parse(e)), l.mapError((t) => t instanceof H ? t : new H({
478
+ reason: `asset index unreadable: ${String(t)}`,
479
+ path: e
480
+ }))), mt = (e) => n.gen(function* () {
481
+ let t = e.progress ?? ut, r = 0;
482
+ return yield* l.runForEach(pt(e.indexPath), (i) => t.done(i.key) ? n.void : lt(e.sink, e.assetsDir, i).pipe(n.andThen(n.sync(() => {
483
+ r++;
484
+ })), n.andThen(t.mark(i.key, i)))), r;
485
+ }), ht = () => typeof M.createZstdCompress == "function", gt = (e) => e === "none" ? "none" : e === "gzip" ? "gzip" : ht() ? "zstd" : "gzip", _t = (e) => e === "zstd" ? ".zst" : e === "gzip" ? ".gz" : "", vt = (e) => e === "zstd" ? M.createZstdCompress() : e === "gzip" ? M.createGzip() : new N(), yt = (e) => e === "zstd" ? M.createZstdDecompress() : e === "gzip" ? M.createGunzip() : new N(), bt = 1, xt = c.Struct({
458
486
  name: c.String,
459
487
  file: c.String,
460
488
  rowCount: c.Number,
@@ -464,12 +492,12 @@ var xe = (e) => {
464
492
  value: c.String
465
493
  }),
466
494
  primaryKey: c.String
467
- }), mt = c.Struct({
495
+ }), St = c.Struct({
468
496
  kind: c.Literal("all", "tenant", "tables"),
469
497
  tenantId: c.optional(c.String),
470
498
  tables: c.optional(c.Array(c.String)),
471
499
  exclude: c.optional(c.Array(c.String))
472
- }), ht = c.Struct({
500
+ }), Ct = c.Struct({
473
501
  count: c.Number,
474
502
  totalBytes: c.Number,
475
503
  index: c.optional(c.String)
@@ -480,23 +508,23 @@ c.Struct({
480
508
  size: c.Number,
481
509
  contentType: c.String
482
510
  });
483
- var gt = c.Struct({
511
+ var wt = c.Struct({
484
512
  formatVersion: c.Number,
485
513
  createdAt: c.String,
486
514
  source: c.Struct({
487
515
  dialect: c.String,
488
516
  schemaFingerprint: c.String
489
517
  }),
490
- scope: mt,
518
+ scope: St,
491
519
  consistency: c.Literal("live", "snapshot"),
492
520
  compression: c.Literal("zstd", "gzip", "none"),
493
- tables: c.Array(pt),
494
- assets: ht,
521
+ tables: c.Array(xt),
522
+ assets: Ct,
495
523
  masking: c.optional(c.Struct({
496
524
  policyId: c.optional(c.String),
497
525
  transformed: c.Array(c.String)
498
526
  }))
499
- }), _t = c.encodeSync(c.parseJson(gt)), vt = c.decodeUnknownSync(c.parseJson(gt)), K = "manifest.json", yt = "README.md", bt = "data", xt = "assets", St = "assets/index.ndjson", Ct = ".ledger.json", wt = (e) => e.kind === "tenant" ? `tenant \`${e.tenantId}\`` : e.kind === "tables" ? `tables \`${(e.tables ?? []).join(", ")}\`` : "all tables", Tt = (e, t) => {
527
+ }), Tt = c.encodeSync(c.parseJson(wt)), Et = c.decodeUnknownSync(c.parseJson(wt)), K = "manifest.json", Dt = "README.md", Ot = "data", kt = "assets", At = "assets/index.ndjson", jt = ".ledger.json", Mt = (e) => e.kind === "tenant" ? `tenant \`${e.tenantId}\`` : e.kind === "tables" ? `tables \`${(e.tables ?? []).join(", ")}\`` : "all tables", Nt = (e, t) => {
500
528
  let n = e.tables.reduce((e, t) => e + t.rowCount, 0), r = e.masking ? `✅ **Masked at the source** — ${e.masking.transformed.length} column(s) transformed${e.masking.policyId ? ` (policy \`${e.masking.policyId}\`)` : ""}. Personal data was replaced with realistic, referentially-consistent fakes before any byte was written.` : "⚠️ **NOT masked — this bundle contains REAL data (PII included).** Treat it as production data: do not copy it into a lower environment or share it without review. To produce a safe copy, re-export under a masking profile (`--profile`).", i = e.masking && e.masking.transformed.length > 0 ? `\n\nMasked columns: ${e.masking.transformed.map((e) => `\`${e}\``).join(", ")}.` : "", a = e.assets.count > 0 ? `${e.assets.count} object(s), ${e.assets.totalBytes} bytes` : "none", o = e.tables.map((e) => `| \`${e.name}\` | ${e.rowCount} |`).join("\n");
501
529
  return `# Voltro data export
502
530
 
@@ -510,7 +538,7 @@ The machine-readable manifest is \`manifest.json\`; this file is a human summary
510
538
  | **Format version** | ${e.formatVersion} |
511
539
  | **Consistency** | ${e.consistency} |
512
540
  | **Compression** | ${e.compression} |
513
- | **Scope** | ${wt(e.scope)} |
541
+ | **Scope** | ${Mt(e.scope)} |
514
542
  | **Tables** | ${e.tables.length} |
515
543
  | **Rows (total)** | ${n} |
516
544
  | **Assets** | ${a} |
@@ -535,26 +563,26 @@ voltro data import <this-directory>
535
563
  voltro data import <this-directory> --target api --api-url <url> --token <secret>
536
564
  \`\`\`
537
565
  `;
538
- }, Et = i.counter("voltro_data_transfer_rows", { description: "Rows exported/imported by @voltro/data-transfer, tagged by phase + table." }), Dt = a.exponential({
566
+ }, Pt = i.counter("voltro_data_transfer_rows", { description: "Rows exported/imported by @voltro/data-transfer, tagged by phase + table." }), Ft = a.exponential({
539
567
  start: .01,
540
568
  factor: 2,
541
569
  count: 16
542
- }), Ot = i.histogram("voltro_data_transfer_table_seconds", Dt, "Per-table export/import duration in seconds, tagged by phase."), q = (e, t) => {
570
+ }), It = i.histogram("voltro_data_transfer_table_seconds", Ft, "Per-table export/import duration in seconds, tagged by phase."), q = (e, t) => {
543
571
  if (e) try {
544
572
  e(t);
545
573
  } catch {}
546
- }, kt = (e, t, r, a, o, s) => n.Do.pipe(n.bind("start", () => n.clockWith((e) => e.currentTimeMillis)), n.bind("result", () => s), n.tap(({ start: r, result: a }) => n.clockWith((e) => e.currentTimeMillis).pipe(n.flatMap((s) => n.zipRight(Ot.pipe(i.tagged("phase", e), i.update((s - r) / 1e3)), Et.pipe(i.tagged("phase", e), i.tagged("table", t), i.update(o(a))))))), n.map(({ result: e }) => e), n.withSpan(`data-transfer.${e}.table`, { attributes: {
574
+ }, Lt = (e, t, r, a, o, s) => n.Do.pipe(n.bind("start", () => n.clockWith((e) => e.currentTimeMillis)), n.bind("result", () => s), n.tap(({ start: r, result: a }) => n.clockWith((e) => e.currentTimeMillis).pipe(n.flatMap((s) => n.zipRight(It.pipe(i.tagged("phase", e), i.update((s - r) / 1e3)), Pt.pipe(i.tagged("phase", e), i.tagged("table", t), i.update(o(a))))))), n.map(({ result: e }) => e), n.withSpan(`data-transfer.${e}.table`, { attributes: {
547
575
  table: t,
548
576
  index: r,
549
577
  tableCount: a,
550
578
  phase: e
551
- } })), At = () => ({
579
+ } })), Rt = () => ({
552
580
  tables: {},
553
581
  assets: {}
554
- }), jt = (e) => n.tryPromise(async () => {
582
+ }), zt = (e) => n.tryPromise(async () => {
555
583
  let t = await (await import("node:fs/promises")).readFile(e, "utf8");
556
584
  return JSON.parse(t);
557
- }).pipe(n.orElseSucceed(At)), J = (e, t) => n.tryPromise({
585
+ }).pipe(n.orElseSucceed(Rt)), J = (e, t) => n.tryPromise({
558
586
  try: async () => {
559
587
  let n = await import("node:fs/promises"), { randomUUID: r } = await import("node:crypto"), i = `${e}.tmp-${r()}`;
560
588
  await n.writeFile(i, JSON.stringify(t)), await n.rename(i, e);
@@ -563,11 +591,11 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
563
591
  reason: `ledger write failed: ${String(t?.message ?? t)}`,
564
592
  path: e
565
593
  })
566
- }), Mt = (e, t) => t in e.tables, Nt = (e, t) => t in e.assets, Pt = /* @__PURE__ */ new Set([
594
+ }), Bt = (e, t) => t in e.tables, Vt = (e, t) => t in e.assets, Ht = /* @__PURE__ */ new Set([
567
595
  "json",
568
596
  "array",
569
597
  "vector"
570
- ]), Ft = (e) => typeof e == "object" && !!e && !Array.isArray(e) && typeof e.$v == "string", It = (e) => Buffer.from(e).toString("base64"), Lt = (e) => new Uint8Array(Buffer.from(e, "base64")), Rt = (e) => e instanceof Date ? e.toISOString() : typeof e == "number" ? new Date(e).toISOString() : String(e), zt = (e, t) => e == null ? null : t !== void 0 && Pt.has(t) ? e : t === "bytes" ? It(e) : t === "timestamp" || t === "date" ? Rt(e) : typeof e == "bigint" ? {
598
+ ]), Ut = (e) => typeof e == "object" && !!e && !Array.isArray(e) && typeof e.$v == "string", Wt = (e) => Buffer.from(e).toString("base64"), Gt = (e) => new Uint8Array(Buffer.from(e, "base64")), Kt = (e) => e instanceof Date ? e.toISOString() : typeof e == "number" ? new Date(e).toISOString() : String(e), qt = (e, t) => e == null ? null : t !== void 0 && Ht.has(t) ? e : t === "bytes" ? Wt(e) : t === "timestamp" || t === "date" ? Kt(e) : typeof e == "bigint" ? {
571
599
  $v: "bigint",
572
600
  d: e.toString()
573
601
  } : typeof e == "number" && !Number.isFinite(e) ? {
@@ -578,30 +606,30 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
578
606
  d: e.toISOString()
579
607
  } : e instanceof Uint8Array ? {
580
608
  $v: "bytes",
581
- d: It(e)
582
- } : e, Bt = (e) => {
609
+ d: Wt(e)
610
+ } : e, Jt = (e) => {
583
611
  switch (e.$v) {
584
612
  case "bigint": return BigInt(e.d);
585
613
  case "number": return Number(e.d);
586
614
  case "date": return new Date(e.d);
587
- case "bytes": return Lt(e.d);
615
+ case "bytes": return Gt(e.d);
588
616
  default: return e;
589
617
  }
590
- }, Vt = (e, t) => e == null ? null : t !== void 0 && Pt.has(t) ? e : Ft(e) ? Bt(e) : t === "bytes" ? Lt(e) : t === "timestamp" || t === "date" ? new Date(e) : e, Ht = (e, t) => {
618
+ }, Yt = (e, t) => e == null ? null : t !== void 0 && Ht.has(t) ? e : Ut(e) ? Jt(e) : t === "bytes" ? Gt(e) : t === "timestamp" || t === "date" ? new Date(e) : e, Xt = (e, t) => {
591
619
  let n = {};
592
- for (let [r, i] of Object.entries(e)) n[r] = zt(i, t[r]);
620
+ for (let [r, i] of Object.entries(e)) n[r] = qt(i, t[r]);
593
621
  return n;
594
- }, Ut = (e, t) => {
622
+ }, Zt = (e, t) => {
595
623
  let n = {};
596
- for (let [r, i] of Object.entries(e)) n[r] = Vt(i, t[r]);
624
+ for (let [r, i] of Object.entries(e)) n[r] = Yt(i, t[r]);
597
625
  return n;
598
- }, Wt = new TextEncoder(), Gt = (e, t) => e.pipe(l.map((e) => Wt.encode(`${JSON.stringify(Ht(e, t))}\n`))), Kt = (e, t, r) => e.pipe(l.decodeText(), l.splitLines, l.filter((e) => e.trim().length > 0), l.mapEffect((e) => n.try({
599
- try: () => Ut(JSON.parse(e), r),
600
- catch: (e) => new We({
626
+ }, Qt = new TextEncoder(), $t = (e, t) => e.pipe(l.map((e) => Qt.encode(`${JSON.stringify(Xt(e, t))}\n`))), en = (e, t, r) => e.pipe(l.decodeText(), l.splitLines, l.filter((e) => e.trim().length > 0), l.mapEffect((e) => n.try({
627
+ try: () => Zt(JSON.parse(e), r),
628
+ catch: (e) => new qe({
601
629
  table: t,
602
630
  reason: String(e?.message ?? e)
603
631
  })
604
- }))), qt = (e, t) => {
632
+ }))), tn = (e, t) => {
605
633
  let n = new Set(e), r = /* @__PURE__ */ new Map();
606
634
  for (let e of t.tables) {
607
635
  if (!n.has(e.name)) continue;
@@ -627,33 +655,33 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
627
655
  let r = typeof t?.message == "string" ? t.message.trim() : "";
628
656
  if (r === "" ? t?.cause !== void 0 && t.cause !== null && n.push(Y(t.cause)) : n.push(r), n.length === 0) {
629
657
  let t = String(e ?? "").trim();
630
- return t === "" || t === "[object Object]" ? Jt(e) : t;
658
+ return t === "" || t === "[object Object]" ? nn(e) : t;
631
659
  }
632
660
  return n.join(": ");
633
- }, Jt = (e) => {
661
+ }, nn = (e) => {
634
662
  try {
635
663
  let t = JSON.stringify(e);
636
664
  return t === void 0 || t === "{}" ? "unknown error (no message, cause or tag)" : t;
637
665
  } catch {
638
666
  return "unknown error (not serialisable)";
639
667
  }
640
- }, Yt = (e, t) => {
668
+ }, rn = (e, t) => {
641
669
  let n = e.tables.find((e) => e.name === t), r = {};
642
670
  for (let e of n?.columns ?? []) e.generatedAs === void 0 && (r[e.name] = e.type);
643
671
  return r;
644
- }, Xt = (e, t) => (e.tables.find((e) => e.name === t)?.columns ?? []).filter((e) => e.generatedAs !== void 0).map((e) => e.name), Zt = (e, t) => {
672
+ }, an = (e, t) => (e.tables.find((e) => e.name === t)?.columns ?? []).filter((e) => e.generatedAs !== void 0).map((e) => e.name), on = (e, t) => {
645
673
  if (t.length === 0) return e;
646
674
  let n = { ...e };
647
675
  for (let e of t) delete n[e];
648
676
  return n;
649
- }, Qt = (e, t) => {
677
+ }, sn = (e, t) => {
650
678
  let n = e.tables.find((e) => e.name === t);
651
679
  if (n === void 0) return { refusal: `${t}: not in the schema snapshot, so its primary key is unknown.` };
652
680
  let r = n.columns.find((e) => e.type === "id");
653
681
  if (r !== void 0) return { column: r.name };
654
682
  let i = n.indexes.find((e) => e.name === `${t}_pkey`)?.columns ?? n.primaryKey ?? [];
655
683
  return i.length === 1 ? { column: i[0] } : i.length > 1 ? { refusal: `${t}: composite primary key (${i.join(", ")}). Keyset export orders by ONE column; ordering by the first alone would split equal values across pages and drop or duplicate rows. Exclude this table from the scope, or give it a single-column key.` } : { refusal: `${t}: no primary key, so there is no stable order to paginate by. A keyset export would return rows in an order the database may change between pages. Exclude this table from the scope.` };
656
- }, $t = (e, t, r) => n.tryPromise({
684
+ }, cn = (e, t, r) => n.tryPromise({
657
685
  try: async () => {
658
686
  let { createWriteStream: n } = await import("node:fs"), i = await import("node:fs/promises"), { createHash: a, randomUUID: o } = await import("node:crypto"), { pipeline: s } = await import("node:stream/promises"), { Readable: c, Transform: u } = await import("node:stream"), d = a("sha256"), f = 0, p = new u({ transform(e, t, n) {
659
687
  d.update(e);
@@ -662,7 +690,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
662
690
  n(null, e);
663
691
  } }), m = c.fromWeb(l.toReadableStream(e)), h = `${t}.tmp-${o()}`;
664
692
  try {
665
- await s(m, p, ut(r), n(h)), await i.rename(h, t);
693
+ await s(m, p, vt(r), n(h)), await i.rename(h, t);
666
694
  } catch (e) {
667
695
  throw await i.rm(h, { force: !0 }).catch(() => {}), e;
668
696
  }
@@ -675,7 +703,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
675
703
  reason: `write table failed: ${Y(e)}`,
676
704
  path: t
677
705
  })
678
- }), en = (e, t) => n.tryPromise({
706
+ }), ln = (e, t) => n.tryPromise({
679
707
  try: async () => {
680
708
  await (await import("node:fs/promises")).appendFile(e, `${t}\n`);
681
709
  },
@@ -683,13 +711,13 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
683
711
  reason: `append failed: ${Y(t)}`,
684
712
  path: e
685
713
  })
686
- }), tn = (e, t) => n.gen(function* () {
714
+ }), un = (e, t) => n.gen(function* () {
687
715
  let r = [], i = t.ordered.length;
688
716
  for (let a = 0; a < t.ordered.length; a++) {
689
- let o = t.ordered[a], s = Yt(t.snapshot, o), c = Qt(t.snapshot, o);
717
+ let o = t.ordered[a], s = rn(t.snapshot, o), c = sn(t.snapshot, o);
690
718
  if ("refusal" in c) return yield* n.fail(new U({ reason: `export: ${c.refusal}` }));
691
- let u = c.column, d = `${bt}/${o}.ndjson${lt(t.compression)}`;
692
- if (Mt(t.ledger, o)) {
719
+ let u = c.column, d = `${Ot}/${o}.ndjson${_t(t.compression)}`;
720
+ if (Bt(t.ledger, o)) {
693
721
  let e = t.ledger.tables[o];
694
722
  q(t.onProgress, {
695
723
  phase: "export",
@@ -723,7 +751,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
723
751
  chunkSize: t.chunkSize,
724
752
  retry: t.retry,
725
753
  ...f === void 0 ? {} : { where: f }
726
- }), m = Xt(t.snapshot, o), h = m.length === 0 ? p : p.pipe(l.map((e) => Zt(e, m))), g = t.mask ? h.pipe(l.map((e) => ze(e, o, t.mask.actions, t.mask.seed, s))) : h, { rowCount: _, checksum: v } = yield* kt("export", o, a, i, (e) => e.rowCount, $t(Gt(g, s), t.bundleFile(d), t.compression));
754
+ }), m = an(t.snapshot, o), h = m.length === 0 ? p : p.pipe(l.map((e) => on(e, m))), g = t.mask ? h.pipe(l.map((e) => He(e, o, t.mask.actions, t.mask.seed, s))) : h, { rowCount: _, checksum: v } = yield* Lt("export", o, a, i, (e) => e.rowCount, cn($t(g, s), t.bundleFile(d), t.compression));
727
755
  t.ledger.tables[o] = {
728
756
  rowCount: _,
729
757
  checksum: v
@@ -745,82 +773,81 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
745
773
  });
746
774
  }
747
775
  return r;
748
- }), nn = (e) => ({
776
+ }), dn = (e) => ({
749
777
  _tag: "RawSqlFragment",
750
778
  strings: [e],
751
779
  values: []
752
- }), rn = (t, i, a) => n.tryPromise({
780
+ }), fn = (t, i, a) => n.tryPromise({
753
781
  try: () => t.transactional(async (t) => {
754
- if (t.raw) for (let e of xe(i)) await t.raw(nn(e));
782
+ if (t.raw) for (let e of we(i)) await t.raw(dn(e));
755
783
  let o = await n.runPromiseExit(a(t));
756
784
  if (r.isFailure(o)) throw Error(e.pretty(o.cause));
757
785
  return o.value;
758
786
  }),
759
787
  catch: (e) => e instanceof H ? e : new H({ reason: `snapshot export failed: ${Y(e)}` })
760
- }), an = (e) => n.gen(function* () {
761
- let t = e.scope ?? { kind: "all" }, r = ct(e.compression), i = e.chunkSize ?? 1e3, a = e.retryTimes ?? 5, o = s.exponential("50 millis").pipe(s.jittered, s.intersect(s.recurs(a))), c = yield* n.promise(() => import("node:path")), u = (t) => c.join(e.outDir, t);
788
+ }), pn = (e) => n.gen(function* () {
789
+ let t = e.scope ?? { kind: "all" }, r = gt(e.compression), i = e.chunkSize ?? 1e3, a = e.retryTimes ?? 5, o = s.exponential("50 millis").pipe(s.jittered, s.intersect(s.recurs(a))), c = yield* n.promise(() => import("node:path")), l = (t) => c.join(e.outDir, t);
762
790
  yield* n.tryPromise({
763
791
  try: async () => {
764
792
  let t = await import("node:fs/promises");
765
- await t.mkdir(u(bt), { recursive: !0 }), e.assets && await t.mkdir(u(xt), { recursive: !0 });
793
+ await t.mkdir(l(Ot), { recursive: !0 }), e.assets && await t.mkdir(l(kt), { recursive: !0 });
766
794
  },
767
795
  catch: (t) => new H({
768
796
  reason: `mkdir failed: ${Y(t)}`,
769
797
  path: e.outDir
770
798
  })
771
799
  });
772
- let d = u(Ct), f = yield* jt(d), p = e.subset ? et(yield* $e(e.store, e.snapshot, e.subset), e.snapshot) : yield* nt(t, e.snapshot, {
800
+ let u = l(jt), d = yield* zt(u), f = e.subset ? rt(yield* nt(e.store, e.snapshot, e.subset), e.snapshot) : yield* at(t, e.snapshot, {
773
801
  store: e.store,
774
802
  ...e.tenantTables ? { tenantTables: e.tenantTables } : {}
775
- }), m = qt(p.tables, e.snapshot), h = e.consistency ?? "live", g, _;
803
+ }), p = tn(f.tables, e.snapshot), m = e.consistency ?? "live", h, g;
776
804
  if (e.masking) {
777
- let t = e.classification ?? Ce(e.snapshot), r = Ie(m.map((t) => ({
805
+ let t = e.classification ?? Ee(e.snapshot), r = ze(p.map((t) => ({
778
806
  name: t,
779
807
  columns: (e.snapshot.tables.find((e) => e.name === t)?.columns ?? []).map((e) => ({
780
808
  name: e.name,
781
809
  type: e.type
782
810
  }))
783
811
  })), t, e.masking);
784
- if (r.unclassified.length > 0 || r.invalid.length > 0) return yield* n.fail(new Ye({
812
+ if (r.unclassified.length > 0 || r.invalid.length > 0) return yield* n.fail(new Qe({
785
813
  unclassified: r.unclassified,
786
814
  ...r.invalid.length > 0 ? { invalidActions: r.invalid.map((e) => `${e.column}: ${JSON.stringify(e.action)}`) } : {}
787
815
  }));
788
- _ = {
816
+ g = {
789
817
  actions: r.actions,
790
818
  seed: e.masking.seed
791
819
  };
792
820
  let i = Object.entries(r.actions).filter(([, e]) => e !== "keep").map(([e]) => e);
793
- g = {
821
+ h = {
794
822
  ...e.masking.id ? { policyId: e.masking.id } : {},
795
823
  transformed: i
796
824
  };
797
825
  }
798
- let v = {
826
+ let _ = {
799
827
  snapshot: e.snapshot,
800
- ordered: m,
801
- resolved: p,
828
+ ordered: p,
829
+ resolved: f,
802
830
  compression: r,
803
831
  chunkSize: i,
804
832
  retry: o,
805
- ledger: f,
806
- ledgerPath: d,
807
- bundleFile: u,
808
- ..._ ? { mask: _ } : {},
833
+ ledger: d,
834
+ ledgerPath: u,
835
+ bundleFile: l,
836
+ ...g ? { mask: g } : {},
809
837
  ...e.onProgress ? { onProgress: e.onProgress } : {}
810
- }, y = h === "snapshot" ? yield* rn(e.store, e.dialect, (e) => tn(e, v)) : yield* tn(e.store, v), b = 0, x = 0;
838
+ }, v = m === "snapshot" ? yield* fn(e.store, e.dialect, (e) => un(e, _)) : yield* un(e.store, _), y = 0, b = 0;
811
839
  if (e.assets) {
812
- let t = u(St);
813
- yield* l.runForEach(e.assets.list(), (r) => r.key in f.assets ? n.void : e.assets.open(r.key).pipe(n.flatMap((e) => at(e, u(xt))), n.flatMap((e) => {
814
- let i = {
815
- key: r.key,
816
- sha256: e.sha256,
817
- size: e.size,
818
- contentType: e.contentType
819
- };
820
- return b++, x += e.size, f.assets[r.key] = !0, en(t, JSON.stringify(i)).pipe(n.andThen(J(d, f)));
821
- }))).pipe(n.mapError((e) => e instanceof H ? e : new H({ reason: `asset export failed: ${String(e)}` })));
840
+ let t = l(At), r = yield* ft({
841
+ source: e.assets,
842
+ assetsDir: l(kt),
843
+ progress: {
844
+ done: (e) => e in d.assets,
845
+ mark: (e, r) => (d.assets[e] = !0, ln(t, JSON.stringify(r)).pipe(n.andThen(J(u, d))))
846
+ }
847
+ });
848
+ y = r.count, b = r.totalBytes;
822
849
  }
823
- let S = {
850
+ let x = {
824
851
  formatVersion: 1,
825
852
  createdAt: e.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
826
853
  source: {
@@ -828,22 +855,22 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
828
855
  schemaFingerprint: re(e.snapshot)
829
856
  },
830
857
  scope: t,
831
- consistency: h,
858
+ consistency: m,
832
859
  compression: r,
833
- tables: y,
834
- assets: b > 0 ? {
835
- count: b,
836
- totalBytes: x,
837
- index: St
860
+ tables: v,
861
+ assets: y > 0 ? {
862
+ count: y,
863
+ totalBytes: b,
864
+ index: At
838
865
  } : {
839
866
  count: 0,
840
867
  totalBytes: 0
841
868
  },
842
- ...g ? { masking: g } : {}
869
+ ...h ? { masking: h } : {}
843
870
  };
844
871
  return yield* n.tryPromise({
845
872
  try: async () => {
846
- await (await import("node:fs/promises")).writeFile(u(K), _t(S));
873
+ await (await import("node:fs/promises")).writeFile(l(K), Tt(x));
847
874
  },
848
875
  catch: (e) => new H({
849
876
  reason: `manifest write failed: ${Y(e)}`,
@@ -852,14 +879,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
852
879
  }), yield* n.tryPromise({
853
880
  try: async () => {
854
881
  let e = await import("node:fs/promises"), t = await import("node:os");
855
- await e.writeFile(u(yt), Tt(S, { hostname: t.hostname() }));
882
+ await e.writeFile(l(Dt), Nt(x, { hostname: t.hostname() }));
856
883
  },
857
884
  catch: (e) => new H({
858
885
  reason: `readme write failed: ${Y(e)}`,
859
- path: yt
886
+ path: Dt
860
887
  })
861
- }), S;
862
- }), on = (e, t) => {
888
+ }), x;
889
+ }), mn = (e, t) => {
863
890
  let n = new Set(t), r = [];
864
891
  for (let t of e.tables) if (!n.has(t.name)) for (let e of t.columns) {
865
892
  let i = e.references?.table;
@@ -870,7 +897,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
870
897
  });
871
898
  }
872
899
  return r;
873
- }, sn = (e) => {
900
+ }, hn = (e) => {
874
901
  let t = /* @__PURE__ */ new Map();
875
902
  for (let n of e) t.set(n.from, [...t.get(n.from) ?? [], n]);
876
903
  let n = [...t.entries()].map(([e, t]) => {
@@ -878,7 +905,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
878
905
  return ` ${e} (${n} row${n === 1 ? "" : "s"}): ${r}`;
879
906
  });
880
907
  return `replace cannot empty this target: ${t.size} table(s) OUTSIDE the bundle hold rows that reference tables INSIDE it. Emptying the bundle's tables would leave those rows pointing at nothing, and the bundle cannot restore them.\n${n.join("\n")}\nNothing has been deleted. Either re-export with a scope that includes those tables, or use --mode upsert if those rows are meant to survive.`;
881
- }, cn = (e) => {
908
+ }, gn = (e) => {
882
909
  switch (e) {
883
910
  case "id":
884
911
  case "text":
@@ -897,12 +924,12 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
897
924
  case "raw": return "raw";
898
925
  default: return "string";
899
926
  }
900
- }, ln = {
927
+ }, _n = {
901
928
  vector: /* @__PURE__ */ new Set(["postgres"]),
902
929
  array: /* @__PURE__ */ new Set(["postgres"]),
903
930
  interval: /* @__PURE__ */ new Set(["postgres"])
904
- }, un = (e, t, n, r) => {
905
- let i = cn(n);
931
+ }, vn = (e, t, n, r) => {
932
+ let i = gn(n);
906
933
  if (i === "raw") return {
907
934
  table: e,
908
935
  column: t,
@@ -910,7 +937,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
910
937
  severity: "block",
911
938
  reason: `raw() is verbatim source-dialect SQL — it cannot be assumed valid on ${r}`
912
939
  };
913
- let a = ln[i];
940
+ let a = _n[i];
914
941
  return !a || a.has(r) ? null : i === "array" || i === "interval" ? {
915
942
  table: e,
916
943
  column: t,
@@ -924,15 +951,15 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
924
951
  severity: "block",
925
952
  reason: `${i} columns require a ${[...a].join("/")} target; ${r} has no compatible column type`
926
953
  };
927
- }, dn = (e, t, n) => {
954
+ }, yn = (e, t, n) => {
928
955
  if (t === n) return [];
929
956
  let r = [];
930
957
  for (let t of e) for (let [e, i] of Object.entries(t.columnTypes)) {
931
- let a = un(t.name, e, i, n);
958
+ let a = vn(t.name, e, i, n);
932
959
  a && r.push(a);
933
960
  }
934
961
  return r;
935
- }, fn = (e) => `[${e.severity}] ${e.table}.${e.column} (${e.type}): ${e.reason}`, pn = (e) => {
962
+ }, bn = (e) => `[${e.severity}] ${e.table}.${e.column} (${e.type}): ${e.reason}`, xn = (e) => {
936
963
  let t = e.constraint ?? e.column, n = t === void 0 ? "" : ` ${t}`;
937
964
  switch (e.kind) {
938
965
  case "foreignKey": return `foreign key${n}: the referenced row does not exist (import it first, or check the bundle's table order)`;
@@ -941,35 +968,35 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
941
968
  case "notNull": return `not-null constraint${n}: the column requires a value`;
942
969
  case "check": return `check constraint${n}: the row does not satisfy it`;
943
970
  }
944
- }, mn = (e) => {
971
+ }, Sn = (e) => {
945
972
  let t = [e.dbCode, e.dbErrno ?? e.dbNumber].filter((e) => e !== void 0).map(String);
946
973
  return t.length > 0 ? t.join("/") : void 0;
947
- }, hn = "Failed to execute statement", gn = (e) => {
974
+ }, Cn = "Failed to execute statement", wn = (e) => {
948
975
  let t = (e.split("\n", 1)[0] ?? "").trim();
949
976
  for (; t.startsWith("(FiberFailure)");) t = t.slice(14).trim();
950
- return t === `SqlError: ${hn}` ? hn : t;
951
- }, _n = (e) => {
977
+ return t === `SqlError: ${Cn}` ? Cn : t;
978
+ }, Tn = (e) => {
952
979
  let t = String(e?.stack ?? e), n = t.length <= 1200 ? t : `${t.slice(0, 1200)}…`, r = (e, t) => ({
953
980
  reason: e.length <= 300 ? e : `${e.slice(0, 300)}…`,
954
981
  unclassified: t,
955
982
  raw: n
956
- }), i = _(e), a = p(i), o = mn(i), s = o === void 0 ? "" : ` [${o}]`;
957
- if (a !== void 0) return r(`${pn(a)}${s}`, !1);
958
- let c = typeof i.dbMessage == "string" ? i.dbMessage : void 0, l = e?.message, u = gn(typeof l == "string" && l.length > 0 ? l : String(e)), d = c !== void 0 && c !== u && !c.startsWith("SqlError:") ? c : u, f = typeof i.dbCauseChain == "string" ? i.dbCauseChain : void 0, m = f !== void 0 && /[←‖]/.test(f) ? ` (via ${f})` : "";
959
- return r(d === hn || d.length === 0 ? `the database refused the write and the driver gave no detail${s}${m}` : `${d}${s}`, d === hn || d.length === 0);
960
- }, vn = (e) => _n(e).reason, yn = (e) => {
983
+ }), i = _(e), a = p(i), o = Sn(i), s = o === void 0 ? "" : ` [${o}]`;
984
+ if (a !== void 0) return r(`${xn(a)}${s}`, !1);
985
+ let c = typeof i.dbMessage == "string" ? i.dbMessage : void 0, l = e?.message, u = wn(typeof l == "string" && l.length > 0 ? l : String(e)), d = c !== void 0 && c !== u && !c.startsWith("SqlError:") ? c : u, f = typeof i.dbCauseChain == "string" ? i.dbCauseChain : void 0, m = f !== void 0 && /[←‖]/.test(f) ? ` (via ${f})` : "";
986
+ return r(d === Cn || d.length === 0 ? `the database refused the write and the driver gave no detail${s}${m}` : `${d}${s}`, d === Cn || d.length === 0);
987
+ }, En = (e) => Tn(e).reason, Dn = (e) => {
961
988
  let t = _(e), n = p(t);
962
989
  if (n?.kind === "foreignKeyInUse") {
963
- let e = n.constraint ?? n.column, r = e === void 0 ? "" : ` ${e}`, i = mn(t);
990
+ let e = n.constraint ?? n.column, r = e === void 0 ? "" : ` ${e}`, i = Sn(t);
964
991
  return `foreign key${r}: rows elsewhere still reference this table${i === void 0 ? "" : ` [${i}]`}`;
965
992
  }
966
- return vn(e);
967
- }, bn = "_voltro_staging_", X = (e) => `${bn}${e}`, xn = (e) => typeof e.run == "function", Sn = (e) => `staging is not available for this run — loading directly into the target instead: ${e}\n The load therefore holds the destructive transaction open for its whole duration, so a
993
+ return En(e);
994
+ }, On = "_voltro_staging_", X = (e) => `${On}${e}`, kn = (e) => typeof e.run == "function", An = (e) => `staging is not available for this run — loading directly into the target instead: ${e}\n The load therefore holds the destructive transaction open for its whole duration, so a
968
995
  process that dies mid-load depends on the database rolling it back. The rollback capture
969
- written before the first delete is what covers that case.`, Cn = /^[a-zA-Z_][a-zA-Z0-9_]*$/, Z = (e, t) => {
970
- if (!Cn.test(e)) throw Error(`refusing to build SQL for the table name ${JSON.stringify(e)}: it is outside the identifier class the framework allows. A name from a bundle manifest reaches this concatenation, so it is checked here rather than assumed to still be what the declaration validated.`);
996
+ written before the first delete is what covers that case.`, jn = /^[a-zA-Z_][a-zA-Z0-9_]*$/, Z = (e, t) => {
997
+ if (!jn.test(e)) throw Error(`refusing to build SQL for the table name ${JSON.stringify(e)}: it is outside the identifier class the framework allows. A name from a bundle manifest reaches this concatenation, so it is checked here rather than assumed to still be what the declaration validated.`);
971
998
  return t === "mysql" || t === "mariadb" ? `\`${e}\`` : t === "mssql" ? `[${e}]` : `"${e}"`;
972
- }, wn = (e, t) => {
999
+ }, Mn = (e, t) => {
973
1000
  let n = Z(e, t), r = Z(X(e), t);
974
1001
  switch (t) {
975
1002
  case "postgres": return `CREATE TABLE ${r} (LIKE ${n})`;
@@ -978,10 +1005,10 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
978
1005
  case "sqlite": return `CREATE TABLE ${r} AS SELECT * FROM ${n} WHERE 0`;
979
1006
  case "mssql": return `SELECT * INTO ${r} FROM ${n} WHERE 1 = 0`;
980
1007
  }
981
- }, Tn = (e, t) => {
1008
+ }, Nn = (e, t) => {
982
1009
  let n = Z(X(e), t);
983
1010
  return t === "mssql" ? `IF OBJECT_ID('${X(e)}', 'U') IS NOT NULL DROP TABLE ${n}` : `DROP TABLE IF EXISTS ${n}`;
984
- }, En = (e, t) => {
1011
+ }, Pn = (e, t) => {
985
1012
  let n = t === "mysql" || t === "mariadb", r = [];
986
1013
  n && r.push("SET FOREIGN_KEY_CHECKS = 0");
987
1014
  for (let n of [...e].reverse()) r.push(`DELETE FROM ${Z(n.name, t)}`);
@@ -991,7 +1018,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
991
1018
  r.push(`INSERT INTO ${Z(n.name, t)} (${e}) SELECT ${e} FROM ${Z(X(n.name), t)}`);
992
1019
  }
993
1020
  return n && r.push("SET FOREIGN_KEY_CHECKS = 1"), r;
994
- }, Dn = (e, t) => {
1021
+ }, Fn = (e, t) => {
995
1022
  let n = [], r = () => {
996
1023
  for (let e of n) t.unregisterTable(e);
997
1024
  };
@@ -1013,7 +1040,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1013
1040
  staged: n,
1014
1041
  undo: r
1015
1042
  };
1016
- }, On = (e, t) => {
1043
+ }, In = (e, t) => {
1017
1044
  let n = new Set(t), r = [];
1018
1045
  for (let t of e.tables) {
1019
1046
  if (!n.has(t.name)) continue;
@@ -1030,22 +1057,22 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1030
1057
  }
1031
1058
  }
1032
1059
  return r;
1033
- }, kn = (e, t) => {
1060
+ }, Ln = (e, t) => {
1034
1061
  let n = Z(X(e.from), t), r = Z(X(e.to), t), i = Z(e.column, t), a = Z(e.toColumn, t);
1035
1062
  return `SELECT ${Z(e.primaryKey, t)} AS pk, ${i} AS value FROM ${n} c WHERE ${i} IS NOT NULL AND NOT EXISTS (SELECT 1 FROM ${r} p WHERE p.${a} = c.${i})`;
1036
- }, An = (e) => {
1063
+ }, Rn = (e) => {
1037
1064
  if (e.length === 0) return;
1038
1065
  let t = e.slice(0, 20), n = t.map((e) => ` ${e.table}.${e.primaryKey}: ${e.column} = ${JSON.stringify(e.value)} — no such row in ${e.references}`);
1039
1066
  return `the swap could not run: ${e.length} row(s) in the bundle reference a row the bundle does not carry.\n${n.join("\n")}\n` + (e.length > t.length ? ` … and ${e.length - t.length} more\n` : "") + " The target is UNCHANGED — the swap runs in one transaction and none of it committed.\n Every offending row is listed above rather than only the first, so this can be fixed in one pass.";
1040
- }, jn = async (e, t) => {
1041
- t.length !== 0 && await e.run(P.SqlClient.pipe(n.flatMap((e) => n.forEach(t, (t) => e.unsafe(t), { discard: !0 }))));
1042
- }, Mn = async (e, t, r) => {
1043
- let i = En(t, r);
1044
- i.length !== 0 && await e.run(P.SqlClient.pipe(n.flatMap((e) => e.withTransaction(n.forEach(i, (t) => e.unsafe(t), { discard: !0 })))));
1045
- }, Nn = async (e, t, r) => {
1067
+ }, zn = async (e, t) => {
1068
+ t.length !== 0 && await e.run(_e.SqlClient.pipe(n.flatMap((e) => n.forEach(t, (t) => e.unsafe(t), { discard: !0 }))));
1069
+ }, Bn = async (e, t, r) => {
1070
+ let i = Pn(t, r);
1071
+ i.length !== 0 && await e.run(_e.SqlClient.pipe(n.flatMap((e) => e.withTransaction(n.forEach(i, (t) => e.unsafe(t), { discard: !0 })))));
1072
+ }, Vn = async (e, t, r) => {
1046
1073
  let i = [];
1047
1074
  for (let a of t) {
1048
- let t = await e.run(P.SqlClient.pipe(n.flatMap((e) => e.unsafe(kn(a, r)))));
1075
+ let t = await e.run(_e.SqlClient.pipe(n.flatMap((e) => e.unsafe(Ln(a, r)))));
1049
1076
  for (let e of t) i.push({
1050
1077
  table: a.from,
1051
1078
  primaryKey: String(e.pk ?? ""),
@@ -1055,14 +1082,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1055
1082
  });
1056
1083
  }
1057
1084
  return i;
1058
- }, Pn = (e, t) => {
1085
+ }, Hn = (e, t) => {
1059
1086
  let n = new Map(t.map((e, t) => [e, t]));
1060
1087
  return e.filter((e) => {
1061
1088
  if (e.from === e.to) return !1;
1062
1089
  let t = n.get(e.from), r = n.get(e.to);
1063
1090
  return t === void 0 || r === void 0 ? !1 : r > t;
1064
1091
  });
1065
- }, Fn = (e) => e === "mysql" || e === "mariadb", In = (e) => {
1092
+ }, Un = (e) => e === "mysql" || e === "mariadb", Wn = (e) => {
1066
1093
  if (e.mode !== "replace") return {
1067
1094
  active: !1,
1068
1095
  tables: [],
@@ -1112,7 +1139,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1112
1139
  tables: [],
1113
1140
  blocker: "every table in the bundle is one that describes a deployment, so there is nothing for a staged swap to move."
1114
1141
  };
1115
- let s = o.map((e) => e.name), c = Fn(t) ? [] : Pn(On(n, s), s);
1142
+ let s = o.map((e) => e.name), c = Un(t) ? [] : Hn(In(n, s), s);
1116
1143
  return c.length > 0 ? {
1117
1144
  active: !1,
1118
1145
  tables: [],
@@ -1121,7 +1148,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1121
1148
  active: !0,
1122
1149
  tables: o
1123
1150
  };
1124
- }, Ln = (e) => n.gen(function* () {
1151
+ }, Gn = (e) => n.gen(function* () {
1125
1152
  if (e.mode !== "replace" || e.dir === void 0 || e.tables.length === 0) return;
1126
1153
  if (e.snapshot === void 0) return yield* n.fail(new H({
1127
1154
  reason: "rollback capture needs the TARGET's schema, and this run has none.\n `--mode replace` empties the target first, so a run without a capture can leave it\n emptied and unfilled if the process does not survive to roll back. Pass the target\n snapshot, or `--no-rollback` to accept that risk deliberately.",
@@ -1134,7 +1161,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1134
1161
  if (t.tables.length === 0) return;
1135
1162
  e.onWarn?.(`capturing the target's current rows before emptying it → ${e.dir}\n This is what a failed replace is restored FROM. It is written before the first delete,
1136
1163
  so it survives a run whose process does not.`);
1137
- let r = yield* an({
1164
+ let r = yield* pn({
1138
1165
  store: e.store,
1139
1166
  snapshot: t,
1140
1167
  dialect: e.dialect ?? "unknown",
@@ -1150,18 +1177,18 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1150
1177
  rows: r.tables.reduce((e, t) => e + t.rowCount, 0),
1151
1178
  tables: r.tables.length
1152
1179
  };
1153
- }), Rn = (e) => `rollback capture: ${e.rows} row(s) across ${e.tables} table(s) → ${e.dir}\n If this run does not finish, restore with: voltro data import ${e.dir} --mode replace`, zn = (e, t) => e.tables.find((e) => e.name === t), Bn = (e, t) => new Map((zn(e, t)?.columns ?? []).map((e) => [e.name, e])), Vn = /__dropped_\d+$/, Hn = (e, t) => {
1180
+ }), Kn = (e) => `rollback capture: ${e.rows} row(s) across ${e.tables} table(s) → ${e.dir}\n If this run does not finish, restore with: voltro data import ${e.dir} --mode replace`, qn = (e, t) => e.tables.find((e) => e.name === t), Jn = (e, t) => new Map((qn(e, t)?.columns ?? []).map((e) => [e.name, e])), Yn = /__dropped_\d+$/, Xn = (e, t) => {
1154
1181
  let n = [];
1155
1182
  for (let r of [...e.tables].sort((e, t) => e.name.localeCompare(t.name))) {
1156
- if (zn(t, r.name) === void 0) {
1183
+ if (qn(t, r.name) === void 0) {
1157
1184
  n.push(`table '${r.name}' is in the bundle but MISSING from the target — its rows have nowhere to go`);
1158
1185
  continue;
1159
1186
  }
1160
- let e = Bn(t, r.name), i = new Map(r.columns.map((e) => [e.name, e]));
1187
+ let e = Jn(t, r.name), i = new Map(r.columns.map((e) => [e.name, e]));
1161
1188
  for (let [t, a] of i) {
1162
1189
  let i = e.get(t);
1163
1190
  if (i === void 0) {
1164
- n.push(Vn.test(t) ? `${r.name}.${t}: a soft-dropped column, present only in the SOURCE — reclaim it there (voltro db gc-snapshots --before <date>) or re-export without it; the target is not missing anything` : `${r.name}.${t}: in the bundle, MISSING from the target — the value has nowhere to go`);
1191
+ n.push(Yn.test(t) ? `${r.name}.${t}: a soft-dropped column, present only in the SOURCE — reclaim it there (voltro db gc-snapshots --before <date>) or re-export without it; the target is not missing anything` : `${r.name}.${t}: in the bundle, MISSING from the target — the value has nowhere to go`);
1165
1192
  continue;
1166
1193
  }
1167
1194
  i.type !== a.type && n.push(`${r.name}.${t}: type '${a.type}' (bundle) vs '${i.type}' (target)`);
@@ -1169,7 +1196,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1169
1196
  for (let [t, a] of e) i.has(t) || !a.nullable && !a.hasDefault && n.push(`${r.name}.${t}: the target requires it (NOT NULL, no default) and the bundle carries no value — every row of this table would fail`);
1170
1197
  }
1171
1198
  return n.length > 30 ? [...n.slice(0, 30), `… and ${n.length - 30} more difference(s)`] : n;
1172
- }, Un = (e, t, n) => {
1199
+ }, Zn = (e, t, n) => {
1173
1200
  let r = re(t);
1174
1201
  if (r === e || n === void 0) return {
1175
1202
  drifted: !1,
@@ -1177,14 +1204,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1177
1204
  targetFingerprint: r,
1178
1205
  diff: []
1179
1206
  };
1180
- let i = Hn(n, t);
1207
+ let i = Xn(n, t);
1181
1208
  return {
1182
1209
  drifted: i.length > 0,
1183
1210
  bundleFingerprint: e,
1184
1211
  targetFingerprint: r,
1185
1212
  diff: i
1186
1213
  };
1187
- }, Wn = 2e3, Gn = 200, Kn = /* @__PURE__ */ new Set([
1214
+ }, Qn = 2e3, $n = 200, er = /* @__PURE__ */ new Set([
1188
1215
  "BundleError",
1189
1216
  "CodecError",
1190
1217
  "IntegrityError",
@@ -1193,29 +1220,29 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1193
1220
  "RowsRefusedError",
1194
1221
  "SchemaDriftError",
1195
1222
  "StorageError"
1196
- ]), qn = (t) => {
1223
+ ]), tr = (t) => {
1197
1224
  let n = o.isFiberFailure(t) ? [...e.failures(t[o.FiberFailureCauseId]), ...e.defects(t[o.FiberFailureCauseId])] : [t];
1198
1225
  for (let e of n) {
1199
1226
  let t = e?._tag;
1200
- if (typeof t == "string" && Kn.has(t)) return e;
1227
+ if (typeof t == "string" && er.has(t)) return e;
1201
1228
  if (o.isFiberFailure(e)) {
1202
- let t = qn(e);
1229
+ let t = tr(e);
1203
1230
  if (t) return t;
1204
1231
  }
1205
1232
  }
1206
- }, Jn = (t) => [...e.failures(t)][0] ?? Error(e.pretty(t)), Yn = (e) => n.tryPromise({
1233
+ }, nr = (t) => [...e.failures(t)][0] ?? Error(e.pretty(t)), rr = (e) => n.tryPromise({
1207
1234
  try: async () => {
1208
1235
  let t = await import("node:fs/promises"), n = await import("node:path");
1209
- return vt(await t.readFile(n.join(e, K), "utf8"));
1236
+ return Et(await t.readFile(n.join(e, K), "utf8"));
1210
1237
  },
1211
1238
  catch: (e) => new H({
1212
1239
  reason: `manifest read/parse failed: ${String(e?.message ?? e)}`,
1213
1240
  path: K
1214
1241
  })
1215
- }), Xn = (e) => {
1242
+ }), ir = (e) => {
1216
1243
  let t;
1217
1244
  return n.gen(function* () {
1218
- let i = yield* n.promise(() => import("node:path")), a = yield* Yn(e.bundleDir);
1245
+ let i = yield* n.promise(() => import("node:path")), a = yield* rr(e.bundleDir);
1219
1246
  if (a.formatVersion !== 1) return yield* n.fail(new H({ reason: `unsupported bundle formatVersion ${a.formatVersion} (expected 1)` }));
1220
1247
  if (e.tables !== void 0) {
1221
1248
  let t = new Set(a.tables.map((e) => e.name)), r = e.tables.filter((e) => !t.has(e));
@@ -1236,9 +1263,9 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1236
1263
  unique: !1,
1237
1264
  hasDefault: !1
1238
1265
  }))
1239
- })) }, r = Un(s.source.schemaFingerprint, e.targetSnapshot, t);
1266
+ })) }, r = Zn(s.source.schemaFingerprint, e.targetSnapshot, t);
1240
1267
  if (r.drifted) {
1241
- if (!e.force) return yield* n.fail(new Je({
1268
+ if (!e.force) return yield* n.fail(new Ze({
1242
1269
  bundleFingerprint: r.bundleFingerprint,
1243
1270
  targetFingerprint: r.targetFingerprint,
1244
1271
  diff: r.diff
@@ -1247,15 +1274,15 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1247
1274
  }
1248
1275
  }
1249
1276
  if (e.targetDialect && e.targetDialect !== s.source.dialect) {
1250
- let t = dn(s.tables, s.source.dialect, e.targetDialect).filter((e) => e.severity === "block");
1251
- if (t.length > 0 && !e.allowIncompatible) return yield* n.fail(new Ze({
1277
+ let t = yn(s.tables, s.source.dialect, e.targetDialect).filter((e) => e.severity === "block");
1278
+ if (t.length > 0 && !e.allowIncompatible) return yield* n.fail(new et({
1252
1279
  sourceDialect: s.source.dialect,
1253
1280
  targetDialect: e.targetDialect,
1254
- blocking: t.map(fn)
1281
+ blocking: t.map(bn)
1255
1282
  }));
1256
1283
  }
1257
- let c = e.verify ?? !0, p = e.mode ?? "upsert", g = e.atomic ?? p === "replace", _ = e.onConflict ?? "skip", y = e.ledgerPath ?? i.join(e.bundleDir, ".import..ledger.json"), x = yield* jt(y);
1258
- if (p === "replace" && s.scope.kind !== "all") return yield* n.fail(new Xe({
1284
+ let c = e.verify ?? !0, p = e.mode ?? "upsert", g = e.atomic ?? p === "replace", _ = e.onConflict ?? "skip", y = e.ledgerPath ?? i.join(e.bundleDir, ".import..ledger.json"), x = yield* zt(y);
1285
+ if (p === "replace" && s.scope.kind !== "all") return yield* n.fail(new $e({
1259
1286
  mode: p,
1260
1287
  reason: `replace refuses a partial bundle (scope='${s.scope.kind}') — truncating would delete rows not in the bundle. Use --mode upsert, or re-export with full scope. To leave specific tables out of a FULL export, use \`--exclude a,b\`: it keeps the scope \`all\` and records what it left out.`
1261
1288
  }));
@@ -1267,8 +1294,8 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1267
1294
  if (p === "replace") {
1268
1295
  let t = s.tables.map((e) => e.name), r = e.store.incomingForeignKeys ? yield* n.tryPromise({
1269
1296
  try: () => e.store.incomingForeignKeys(t),
1270
- catch: (e) => new H({ reason: `foreign-key pre-flight failed: ${yn(e)}` })
1271
- }) : e.targetSnapshot === void 0 ? [] : on(e.targetSnapshot, t), i = [], a = /* @__PURE__ */ new Map();
1297
+ catch: (e) => new H({ reason: `foreign-key pre-flight failed: ${Dn(e)}` })
1298
+ }) : e.targetSnapshot === void 0 ? [] : mn(e.targetSnapshot, t), i = [], a = /* @__PURE__ */ new Map();
1272
1299
  for (let t of r) {
1273
1300
  if (!a.has(t.from)) {
1274
1301
  let r = yield* n.tryPromise({
@@ -1290,9 +1317,9 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1290
1317
  rowCount: r
1291
1318
  });
1292
1319
  }
1293
- if (i.length > 0) return yield* n.fail(new Xe({
1320
+ if (i.length > 0) return yield* n.fail(new $e({
1294
1321
  mode: p,
1295
- reason: sn(i)
1322
+ reason: hn(i)
1296
1323
  }));
1297
1324
  }
1298
1325
  if (e.dryRun === !0) return e.traceId !== void 0 && (yield* n.promise(() => e.store.update(u, e.traceId, {
@@ -1320,14 +1347,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1320
1347
  for (let e of n) e in t && (r ??= { ...t }, delete r[e]);
1321
1348
  return r ?? t;
1322
1349
  }, T = (e, t, n, r = !1) => {
1323
- let i = j ? X(t.name) : t.name, a = t.primaryKey, o = re(t.name, n);
1350
+ let i = k ? X(t.name) : t.name, a = t.primaryKey, o = re(t.name, n);
1324
1351
  return p === "append" ? _ === "fail" ? e.insert(i, o) : e.insertIgnore(i, o, { conflictColumns: [a] }) : p === "replace" ? r ? e.upsert(i, o, { conflictColumns: [a] }) : e.insert(i, o) : e.upsert(i, o, { conflictColumns: [a] });
1325
- }, ie = (e, t) => e.savepoint ? e.savepoint(t) : t(), E = 0, ae = (t, n, r) => {
1326
- r.unclassified && (E++, !(E > 3) && e.onWarn?.(`row refused with no driver detail — table '${t.name}', row '${String(n.id ?? "?")}'. The full rendering follows so the LAYER that refused is on the record; it is logged, never returned. ${r.raw}` + (E === 3 ? " (further unclassified refusals are counted, not logged)" : "")));
1327
- }, D = (e, t, r = !0) => n.tryPromise({
1352
+ }, E = (e, t) => e.savepoint ? e.savepoint(t) : t(), D = 0, ie = (t, n, r) => {
1353
+ r.unclassified && (D++, !(D > 3) && e.onWarn?.(`row refused with no driver detail — table '${t.name}', row '${String(n.id ?? "?")}'. The full rendering follows so the LAYER that refused is on the record; it is logged, never returned. ${r.raw}` + (D === 3 ? " (further unclassified refusals are counted, not logged)" : "")));
1354
+ }, ae = (e, t, r = !0) => n.tryPromise({
1328
1355
  try: e,
1329
- catch: (e) => _n(e)
1330
- }).pipe(n.map(() => !0), n.catchAll((e) => n.sync(() => (r && (t.reason = e.reason, ae(t.entry, t.row, e)), !1)))), oe = (e) => {
1356
+ catch: (e) => Tn(e)
1357
+ }).pipe(n.map(() => !0), n.catchAll((e) => n.sync(() => (r && (t.reason = e.reason, ie(t.entry, t.row, e)), !1)))), oe = (e) => {
1331
1358
  let t = Object.entries(e.entry.columnTypes).filter(([t, n]) => n === "reference" && e.row[t] !== null && e.row[t] !== void 0).map(([e]) => e);
1332
1359
  if (t.length !== 0) return {
1333
1360
  ...e.row,
@@ -1351,7 +1378,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1351
1378
  };
1352
1379
  t.refused++, e.derived || t.primary++, a.set(e.table, t);
1353
1380
  }
1354
- return new qe({
1381
+ return new Xe({
1355
1382
  rows: i.slice(0, 20),
1356
1383
  primaryCount: r.filter((e) => !e.derived).length,
1357
1384
  totalCount: e.length,
@@ -1361,38 +1388,38 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1361
1388
  primary: t.primary
1362
1389
  })).sort((e, t) => t.refused - e.refused || e.table.localeCompare(t.table)).slice(0, 100)
1363
1390
  });
1364
- }, le = (e, t) => n.gen(function* () {
1391
+ }, ce = (e, t) => n.gen(function* () {
1365
1392
  let r = t, i = [], a = !0;
1366
1393
  for (; r.length > 0 && a;) {
1367
1394
  a = !1;
1368
1395
  let t = [];
1369
- for (let n of r) (yield* D(() => ie(e, () => T(e, n.entry, n.row, !0)), n)) ? a = !0 : t.push(n);
1396
+ for (let n of r) (yield* ae(() => E(e, () => T(e, n.entry, n.row, !0)), n)) ? a = !0 : t.push(n);
1370
1397
  if (!a && t.length > 0) for (let n = t.length - 1; n >= 0; n--) {
1371
1398
  let r = t[n], o = oe(r);
1372
- o !== void 0 && (yield* D(() => ie(e, () => T(e, r.entry, o, !0)), r, !1)) && (i.push(r), t.splice(n, 1), a = !0);
1399
+ o !== void 0 && (yield* ae(() => E(e, () => T(e, r.entry, o, !0)), r, !1)) && (i.push(r), t.splice(n, 1), a = !0);
1373
1400
  }
1374
1401
  r = t;
1375
1402
  }
1376
- for (let t of i) (yield* D(() => ie(e, () => e.upsert(t.entry.name, t.row, { conflictColumns: [t.entry.primaryKey] })), t)) || (r = [...r, t]);
1403
+ for (let t of i) (yield* ae(() => E(e, () => e.upsert(t.entry.name, t.row, { conflictColumns: [t.entry.primaryKey] })), t)) || (r = [...r, t]);
1377
1404
  if (r.length > 0) return yield* n.fail(se(r));
1378
1405
  }), O = (() => {
1379
1406
  let t = e.targetDialect;
1380
1407
  return t === "postgres" || t === "mysql" || t === "mariadb" || t === "sqlite" || t === "mssql" ? t : void 0;
1381
- })(), k = In({
1408
+ })(), ue = Wn({
1382
1409
  mode: p,
1383
1410
  ...e.targetDialect === void 0 ? {} : { targetDialect: e.targetDialect },
1384
1411
  ...e.targetSnapshot === void 0 ? {} : { targetSnapshot: e.targetSnapshot },
1385
1412
  bundleTables: s.tables.map((e) => e.name),
1386
1413
  isSkipped: V,
1387
- canRunSql: xn(e.store)
1388
- }), A = k.tables, ue = s.tables.filter((e) => !V(e.name) && S(e.name)).map((e) => e.name), j = k.active, de = !1, M = 0, N = 0, pe, P = 0, F = 0, me = (t, r) => n.gen(function* () {
1389
- if (p === "replace" && !j && !(r && x.truncated)) {
1414
+ canRunSql: kn(e.store)
1415
+ }), de = ue.tables, fe = s.tables.filter((e) => !V(e.name) && S(e.name)).map((e) => e.name), k = ue.active, pe = !1, A = 0, j = 0, he, M = 0, N = 0, ge = (t, r) => n.gen(function* () {
1416
+ if (p === "replace" && !k && !(r && x.truncated)) {
1390
1417
  e.recordInterruption === !0 && (yield* n.tryPromise({
1391
1418
  try: () => t.insert(d, {
1392
- id: m("repl", he),
1393
- startedAt: ge,
1419
+ id: m("repl", _e),
1420
+ startedAt: P,
1394
1421
  tables: String(s.tables.length),
1395
- capture: I?.dir ?? null,
1422
+ capture: F?.dir ?? null,
1396
1423
  via: e.via ?? "direct"
1397
1424
  }),
1398
1425
  catch: (e) => new H({ reason: `could not record that this replace started: ${String(e?.message ?? e)}\n The marker is what makes an interrupted run visible instead of silent, so the run does
@@ -1405,7 +1432,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1405
1432
  });
1406
1433
  yield* n.tryPromise({
1407
1434
  try: o,
1408
- catch: (e) => new H({ reason: `emptying the target for --mode replace failed (nothing was deleted): ${yn(e)}` })
1435
+ catch: (e) => new H({ reason: `emptying the target for --mode replace failed (nothing was deleted): ${Dn(e)}` })
1409
1436
  }), r && (x.truncated = !0, yield* J(y, x));
1410
1437
  }
1411
1438
  let a = [], o = [], u = [], f = [], h = s.tables.length;
@@ -1416,7 +1443,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1416
1443
  continue;
1417
1444
  }
1418
1445
  if (r && m.name in x.tables) {
1419
- u.push(m.name), F++, P += x.tables[m.name].rowCount, q(e.onProgress, {
1446
+ u.push(m.name), N++, M += x.tables[m.name].rowCount, q(e.onProgress, {
1420
1447
  phase: "import",
1421
1448
  table: m.name,
1422
1449
  index: d,
@@ -1438,22 +1465,22 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1438
1465
  total: m.rowCount
1439
1466
  });
1440
1467
  let v = a.length, b = n.gen(function* () {
1441
- let { createHash: r } = yield* n.promise(() => import("node:crypto")), i = r("sha256"), o = 0, c = ce("bundle", () => fe(_).pipe(dt(s.compression))).pipe(l.tap((e) => n.sync(() => i.update(e)))), u = async (e) => {
1468
+ let { createHash: r } = yield* n.promise(() => import("node:crypto")), i = r("sha256"), o = 0, c = me("bundle", () => le(_).pipe(yt(s.compression))).pipe(l.tap((e) => n.sync(() => i.update(e)))), u = async (e) => {
1442
1469
  let n = {
1443
1470
  entry: m,
1444
1471
  row: e,
1445
1472
  reason: ""
1446
1473
  };
1447
1474
  try {
1448
- await ie(t, () => T(t, m, e));
1475
+ await E(t, () => T(t, m, e));
1449
1476
  } catch (t) {
1450
- let r = _n(t);
1451
- n.reason = r.reason, ae(m, e, r), a.push(n);
1477
+ let r = Tn(t);
1478
+ n.reason = r.reason, ie(m, e, r), a.push(n);
1452
1479
  }
1453
1480
  }, d = yield* n.promise(async () => {
1454
1481
  let n = e.copyLoader;
1455
1482
  if (!n || n.dialect !== "postgres") return !1;
1456
- if (g) return de || (de = !0, e.onWarn?.("bulk COPY is off for this run: it needs its own connection and this import runs in ONE transaction (the default for --mode replace, so a failure mid-load cannot leave the target emptied and unfilled). Pass --no-atomic to trade that guarantee back for COPY.")), !1;
1483
+ if (g) return pe || (pe = !0, e.onWarn?.("bulk COPY is off for this run: it needs its own connection and this import runs in ONE transaction (the default for --mode replace, so a failure mid-load cannot leave the target emptied and unfilled). Pass --no-atomic to trade that guarantee back for COPY.")), !1;
1457
1484
  if (p === "replace") return !0;
1458
1485
  if (p !== "upsert") return !1;
1459
1486
  try {
@@ -1495,7 +1522,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1495
1522
  for (let t of e) await u(t);
1496
1523
  }
1497
1524
  };
1498
- return yield* l.runForEach(Kt(c, m.name, m.columnTypes), (e) => n.promise(async () => {
1525
+ return yield* l.runForEach(en(c, m.name, m.columnTypes), (e) => n.promise(async () => {
1499
1526
  if (o++, d) {
1500
1527
  v.push(e), v.length >= h && await y();
1501
1528
  return;
@@ -1509,14 +1536,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1509
1536
  rowCount: o,
1510
1537
  checksum: i.digest("hex")
1511
1538
  };
1512
- }), { rowCount: S, checksum: C } = yield* kt("import", m.name, d, h, (e) => e.rowCount, b);
1539
+ }), { rowCount: S, checksum: C } = yield* Lt("import", m.name, d, h, (e) => e.rowCount, b);
1513
1540
  if (c) {
1514
- if (C !== m.checksum) return yield* n.fail(new Ge({
1541
+ if (C !== m.checksum) return yield* n.fail(new Je({
1515
1542
  what: `table ${m.name} checksum`,
1516
1543
  expected: m.checksum,
1517
1544
  actual: C
1518
1545
  }));
1519
- if (S !== m.rowCount) return yield* n.fail(new Ge({
1546
+ if (S !== m.rowCount) return yield* n.fail(new Je({
1520
1547
  what: `table ${m.name} rowCount`,
1521
1548
  expected: String(m.rowCount),
1522
1549
  actual: String(S)
@@ -1530,7 +1557,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1530
1557
  event: "done",
1531
1558
  rowsDone: S,
1532
1559
  total: m.rowCount
1533
- }), N++, M += S, pe?.(), r && (a.length > v ? o.push({
1560
+ }), j++, A += S, he?.(), r && (a.length > v ? o.push({
1534
1561
  name: m.name,
1535
1562
  rowCount: S
1536
1563
  }) : (x.tables[m.name] = {
@@ -1538,10 +1565,10 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1538
1565
  checksum: m.checksum
1539
1566
  }, yield* J(y, x)));
1540
1567
  }
1541
- if (a.length > 0 && (yield* le(t, a)), p === "replace" && (yield* n.promise(() => t.deleteMany(d, { where: {
1568
+ if (a.length > 0 && (yield* ce(t, a)), p === "replace" && (yield* n.promise(() => t.deleteMany(d, { where: {
1542
1569
  column: "startedAt",
1543
1570
  op: "lte",
1544
- value: ge
1571
+ value: P
1545
1572
  } }).then(() => void 0, () => void 0))), r && o.length > 0) {
1546
1573
  for (let e of o) {
1547
1574
  let t = s.tables.find((t) => t.name === e.name);
@@ -1553,14 +1580,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1553
1580
  yield* J(y, x);
1554
1581
  }
1555
1582
  {
1556
- let t = Ue(f, "skipped");
1583
+ let t = Ke(f, "skipped");
1557
1584
  t !== void 0 && e.onWarn?.(t);
1558
1585
  }
1559
1586
  if (u.length > 0) {
1560
1587
  let t = u.length === s.tables.length;
1561
1588
  e.onWarn?.(`resume: ${u.length} of ${s.tables.length} table(s) were already applied by an earlier run of THIS bundle directory, so this run wrote NO rows for them${t ? " — that is every table in the bundle, so nothing was written at all" : ""}. Tables: ${u.join(", ")}. Delete ${y} to force a full re-import.`);
1562
1589
  }
1563
- }), he = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`, ge = /* @__PURE__ */ new Date(), I = yield* Ln({
1590
+ }), _e = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`, P = /* @__PURE__ */ new Date(), F = yield* Gn({
1564
1591
  store: e.store,
1565
1592
  mode: p,
1566
1593
  dir: e.rollbackDir,
@@ -1569,16 +1596,16 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1569
1596
  tables: s.tables.map((e) => e.name).filter((e) => !V(e)),
1570
1597
  onWarn: e.onWarn
1571
1598
  });
1572
- I !== void 0 && (e.onRollbackCaptured !== void 0 && (yield* n.tryPromise({
1573
- try: () => e.onRollbackCaptured(I),
1599
+ F !== void 0 && (e.onRollbackCaptured !== void 0 && (yield* n.tryPromise({
1600
+ try: () => e.onRollbackCaptured(F),
1574
1601
  catch: (e) => new H({
1575
1602
  reason: `the rollback capture could not be stored durably, so the import did not start and the target is untouched: ${String(e?.message ?? e)}\n The capture only helps if it outlives this process — that is the failure it exists for.`,
1576
- path: I.dir
1603
+ path: F.dir
1577
1604
  })
1578
- })), e.onWarn?.(Rn(I)));
1579
- let _e = (e) => p === "replace" ? ee(e) : e(), L = (e) => p === "replace" ? te(e) : e, R = e.traceId ?? m("dimp", `${Date.now()}-${s.source.schemaFingerprint ?? ""}`), ve = e.traceId !== void 0, ye = (e.targetSnapshot?.tables.some((e) => e.name === u) ?? !1) || v(u) !== void 0;
1580
- ye && h(f), ye && e.traceId === void 0 && (yield* n.promise(() => e.store.insert(u, {
1581
- id: R,
1605
+ })), e.onWarn?.(Kn(F)));
1606
+ let ve = (e) => p === "replace" ? ee(e) : e(), I = (e) => p === "replace" ? te(e) : e, L = e.traceId ?? m("dimp", `${Date.now()}-${s.source.schemaFingerprint ?? ""}`), ye = e.traceId !== void 0, R = (e.targetSnapshot?.tables.some((e) => e.name === u) ?? !1) || v(u) !== void 0;
1607
+ R && h(f), R && e.traceId === void 0 && (yield* n.promise(() => e.store.insert(u, {
1608
+ id: L,
1582
1609
  mode: p,
1583
1610
  via: e.via ?? "direct",
1584
1611
  direction: "import",
@@ -1586,38 +1613,38 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1586
1613
  sourceFingerprint: s.source.schemaFingerprint ?? null,
1587
1614
  tablesWritten: 0,
1588
1615
  rowsWritten: 0,
1589
- staged: p === "replace" ? j : null
1616
+ staged: p === "replace" ? k : null
1590
1617
  }).then(() => {
1591
- ve = !0;
1618
+ ye = !0;
1592
1619
  }, (t) => {
1593
1620
  e.onWarn?.(`the import trace could not be written (${String(t?.message ?? t)}).\n The import continues — this is a record of what happened, not a safety check. Run
1594
1621
  \`voltro db apply\` so the next one is recorded.`);
1595
- }))), e.traceId !== void 0 && ye && (yield* n.promise(() => e.store.update(u, R, {
1596
- staged: p === "replace" ? j : null,
1622
+ }))), e.traceId !== void 0 && R && (yield* n.promise(() => e.store.update(u, L, {
1623
+ staged: p === "replace" ? k : null,
1597
1624
  sourceFingerprint: s.source.schemaFingerprint ?? null
1598
1625
  }).then(() => void 0, () => void 0)));
1599
1626
  let be = 0, xe = !1;
1600
- pe = () => {
1601
- if (!ve || xe) return;
1627
+ he = () => {
1628
+ if (!ye || xe) return;
1602
1629
  let t = Date.now();
1603
- t - be < Wn || (be = t, e.store.update(u, R, {
1604
- tablesWritten: N,
1605
- rowsWritten: M
1630
+ t - be < Qn || (be = t, e.store.update(u, L, {
1631
+ tablesWritten: j,
1632
+ rowsWritten: A
1606
1633
  }).then(() => void 0, () => {
1607
1634
  xe = !0;
1608
1635
  }));
1609
1636
  };
1610
- let Se = (t) => ve ? e.store.update(u, R, {
1637
+ let Se = (t) => ye ? e.store.update(u, L, {
1611
1638
  finishedAt: t === null ? /* @__PURE__ */ new Date() : null,
1612
- tablesWritten: N,
1613
- rowsWritten: M,
1639
+ tablesWritten: j,
1640
+ rowsWritten: A,
1614
1641
  failure: t
1615
1642
  }).then(() => void 0, () => void 0) : Promise.resolve();
1616
- if (t = (e) => Se(e), p === "replace" && !j && k.blocker !== void 0 && e.onWarn?.(Sn(k.blocker)), p === "replace" && ue.length > 0 && e.onWarn?.(`write recorders are SUSPENDED for this replace (${ue.length} table(s) have one).\n A replace sets a state rather than changing rows, so a per-row history entry would describe
1643
+ if (t = (e) => Se(e), p === "replace" && !k && ue.blocker !== void 0 && e.onWarn?.(An(ue.blocker)), p === "replace" && fe.length > 0 && e.onWarn?.(`write recorders are SUSPENDED for this replace (${fe.length} table(s) have one).\n A replace sets a state rather than changing rows, so a per-row history entry would describe
1617
1644
  something that did not happen — and this path already writes through the raw store, without
1618
- tenant scoping or \`audit()\` stamping, for the same reason.`), j) {
1619
- e.onWarn?.(`staging ${A.length} table(s) before the swap — the target keeps its rows until the load stands.\n The destructive step is one server-side transaction at the end, not the whole load.`);
1620
- let t = e.store, r = A.map((e) => e.name), i = Dn(r, {
1645
+ tenant scoping or \`audit()\` stamping, for the same reason.`), k) {
1646
+ e.onWarn?.(`staging ${de.length} table(s) before the swap — the target keeps its rows until the load stands.\n The destructive step is one server-side transaction at the end, not the whole load.`);
1647
+ let t = e.store, r = de.map((e) => e.name), i = Fn(r, {
1621
1648
  getTable: (e) => v(e),
1622
1649
  registerTable: (e) => {
1623
1650
  C(e);
@@ -1625,59 +1652,65 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1625
1652
  unregisterTable: ne
1626
1653
  }), a = !1;
1627
1654
  try {
1628
- let i = g ? r : r.filter((e) => !Mt(x, e));
1655
+ let i = g ? r : r.filter((e) => !Bt(x, e));
1629
1656
  yield* n.tryPromise({
1630
1657
  try: async () => {
1631
- await jn(t, i.map((e) => Tn(e, O))), await jn(t, i.map((e) => wn(e, O)));
1658
+ await zn(t, i.map((e) => Nn(e, O))), await zn(t, i.map((e) => Mn(e, O)));
1632
1659
  },
1633
1660
  catch: (e) => new H({ reason: `could not prepare the staging tables, so the import did not start and the target is untouched: ${String(e?.message ?? e)}` })
1634
- }), yield* L(me(e.store, !g)), !g && x.truncated === !0 ? a = !0 : yield* n.tryPromise({
1635
- try: () => Mn(t, A, O).then(() => {
1661
+ }), yield* I(ge(e.store, !g)), !g && x.truncated === !0 ? a = !0 : yield* n.tryPromise({
1662
+ try: () => Bn(t, de, O).then(() => {
1636
1663
  a = !0;
1637
1664
  }),
1638
1665
  catch: (e) => new H({ reason: String(e?.message ?? e) })
1639
1666
  }).pipe(n.catchAll((i) => n.gen(function* () {
1640
- let a = An(yield* n.promise(() => Nn(t, On(e.targetSnapshot, r), O).then((e) => e, () => [])));
1667
+ let a = Rn(yield* n.promise(() => Vn(t, In(e.targetSnapshot, r), O).then((e) => e, () => [])));
1641
1668
  return yield* n.fail(new H({ reason: a ?? `the swap failed and the target is UNCHANGED: ${i.reason}` }));
1642
1669
  }))), !g && a && x.truncated !== !0 && (x.truncated = !0, yield* J(y, x));
1643
1670
  } finally {
1644
- i.undo(), a || g ? yield* n.promise(() => jn(t, r.map((e) => Tn(e, O))).then(() => void 0, () => void 0)) : e.onWarn?.("the staged rows are KEPT so a re-run can continue from them rather than reload.\n If you are not going to re-run this bundle, drop them: voltro data clear-staging --yes");
1671
+ i.undo(), a || g ? yield* n.promise(() => zn(t, r.map((e) => Nn(e, O))).then(() => void 0, () => void 0)) : e.onWarn?.("the staged rows are KEPT so a re-run can continue from them rather than reload.\n If you are not going to re-run this bundle, drop them: voltro data clear-staging --yes");
1645
1672
  }
1646
1673
  } else g ? yield* n.tryPromise({
1647
1674
  try: () => e.store.transactional(async (e) => {
1648
- let t = await _e(() => n.runPromiseExit(me(e, !1)));
1649
- if (r.isFailure(t)) throw Jn(t.cause);
1675
+ let t = await ve(() => n.runPromiseExit(ge(e, !1)));
1676
+ if (r.isFailure(t)) throw nr(t.cause);
1650
1677
  }),
1651
- catch: (e) => qn(e) ?? new H({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
1652
- }) : yield* L(me(e.store, !0));
1678
+ catch: (e) => tr(e) ?? new H({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
1679
+ }) : yield* I(ge(e.store, !0));
1653
1680
  if (e.assets && s.assets.index && !e.assetsAlreadyRestored) {
1654
- let t = e.assets, r = i.join(e.bundleDir, xt), a = i.join(e.bundleDir, s.assets.index ?? "assets/index.ndjson"), o = ce("bundle", () => fe(a)).pipe(l.decodeText(), l.splitLines, l.filter((e) => e.trim().length > 0), l.map((e) => JSON.parse(e)));
1655
- yield* l.runForEach(o, (e) => e.key in x.assets ? n.void : ot(t, r, e).pipe(n.andThen(n.sync(() => {
1656
- x.assets[e.key] = !0;
1657
- })), n.andThen(J(y, x))));
1681
+ let t = e.assets;
1682
+ yield* mt({
1683
+ sink: t,
1684
+ assetsDir: i.join(e.bundleDir, kt),
1685
+ indexPath: i.join(e.bundleDir, s.assets.index ?? "assets/index.ndjson"),
1686
+ progress: {
1687
+ done: (e) => e in x.assets,
1688
+ mark: (e) => (x.assets[e] = !0, J(y, x))
1689
+ }
1690
+ });
1658
1691
  }
1659
1692
  return yield* n.promise(() => Se(null)), {
1660
1693
  manifest: s,
1661
- tablesWritten: N,
1662
- rowsWritten: M,
1663
- tablesSkipped: F,
1664
- rowsSkipped: P,
1665
- fullyResumed: N === 0 && F > 0,
1666
- ...I === void 0 ? {} : { rollback: I }
1694
+ tablesWritten: j,
1695
+ rowsWritten: A,
1696
+ tablesSkipped: N,
1697
+ rowsSkipped: M,
1698
+ fullyResumed: j === 0 && N > 0,
1699
+ ...F === void 0 ? {} : { rollback: F }
1667
1700
  };
1668
1701
  }).pipe(n.tapError((e) => n.promise(() => t?.(e?.reason ?? e?._tag ?? "the import did not finish") ?? Promise.resolve())));
1669
- }, Zn = (e) => e, Qn = (e) => {
1702
+ }, ar = (e) => e, or = (e) => {
1670
1703
  if (e.allowLive || e.liveInstance === null || e.sameTarget === "different") return { refuse: !1 };
1671
1704
  let t = e.targetLabel === void 0 ? "" : ` Target: ${e.targetLabel}.`, n = e.sameTarget === "same" ? " That instance is connected to the SAME database." : " We could not confirm which database that instance is connected to, so this is refused on the conservative reading — an older instance, or one whose connection could not be parsed, reports nothing to compare.";
1672
1705
  return {
1673
1706
  refuse: !0,
1674
1707
  message: `refusing to write into a target with a LIVE instance (${e.liveInstance}).${t}${n} A direct import is an uncoordinated concurrent writer — readers see partial state, the reactive layer either storms or goes stale, and rows race with live writes. Re-run with --allow-live to override, or use a live-safe strategy (shadow-swap for replace, or the api target).`
1675
1708
  };
1676
- }, Q = Buffer.from("VBUNDLE2"), $n = 0, er = 1, tr = 2, nr = 32, rr = async (e) => {
1709
+ }, Q = Buffer.from("VBUNDLE2"), sr = 0, cr = 1, lr = 2, ur = 32, dr = async (e) => {
1677
1710
  let t = [], n = async (r) => {
1678
1711
  let i;
1679
1712
  try {
1680
- i = await me(L(e, r), { withFileTypes: !0 });
1713
+ i = await F(R(e, r), { withFileTypes: !0 });
1681
1714
  } catch {
1682
1715
  return;
1683
1716
  }
@@ -1687,22 +1720,22 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1687
1720
  }
1688
1721
  };
1689
1722
  return await n(""), t.sort();
1690
- }, ir = (e, t) => {
1723
+ }, fr = (e, t) => {
1691
1724
  let n = Buffer.from(e, "utf8"), r = Buffer.alloc(5 + n.length + 8);
1692
- return r.writeUInt8(er, 0), r.writeUInt32BE(n.length, 1), n.copy(r, 5), r.writeBigUInt64BE(BigInt(t), 5 + n.length), r;
1693
- }, ar = (e, t, n) => {
1725
+ return r.writeUInt8(cr, 0), r.writeUInt32BE(n.length, 1), n.copy(r, 5), r.writeBigUInt64BE(BigInt(t), 5 + n.length), r;
1726
+ }, pr = (e, t, n) => {
1694
1727
  let r = Buffer.from(e, "utf8"), i = Buffer.from(t, "utf8"), a = Buffer.alloc(5 + r.length + 2 + i.length + 8), o = 0;
1695
- return a.writeUInt8(tr, o), o += 1, a.writeUInt32BE(r.length, o), o += 4, r.copy(a, o), o += r.length, a.writeUInt16BE(i.length, o), o += 2, i.copy(a, o), o += i.length, a.writeBigUInt64BE(BigInt(n), o), a;
1728
+ return a.writeUInt8(lr, o), o += 1, a.writeUInt32BE(r.length, o), o += 4, r.copy(a, o), o += r.length, a.writeUInt16BE(i.length, o), o += 2, i.copy(a, o), o += i.length, a.writeBigUInt64BE(BigInt(n), o), a;
1696
1729
  };
1697
- async function* or(e) {
1730
+ async function* mr(e) {
1698
1731
  yield new Uint8Array(Q);
1699
- for (let t of await rr(e.dir)) {
1700
- let n = L(e.dir, t), r = await he(n);
1701
- if (yield new Uint8Array(ir(t, r.size)), r.size > 0) for await (let e of fe(n)) yield new Uint8Array(e);
1732
+ for (let t of await dr(e.dir)) {
1733
+ let n = R(e.dir, t), r = await ve(n);
1734
+ if (yield new Uint8Array(fr(t, r.size)), r.size > 0) for await (let e of le(n)) yield new Uint8Array(e);
1702
1735
  }
1703
1736
  if (e.blobs) for await (let t of e.blobs.list()) {
1704
- yield new Uint8Array(ar(t.key, t.contentType, t.size));
1705
- let n = E("sha256"), r = 0;
1737
+ yield new Uint8Array(pr(t.key, t.contentType, t.size));
1738
+ let n = D("sha256"), r = 0;
1706
1739
  for await (let i of e.blobs.open(t.key)) {
1707
1740
  let e = Buffer.from(i);
1708
1741
  n.update(e), r += e.length, yield new Uint8Array(e);
@@ -1710,11 +1743,11 @@ async function* or(e) {
1710
1743
  if (r !== t.size) throw Error(`blob '${t.key}' size mismatch: header ${t.size}, streamed ${r}`);
1711
1744
  yield new Uint8Array(n.digest());
1712
1745
  }
1713
- yield new Uint8Array(Buffer.from([$n]));
1746
+ yield new Uint8Array(Buffer.from([sr]));
1714
1747
  }
1715
- var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr = (e) => new Promise((t) => e.end(t)), lr = async (e, t) => {
1716
- let n = R(t.dir);
1717
- await F(n, { recursive: !0 });
1748
+ var hr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), gr = (e) => new Promise((t) => e.end(t)), _r = async (e, t) => {
1749
+ let n = be(t.dir);
1750
+ await P(n, { recursive: !0 });
1718
1751
  let r = Buffer.alloc(0), i = e[Symbol.asyncIterator](), a = !1, o = async () => {
1719
1752
  let { value: e, done: t } = await i.next();
1720
1753
  return t ? (a = !0, !1) : (r = r.length === 0 ? Buffer.from(e) : Buffer.concat([r, Buffer.from(e)]), !0);
@@ -1729,24 +1762,24 @@ var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr
1729
1762
  for (;;) {
1730
1763
  await s(1);
1731
1764
  let e = c(1).readUInt8(0);
1732
- if (e === $n) return;
1733
- if (e === er) {
1765
+ if (e === sr) return;
1766
+ if (e === cr) {
1734
1767
  await s(4);
1735
1768
  let e = c(4).readUInt32BE(0);
1736
1769
  await s(e);
1737
1770
  let t = c(e).toString("utf8");
1738
1771
  await s(8);
1739
- let i = c(8).readBigUInt64BE(0), a = R(n, t);
1740
- if (a !== n && !a.startsWith(n + ve)) throw Error(`archive path '${t}' escapes the destination`);
1741
- await F(_e(a), { recursive: !0 });
1742
- let o = M(a);
1772
+ let i = c(8).readBigUInt64BE(0), a = be(n, t);
1773
+ if (a !== n && !a.startsWith(n + xe)) throw Error(`archive path '${t}' escapes the destination`);
1774
+ await P(ye(a), { recursive: !0 });
1775
+ let o = O(a);
1743
1776
  for (; i > 0n;) {
1744
1777
  r.length === 0 && await s(1);
1745
1778
  let e = i < BigInt(r.length) ? Number(i) : r.length;
1746
- await sr(o, c(e)), i -= BigInt(e);
1779
+ await hr(o, c(e)), i -= BigInt(e);
1747
1780
  }
1748
- await cr(o);
1749
- } else if (e === tr) {
1781
+ await gr(o);
1782
+ } else if (e === lr) {
1750
1783
  await s(4);
1751
1784
  let e = c(4).readUInt32BE(0);
1752
1785
  await s(e);
@@ -1756,24 +1789,24 @@ var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr
1756
1789
  await s(i);
1757
1790
  let a = c(i).toString("utf8");
1758
1791
  await s(8);
1759
- let o = c(8).readBigUInt64BE(0), l = await t.blobs.has(n), u = E("sha256"), d = new ue(), f = l ? Promise.resolve() : t.blobs.write(n, d, {
1792
+ let o = c(8).readBigUInt64BE(0), l = await t.blobs.has(n), u = D("sha256"), d = new N(), f = l ? Promise.resolve() : t.blobs.write(n, d, {
1760
1793
  contentType: a,
1761
1794
  size: Number(o)
1762
1795
  }), p = o;
1763
1796
  for (; p > 0n;) {
1764
1797
  r.length === 0 && await s(1);
1765
1798
  let e = p < BigInt(r.length) ? Number(p) : r.length, t = c(e);
1766
- u.update(t), l || await sr(d, t), p -= BigInt(e);
1799
+ u.update(t), l || await hr(d, t), p -= BigInt(e);
1767
1800
  }
1768
- l ? d.destroy() : await cr(d), await f, await s(nr);
1769
- let m = c(nr);
1801
+ l ? d.destroy() : await gr(d), await f, await s(ur);
1802
+ let m = c(ur);
1770
1803
  if (!u.digest().equals(m)) throw Error(`blob '${n}' failed integrity (sha mismatch)`);
1771
1804
  } else throw Error(`unknown bundle entry kind ${e}`);
1772
1805
  }
1773
1806
  } finally {
1774
1807
  a || await Promise.resolve(i.return?.()).catch(() => void 0);
1775
1808
  }
1776
- }, ur = async (e, t) => {
1809
+ }, vr = async (e, t) => {
1777
1810
  let n = new Set(t), r = /* @__PURE__ */ new Map(), i = Buffer.alloc(0), a = e[Symbol.asyncIterator](), o = async () => {
1778
1811
  let { value: e, done: t } = await a.next();
1779
1812
  return !t && (i = i.length === 0 ? Buffer.from(e) : Buffer.concat([i, Buffer.from(e)]), !0);
@@ -1795,8 +1828,8 @@ var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr
1795
1828
  if (!await s(Q.length) || !c(Q.length).equals(Q)) throw Error("not a bundle archive (bad magic)");
1796
1829
  for (; await s(1);) {
1797
1830
  let e = c(1).readUInt8(0);
1798
- if (e === $n || e === tr) break;
1799
- if (e !== er) throw Error(`unknown bundle entry kind ${e}`);
1831
+ if (e === sr || e === lr) break;
1832
+ if (e !== cr) throw Error(`unknown bundle entry kind ${e}`);
1800
1833
  if (!await s(4)) break;
1801
1834
  let t = c(4).readUInt32BE(0);
1802
1835
  if (!await s(t)) break;
@@ -1806,22 +1839,22 @@ var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr
1806
1839
  if (a === null || n.has(i) && (r.set(i, a), n.delete(i), n.size === 0)) break;
1807
1840
  }
1808
1841
  return r;
1809
- }, dr = (e, t) => lr(e, {
1842
+ }, yr = (e, t) => _r(e, {
1810
1843
  dir: t,
1811
- blobs: fr(t)
1812
- }), fr = (e) => {
1844
+ blobs: br(t)
1845
+ }), br = (e) => {
1813
1846
  let t = /* @__PURE__ */ new Set();
1814
1847
  return {
1815
1848
  has: async (e) => t.has(e),
1816
1849
  write: async (n, r, i) => {
1817
- let a = await import("node:fs/promises"), { pipeline: o } = await import("node:stream/promises"), { Transform: s } = await import("node:stream"), c = L(e, "assets");
1818
- await F(c, { recursive: !0 });
1819
- let l = E("sha256"), u = 0, d = new s({ transform(e, t, n) {
1850
+ let a = await import("node:fs/promises"), { pipeline: o } = await import("node:stream/promises"), { Transform: s } = await import("node:stream"), c = R(e, "assets");
1851
+ await P(c, { recursive: !0 });
1852
+ let l = D("sha256"), u = 0, d = new s({ transform(e, t, n) {
1820
1853
  l.update(e), u += e.length, n(null, e);
1821
- } }), f = L(c, `.tmp-${Date.now()}-${t.size}`);
1822
- await o(r, d, M(f));
1854
+ } }), f = R(c, `.tmp-${Date.now()}-${t.size}`);
1855
+ await o(r, d, O(f));
1823
1856
  let p = l.digest("hex");
1824
- await a.rename(f, L(c, p)), await a.appendFile(L(c, "index.ndjson"), `${JSON.stringify({
1857
+ await a.rename(f, R(c, p)), await a.appendFile(R(c, "index.ndjson"), `${JSON.stringify({
1825
1858
  key: n,
1826
1859
  sha256: p,
1827
1860
  size: u,
@@ -1829,33 +1862,33 @@ var sr = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), cr
1829
1862
  })}\n`), t.add(n);
1830
1863
  }
1831
1864
  };
1832
- }, pr = ye(oe), mr = Buffer.from("VENC1\0\0\0"), hr = 32, gr = 16, _r = 7, vr = 16, yr = 262144, br = {
1865
+ }, xr = Se(se), Sr = Buffer.from("VENC1\0\0\0"), Cr = 32, wr = 16, Tr = 7, Er = 16, Dr = 262144, Or = {
1833
1866
  N: 32768,
1834
1867
  r: 8,
1835
1868
  p: 1
1836
- }, xr = 134217728, Sr = 43, Cr = (e, t, n) => {
1869
+ }, kr = 134217728, Ar = 43, jr = (e, t, n) => {
1837
1870
  let r = Buffer.alloc(12);
1838
- return e.copy(r, 0, 0, _r), r.writeUInt32BE(t >>> 0, _r), r.writeUInt8(+!!n, 11), r;
1871
+ return e.copy(r, 0, 0, Tr), r.writeUInt32BE(t >>> 0, Tr), r.writeUInt8(+!!n, 11), r;
1839
1872
  };
1840
- async function* wr(e, t) {
1873
+ async function* Mr(e, t) {
1841
1874
  if (!t) throw Error("encryptStream: a non-empty passphrase is required");
1842
- let n = D(gr), r = D(_r), i = await pr(t, n, hr, {
1843
- ...br,
1844
- maxmem: xr
1845
- }), a = Buffer.alloc(Sr);
1846
- mr.copy(a, 0), a.writeUInt32BE(br.N, 8), a.writeUInt32BE(br.r, 12), a.writeUInt32BE(br.p, 16), n.copy(a, 20), r.copy(a, 36), yield new Uint8Array(a);
1875
+ let n = ae(wr), r = ae(Tr), i = await xr(t, n, Cr, {
1876
+ ...Or,
1877
+ maxmem: kr
1878
+ }), a = Buffer.alloc(Ar);
1879
+ Sr.copy(a, 0), a.writeUInt32BE(Or.N, 8), a.writeUInt32BE(Or.r, 12), a.writeUInt32BE(Or.p, 16), n.copy(a, 20), r.copy(a, 36), yield new Uint8Array(a);
1847
1880
  let o = 0, s = (e, t) => {
1848
- let n = T("aes-256-gcm", i, Cr(r, o, t));
1881
+ let n = T("aes-256-gcm", i, jr(r, o, t));
1849
1882
  o === 0 && n.setAAD(a);
1850
1883
  let s = Buffer.concat([n.update(e), n.final()]), c = n.getAuthTag();
1851
1884
  o++;
1852
- let l = Buffer.alloc(5 + s.length + vr);
1853
- return l.writeUInt8(+!!t, 0), l.writeUInt32BE(s.length + vr, 1), s.copy(l, 5), c.copy(l, 5 + s.length), new Uint8Array(l);
1885
+ let l = Buffer.alloc(5 + s.length + Er);
1886
+ return l.writeUInt8(+!!t, 0), l.writeUInt32BE(s.length + Er, 1), s.copy(l, 5), c.copy(l, 5 + s.length), new Uint8Array(l);
1854
1887
  }, c = Buffer.alloc(0);
1855
- for await (let t of e) for (c = c.length === 0 ? Buffer.from(t) : Buffer.concat([c, Buffer.from(t)]); c.length > yr;) yield s(c.subarray(0, yr), !1), c = c.subarray(yr);
1888
+ for await (let t of e) for (c = c.length === 0 ? Buffer.from(t) : Buffer.concat([c, Buffer.from(t)]); c.length > Dr;) yield s(c.subarray(0, Dr), !1), c = c.subarray(Dr);
1856
1889
  yield s(c, !0);
1857
1890
  }
1858
- async function* Tr(e, t) {
1891
+ async function* Nr(e, t) {
1859
1892
  if (!t) throw Error("decryptStream: a non-empty passphrase is required");
1860
1893
  let n = e[Symbol.asyncIterator](), r = Buffer.alloc(0), i = !1, a = async () => {
1861
1894
  let { value: e, done: t } = await n.next();
@@ -1864,16 +1897,16 @@ async function* Tr(e, t) {
1864
1897
  for (; r.length < e && !i && await a(););
1865
1898
  return r.length >= e;
1866
1899
  };
1867
- if (!await o(Sr)) throw Error("encrypted bundle truncated (no header)");
1868
- let s = r.subarray(0, Sr);
1869
- if (!s.subarray(0, 8).equals(mr)) throw Error("not an encrypted bundle (bad magic / wrong passphrase target)");
1870
- let c = s.readUInt32BE(8), l = s.readUInt32BE(12), u = s.readUInt32BE(16), d = Buffer.from(s.subarray(20, 36)), f = Buffer.from(s.subarray(36, Sr)), p = await pr(t, d, hr, {
1900
+ if (!await o(Ar)) throw Error("encrypted bundle truncated (no header)");
1901
+ let s = r.subarray(0, Ar);
1902
+ if (!s.subarray(0, 8).equals(Sr)) throw Error("not an encrypted bundle (bad magic / wrong passphrase target)");
1903
+ let c = s.readUInt32BE(8), l = s.readUInt32BE(12), u = s.readUInt32BE(16), d = Buffer.from(s.subarray(20, 36)), f = Buffer.from(s.subarray(36, Ar)), p = await xr(t, d, Cr, {
1871
1904
  N: c,
1872
1905
  r: l,
1873
1906
  p: u,
1874
- maxmem: xr
1907
+ maxmem: kr
1875
1908
  });
1876
- r = r.subarray(Sr);
1909
+ r = r.subarray(Ar);
1877
1910
  let m = 0, h = !1;
1878
1911
  for (;;) {
1879
1912
  if (!await o(5)) {
@@ -1882,11 +1915,11 @@ async function* Tr(e, t) {
1882
1915
  }
1883
1916
  if (h) throw Error("encrypted bundle has trailing data after the final frame");
1884
1917
  let e = r.readUInt8(0) === 1, t = r.readUInt32BE(1);
1885
- if (t < vr) throw Error("encrypted bundle corrupt (short frame)");
1918
+ if (t < Er) throw Error("encrypted bundle corrupt (short frame)");
1886
1919
  if (!await o(5 + t)) throw Error("encrypted bundle truncated (frame body)");
1887
- let n = r.subarray(5, 5 + t - vr), i = r.subarray(5 + t - vr, 5 + t);
1920
+ let n = r.subarray(5, 5 + t - Er), i = r.subarray(5 + t - Er, 5 + t);
1888
1921
  r = r.subarray(5 + t);
1889
- let a = ie("aes-256-gcm", p, Cr(f, m, e));
1922
+ let a = E("aes-256-gcm", p, jr(f, m, e));
1890
1923
  m === 0 && a.setAAD(s), a.setAuthTag(i);
1891
1924
  let c = Buffer.concat([a.update(n), a.final()]);
1892
1925
  m++, e && (h = !0), c.length > 0 && (yield new Uint8Array(c));
@@ -1894,7 +1927,7 @@ async function* Tr(e, t) {
1894
1927
  }
1895
1928
  //#endregion
1896
1929
  //#region src/blobStorage.ts
1897
- var Er = (e, t) => ({
1930
+ var Pr = (e, t) => ({
1898
1931
  list: () => {
1899
1932
  let e = t();
1900
1933
  return { async *[Symbol.asyncIterator]() {
@@ -1907,29 +1940,32 @@ var Er = (e, t) => ({
1907
1940
  } };
1908
1941
  },
1909
1942
  open: (t) => ({ async *[Symbol.asyncIterator]() {
1910
- let r = await n.runPromise(le(e, t)), i = await k(r.stream);
1943
+ let r = await n.runPromise(A(e, t)), i = await he(r.stream);
1911
1944
  for await (let e of i) yield e instanceof Uint8Array ? e : new Uint8Array(e);
1912
1945
  } })
1913
- }), Dr = (e, t) => Er(e, () => w(t, {
1914
- table: se,
1946
+ }), Fr = (e, t) => Pr(e, () => w(t, {
1947
+ table: pe,
1915
1948
  chunkSize: 500
1916
1949
  }).pipe(l.map((e) => ({
1917
1950
  key: String(e.key),
1918
1951
  contentType: String(e.contentType ?? "application/octet-stream"),
1919
1952
  size: Number(e.size ?? 0)
1920
- })))), Or = (e) => ({
1953
+ })))), Ir = (e) => ({
1921
1954
  has: (t) => n.runPromise(e.head(t).pipe(n.map((e) => e !== null))),
1922
1955
  write: async (t, r, i) => {
1923
- let a = ce("storage", () => j.from(r));
1924
- await n.runPromise(O(e, t, a, {
1956
+ let a = me("storage", () => ge.from(r));
1957
+ await n.runPromise(j(e, t, a, {
1925
1958
  contentType: i.contentType,
1926
1959
  totalSize: i.size
1927
1960
  }));
1928
1961
  }
1929
- }), kr = (e, t) => {
1962
+ }), Lr = (e, t) => {
1930
1963
  let n = t === "dump" ? "mariadb-dump" : "mariadb", r = t === "dump" ? "mysqldump" : "mysql";
1931
- return e === "mariadb" && Ar(n) ? n : r;
1932
- }, Ar = (e) => (process.env.PATH ?? "").split(I).filter((e) => e !== "").some((t) => N(L(t, e))), jr = (e) => {
1964
+ return e === "mariadb" ? Rr(n) ? { tool: n } : {
1965
+ tool: r,
1966
+ hint: `'${n}' is not on PATH, so this ran '${r}' instead. If that binary came from Oracle's MySQL client it queries information_schema.COLUMN_STATISTICS, which MariaDB does not have, and the run dies with error 1109 after the first table. Install the MariaDB client package (which ships '${n}') and re-run. Do NOT reach for --column-statistics=0: that flag does not exist on '${n}', so it fixes the wrong client and breaks the right one. Note: a MariaDB 12.x client requires TLS by default, so running '${n}' BY HAND against a server without it fails with "TLS/SSL error: SSL is required" (2026) and needs --skip-ssl. This command is not affected.`
1967
+ } : { tool: r };
1968
+ }, Rr = (e) => (process.env.PATH ?? "").split(L).filter((e) => e !== "").some((t) => ue(R(t, e))), zr = (e) => {
1933
1969
  switch (e) {
1934
1970
  case "postgres": return "db.dump";
1935
1971
  case "mysql":
@@ -1939,7 +1975,7 @@ var Er = (e, t) => ({
1939
1975
  case "mssql": return "db.bacpac";
1940
1976
  default: return "db.dump";
1941
1977
  }
1942
- }, Mr = (e) => e.filename ?? e.database ?? ((e.url ?? "").replace(/^file:/, "") || "app.sqlite"), $ = (e) => {
1978
+ }, Br = (e) => e.filename ?? e.database ?? ((e.url ?? "").replace(/^file:/, "") || "app.sqlite"), $ = (e) => {
1943
1979
  if (e.host || e.database) return {
1944
1980
  host: e.host ?? "localhost",
1945
1981
  port: e.port ?? 3306,
@@ -1955,7 +1991,7 @@ var Er = (e, t) => ({
1955
1991
  password: decodeURIComponent(t.password) || "",
1956
1992
  database: t.pathname.replace(/^\//, "") || ""
1957
1993
  };
1958
- }, Nr = (e) => `Server=${e.host},${e.port};Database=${e.database};User ID=${e.username};Password=${e.password};TrustServerCertificate=True`, Pr = (e, t, n) => {
1994
+ }, Vr = (e) => `Server=${e.host},${e.port};Database=${e.database};User ID=${e.username};Password=${e.password};TrustServerCertificate=True`, Hr = (e, t, n) => {
1959
1995
  switch (e) {
1960
1996
  case "postgres": {
1961
1997
  if (t.url) return {
@@ -1965,6 +2001,7 @@ var Er = (e, t) => ({
1965
2001
  "--format=custom",
1966
2002
  "--no-owner",
1967
2003
  "--no-privileges",
2004
+ ...Ur,
1968
2005
  "--dbname",
1969
2006
  t.url,
1970
2007
  "--file",
@@ -1983,6 +2020,7 @@ var Er = (e, t) => ({
1983
2020
  "--format=custom",
1984
2021
  "--no-owner",
1985
2022
  "--no-privileges",
2023
+ ...Ur,
1986
2024
  "-h",
1987
2025
  e.host,
1988
2026
  "-p",
@@ -2002,13 +2040,14 @@ var Er = (e, t) => ({
2002
2040
  let r = $(t);
2003
2041
  return {
2004
2042
  kind: "spawn",
2005
- tool: kr(e, "dump"),
2043
+ ...Lr(e, "dump"),
2006
2044
  args: [
2007
2045
  "--single-transaction",
2008
2046
  "--routines",
2009
2047
  "--triggers",
2010
2048
  "--no-tablespaces",
2011
2049
  "--protocol=TCP",
2050
+ `--ignore-table=${r.database}.${d}`,
2012
2051
  "-h",
2013
2052
  r.host,
2014
2053
  "-P",
@@ -2024,7 +2063,7 @@ var Er = (e, t) => ({
2024
2063
  case "sqlite":
2025
2064
  case "turso": return {
2026
2065
  kind: "copy",
2027
- from: Mr(t),
2066
+ from: Br(t),
2028
2067
  to: n
2029
2068
  };
2030
2069
  case "mssql": return {
@@ -2032,7 +2071,7 @@ var Er = (e, t) => ({
2032
2071
  tool: "sqlpackage",
2033
2072
  args: [
2034
2073
  "/Action:Export",
2035
- `/SourceConnectionString:${Nr($({
2074
+ `/SourceConnectionString:${Vr($({
2036
2075
  ...t,
2037
2076
  port: t.port ?? 1433
2038
2077
  }))}`,
@@ -2045,7 +2084,7 @@ var Er = (e, t) => ({
2045
2084
  reason: `no native backup for dialect '${e}'`
2046
2085
  });
2047
2086
  }
2048
- }, Fr = (e, t, n) => {
2087
+ }, Ur = ["--exclude-table", d], Wr = (e, t, n) => {
2049
2088
  switch (e) {
2050
2089
  case "postgres": {
2051
2090
  if (t.url) return {
@@ -2090,7 +2129,7 @@ var Er = (e, t) => ({
2090
2129
  let r = $(t);
2091
2130
  return {
2092
2131
  kind: "spawn",
2093
- tool: kr(e, "client"),
2132
+ ...Lr(e, "client"),
2094
2133
  args: [
2095
2134
  "--protocol=TCP",
2096
2135
  "-h",
@@ -2109,14 +2148,14 @@ var Er = (e, t) => ({
2109
2148
  case "turso": return {
2110
2149
  kind: "copy",
2111
2150
  from: n,
2112
- to: Mr(t)
2151
+ to: Br(t)
2113
2152
  };
2114
2153
  case "mssql": return {
2115
2154
  kind: "spawn",
2116
2155
  tool: "sqlpackage",
2117
2156
  args: [
2118
2157
  "/Action:Import",
2119
- `/TargetConnectionString:${Nr($({
2158
+ `/TargetConnectionString:${Vr($({
2120
2159
  ...t,
2121
2160
  port: t.port ?? 1433
2122
2161
  }))}`,
@@ -2129,13 +2168,31 @@ var Er = (e, t) => ({
2129
2168
  reason: `no native restore for dialect '${e}'`
2130
2169
  });
2131
2170
  }
2132
- }, Ir = (e) => e.kind === "copy" ? n.async((t) => {
2133
- de(e.from, e.to, (r) => t(r ? n.fail(new W({
2134
- tool: "copy",
2135
- reason: `copy ${e.from} → ${e.to}: ${r.message}`
2136
- })) : n.void));
2171
+ }, Gr = (e) => e.kind === "copy" ? n.async((t) => {
2172
+ let r = `${e.to}.restoring-${oe()}`, i = (e) => {
2173
+ try {
2174
+ k(r);
2175
+ } catch {}
2176
+ t(n.fail(new W({
2177
+ tool: "copy",
2178
+ reason: e
2179
+ })));
2180
+ };
2181
+ ce(e.from, r, (a) => {
2182
+ if (a) {
2183
+ i(`copy ${e.from} → ${e.to}: ${a.message}`);
2184
+ return;
2185
+ }
2186
+ de(r, e.to, (r) => {
2187
+ if (r) {
2188
+ i(`copy ${e.from} → ${e.to}: ${r.message}`);
2189
+ return;
2190
+ }
2191
+ t(n.void);
2192
+ });
2193
+ });
2137
2194
  }) : n.async((t) => {
2138
- let r = be(e.tool, [...e.args], {
2195
+ let r = Ce(e.tool, [...e.args], {
2139
2196
  env: {
2140
2197
  ...process.env,
2141
2198
  ...e.env
@@ -2148,33 +2205,63 @@ var Er = (e, t) => ({
2148
2205
  }), i = "";
2149
2206
  r.stderr?.on("data", (e) => {
2150
2207
  i += String(e);
2151
- }), e.stdoutFile && r.stdout && r.stdout.pipe(M(e.stdoutFile)), e.stdinFile && r.stdin && fe(e.stdinFile).pipe(r.stdin);
2152
- let a = () => {
2208
+ });
2209
+ let a = !1, o = (e) => {
2210
+ a || (a = !0, t(e));
2211
+ }, s, c = (e) => {
2212
+ s ??= e;
2213
+ };
2214
+ if (e.stdoutFile && r.stdout) {
2215
+ let t = O(e.stdoutFile);
2216
+ t.on("error", (t) => c(`writing ${I(e.stdoutFile)}: ${t.message}`)), r.stdout.on("error", (e) => c(`reading the tool's output: ${e.message}`)), r.stdout.pipe(t);
2217
+ }
2218
+ let l = 0;
2219
+ if (e.stdinFile && r.stdin) {
2220
+ let t = le(e.stdinFile);
2221
+ t.on("data", (e) => {
2222
+ l += e.length;
2223
+ }), t.on("error", (t) => {
2224
+ c(`reading ${I(e.stdinFile)}: ${t.message}`), r.stdin?.end();
2225
+ }), r.stdin.on("error", (t) => {
2226
+ t.code !== "EPIPE" && c(`feeding ${I(e.stdinFile)} to ${e.tool}: ${t.message}`);
2227
+ }), t.pipe(r.stdin);
2228
+ }
2229
+ let u = () => {
2153
2230
  if (e.stdoutFile !== void 0) try {
2154
- pe(e.stdoutFile);
2231
+ k(e.stdoutFile);
2155
2232
  } catch {}
2156
2233
  };
2157
- r.on("error", (r) => {
2158
- a(), t(n.fail(new W({
2234
+ r.on("error", (t) => {
2235
+ u(), o(n.fail(new W({
2159
2236
  tool: e.tool,
2160
- reason: `failed to launch (is '${e.tool}' installed + on PATH?): ${r.message}`
2237
+ reason: `failed to launch (is '${e.tool}' installed + on PATH?): ${t.message}`,
2238
+ ...e.hint === void 0 ? {} : { hint: e.hint }
2161
2239
  })));
2162
- }), r.on("close", (r) => {
2163
- if (r === 0) {
2164
- t(n.void);
2240
+ }), r.on("close", (t) => {
2241
+ if (t === 0 && s === void 0) {
2242
+ o(n.void);
2165
2243
  return;
2166
2244
  }
2167
- a(), t(n.fail(new W({
2245
+ u();
2246
+ let r = e.stdinFile === void 0 ? "" : ` — ${l} of ${Kr(e.stdinFile)} byte(s) of ${I(e.stdinFile)} had been fed to it`;
2247
+ o(n.fail(new W({
2168
2248
  tool: e.tool,
2169
- reason: `exited with code ${r}` + (e.stdoutFile === void 0 ? "" : ` — the partial ${ge(e.stdoutFile)} was removed, so it cannot be mistaken for a backup`),
2170
- stderr: i.slice(-2e3)
2249
+ reason: (t === 0 ? `exited cleanly, but ${s}` : `exited with code ${t}${s === void 0 ? "" : ` (${s})`}`) + r + (e.stdoutFile === void 0 ? "" : ` — the partial ${I(e.stdoutFile)} was removed, so it cannot be mistaken for a backup`),
2250
+ stderr: i.trim() === "" ? `(${e.tool} printed nothing to stderr)` : i.slice(-2e3),
2251
+ ...e.hint === void 0 ? {} : { hint: e.hint }
2171
2252
  })));
2172
2253
  });
2173
- }), Lr = (e) => typeof e == "object" && e ? "fake" in e ? `fake:${e.fake}` : "custom" : String(e), Rr = (e) => n.gen(function* () {
2174
- let t = yield* nt(e.scope ?? { kind: "all" }, e.snapshot, {
2254
+ }), Kr = (e) => {
2255
+ try {
2256
+ return String(fe(e).size);
2257
+ } catch {
2258
+ return "?";
2259
+ }
2260
+ }, qr = (e) => typeof e == "object" && e ? "fake" in e ? `fake:${e.fake}` : "custom" : String(e), Jr = (e) => n.gen(function* () {
2261
+ let t = yield* at(e.scope ?? { kind: "all" }, e.snapshot, {
2175
2262
  store: e.store,
2176
2263
  ...e.tenantTables ? { tenantTables: e.tenantTables } : {}
2177
- }), r = qt(t.tables, e.snapshot), i = e.classification ?? Ce(e.snapshot), a = e.sampleSize ?? 20, o = Ie(r.map((t) => ({
2264
+ }), r = tn(t.tables, e.snapshot), i = e.classification ?? Ee(e.snapshot), a = e.sampleSize ?? 20, o = ze(r.map((t) => ({
2178
2265
  name: t,
2179
2266
  columns: (e.snapshot.tables.find((e) => e.name === t)?.columns ?? []).map((e) => ({
2180
2267
  name: e.name,
@@ -2186,15 +2273,15 @@ var Er = (e, t) => ({
2186
2273
  table: i,
2187
2274
  chunkSize: a,
2188
2275
  ...r === void 0 ? {} : { where: r }
2189
- }).pipe(l.take(a), l.runCollect, n.map((e) => [...e])), d = u.map((t) => ze(t, i, o.actions, e.masking.seed));
2190
- c.push(...Re(d, i, o.actions));
2276
+ }).pipe(l.take(a), l.runCollect, n.map((e) => [...e])), d = u.map((t) => He(t, i, o.actions, e.masking.seed));
2277
+ c.push(...Ve(d, i, o.actions));
2191
2278
  let f = u[0], p = d[0], m = [];
2192
2279
  if (f && p) for (let [e, t] of Object.entries(o.actions)) {
2193
2280
  if (!e.startsWith(`${i}.`) || t === "keep") continue;
2194
2281
  let n = e.slice(i.length + 1);
2195
2282
  m.push({
2196
2283
  column: n,
2197
- action: Lr(t),
2284
+ action: qr(t),
2198
2285
  before: f[n],
2199
2286
  after: p[n]
2200
2287
  });
@@ -2209,7 +2296,7 @@ var Er = (e, t) => ({
2209
2296
  leaks: c,
2210
2297
  unclassified: o.unclassified
2211
2298
  };
2212
- }), zr = (e, t) => {
2299
+ }), Yr = (e, t) => {
2213
2300
  let n = new Map(t.map((e) => [e.name, e])), r = [], i = {};
2214
2301
  for (let t of e) {
2215
2302
  let e = n.get(t.name);
@@ -2264,7 +2351,7 @@ var Er = (e, t) => ({
2264
2351
  skipColumns: i,
2265
2352
  refuse: r.some((e) => e.verdict === "refuse")
2266
2353
  };
2267
- }, Br = (e) => {
2354
+ }, Xr = (e) => {
2268
2355
  if (e.findings.length === 0) return [" schema matches the bundle"];
2269
2356
  let t = {
2270
2357
  safe: "✓",
@@ -2275,4 +2362,4 @@ var Er = (e, t) => ({
2275
2362
  return n.push(""), n.push(` discarded: ${r("value-dropped")} defaulted: ${r("filled-by-default")} refused: ${r("refuse")}`), e.refuse && (n.push(""), n.push(" REFUSED — no row was written. These are the differences that would make"), n.push(" imported rows WRONG rather than merely incomplete.")), n;
2276
2363
  };
2277
2364
  //#endregion
2278
- export { xt as ASSETS_DIR, St as ASSET_INDEX_FILE, H as BundleError, We as CodecError, Ke as CompressionError, Ze as CrossDialectError, bt as DATA_DIR, Se as DEFAULT_CLASS_ACTIONS, Be as ENVIRONMENT_LOCAL_TABLES, Ve as ENVIRONMENT_PORTABLE_TABLES, ft as FORMAT_VERSION, Xe as ImportModeError, Ge as IntegrityError, Ct as LEDGER_FILE, K as MANIFEST_FILE, Ye as MaskingError, W as NativeToolError, qe as RowsRefusedError, Gn as SAVEPOINT_BATCH_SIZE, bn as STAGING_PREFIX, Je as SchemaDriftError, U as ScopeError, Pe as applyAction, qn as asImportError, Qn as assessLiveImport, Nt as assetDone, jr as backupArtifactName, Pr as backupCommand, cn as canonicalType, dn as checkPortability, Un as checkSchemaDrift, Ce as classificationFromSnapshot, zr as classifyImportDrift, lt as compressionExt, $e as computeSubsetIds, In as decideStaging, vt as decodeManifest, Ut as decodeRow, Vt as decodeValue, Tr as decryptStream, Zn as defineDataProfile, Hn as diffSnapshots, fr as dirBlobSink, Tn as dropStagingSql, At as emptyLedger, _t as encodeManifest, Ht as encodeRow, zt as encodeValue, wr as encryptStream, Ue as environmentLocalNotice, He as environmentLocalReason, jn as execStatements, Br as formatImportDrift, fn as formatIssue, st as hasZstd, V as isEnvironmentLocal, ut as makeCompressor, dt as makeDecompressor, ze as maskRow, Kt as ndjsonToRows, sn as outsideReferenceRefusal, on as outsideReferencesInto, or as packBundle, ur as peekBundle, ct as pickCompression, Ie as planMasking, Rr as previewMasking, jt as readLedger, we as resolveAction, nt as resolveScope, ot as restoreAssetFromCas, Fr as restoreCommand, Gt as rowsToNdjson, an as runExport, Xn as runImport, Ir as runNativeStep, Re as scanForLeaks, X as stagingNameFor, it as storageAssetSink, rt as storageAssetSource, Or as storageBlobSink, Er as storageBlobSource, Dr as storageRefsBlobSource, et as subsetToScope, Mt as tableDone, qt as topoSortTables, lr as unpackBundle, dr as unpackBundleToDir, at as writeAssetToCas, J as writeLedger };
2365
+ export { kt as ASSETS_DIR, At as ASSET_INDEX_FILE, H as BundleError, qe as CodecError, Ye as CompressionError, et as CrossDialectError, Ot as DATA_DIR, Te as DEFAULT_CLASS_ACTIONS, Ue as ENVIRONMENT_LOCAL_TABLES, We as ENVIRONMENT_PORTABLE_TABLES, bt as FORMAT_VERSION, $e as ImportModeError, Je as IntegrityError, jt as LEDGER_FILE, K as MANIFEST_FILE, Qe as MaskingError, W as NativeToolError, Xe as RowsRefusedError, $n as SAVEPOINT_BATCH_SIZE, On as STAGING_PREFIX, Ze as SchemaDriftError, U as ScopeError, Le as applyAction, tr as asImportError, or as assessLiveImport, Vt as assetDone, zr as backupArtifactName, Hr as backupCommand, gn as canonicalType, ft as captureAssetsToCas, yn as checkPortability, Zn as checkSchemaDrift, Ee as classificationFromSnapshot, Yr as classifyImportDrift, _t as compressionExt, nt as computeSubsetIds, Wn as decideStaging, Et as decodeManifest, Zt as decodeRow, Yt as decodeValue, Nr as decryptStream, ar as defineDataProfile, Xn as diffSnapshots, br as dirBlobSink, Nn as dropStagingSql, Rt as emptyLedger, Tt as encodeManifest, Xt as encodeRow, qt as encodeValue, Mr as encryptStream, Ke as environmentLocalNotice, Ge as environmentLocalReason, zn as execStatements, Xr as formatImportDrift, bn as formatIssue, ht as hasZstd, V as isEnvironmentLocal, vt as makeCompressor, yt as makeDecompressor, He as maskRow, en as ndjsonToRows, ut as noAssetProgress, hn as outsideReferenceRefusal, mn as outsideReferencesInto, mr as packBundle, vr as peekBundle, gt as pickCompression, ze as planMasking, Jr as previewMasking, pt as readAssetIndex, zt as readLedger, De as resolveAction, at as resolveScope, lt as restoreAssetFromCas, mt as restoreAssetsFromCas, Wr as restoreCommand, $t as rowsToNdjson, pn as runExport, ir as runImport, Gr as runNativeStep, Ve as scanForLeaks, X as stagingNameFor, st as storageAssetSink, ot as storageAssetSource, Ir as storageBlobSink, Pr as storageBlobSource, Fr as storageRefsBlobSource, rt as subsetToScope, Bt as tableDone, tn as topoSortTables, _r as unpackBundle, yr as unpackBundleToDir, ct as writeAssetToCas, J as writeLedger };