@voltro/data-transfer 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/index.js +279 -252
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ var ge = (e) => {
56
56
  return r.classes?.[e] ?? _e[e] ?? "redact";
57
57
  }
58
58
  return n?.safe ? r.onSafe ?? "keep" : n?.columnType === "id" || n?.columnType === "reference" ? "keep" : r.onUnclassified ?? "error";
59
- }, k = (e, t) => v("sha256", e).update(t == null ? "∅" : String(t)).digest(), A = (e, t) => e.readUInt32BE(t * 4 % (e.length - 4)), j = [
59
+ }, be = (e, t) => v("sha256", e).update(t == null ? "∅" : String(t)).digest(), k = (e, t) => e.readUInt32BE(t * 4 % (e.length - 4)), A = [
60
60
  "Ada",
61
61
  "Alan",
62
62
  "Grace",
@@ -69,7 +69,7 @@ var ge = (e) => {
69
69
  "Guido",
70
70
  "Margaret",
71
71
  "Bjarne"
72
- ], M = [
72
+ ], xe = [
73
73
  "Lovelace",
74
74
  "Turing",
75
75
  "Hopper",
@@ -82,7 +82,7 @@ var ge = (e) => {
82
82
  "Rossum",
83
83
  "Hamilton",
84
84
  "Stroustrup"
85
- ], be = [
85
+ ], Se = [
86
86
  "Maple",
87
87
  "Oak",
88
88
  "Cedar",
@@ -91,7 +91,7 @@ var ge = (e) => {
91
91
  "Birch",
92
92
  "Willow",
93
93
  "Ash"
94
- ], xe = [
94
+ ], Ce = [
95
95
  "Initech",
96
96
  "Hooli",
97
97
  "Umbrella",
@@ -100,23 +100,23 @@ var ge = (e) => {
100
100
  "Soylent",
101
101
  "Stark",
102
102
  "Wayne"
103
- ], N = (e, t, n) => e[A(t, n) % e.length], Se = (e, t, n) => {
104
- let r = k(n, `${e}:${String(t)}`), i = A(r, 1) % 1e4;
103
+ ], j = (e, t, n) => e[k(t, n) % e.length], we = (e, t, n) => {
104
+ let r = be(n, `${e}:${String(t)}`), i = k(r, 1) % 1e4;
105
105
  switch (e) {
106
- case "email": return `${N(j, r, 0).toLowerCase()}.${N(M, r, 2).toLowerCase()}${i}@example.com`;
107
- case "fullName": return `${N(j, r, 0)} ${N(M, r, 1)}`;
108
- case "firstName": return N(j, r, 0);
109
- case "lastName": return N(M, r, 1);
110
- case "username": return `${N(j, r, 0).toLowerCase()}${i}`;
111
- case "phone": return `+1${String(A(r, 0) % 1e10).padStart(10, "0")}`;
112
- case "address": return `${A(r, 0) % 9899 + 100} ${N(be, r, 1)} St`;
113
- case "company": return N(xe, r, 0);
106
+ case "email": return `${j(A, r, 0).toLowerCase()}.${j(xe, r, 2).toLowerCase()}${i}@example.com`;
107
+ case "fullName": return `${j(A, r, 0)} ${j(xe, r, 1)}`;
108
+ case "firstName": return j(A, r, 0);
109
+ case "lastName": return j(xe, r, 1);
110
+ case "username": return `${j(A, r, 0).toLowerCase()}${i}`;
111
+ case "phone": return `+1${String(k(r, 0) % 1e10).padStart(10, "0")}`;
112
+ case "address": return `${k(r, 0) % 9899 + 100} ${j(Se, r, 1)} St`;
113
+ case "company": return j(Ce, r, 0);
114
114
  case "url": return `https://example.com/${r.toString("hex").slice(0, 12)}`;
115
- case "ip": return `${A(r, 0) % 256}.${A(r, 1) % 256}.${A(r, 2) % 256}.${A(r, 3) % 254 + 1}`;
116
- case "creditCard": return Ce(`4${r.toString("hex").replace(/\D/g, "").padEnd(14, "0").slice(0, 14)}`);
115
+ case "ip": return `${k(r, 0) % 256}.${k(r, 1) % 256}.${k(r, 2) % 256}.${k(r, 3) % 254 + 1}`;
116
+ case "creditCard": return Te(`4${r.toString("hex").replace(/\D/g, "").padEnd(14, "0").slice(0, 14)}`);
117
117
  default: return `${e}_${r.toString("hex").slice(0, 8)}`;
118
118
  }
119
- }, Ce = (e) => {
119
+ }, Te = (e) => {
120
120
  let t = e.slice(0, 15).split("").map(Number), n = 0;
121
121
  t.forEach((e, t) => {
122
122
  let r = e;
@@ -124,16 +124,16 @@ var ge = (e) => {
124
124
  });
125
125
  let r = (10 - n % 10) % 10;
126
126
  return e.slice(0, 15) + String(r);
127
- }, we = 864e5, Te = (e, t) => {
127
+ }, Ee = 864e5, De = (e, t) => {
128
128
  let n = e instanceof Date ? e.getTime() : Date.parse(String(e));
129
129
  if (Number.isNaN(n)) return e;
130
- let r = A(k(t, "date-shift-offset"), 0) % 730 - 365, i = new Date(n + r * we);
130
+ let r = k(be(t, "date-shift-offset"), 0) % 730 - 365, i = new Date(n + r * Ee);
131
131
  return e instanceof Date ? i : i.toISOString();
132
- }, Ee = (e, t) => {
132
+ }, Oe = (e, t) => {
133
133
  if (t.value === null || t.value === void 0) return null;
134
134
  if (e === "error") throw Error(`masking: unresolved 'error' action for ${t.table}.${t.column}`);
135
- return e === "keep" ? t.value : e === "null" ? null : e === "redact" ? t.columnType === "text" || typeof t.value == "string" ? "[redacted]" : null : e === "hash" ? k(t.seed, t.value).toString("hex").slice(0, 16) : e === "dateShift" ? Te(t.value, t.seed) : typeof e == "object" && "fake" in e ? Se(e.fake, t.value, t.seed) : typeof e == "object" && "custom" in e ? e.custom(t) : t.value;
136
- }, De = (e, t, n) => {
135
+ return e === "keep" ? t.value : e === "null" ? null : e === "redact" ? t.columnType === "text" || typeof t.value == "string" ? "[redacted]" : null : e === "hash" ? be(t.seed, t.value).toString("hex").slice(0, 16) : e === "dateShift" ? De(t.value, t.seed) : typeof e == "object" && "fake" in e ? we(e.fake, t.value, t.seed) : typeof e == "object" && "custom" in e ? e.custom(t) : t.value;
136
+ }, M = (e, t, n) => {
137
137
  let r = {}, i = [];
138
138
  for (let a of e) for (let e of a.columns) {
139
139
  let o = `${a.name}.${e.name}`, s = ye(a.name, e.name, t[a.name]?.[e.name], n);
@@ -143,7 +143,7 @@ var ge = (e) => {
143
143
  actions: r,
144
144
  unclassified: i
145
145
  };
146
- }, Oe = [
146
+ }, ke = [
147
147
  {
148
148
  name: "email",
149
149
  re: /[\w.+-]+@[\w-]+\.[\w.-]+/
@@ -160,7 +160,7 @@ var ge = (e) => {
160
160
  name: "creditCard",
161
161
  re: /\b(?:\d[ -]?){13,16}\b/
162
162
  }
163
- ], ke = (e, t, n) => {
163
+ ], Ae = (e, t, n) => {
164
164
  let r = [], i = /* @__PURE__ */ new Set();
165
165
  for (let [a, o] of Object.entries(n)) {
166
166
  if (!a.startsWith(`${t}.`) || o !== "keep") continue;
@@ -168,7 +168,7 @@ var ge = (e) => {
168
168
  for (let a of e) {
169
169
  let e = a[n];
170
170
  if (typeof e != "string" || e.length === 0) continue;
171
- let o = Oe.find((t) => t.re.test(e));
171
+ let o = ke.find((t) => t.re.test(e));
172
172
  if (o && !i.has(n)) {
173
173
  i.add(n), r.push({
174
174
  table: t,
@@ -181,9 +181,9 @@ var ge = (e) => {
181
181
  }
182
182
  }
183
183
  return r;
184
- }, P = (e, t, n, r, i) => {
184
+ }, N = (e, t, n, r, i) => {
185
185
  let a = {};
186
- for (let [o, s] of Object.entries(e)) a[o] = Ee(n[`${t}.${o}`] ?? "keep", {
186
+ for (let [o, s] of Object.entries(e)) a[o] = Oe(n[`${t}.${o}`] ?? "keep", {
187
187
  value: s,
188
188
  table: t,
189
189
  column: o,
@@ -191,17 +191,17 @@ var ge = (e) => {
191
191
  ...i?.[o] ? { columnType: i[o] } : {}
192
192
  });
193
193
  return a;
194
- }, F = class extends s.TaggedError()("BundleError", {
194
+ }, P = class extends s.TaggedError()("BundleError", {
195
195
  reason: s.String,
196
196
  path: s.optional(s.String)
197
- }) {}, Ae = class extends s.TaggedError()("CodecError", {
197
+ }) {}, je = class extends s.TaggedError()("CodecError", {
198
198
  table: s.String,
199
199
  reason: s.String
200
- }) {}, I = class extends s.TaggedError()("IntegrityError", {
200
+ }) {}, F = class extends s.TaggedError()("IntegrityError", {
201
201
  what: s.String,
202
202
  expected: s.String,
203
203
  actual: s.String
204
- }) {}, je = class extends t.TaggedError("CompressionError") {}, Me = class extends s.TaggedError()("ScopeError", { reason: s.String }) {}, Ne = class extends s.TaggedError()("DanglingReferenceError", {
204
+ }) {}, Me = class extends t.TaggedError("CompressionError") {}, I = class extends s.TaggedError()("ScopeError", { reason: s.String }) {}, Ne = class extends s.TaggedError()("DanglingReferenceError", {
205
205
  rows: s.Array(s.Struct({
206
206
  table: s.String,
207
207
  id: s.String,
@@ -286,23 +286,25 @@ var ge = (e) => {
286
286
  let r = e.get(n);
287
287
  return r ? u(R(t, n), [...r]) : void 0;
288
288
  }
289
- }), B = "tenantId", Be = (e, t, r) => n.gen(function* () {
289
+ }), B = "tenantId", V = (e, t, r) => n.gen(function* () {
290
290
  let i = t.tables.map((e) => e.name), a = new Map(t.tables.map((e) => [e.name, e]));
291
291
  if (e.kind === "all") return {
292
292
  tables: i,
293
293
  predicateFor: () => void 0
294
294
  };
295
295
  if (e.kind === "tables") {
296
- let t = new Set(e.tables ?? []);
296
+ let t = e.tables ?? [], r = new Set(i), a = t.filter((e) => !r.has(e));
297
+ if (a.length > 0) return yield* n.fail(new I({ reason: `scope { kind: 'tables' } names ${a.length} table(s) that are not in the schema: ${a.join(", ")}. Refusing to write a bundle that silently omits them. Known tables: ${i.length}.` }));
298
+ let o = new Set(t);
297
299
  return {
298
- tables: i.filter((e) => t.has(e)),
300
+ tables: i.filter((e) => o.has(e)),
299
301
  predicateFor: () => void 0
300
302
  };
301
303
  }
302
304
  let o = e.tenantId;
303
- if (o === void 0 || o === "") return yield* n.fail(new Me({ reason: "scope { kind: 'tenant' } requires a tenantId — pass --tenant <id> (CLI) or scope.tenantId (API). Refusing to fall back to an unfiltered export." }));
305
+ if (o === void 0 || o === "") return yield* n.fail(new I({ reason: "scope { kind: 'tenant' } requires a tenantId — pass --tenant <id> (CLI) or scope.tenantId (API). Refusing to fall back to an unfiltered export." }));
304
306
  let s = r.tenantTables ? r.tenantTables.filter((e) => a.has(e)) : i.filter((e) => a.get(e)?.columns.some((e) => e.name === B) ?? !1);
305
- if (s.length === 0) return yield* n.fail(new Me({ reason: r.tenantTables ? "tenant scope: none of the provided tenantTables exist in the schema — nothing to filter." : `tenant scope: no table carries a '${B}' column — nothing to filter. A tenant export of a schema without tenant-scoped tables would be the full database; refusing.` }));
307
+ if (s.length === 0) return yield* n.fail(new I({ reason: r.tenantTables ? "tenant scope: none of the provided tenantTables exist in the schema — nothing to filter." : `tenant scope: no table carries a '${B}' column — nothing to filter. A tenant export of a schema without tenant-scoped tables would be the full database; refusing.` }));
306
308
  let c = yield* z(r.store, t, {
307
309
  seeds: Object.fromEntries(s.map((e) => [e, l(B, o)])),
308
310
  pinned: s,
@@ -312,13 +314,13 @@ var ge = (e) => {
312
314
  tables: [...s, ...d],
313
315
  predicateFor: (e) => f.has(e) ? l(B, o) : c.has(e) ? u(R(t, e), [...c.get(e)]) : void 0
314
316
  };
315
- }), Ve = (e, t) => ({
317
+ }), Be = (e, t) => ({
316
318
  list: t,
317
319
  open: (t) => C(e, t)
318
- }), He = (e) => ({
320
+ }), Ve = (e) => ({
319
321
  write: (t, n, r) => ee(e, t, n, r),
320
322
  has: (t) => e.head(t).pipe(n.map((e) => e !== null))
321
- }), Ue = (e, t) => n.tryPromise({
323
+ }), He = (e, t) => n.tryPromise({
322
324
  try: async () => {
323
325
  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) {
324
326
  u.update(e), d += e.length, n(null, e);
@@ -336,23 +338,23 @@ var ge = (e) => {
336
338
  contentType: e.contentType
337
339
  };
338
340
  },
339
- catch: (e) => new F({
341
+ catch: (e) => new P({
340
342
  reason: `asset write failed: ${String(e?.message ?? e)}`,
341
343
  path: t
342
344
  })
343
- }), We = (e, t, r) => n.gen(function* () {
345
+ }), Ue = (e, t, r) => n.gen(function* () {
344
346
  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), l = o("sha256"), u = S("bundle", () => a(s)).pipe(c.tap((e) => n.sync(() => l.update(e))));
345
347
  yield* e.write(r.key, u, {
346
348
  contentType: r.contentType,
347
349
  totalSize: r.size
348
350
  });
349
351
  let d = l.digest("hex");
350
- if (d !== r.sha256) return yield* n.fail(new I({
352
+ if (d !== r.sha256) return yield* n.fail(new F({
351
353
  what: `asset ${r.key}`,
352
354
  expected: r.sha256,
353
355
  actual: d
354
356
  }));
355
- }), Ge = () => typeof w.createZstdCompress == "function", Ke = (e) => e === "none" ? "none" : e === "gzip" ? "gzip" : Ge() ? "zstd" : "gzip", qe = (e) => e === "zstd" ? ".zst" : e === "gzip" ? ".gz" : "", Je = (e) => e === "zstd" ? w.createZstdCompress() : e === "gzip" ? w.createGzip() : new T(), Ye = (e) => e === "zstd" ? w.createZstdDecompress() : e === "gzip" ? w.createGunzip() : new T(), Xe = 1, Ze = s.Struct({
357
+ }), We = () => typeof w.createZstdCompress == "function", Ge = (e) => e === "none" ? "none" : e === "gzip" ? "gzip" : We() ? "zstd" : "gzip", Ke = (e) => e === "zstd" ? ".zst" : e === "gzip" ? ".gz" : "", qe = (e) => e === "zstd" ? w.createZstdCompress() : e === "gzip" ? w.createGzip() : new T(), Je = (e) => e === "zstd" ? w.createZstdDecompress() : e === "gzip" ? w.createGunzip() : new T(), Ye = 1, Xe = s.Struct({
356
358
  name: s.String,
357
359
  file: s.String,
358
360
  rowCount: s.Number,
@@ -362,11 +364,11 @@ var ge = (e) => {
362
364
  value: s.String
363
365
  }),
364
366
  primaryKey: s.String
365
- }), Qe = s.Struct({
367
+ }), Ze = s.Struct({
366
368
  kind: s.Literal("all", "tenant", "tables"),
367
369
  tenantId: s.optional(s.String),
368
370
  tables: s.optional(s.Array(s.String))
369
- }), $e = s.Struct({
371
+ }), Qe = s.Struct({
370
372
  count: s.Number,
371
373
  totalBytes: s.Number,
372
374
  index: s.optional(s.String)
@@ -377,23 +379,23 @@ s.Struct({
377
379
  size: s.Number,
378
380
  contentType: s.String
379
381
  });
380
- var et = s.Struct({
382
+ var $e = s.Struct({
381
383
  formatVersion: s.Number,
382
384
  createdAt: s.String,
383
385
  source: s.Struct({
384
386
  dialect: s.String,
385
387
  schemaFingerprint: s.String
386
388
  }),
387
- scope: Qe,
389
+ scope: Ze,
388
390
  consistency: s.Literal("live", "snapshot"),
389
391
  compression: s.Literal("zstd", "gzip", "none"),
390
- tables: s.Array(Ze),
391
- assets: $e,
392
+ tables: s.Array(Xe),
393
+ assets: Qe,
392
394
  masking: s.optional(s.Struct({
393
395
  policyId: s.optional(s.String),
394
396
  transformed: s.Array(s.String)
395
397
  }))
396
- }), tt = s.encodeSync(s.parseJson(et)), nt = s.decodeUnknownSync(s.parseJson(et)), V = "manifest.json", rt = "README.md", it = "data", H = "assets", U = "assets/index.ndjson", at = ".ledger.json", ot = (e) => e.kind === "tenant" ? `tenant \`${e.tenantId}\`` : e.kind === "tables" ? `tables \`${(e.tables ?? []).join(", ")}\`` : "all tables", st = (e, t) => {
398
+ }), et = s.encodeSync(s.parseJson($e)), tt = s.decodeUnknownSync(s.parseJson($e)), H = "manifest.json", nt = "README.md", U = "data", W = "assets", G = "assets/index.ndjson", rt = ".ledger.json", it = (e) => e.kind === "tenant" ? `tenant \`${e.tenantId}\`` : e.kind === "tables" ? `tables \`${(e.tables ?? []).join(", ")}\`` : "all tables", at = (e, t) => {
397
399
  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");
398
400
  return `# Voltro data export
399
401
 
@@ -407,7 +409,7 @@ The machine-readable manifest is \`manifest.json\`; this file is a human summary
407
409
  | **Format version** | ${e.formatVersion} |
408
410
  | **Consistency** | ${e.consistency} |
409
411
  | **Compression** | ${e.compression} |
410
- | **Scope** | ${ot(e.scope)} |
412
+ | **Scope** | ${it(e.scope)} |
411
413
  | **Tables** | ${e.tables.length} |
412
414
  | **Rows (total)** | ${n} |
413
415
  | **Assets** | ${a} |
@@ -432,39 +434,39 @@ voltro data import <this-directory>
432
434
  voltro data import <this-directory> --target api --api-url <url> --token <secret>
433
435
  \`\`\`
434
436
  `;
435
- }, ct = i.counter("voltro_data_transfer_rows", { description: "Rows exported/imported by @voltro/data-transfer, tagged by phase + table." }), lt = a.exponential({
437
+ }, ot = i.counter("voltro_data_transfer_rows", { description: "Rows exported/imported by @voltro/data-transfer, tagged by phase + table." }), st = a.exponential({
436
438
  start: .01,
437
439
  factor: 2,
438
440
  count: 16
439
- }), ut = i.histogram("voltro_data_transfer_table_seconds", lt, "Per-table export/import duration in seconds, tagged by phase."), W = (e, t) => {
441
+ }), ct = i.histogram("voltro_data_transfer_table_seconds", st, "Per-table export/import duration in seconds, tagged by phase."), K = (e, t) => {
440
442
  if (e) try {
441
443
  e(t);
442
444
  } catch {}
443
- }, dt = (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(ut.pipe(i.tagged("phase", e), i.update((s - r) / 1e3)), ct.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: {
445
+ }, 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(ct.pipe(i.tagged("phase", e), i.update((s - r) / 1e3)), ot.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: {
444
446
  table: t,
445
447
  index: r,
446
448
  tableCount: a,
447
449
  phase: e
448
- } })), ft = () => ({
450
+ } })), ut = () => ({
449
451
  tables: {},
450
452
  assets: {}
451
- }), G = (e) => n.tryPromise(async () => {
453
+ }), dt = (e) => n.tryPromise(async () => {
452
454
  let t = await (await import("node:fs/promises")).readFile(e, "utf8");
453
455
  return JSON.parse(t);
454
- }).pipe(n.orElseSucceed(ft)), K = (e, t) => n.tryPromise({
456
+ }).pipe(n.orElseSucceed(ut)), q = (e, t) => n.tryPromise({
455
457
  try: async () => {
456
458
  let n = await import("node:fs/promises"), { randomUUID: r } = await import("node:crypto"), i = `${e}.tmp-${r()}`;
457
459
  await n.writeFile(i, JSON.stringify(t)), await n.rename(i, e);
458
460
  },
459
- catch: (t) => new F({
461
+ catch: (t) => new P({
460
462
  reason: `ledger write failed: ${String(t?.message ?? t)}`,
461
463
  path: e
462
464
  })
463
- }), pt = (e, t) => t in e.tables, mt = (e, t) => t in e.assets, ht = /* @__PURE__ */ new Set([
465
+ }), ft = (e, t) => t in e.tables, pt = (e, t) => t in e.assets, mt = /* @__PURE__ */ new Set([
464
466
  "json",
465
467
  "array",
466
468
  "vector"
467
- ]), gt = (e) => typeof e == "object" && !!e && !Array.isArray(e) && typeof e.$v == "string", _t = (e) => Buffer.from(e).toString("base64"), vt = (e) => new Uint8Array(Buffer.from(e, "base64")), yt = (e) => e instanceof Date ? e.toISOString() : typeof e == "number" ? new Date(e).toISOString() : String(e), bt = (e, t) => e == null ? null : t !== void 0 && ht.has(t) ? e : t === "bytes" ? _t(e) : t === "timestamp" || t === "date" ? yt(e) : typeof e == "bigint" ? {
469
+ ]), ht = (e) => typeof e == "object" && !!e && !Array.isArray(e) && typeof e.$v == "string", gt = (e) => Buffer.from(e).toString("base64"), _t = (e) => new Uint8Array(Buffer.from(e, "base64")), vt = (e) => e instanceof Date ? e.toISOString() : typeof e == "number" ? new Date(e).toISOString() : String(e), yt = (e, t) => e == null ? null : t !== void 0 && mt.has(t) ? e : t === "bytes" ? gt(e) : t === "timestamp" || t === "date" ? vt(e) : typeof e == "bigint" ? {
468
470
  $v: "bigint",
469
471
  d: e.toString()
470
472
  } : typeof e == "number" && !Number.isFinite(e) ? {
@@ -475,30 +477,30 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
475
477
  d: e.toISOString()
476
478
  } : e instanceof Uint8Array ? {
477
479
  $v: "bytes",
478
- d: _t(e)
479
- } : e, xt = (e) => {
480
+ d: gt(e)
481
+ } : e, bt = (e) => {
480
482
  switch (e.$v) {
481
483
  case "bigint": return BigInt(e.d);
482
484
  case "number": return Number(e.d);
483
485
  case "date": return new Date(e.d);
484
- case "bytes": return vt(e.d);
486
+ case "bytes": return _t(e.d);
485
487
  default: return e;
486
488
  }
487
- }, St = (e, t) => e == null ? null : t !== void 0 && ht.has(t) ? e : gt(e) ? xt(e) : t === "bytes" ? vt(e) : t === "timestamp" || t === "date" ? new Date(e) : e, Ct = (e, t) => {
489
+ }, xt = (e, t) => e == null ? null : t !== void 0 && mt.has(t) ? e : ht(e) ? bt(e) : t === "bytes" ? _t(e) : t === "timestamp" || t === "date" ? new Date(e) : e, St = (e, t) => {
488
490
  let n = {};
489
- for (let [r, i] of Object.entries(e)) n[r] = bt(i, t[r]);
491
+ for (let [r, i] of Object.entries(e)) n[r] = yt(i, t[r]);
490
492
  return n;
491
- }, wt = (e, t) => {
493
+ }, Ct = (e, t) => {
492
494
  let n = {};
493
- for (let [r, i] of Object.entries(e)) n[r] = St(i, t[r]);
495
+ for (let [r, i] of Object.entries(e)) n[r] = xt(i, t[r]);
494
496
  return n;
495
- }, Tt = new TextEncoder(), Et = (e, t) => e.pipe(c.map((e) => Tt.encode(`${JSON.stringify(Ct(e, t))}\n`))), Dt = (e, t, r) => e.pipe(c.decodeText(), c.splitLines, c.filter((e) => e.trim().length > 0), c.mapEffect((e) => n.try({
496
- try: () => wt(JSON.parse(e), r),
497
- catch: (e) => new Ae({
497
+ }, wt = new TextEncoder(), Tt = (e, t) => e.pipe(c.map((e) => wt.encode(`${JSON.stringify(St(e, t))}\n`))), Et = (e, t, r) => e.pipe(c.decodeText(), c.splitLines, c.filter((e) => e.trim().length > 0), c.mapEffect((e) => n.try({
498
+ try: () => Ct(JSON.parse(e), r),
499
+ catch: (e) => new je({
498
500
  table: t,
499
501
  reason: String(e?.message ?? e)
500
502
  })
501
- }))), q = (e, t) => {
503
+ }))), Dt = (e, t) => {
502
504
  let n = new Set(e), r = /* @__PURE__ */ new Map();
503
505
  for (let e of t.tables) {
504
506
  if (!n.has(e.name)) continue;
@@ -518,11 +520,34 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
518
520
  };
519
521
  for (let t of e) n.has(t) && s(t);
520
522
  return i;
521
- }, Ot = (e, t) => {
523
+ }, J = (e) => {
524
+ let t = e, n = [];
525
+ typeof t?._tag == "string" && t._tag !== "" && n.push(t._tag);
526
+ let r = typeof t?.message == "string" ? t.message.trim() : "";
527
+ if (r === "" ? t?.cause !== void 0 && t.cause !== null && n.push(J(t.cause)) : n.push(r), n.length === 0) {
528
+ let t = String(e ?? "").trim();
529
+ return t === "" || t === "[object Object]" ? Ot(e) : t;
530
+ }
531
+ return n.join(": ");
532
+ }, Ot = (e) => {
533
+ try {
534
+ let t = JSON.stringify(e);
535
+ return t === void 0 || t === "{}" ? "unknown error (no message, cause or tag)" : t;
536
+ } catch {
537
+ return "unknown error (not serialisable)";
538
+ }
539
+ }, kt = (e, t) => {
522
540
  let n = e.tables.find((e) => e.name === t), r = {};
523
541
  for (let e of n?.columns ?? []) r[e.name] = e.type;
524
542
  return r;
525
- }, kt = (e, t) => e.tables.find((e) => e.name === t)?.columns.find((e) => e.type === "id")?.name ?? "id", At = (e, t, r) => n.tryPromise({
543
+ }, At = (e, t) => {
544
+ let n = e.tables.find((e) => e.name === t);
545
+ if (n === void 0) return { refusal: `${t}: not in the schema snapshot, so its primary key is unknown.` };
546
+ let r = n.columns.find((e) => e.type === "id");
547
+ if (r !== void 0) return { column: r.name };
548
+ let i = n.indexes.find((e) => e.name === `${t}_pkey`)?.columns ?? n.primaryKey ?? [];
549
+ 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.` };
550
+ }, jt = (e, t, r) => n.tryPromise({
526
551
  try: async () => {
527
552
  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: l, Transform: u } = await import("node:stream"), d = a("sha256"), f = 0, p = new u({ transform(e, t, n) {
528
553
  d.update(e);
@@ -531,7 +556,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
531
556
  n(null, e);
532
557
  } }), m = l.fromWeb(c.toReadableStream(e)), h = `${t}.tmp-${o()}`;
533
558
  try {
534
- await s(m, p, Je(r), n(h)), await i.rename(h, t);
559
+ await s(m, p, qe(r), n(h)), await i.rename(h, t);
535
560
  } catch (e) {
536
561
  throw await i.rm(h, { force: !0 }).catch(() => {}), e;
537
562
  }
@@ -540,108 +565,110 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
540
565
  checksum: d.digest("hex")
541
566
  };
542
567
  },
543
- catch: (e) => new F({
544
- reason: `write table failed: ${String(e?.message ?? e)}`,
568
+ catch: (e) => new P({
569
+ reason: `write table failed: ${J(e)}`,
545
570
  path: t
546
571
  })
547
- }), jt = (e, t) => n.tryPromise({
572
+ }), Mt = (e, t) => n.tryPromise({
548
573
  try: async () => {
549
574
  await (await import("node:fs/promises")).appendFile(e, `${t}\n`);
550
575
  },
551
- catch: (t) => new F({
552
- reason: `append failed: ${String(t?.message ?? t)}`,
576
+ catch: (t) => new P({
577
+ reason: `append failed: ${J(t)}`,
553
578
  path: e
554
579
  })
555
- }), Mt = (e, t) => n.gen(function* () {
556
- let n = [], r = t.ordered.length;
557
- for (let i = 0; i < t.ordered.length; i++) {
558
- let a = t.ordered[i], o = Ot(t.snapshot, a), s = kt(t.snapshot, a), l = `${it}/${a}.ndjson${qe(t.compression)}`;
559
- if (pt(t.ledger, a)) {
560
- let e = t.ledger.tables[a];
561
- W(t.onProgress, {
580
+ }), Nt = (e, t) => n.gen(function* () {
581
+ let r = [], i = t.ordered.length;
582
+ for (let a = 0; a < t.ordered.length; a++) {
583
+ let o = t.ordered[a], s = kt(t.snapshot, o), l = At(t.snapshot, o);
584
+ if ("refusal" in l) return yield* n.fail(new I({ reason: `export: ${l.refusal}` }));
585
+ let u = l.column, d = `${U}/${o}.ndjson${Ke(t.compression)}`;
586
+ if (ft(t.ledger, o)) {
587
+ let e = t.ledger.tables[o];
588
+ K(t.onProgress, {
562
589
  phase: "export",
563
- table: a,
564
- index: i,
565
- tableCount: r,
590
+ table: o,
591
+ index: a,
592
+ tableCount: i,
566
593
  event: "done",
567
594
  rowsDone: e.rowCount,
568
595
  total: e.rowCount
569
- }), n.push({
570
- name: a,
571
- file: l,
596
+ }), r.push({
597
+ name: o,
598
+ file: d,
572
599
  rowCount: e.rowCount,
573
600
  checksum: e.checksum,
574
- columnTypes: o,
575
- primaryKey: s
601
+ columnTypes: s,
602
+ primaryKey: u
576
603
  });
577
604
  continue;
578
605
  }
579
- W(t.onProgress, {
606
+ K(t.onProgress, {
580
607
  phase: "export",
581
- table: a,
582
- index: i,
583
- tableCount: r,
608
+ table: o,
609
+ index: a,
610
+ tableCount: i,
584
611
  event: "start",
585
612
  rowsDone: 0
586
613
  });
587
- let u = t.resolved.predicateFor(a), d = p(e, {
588
- table: a,
589
- pk: s,
614
+ let f = t.resolved.predicateFor(o), m = p(e, {
615
+ table: o,
616
+ pk: u,
590
617
  chunkSize: t.chunkSize,
591
618
  retry: t.retry,
592
- ...u === void 0 ? {} : { where: u }
593
- }), f = t.mask ? d.pipe(c.map((e) => P(e, a, t.mask.actions, t.mask.seed, o))) : d, { rowCount: m, checksum: h } = yield* dt("export", a, i, r, (e) => e.rowCount, At(Et(f, o), t.bundleFile(l), t.compression));
594
- t.ledger.tables[a] = {
595
- rowCount: m,
596
- checksum: h
597
- }, yield* K(t.ledgerPath, t.ledger), W(t.onProgress, {
619
+ ...f === void 0 ? {} : { where: f }
620
+ }), h = t.mask ? m.pipe(c.map((e) => N(e, o, t.mask.actions, t.mask.seed, s))) : m, { rowCount: g, checksum: _ } = yield* lt("export", o, a, i, (e) => e.rowCount, jt(Tt(h, s), t.bundleFile(d), t.compression));
621
+ t.ledger.tables[o] = {
622
+ rowCount: g,
623
+ checksum: _
624
+ }, yield* q(t.ledgerPath, t.ledger), K(t.onProgress, {
598
625
  phase: "export",
599
- table: a,
600
- index: i,
601
- tableCount: r,
626
+ table: o,
627
+ index: a,
628
+ tableCount: i,
602
629
  event: "done",
603
- rowsDone: m,
604
- total: m
605
- }), n.push({
606
- name: a,
607
- file: l,
608
- rowCount: m,
609
- checksum: h,
610
- columnTypes: o,
611
- primaryKey: s
630
+ rowsDone: g,
631
+ total: g
632
+ }), r.push({
633
+ name: o,
634
+ file: d,
635
+ rowCount: g,
636
+ checksum: _,
637
+ columnTypes: s,
638
+ primaryKey: u
612
639
  });
613
640
  }
614
- return n;
615
- }), Nt = (e) => ({
641
+ return r;
642
+ }), Pt = (e) => ({
616
643
  _tag: "RawSqlFragment",
617
644
  strings: [e],
618
645
  values: []
619
- }), Pt = (t, i, a) => n.tryPromise({
646
+ }), Ft = (t, i, a) => n.tryPromise({
620
647
  try: () => t.transactional(async (t) => {
621
- if (t.raw) for (let e of ge(i)) await t.raw(Nt(e));
648
+ if (t.raw) for (let e of ge(i)) await t.raw(Pt(e));
622
649
  let o = await n.runPromiseExit(a(t));
623
650
  if (r.isFailure(o)) throw Error(e.pretty(o.cause));
624
651
  return o.value;
625
652
  }),
626
- catch: (e) => e instanceof F ? e : new F({ reason: `snapshot export failed: ${String(e?.message ?? e)}` })
627
- }), Ft = (e) => n.gen(function* () {
628
- let t = e.scope ?? { kind: "all" }, r = Ke(e.compression), i = e.chunkSize ?? 1e3, a = e.retryTimes ?? 5, s = o.exponential("50 millis").pipe(o.jittered, o.intersect(o.recurs(a))), l = yield* n.promise(() => import("node:path")), u = (t) => l.join(e.outDir, t);
653
+ catch: (e) => e instanceof P ? e : new P({ reason: `snapshot export failed: ${J(e)}` })
654
+ }), It = (e) => n.gen(function* () {
655
+ let t = e.scope ?? { kind: "all" }, r = Ge(e.compression), i = e.chunkSize ?? 1e3, a = e.retryTimes ?? 5, s = o.exponential("50 millis").pipe(o.jittered, o.intersect(o.recurs(a))), l = yield* n.promise(() => import("node:path")), u = (t) => l.join(e.outDir, t);
629
656
  yield* n.tryPromise({
630
657
  try: async () => {
631
658
  let t = await import("node:fs/promises");
632
- await t.mkdir(u(it), { recursive: !0 }), e.assets && await t.mkdir(u(H), { recursive: !0 });
659
+ await t.mkdir(u(U), { recursive: !0 }), e.assets && await t.mkdir(u(W), { recursive: !0 });
633
660
  },
634
- catch: (t) => new F({
635
- reason: `mkdir failed: ${String(t?.message ?? t)}`,
661
+ catch: (t) => new P({
662
+ reason: `mkdir failed: ${J(t)}`,
636
663
  path: e.outDir
637
664
  })
638
665
  });
639
- let d = u(at), f = yield* G(d), p = e.subset ? ze(yield* z(e.store, e.snapshot, e.subset), e.snapshot) : yield* Be(t, e.snapshot, {
666
+ let d = u(rt), f = yield* dt(d), p = e.subset ? ze(yield* z(e.store, e.snapshot, e.subset), e.snapshot) : yield* V(t, e.snapshot, {
640
667
  store: e.store,
641
668
  ...e.tenantTables ? { tenantTables: e.tenantTables } : {}
642
- }), h = q(p.tables, e.snapshot), g = e.consistency ?? "live", _, v;
669
+ }), h = Dt(p.tables, e.snapshot), g = e.consistency ?? "live", _, v;
643
670
  if (e.masking) {
644
- let t = e.classification ?? ve(e.snapshot), r = De(h.map((t) => ({
671
+ let t = e.classification ?? ve(e.snapshot), r = M(h.map((t) => ({
645
672
  name: t,
646
673
  columns: (e.snapshot.tables.find((e) => e.name === t)?.columns ?? []).map((e) => ({
647
674
  name: e.name,
@@ -671,18 +698,18 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
671
698
  bundleFile: u,
672
699
  ...v ? { mask: v } : {},
673
700
  ...e.onProgress ? { onProgress: e.onProgress } : {}
674
- }, b = g === "snapshot" ? yield* Pt(e.store, e.dialect, (e) => Mt(e, y)) : yield* Mt(e.store, y), x = 0, S = 0;
701
+ }, b = g === "snapshot" ? yield* Ft(e.store, e.dialect, (e) => Nt(e, y)) : yield* Nt(e.store, y), x = 0, S = 0;
675
702
  if (e.assets) {
676
- let t = u(U);
677
- yield* c.runForEach(e.assets.list(), (r) => r.key in f.assets ? n.void : e.assets.open(r.key).pipe(n.flatMap((e) => Ue(e, u(H))), n.flatMap((e) => {
703
+ let t = u(G);
704
+ yield* c.runForEach(e.assets.list(), (r) => r.key in f.assets ? n.void : e.assets.open(r.key).pipe(n.flatMap((e) => He(e, u(W))), n.flatMap((e) => {
678
705
  let i = {
679
706
  key: r.key,
680
707
  sha256: e.sha256,
681
708
  size: e.size,
682
709
  contentType: e.contentType
683
710
  };
684
- return x++, S += e.size, f.assets[r.key] = !0, jt(t, JSON.stringify(i)).pipe(n.andThen(K(d, f)));
685
- }))).pipe(n.mapError((e) => e instanceof F ? e : new F({ reason: `asset export failed: ${String(e)}` })));
711
+ return x++, S += e.size, f.assets[r.key] = !0, Mt(t, JSON.stringify(i)).pipe(n.andThen(q(d, f)));
712
+ }))).pipe(n.mapError((e) => e instanceof P ? e : new P({ reason: `asset export failed: ${String(e)}` })));
686
713
  }
687
714
  let C = {
688
715
  formatVersion: 1,
@@ -698,7 +725,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
698
725
  assets: x > 0 ? {
699
726
  count: x,
700
727
  totalBytes: S,
701
- index: U
728
+ index: G
702
729
  } : {
703
730
  count: 0,
704
731
  totalBytes: 0
@@ -707,23 +734,23 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
707
734
  };
708
735
  return yield* n.tryPromise({
709
736
  try: async () => {
710
- await (await import("node:fs/promises")).writeFile(u(V), tt(C));
737
+ await (await import("node:fs/promises")).writeFile(u(H), et(C));
711
738
  },
712
- catch: (e) => new F({
713
- reason: `manifest write failed: ${String(e?.message ?? e)}`,
714
- path: V
739
+ catch: (e) => new P({
740
+ reason: `manifest write failed: ${J(e)}`,
741
+ path: H
715
742
  })
716
743
  }), yield* n.tryPromise({
717
744
  try: async () => {
718
745
  let e = await import("node:fs/promises"), t = await import("node:os");
719
- await e.writeFile(u(rt), st(C, { hostname: t.hostname() }));
746
+ await e.writeFile(u(nt), at(C, { hostname: t.hostname() }));
720
747
  },
721
- catch: (e) => new F({
722
- reason: `readme write failed: ${String(e?.message ?? e)}`,
723
- path: rt
748
+ catch: (e) => new P({
749
+ reason: `readme write failed: ${J(e)}`,
750
+ path: nt
724
751
  })
725
752
  }), C;
726
- }), It = (e) => {
753
+ }), Lt = (e) => {
727
754
  switch (e) {
728
755
  case "id":
729
756
  case "text":
@@ -742,12 +769,12 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
742
769
  case "raw": return "raw";
743
770
  default: return "string";
744
771
  }
745
- }, Lt = {
772
+ }, Rt = {
746
773
  vector: /* @__PURE__ */ new Set(["postgres"]),
747
774
  array: /* @__PURE__ */ new Set(["postgres"]),
748
775
  interval: /* @__PURE__ */ new Set(["postgres"])
749
- }, Rt = (e, t, n, r) => {
750
- let i = It(n);
776
+ }, zt = (e, t, n, r) => {
777
+ let i = Lt(n);
751
778
  if (i === "raw") return {
752
779
  table: e,
753
780
  column: t,
@@ -755,7 +782,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
755
782
  severity: "block",
756
783
  reason: `raw() is verbatim source-dialect SQL — it cannot be assumed valid on ${r}`
757
784
  };
758
- let a = Lt[i];
785
+ let a = Rt[i];
759
786
  return !a || a.has(r) ? null : i === "array" || i === "interval" ? {
760
787
  table: e,
761
788
  column: t,
@@ -769,20 +796,20 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
769
796
  severity: "block",
770
797
  reason: `${i} columns require a ${[...a].join("/")} target; ${r} has no compatible column type`
771
798
  };
772
- }, zt = (e, t, n) => {
799
+ }, Bt = (e, t, n) => {
773
800
  if (t === n) return [];
774
801
  let r = [];
775
802
  for (let t of e) for (let [e, i] of Object.entries(t.columnTypes)) {
776
- let a = Rt(t.name, e, i, n);
803
+ let a = zt(t.name, e, i, n);
777
804
  a && r.push(a);
778
805
  }
779
806
  return r;
780
- }, Bt = (e) => `[${e.severity}] ${e.table}.${e.column} (${e.type}): ${e.reason}`, Vt = (e, t) => new Map((e.tables.find((e) => e.name === t)?.columns ?? []).map((e) => [e.name, e.type])), Ht = (e, t) => {
807
+ }, Vt = (e) => `[${e.severity}] ${e.table}.${e.column} (${e.type}): ${e.reason}`, Ht = (e, t) => new Map((e.tables.find((e) => e.name === t)?.columns ?? []).map((e) => [e.name, e.type])), Ut = (e, t) => {
781
808
  let n = [], r = new Set(e.tables.map((e) => e.name)), i = new Set(t.tables.map((e) => e.name));
782
809
  for (let e of [...r].filter((e) => !i.has(e)).sort()) n.push(`table '${e}' is in the bundle but MISSING from the target`);
783
810
  for (let e of [...i].filter((e) => !r.has(e)).sort()) n.push(`table '${e}' is in the target but NOT in the bundle (import leaves it untouched)`);
784
811
  for (let a of [...r].filter((e) => i.has(e)).sort()) {
785
- let r = Vt(e, a), i = Vt(t, a);
812
+ let r = Ht(e, a), i = Ht(t, a);
786
813
  for (let [e] of r) i.has(e) || n.push(`${a}.${e}: in the bundle, MISSING from the target`);
787
814
  for (let [e] of i) r.has(e) || n.push(`${a}.${e}: in the target, not in the bundle`);
788
815
  for (let [e, t] of r) {
@@ -791,7 +818,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
791
818
  }
792
819
  }
793
820
  return n.length > 30 ? [...n.slice(0, 30), `… and ${n.length - 30} more difference(s)`] : n.length > 0 ? n : ["the schema shape differs (indexes, nullability, or defaults) — the specific change is below the table/column granularity shown here"];
794
- }, Ut = (e, t, n) => {
821
+ }, Wt = (e, t, n) => {
795
822
  let r = m(t);
796
823
  return r === e ? {
797
824
  drifted: !1,
@@ -802,20 +829,20 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
802
829
  drifted: !0,
803
830
  bundleFingerprint: e,
804
831
  targetFingerprint: r,
805
- diff: n ? Ht(n, t) : ["the target schema fingerprint does not match the bundle (no source schema available to itemise the diff — the manifest records only the fingerprint)"]
832
+ diff: n ? Ut(n, t) : ["the target schema fingerprint does not match the bundle (no source schema available to itemise the diff — the manifest records only the fingerprint)"]
806
833
  };
807
- }, Wt = (e) => n.tryPromise({
834
+ }, Gt = (e) => n.tryPromise({
808
835
  try: async () => {
809
836
  let t = await import("node:fs/promises"), n = await import("node:path");
810
- return nt(await t.readFile(n.join(e, V), "utf8"));
837
+ return tt(await t.readFile(n.join(e, H), "utf8"));
811
838
  },
812
- catch: (e) => new F({
839
+ catch: (e) => new P({
813
840
  reason: `manifest read/parse failed: ${String(e?.message ?? e)}`,
814
- path: V
841
+ path: H
815
842
  })
816
- }), Gt = (t) => n.gen(function* () {
817
- let i = yield* n.promise(() => import("node:path")), a = yield* Wt(t.bundleDir);
818
- if (a.formatVersion !== 1) return yield* n.fail(new F({ reason: `unsupported bundle formatVersion ${a.formatVersion} (expected 1)` }));
843
+ }), Kt = (t) => n.gen(function* () {
844
+ let i = yield* n.promise(() => import("node:path")), a = yield* Gt(t.bundleDir);
845
+ if (a.formatVersion !== 1) return yield* n.fail(new P({ reason: `unsupported bundle formatVersion ${a.formatVersion} (expected 1)` }));
819
846
  if (t.targetSnapshot) {
820
847
  let e = { tables: a.tables.map((e) => ({
821
848
  name: e.name,
@@ -827,7 +854,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
827
854
  unique: !1,
828
855
  hasDefault: !1
829
856
  }))
830
- })) }, r = Ut(a.source.schemaFingerprint, t.targetSnapshot, e);
857
+ })) }, r = Wt(a.source.schemaFingerprint, t.targetSnapshot, e);
831
858
  if (r.drifted) {
832
859
  if (!t.force) return yield* n.fail(new Pe({
833
860
  bundleFingerprint: r.bundleFingerprint,
@@ -838,14 +865,14 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
838
865
  }
839
866
  }
840
867
  if (t.targetDialect && t.targetDialect !== a.source.dialect) {
841
- let e = zt(a.tables, a.source.dialect, t.targetDialect).filter((e) => e.severity === "block");
868
+ let e = Bt(a.tables, a.source.dialect, t.targetDialect).filter((e) => e.severity === "block");
842
869
  if (e.length > 0 && !t.allowIncompatible) return yield* n.fail(new Le({
843
870
  sourceDialect: a.source.dialect,
844
871
  targetDialect: t.targetDialect,
845
- blocking: e.map(Bt)
872
+ blocking: e.map(Vt)
846
873
  }));
847
874
  }
848
- let o = t.verify ?? !0, s = t.mode ?? "upsert", l = t.onConflict ?? "skip", u = t.ledgerPath ?? i.join(t.bundleDir, ".import..ledger.json"), f = yield* G(u);
875
+ let o = t.verify ?? !0, s = t.mode ?? "upsert", l = t.onConflict ?? "skip", u = t.ledgerPath ?? i.join(t.bundleDir, ".import..ledger.json"), f = yield* dt(u);
849
876
  if (s === "replace" && a.scope.kind !== "all") return yield* n.fail(new Ie({
850
877
  mode: s,
851
878
  reason: `replace refuses a partial bundle (scope='${a.scope.kind}') — truncating would delete rows not in the bundle. Use --mode upsert, or re-export with full scope.`
@@ -887,15 +914,15 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
887
914
  if (s === "replace" && !(r && f.truncated)) {
888
915
  for (let t of [...a.tables].reverse()) yield* n.tryPromise({
889
916
  try: () => e.deleteMany(t.name, { where: d(t.primaryKey) }),
890
- catch: (e) => new F({ reason: `truncate ${t.name} failed: ${String(e?.message ?? e)}` })
917
+ catch: (e) => new P({ reason: `truncate ${t.name} failed: ${String(e?.message ?? e)}` })
891
918
  });
892
- r && (f.truncated = !0, yield* K(u, f));
919
+ r && (f.truncated = !0, yield* q(u, f));
893
920
  }
894
921
  let l = [], m = [], h = a.tables.length;
895
922
  for (let d = 0; d < a.tables.length; d++) {
896
923
  let g = a.tables[d];
897
924
  if (r && g.name in f.tables) {
898
- W(t.onProgress, {
925
+ K(t.onProgress, {
899
926
  phase: "import",
900
927
  table: g.name,
901
928
  index: d,
@@ -907,7 +934,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
907
934
  continue;
908
935
  }
909
936
  let _ = i.join(t.bundleDir, g.file);
910
- W(t.onProgress, {
937
+ K(t.onProgress, {
911
938
  phase: "import",
912
939
  table: g.name,
913
940
  index: d,
@@ -917,7 +944,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
917
944
  total: g.rowCount
918
945
  });
919
946
  let v = l.length, y = n.gen(function* () {
920
- let { createHash: r } = yield* n.promise(() => import("node:crypto")), i = r("sha256"), o = 0, u = S("bundle", () => E(_).pipe(Ye(a.compression))).pipe(c.tap((e) => n.sync(() => i.update(e)))), d = async (t) => {
947
+ let { createHash: r } = yield* n.promise(() => import("node:crypto")), i = r("sha256"), o = 0, u = S("bundle", () => E(_).pipe(Je(a.compression))).pipe(c.tap((e) => n.sync(() => i.update(e)))), d = async (t) => {
921
948
  let n = {
922
949
  entry: g,
923
950
  row: t,
@@ -961,7 +988,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
961
988
  for (let t of e) await d(t);
962
989
  }
963
990
  };
964
- return yield* c.runForEach(Dt(u, g.name, g.columnTypes), (e) => n.promise(async () => {
991
+ return yield* c.runForEach(Et(u, g.name, g.columnTypes), (e) => n.promise(async () => {
965
992
  if (o++, f) {
966
993
  v.push(e), v.length >= h && await y();
967
994
  return;
@@ -971,20 +998,20 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
971
998
  rowCount: o,
972
999
  checksum: i.digest("hex")
973
1000
  };
974
- }), { rowCount: b, checksum: x } = yield* dt("import", g.name, d, h, (e) => e.rowCount, y);
1001
+ }), { rowCount: b, checksum: x } = yield* lt("import", g.name, d, h, (e) => e.rowCount, y);
975
1002
  if (o) {
976
- if (x !== g.checksum) return yield* n.fail(new I({
1003
+ if (x !== g.checksum) return yield* n.fail(new F({
977
1004
  what: `table ${g.name} checksum`,
978
1005
  expected: g.checksum,
979
1006
  actual: x
980
1007
  }));
981
- if (b !== g.rowCount) return yield* n.fail(new I({
1008
+ if (b !== g.rowCount) return yield* n.fail(new F({
982
1009
  what: `table ${g.name} rowCount`,
983
1010
  expected: String(g.rowCount),
984
1011
  actual: String(b)
985
1012
  }));
986
1013
  }
987
- W(t.onProgress, {
1014
+ K(t.onProgress, {
988
1015
  phase: "import",
989
1016
  table: g.name,
990
1017
  index: d,
@@ -998,7 +1025,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
998
1025
  }) : (f.tables[g.name] = {
999
1026
  rowCount: b,
1000
1027
  checksum: g.checksum
1001
- }, yield* K(u, f)));
1028
+ }, yield* q(u, f)));
1002
1029
  }
1003
1030
  if (l.length > 0 && (yield* g(e, l)), r && m.length > 0) {
1004
1031
  for (let e of m) {
@@ -1008,7 +1035,7 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1008
1035
  checksum: t.checksum
1009
1036
  };
1010
1037
  }
1011
- yield* K(u, f);
1038
+ yield* q(u, f);
1012
1039
  }
1013
1040
  });
1014
1041
  if (t.atomic ? yield* n.tryPromise({
@@ -1016,22 +1043,22 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1016
1043
  let i = await n.runPromiseExit(_(t, !1));
1017
1044
  if (r.isFailure(i)) throw Error(e.pretty(i.cause));
1018
1045
  }),
1019
- catch: (e) => new F({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
1046
+ catch: (e) => new P({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
1020
1047
  }) : yield* _(t.store, !0), t.assets && a.assets.index && !t.assetsAlreadyRestored) {
1021
- let e = t.assets, r = i.join(t.bundleDir, H), o = i.join(t.bundleDir, a.assets.index ?? "assets/index.ndjson"), s = S("bundle", () => E(o)).pipe(c.decodeText(), c.splitLines, c.filter((e) => e.trim().length > 0), c.map((e) => JSON.parse(e)));
1022
- yield* c.runForEach(s, (t) => t.key in f.assets ? n.void : We(e, r, t).pipe(n.andThen(n.sync(() => {
1048
+ let e = t.assets, r = i.join(t.bundleDir, W), o = i.join(t.bundleDir, a.assets.index ?? "assets/index.ndjson"), s = S("bundle", () => E(o)).pipe(c.decodeText(), c.splitLines, c.filter((e) => e.trim().length > 0), c.map((e) => JSON.parse(e)));
1049
+ yield* c.runForEach(s, (t) => t.key in f.assets ? n.void : Ue(e, r, t).pipe(n.andThen(n.sync(() => {
1023
1050
  f.assets[t.key] = !0;
1024
- })), n.andThen(K(u, f))));
1051
+ })), n.andThen(q(u, f))));
1025
1052
  }
1026
1053
  return a;
1027
- }), Kt = (e) => e, qt = (e) => {
1054
+ }), qt = (e) => e, Jt = (e) => {
1028
1055
  if (e.allowLive || e.liveInstance === null || e.sameTarget === "different") return { refuse: !1 };
1029
1056
  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.";
1030
1057
  return {
1031
1058
  refuse: !0,
1032
1059
  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).`
1033
1060
  };
1034
- }, J = Buffer.from("VBUNDLE2"), Y = 0, Jt = 1, Yt = 2, Xt = 32, Zt = async (e) => {
1061
+ }, Y = Buffer.from("VBUNDLE2"), Yt = 0, Xt = 1, Zt = 2, Qt = 32, $t = async (e) => {
1035
1062
  let t = [], n = async (r) => {
1036
1063
  let i;
1037
1064
  try {
@@ -1045,21 +1072,21 @@ voltro data import <this-directory> --target api --api-url <url> --token <secret
1045
1072
  }
1046
1073
  };
1047
1074
  return await n(""), t.sort();
1048
- }, Qt = (e, t) => {
1075
+ }, en = (e, t) => {
1049
1076
  let n = Buffer.from(e, "utf8"), r = Buffer.alloc(5 + n.length + 8);
1050
- return r.writeUInt8(Jt, 0), r.writeUInt32BE(n.length, 1), n.copy(r, 5), r.writeBigUInt64BE(BigInt(t), 5 + n.length), r;
1051
- }, $t = (e, t, n) => {
1077
+ return r.writeUInt8(Xt, 0), r.writeUInt32BE(n.length, 1), n.copy(r, 5), r.writeBigUInt64BE(BigInt(t), 5 + n.length), r;
1078
+ }, tn = (e, t, n) => {
1052
1079
  let r = Buffer.from(e, "utf8"), i = Buffer.from(t, "utf8"), a = Buffer.alloc(5 + r.length + 2 + i.length + 8), o = 0;
1053
- return a.writeUInt8(Yt, 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;
1080
+ return a.writeUInt8(Zt, 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;
1054
1081
  };
1055
- async function* en(e) {
1056
- yield new Uint8Array(J);
1057
- for (let t of await Zt(e.dir)) {
1082
+ async function* nn(e) {
1083
+ yield new Uint8Array(Y);
1084
+ for (let t of await $t(e.dir)) {
1058
1085
  let n = O(e.dir, t), r = await ce(n);
1059
- if (yield new Uint8Array(Qt(t, r.size)), r.size > 0) for await (let e of E(n)) yield new Uint8Array(e);
1086
+ if (yield new Uint8Array(en(t, r.size)), r.size > 0) for await (let e of E(n)) yield new Uint8Array(e);
1060
1087
  }
1061
1088
  if (e.blobs) for await (let t of e.blobs.list()) {
1062
- yield new Uint8Array($t(t.key, t.contentType, t.size));
1089
+ yield new Uint8Array(tn(t.key, t.contentType, t.size));
1063
1090
  let n = _("sha256"), r = 0;
1064
1091
  for await (let i of e.blobs.open(t.key)) {
1065
1092
  let e = Buffer.from(i);
@@ -1068,9 +1095,9 @@ async function* en(e) {
1068
1095
  if (r !== t.size) throw Error(`blob '${t.key}' size mismatch: header ${t.size}, streamed ${r}`);
1069
1096
  yield new Uint8Array(n.digest());
1070
1097
  }
1071
- yield new Uint8Array(Buffer.from([Y]));
1098
+ yield new Uint8Array(Buffer.from([Yt]));
1072
1099
  }
1073
- var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn = (e) => new Promise((t) => e.end(t)), rn = async (e, t) => {
1100
+ var rn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), an = (e) => new Promise((t) => e.end(t)), on = async (e, t) => {
1074
1101
  let n = fe(t.dir);
1075
1102
  await oe(n, { recursive: !0 });
1076
1103
  let r = Buffer.alloc(0), i = e[Symbol.asyncIterator](), a = !1, o = async () => {
@@ -1083,12 +1110,12 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1083
1110
  return r = r.subarray(e), t;
1084
1111
  };
1085
1112
  try {
1086
- if (await s(J.length), !c(J.length).equals(J)) throw Error("not a bundle archive (bad magic)");
1113
+ if (await s(Y.length), !c(Y.length).equals(Y)) throw Error("not a bundle archive (bad magic)");
1087
1114
  for (;;) {
1088
1115
  await s(1);
1089
1116
  let e = c(1).readUInt8(0);
1090
- if (e === Y) return;
1091
- if (e === Jt) {
1117
+ if (e === Yt) return;
1118
+ if (e === Xt) {
1092
1119
  await s(4);
1093
1120
  let e = c(4).readUInt32BE(0);
1094
1121
  await s(e);
@@ -1101,10 +1128,10 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1101
1128
  for (; i > 0n;) {
1102
1129
  r.length === 0 && await s(1);
1103
1130
  let e = i < BigInt(r.length) ? Number(i) : r.length;
1104
- await tn(o, c(e)), i -= BigInt(e);
1131
+ await rn(o, c(e)), i -= BigInt(e);
1105
1132
  }
1106
- await nn(o);
1107
- } else if (e === Yt) {
1133
+ await an(o);
1134
+ } else if (e === Zt) {
1108
1135
  await s(4);
1109
1136
  let e = c(4).readUInt32BE(0);
1110
1137
  await s(e);
@@ -1121,17 +1148,17 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1121
1148
  for (; p > 0n;) {
1122
1149
  r.length === 0 && await s(1);
1123
1150
  let e = p < BigInt(r.length) ? Number(p) : r.length, t = c(e);
1124
- u.update(t), l || await tn(d, t), p -= BigInt(e);
1151
+ u.update(t), l || await rn(d, t), p -= BigInt(e);
1125
1152
  }
1126
- l ? d.destroy() : await nn(d), await f, await s(Xt);
1127
- let m = c(Xt);
1153
+ l ? d.destroy() : await an(d), await f, await s(Qt);
1154
+ let m = c(Qt);
1128
1155
  if (!u.digest().equals(m)) throw Error(`blob '${n}' failed integrity (sha mismatch)`);
1129
1156
  } else throw Error(`unknown bundle entry kind ${e}`);
1130
1157
  }
1131
1158
  } finally {
1132
1159
  a || await Promise.resolve(i.return?.()).catch(() => void 0);
1133
1160
  }
1134
- }, an = async (e, t) => {
1161
+ }, sn = async (e, t) => {
1135
1162
  let n = new Set(t), r = /* @__PURE__ */ new Map(), i = Buffer.alloc(0), a = e[Symbol.asyncIterator](), o = async () => {
1136
1163
  let { value: e, done: t } = await a.next();
1137
1164
  return !t && (i = i.length === 0 ? Buffer.from(e) : Buffer.concat([i, Buffer.from(e)]), !0);
@@ -1150,11 +1177,11 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1150
1177
  }
1151
1178
  return Buffer.concat(t);
1152
1179
  };
1153
- if (!await s(J.length) || !c(J.length).equals(J)) throw Error("not a bundle archive (bad magic)");
1180
+ if (!await s(Y.length) || !c(Y.length).equals(Y)) throw Error("not a bundle archive (bad magic)");
1154
1181
  for (; await s(1);) {
1155
1182
  let e = c(1).readUInt8(0);
1156
- if (e === Y || e === Yt) break;
1157
- if (e !== Jt) throw Error(`unknown bundle entry kind ${e}`);
1183
+ if (e === Yt || e === Zt) break;
1184
+ if (e !== Xt) throw Error(`unknown bundle entry kind ${e}`);
1158
1185
  if (!await s(4)) break;
1159
1186
  let t = c(4).readUInt32BE(0);
1160
1187
  if (!await s(t)) break;
@@ -1164,10 +1191,10 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1164
1191
  if (a === null || n.has(i) && (r.set(i, a), n.delete(i), n.size === 0)) break;
1165
1192
  }
1166
1193
  return r;
1167
- }, on = (e, t) => rn(e, {
1194
+ }, cn = (e, t) => on(e, {
1168
1195
  dir: t,
1169
- blobs: sn(t)
1170
- }), sn = (e) => {
1196
+ blobs: ln(t)
1197
+ }), ln = (e) => {
1171
1198
  let t = /* @__PURE__ */ new Set();
1172
1199
  return {
1173
1200
  has: async (e) => t.has(e),
@@ -1187,33 +1214,33 @@ var tn = (e, t) => new Promise((n, r) => e.write(t, (e) => e ? r(e) : n())), nn
1187
1214
  })}\n`), t.add(n);
1188
1215
  }
1189
1216
  };
1190
- }, cn = me(b), ln = Buffer.from("VENC1\0\0\0"), un = 32, dn = 16, fn = 7, X = 16, pn = 262144, Z = {
1217
+ }, un = me(b), dn = Buffer.from("VENC1\0\0\0"), fn = 32, pn = 16, mn = 7, X = 16, hn = 262144, Z = {
1191
1218
  N: 32768,
1192
1219
  r: 8,
1193
1220
  p: 1
1194
- }, mn = 134217728, Q = 43, hn = (e, t, n) => {
1221
+ }, gn = 134217728, Q = 43, _n = (e, t, n) => {
1195
1222
  let r = Buffer.alloc(12);
1196
- return e.copy(r, 0, 0, fn), r.writeUInt32BE(t >>> 0, fn), r.writeUInt8(+!!n, 11), r;
1223
+ return e.copy(r, 0, 0, mn), r.writeUInt32BE(t >>> 0, mn), r.writeUInt8(+!!n, 11), r;
1197
1224
  };
1198
- async function* gn(e, t) {
1225
+ async function* vn(e, t) {
1199
1226
  if (!t) throw Error("encryptStream: a non-empty passphrase is required");
1200
- let n = y(dn), r = y(fn), i = await cn(t, n, un, {
1227
+ let n = y(pn), r = y(mn), i = await un(t, n, fn, {
1201
1228
  ...Z,
1202
- maxmem: mn
1229
+ maxmem: gn
1203
1230
  }), a = Buffer.alloc(Q);
1204
- ln.copy(a, 0), a.writeUInt32BE(Z.N, 8), a.writeUInt32BE(Z.r, 12), a.writeUInt32BE(Z.p, 16), n.copy(a, 20), r.copy(a, 36), yield new Uint8Array(a);
1231
+ dn.copy(a, 0), a.writeUInt32BE(Z.N, 8), a.writeUInt32BE(Z.r, 12), a.writeUInt32BE(Z.p, 16), n.copy(a, 20), r.copy(a, 36), yield new Uint8Array(a);
1205
1232
  let o = 0, s = (e, t) => {
1206
- let n = h("aes-256-gcm", i, hn(r, o, t));
1233
+ let n = h("aes-256-gcm", i, _n(r, o, t));
1207
1234
  o === 0 && n.setAAD(a);
1208
1235
  let s = Buffer.concat([n.update(e), n.final()]), c = n.getAuthTag();
1209
1236
  o++;
1210
1237
  let l = Buffer.alloc(5 + s.length + X);
1211
1238
  return l.writeUInt8(+!!t, 0), l.writeUInt32BE(s.length + X, 1), s.copy(l, 5), c.copy(l, 5 + s.length), new Uint8Array(l);
1212
1239
  }, c = Buffer.alloc(0);
1213
- for await (let t of e) for (c = c.length === 0 ? Buffer.from(t) : Buffer.concat([c, Buffer.from(t)]); c.length > pn;) yield s(c.subarray(0, pn), !1), c = c.subarray(pn);
1240
+ for await (let t of e) for (c = c.length === 0 ? Buffer.from(t) : Buffer.concat([c, Buffer.from(t)]); c.length > hn;) yield s(c.subarray(0, hn), !1), c = c.subarray(hn);
1214
1241
  yield s(c, !0);
1215
1242
  }
1216
- async function* _n(e, t) {
1243
+ async function* yn(e, t) {
1217
1244
  if (!t) throw Error("decryptStream: a non-empty passphrase is required");
1218
1245
  let n = e[Symbol.asyncIterator](), r = Buffer.alloc(0), i = !1, a = async () => {
1219
1246
  let { value: e, done: t } = await n.next();
@@ -1224,12 +1251,12 @@ async function* _n(e, t) {
1224
1251
  };
1225
1252
  if (!await o(Q)) throw Error("encrypted bundle truncated (no header)");
1226
1253
  let s = r.subarray(0, Q);
1227
- if (!s.subarray(0, 8).equals(ln)) throw Error("not an encrypted bundle (bad magic / wrong passphrase target)");
1228
- 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, Q)), p = await cn(t, d, un, {
1254
+ if (!s.subarray(0, 8).equals(dn)) throw Error("not an encrypted bundle (bad magic / wrong passphrase target)");
1255
+ 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, Q)), p = await un(t, d, fn, {
1229
1256
  N: c,
1230
1257
  r: l,
1231
1258
  p: u,
1232
- maxmem: mn
1259
+ maxmem: gn
1233
1260
  });
1234
1261
  r = r.subarray(Q);
1235
1262
  let m = 0, h = !1;
@@ -1244,7 +1271,7 @@ async function* _n(e, t) {
1244
1271
  if (!await o(5 + t)) throw Error("encrypted bundle truncated (frame body)");
1245
1272
  let n = r.subarray(5, 5 + t - X), i = r.subarray(5 + t - X, 5 + t);
1246
1273
  r = r.subarray(5 + t);
1247
- let a = g("aes-256-gcm", p, hn(f, m, e));
1274
+ let a = g("aes-256-gcm", p, _n(f, m, e));
1248
1275
  m === 0 && a.setAAD(s), a.setAuthTag(i);
1249
1276
  let c = Buffer.concat([a.update(n), a.final()]);
1250
1277
  m++, e && (h = !0), c.length > 0 && (yield new Uint8Array(c));
@@ -1252,7 +1279,7 @@ async function* _n(e, t) {
1252
1279
  }
1253
1280
  //#endregion
1254
1281
  //#region src/blobStorage.ts
1255
- var vn = (e, t) => ({
1282
+ var bn = (e, t) => ({
1256
1283
  list: () => {
1257
1284
  let e = t();
1258
1285
  return { async *[Symbol.asyncIterator]() {
@@ -1268,14 +1295,14 @@ var vn = (e, t) => ({
1268
1295
  let r = await n.runPromise(C(e, t)), i = await te(r.stream);
1269
1296
  for await (let e of i) yield e instanceof Uint8Array ? e : new Uint8Array(e);
1270
1297
  } })
1271
- }), yn = (e, t) => vn(e, () => p(t, {
1298
+ }), xn = (e, t) => bn(e, () => p(t, {
1272
1299
  table: x,
1273
1300
  chunkSize: 500
1274
1301
  }).pipe(c.map((e) => ({
1275
1302
  key: String(e.key),
1276
1303
  contentType: String(e.contentType ?? "application/octet-stream"),
1277
1304
  size: Number(e.size ?? 0)
1278
- })))), bn = (e) => ({
1305
+ })))), Sn = (e) => ({
1279
1306
  has: (t) => n.runPromise(e.head(t).pipe(n.map((e) => e !== null))),
1280
1307
  write: async (t, r, i) => {
1281
1308
  let a = S("storage", () => ne.from(r));
@@ -1284,10 +1311,10 @@ var vn = (e, t) => ({
1284
1311
  totalSize: i.size
1285
1312
  }));
1286
1313
  }
1287
- }), xn = (e, t) => {
1314
+ }), Cn = (e, t) => {
1288
1315
  let n = t === "dump" ? "mariadb-dump" : "mariadb", r = t === "dump" ? "mysqldump" : "mysql";
1289
- return e === "mariadb" && Sn(n) ? n : r;
1290
- }, Sn = (e) => (process.env.PATH ?? "").split(ue).filter((e) => e !== "").some((t) => ie(O(t, e))), Cn = (e) => {
1316
+ return e === "mariadb" && wn(n) ? n : r;
1317
+ }, wn = (e) => (process.env.PATH ?? "").split(ue).filter((e) => e !== "").some((t) => ie(O(t, e))), Tn = (e) => {
1291
1318
  switch (e) {
1292
1319
  case "postgres": return "db.dump";
1293
1320
  case "mysql":
@@ -1297,7 +1324,7 @@ var vn = (e, t) => ({
1297
1324
  case "mssql": return "db.bacpac";
1298
1325
  default: return "db.dump";
1299
1326
  }
1300
- }, wn = (e) => e.filename ?? e.database ?? ((e.url ?? "").replace(/^file:/, "") || "app.sqlite"), $ = (e) => {
1327
+ }, En = (e) => e.filename ?? e.database ?? ((e.url ?? "").replace(/^file:/, "") || "app.sqlite"), $ = (e) => {
1301
1328
  if (e.host || e.database) return {
1302
1329
  host: e.host ?? "localhost",
1303
1330
  port: e.port ?? 3306,
@@ -1313,7 +1340,7 @@ var vn = (e, t) => ({
1313
1340
  password: decodeURIComponent(t.password) || "",
1314
1341
  database: t.pathname.replace(/^\//, "") || ""
1315
1342
  };
1316
- }, Tn = (e) => `Server=${e.host},${e.port};Database=${e.database};User ID=${e.username};Password=${e.password};TrustServerCertificate=True`, En = (e, t, n) => {
1343
+ }, Dn = (e) => `Server=${e.host},${e.port};Database=${e.database};User ID=${e.username};Password=${e.password};TrustServerCertificate=True`, On = (e, t, n) => {
1317
1344
  switch (e) {
1318
1345
  case "postgres": {
1319
1346
  if (t.url) return {
@@ -1360,7 +1387,7 @@ var vn = (e, t) => ({
1360
1387
  let r = $(t);
1361
1388
  return {
1362
1389
  kind: "spawn",
1363
- tool: xn(e, "dump"),
1390
+ tool: Cn(e, "dump"),
1364
1391
  args: [
1365
1392
  "--single-transaction",
1366
1393
  "--routines",
@@ -1382,7 +1409,7 @@ var vn = (e, t) => ({
1382
1409
  case "sqlite":
1383
1410
  case "turso": return {
1384
1411
  kind: "copy",
1385
- from: wn(t),
1412
+ from: En(t),
1386
1413
  to: n
1387
1414
  };
1388
1415
  case "mssql": return {
@@ -1390,7 +1417,7 @@ var vn = (e, t) => ({
1390
1417
  tool: "sqlpackage",
1391
1418
  args: [
1392
1419
  "/Action:Export",
1393
- `/SourceConnectionString:${Tn($({
1420
+ `/SourceConnectionString:${Dn($({
1394
1421
  ...t,
1395
1422
  port: t.port ?? 1433
1396
1423
  }))}`,
@@ -1403,7 +1430,7 @@ var vn = (e, t) => ({
1403
1430
  reason: `no native backup for dialect '${e}'`
1404
1431
  });
1405
1432
  }
1406
- }, Dn = (e, t, n) => {
1433
+ }, kn = (e, t, n) => {
1407
1434
  switch (e) {
1408
1435
  case "postgres": {
1409
1436
  if (t.url) return {
@@ -1448,7 +1475,7 @@ var vn = (e, t) => ({
1448
1475
  let r = $(t);
1449
1476
  return {
1450
1477
  kind: "spawn",
1451
- tool: xn(e, "client"),
1478
+ tool: Cn(e, "client"),
1452
1479
  args: [
1453
1480
  "--protocol=TCP",
1454
1481
  "-h",
@@ -1467,14 +1494,14 @@ var vn = (e, t) => ({
1467
1494
  case "turso": return {
1468
1495
  kind: "copy",
1469
1496
  from: n,
1470
- to: wn(t)
1497
+ to: En(t)
1471
1498
  };
1472
1499
  case "mssql": return {
1473
1500
  kind: "spawn",
1474
1501
  tool: "sqlpackage",
1475
1502
  args: [
1476
1503
  "/Action:Import",
1477
- `/TargetConnectionString:${Tn($({
1504
+ `/TargetConnectionString:${Dn($({
1478
1505
  ...t,
1479
1506
  port: t.port ?? 1433
1480
1507
  }))}`,
@@ -1487,7 +1514,7 @@ var vn = (e, t) => ({
1487
1514
  reason: `no native restore for dialect '${e}'`
1488
1515
  });
1489
1516
  }
1490
- }, On = (e) => e.kind === "copy" ? n.async((t) => {
1517
+ }, An = (e) => e.kind === "copy" ? n.async((t) => {
1491
1518
  re(e.from, e.to, (r) => t(r ? n.fail(new L({
1492
1519
  tool: "copy",
1493
1520
  reason: `copy ${e.from} → ${e.to}: ${r.message}`
@@ -1528,11 +1555,11 @@ var vn = (e, t) => ({
1528
1555
  stderr: i.slice(-2e3)
1529
1556
  })));
1530
1557
  });
1531
- }), kn = (e) => typeof e == "object" && e ? "fake" in e ? `fake:${e.fake}` : "custom" : String(e), An = (e) => n.gen(function* () {
1532
- let t = yield* Be(e.scope ?? { kind: "all" }, e.snapshot, {
1558
+ }), jn = (e) => typeof e == "object" && e ? "fake" in e ? `fake:${e.fake}` : "custom" : String(e), Mn = (e) => n.gen(function* () {
1559
+ let t = yield* V(e.scope ?? { kind: "all" }, e.snapshot, {
1533
1560
  store: e.store,
1534
1561
  ...e.tenantTables ? { tenantTables: e.tenantTables } : {}
1535
- }), r = q(t.tables, e.snapshot), i = e.classification ?? ve(e.snapshot), a = e.sampleSize ?? 20, o = De(r.map((t) => ({
1562
+ }), r = Dt(t.tables, e.snapshot), i = e.classification ?? ve(e.snapshot), a = e.sampleSize ?? 20, o = M(r.map((t) => ({
1536
1563
  name: t,
1537
1564
  columns: (e.snapshot.tables.find((e) => e.name === t)?.columns ?? []).map((e) => ({
1538
1565
  name: e.name,
@@ -1544,15 +1571,15 @@ var vn = (e, t) => ({
1544
1571
  table: i,
1545
1572
  chunkSize: a,
1546
1573
  ...r === void 0 ? {} : { where: r }
1547
- }).pipe(c.take(a), c.runCollect, n.map((e) => [...e])), d = u.map((t) => P(t, i, o.actions, e.masking.seed));
1548
- l.push(...ke(d, i, o.actions));
1574
+ }).pipe(c.take(a), c.runCollect, n.map((e) => [...e])), d = u.map((t) => N(t, i, o.actions, e.masking.seed));
1575
+ l.push(...Ae(d, i, o.actions));
1549
1576
  let f = u[0], m = d[0], h = [];
1550
1577
  if (f && m) for (let [e, t] of Object.entries(o.actions)) {
1551
1578
  if (!e.startsWith(`${i}.`) || t === "keep") continue;
1552
1579
  let n = e.slice(i.length + 1);
1553
1580
  h.push({
1554
1581
  column: n,
1555
- action: kn(t),
1582
+ action: jn(t),
1556
1583
  before: f[n],
1557
1584
  after: m[n]
1558
1585
  });
@@ -1567,7 +1594,7 @@ var vn = (e, t) => ({
1567
1594
  leaks: l,
1568
1595
  unclassified: o.unclassified
1569
1596
  };
1570
- }), jn = (e, t) => {
1597
+ }), Nn = (e, t) => {
1571
1598
  let n = new Map(t.map((e) => [e.name, e])), r = [], i = {};
1572
1599
  for (let t of e) {
1573
1600
  let e = n.get(t.name);
@@ -1622,7 +1649,7 @@ var vn = (e, t) => ({
1622
1649
  skipColumns: i,
1623
1650
  refuse: r.some((e) => e.verdict === "refuse")
1624
1651
  };
1625
- }, Mn = (e) => {
1652
+ }, Pn = (e) => {
1626
1653
  if (e.findings.length === 0) return [" schema matches the bundle"];
1627
1654
  let t = {
1628
1655
  safe: "✓",
@@ -1633,4 +1660,4 @@ var vn = (e, t) => ({
1633
1660
  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;
1634
1661
  };
1635
1662
  //#endregion
1636
- export { H as ASSETS_DIR, U as ASSET_INDEX_FILE, F as BundleError, Ae as CodecError, je as CompressionError, Le as CrossDialectError, it as DATA_DIR, _e as DEFAULT_CLASS_ACTIONS, Ne as DanglingReferenceError, Xe as FORMAT_VERSION, Ie as ImportModeError, I as IntegrityError, at as LEDGER_FILE, V as MANIFEST_FILE, Fe as MaskingError, L as NativeToolError, Pe as SchemaDriftError, Me as ScopeError, Ee as applyAction, qt as assessLiveImport, mt as assetDone, Cn as backupArtifactName, En as backupCommand, It as canonicalType, zt as checkPortability, Ut as checkSchemaDrift, ve as classificationFromSnapshot, jn as classifyImportDrift, qe as compressionExt, z as computeSubsetIds, nt as decodeManifest, wt as decodeRow, St as decodeValue, _n as decryptStream, Kt as defineDataProfile, Ht as diffSnapshots, sn as dirBlobSink, ft as emptyLedger, tt as encodeManifest, Ct as encodeRow, bt as encodeValue, gn as encryptStream, Mn as formatImportDrift, Bt as formatIssue, Ge as hasZstd, Je as makeCompressor, Ye as makeDecompressor, P as maskRow, Dt as ndjsonToRows, en as packBundle, an as peekBundle, Ke as pickCompression, De as planMasking, An as previewMasking, G as readLedger, ye as resolveAction, Be as resolveScope, We as restoreAssetFromCas, Dn as restoreCommand, Et as rowsToNdjson, Ft as runExport, Gt as runImport, On as runNativeStep, ke as scanForLeaks, He as storageAssetSink, Ve as storageAssetSource, bn as storageBlobSink, vn as storageBlobSource, yn as storageRefsBlobSource, ze as subsetToScope, pt as tableDone, q as topoSortTables, rn as unpackBundle, on as unpackBundleToDir, Ue as writeAssetToCas, K as writeLedger };
1663
+ export { W as ASSETS_DIR, G as ASSET_INDEX_FILE, P as BundleError, je as CodecError, Me as CompressionError, Le as CrossDialectError, U as DATA_DIR, _e as DEFAULT_CLASS_ACTIONS, Ne as DanglingReferenceError, Ye as FORMAT_VERSION, Ie as ImportModeError, F as IntegrityError, rt as LEDGER_FILE, H as MANIFEST_FILE, Fe as MaskingError, L as NativeToolError, Pe as SchemaDriftError, I as ScopeError, Oe as applyAction, Jt as assessLiveImport, pt as assetDone, Tn as backupArtifactName, On as backupCommand, Lt as canonicalType, Bt as checkPortability, Wt as checkSchemaDrift, ve as classificationFromSnapshot, Nn as classifyImportDrift, Ke as compressionExt, z as computeSubsetIds, tt as decodeManifest, Ct as decodeRow, xt as decodeValue, yn as decryptStream, qt as defineDataProfile, Ut as diffSnapshots, ln as dirBlobSink, ut as emptyLedger, et as encodeManifest, St as encodeRow, yt as encodeValue, vn as encryptStream, Pn as formatImportDrift, Vt as formatIssue, We as hasZstd, qe as makeCompressor, Je as makeDecompressor, N as maskRow, Et as ndjsonToRows, nn as packBundle, sn as peekBundle, Ge as pickCompression, M as planMasking, Mn as previewMasking, dt as readLedger, ye as resolveAction, V as resolveScope, Ue as restoreAssetFromCas, kn as restoreCommand, Tt as rowsToNdjson, It as runExport, Kt as runImport, An as runNativeStep, Ae as scanForLeaks, Ve as storageAssetSink, Be as storageAssetSource, Sn as storageBlobSink, bn as storageBlobSource, xn as storageRefsBlobSource, ze as subsetToScope, ft as tableDone, Dt as topoSortTables, on as unpackBundle, cn as unpackBundleToDir, He as writeAssetToCas, q as writeLedger };