@voltro/data-transfer 0.85.0 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5987 -0
- package/THIRD-PARTY-NOTICES.md +860 -249
- package/dist/assetAdmission.js +92 -0
- package/dist/assets.js +68 -0
- package/dist/blobStorage.js +64 -0
- package/dist/bundleArchive.js +310 -0
- package/dist/bundleCrypto.js +106 -0
- package/dist/bundlePaths.js +4 -0
- package/dist/casAssetPhase.js +87 -0
- package/dist/compress.js +6 -0
- package/dist/consistency.js +14 -0
- package/dist/crossDialect.js +58 -0
- package/dist/driftClassification.js +58 -0
- package/dist/environmentLocal.js +386 -0
- package/dist/errors.js +89 -0
- package/dist/exporter.js +271 -0
- package/dist/filesystemAdmission.js +33 -0
- package/dist/importer.js +576 -0
- package/dist/index.d.ts +202 -46
- package/dist/index.js +30 -2673
- package/dist/ledger.js +21 -0
- package/dist/liveGuard.js +11 -0
- package/dist/manifest.js +56 -0
- package/dist/masking.js +246 -0
- package/dist/maskingPreview.js +48 -0
- package/dist/nativeDump.js +418 -0
- package/dist/ndjson.js +13 -0
- package/dist/physicalRequest.js +10 -0
- package/dist/profile.js +4 -0
- package/dist/progress.js +17 -0
- package/dist/readme.js +43 -0
- package/dist/replacePreflight.js +23 -0
- package/dist/rollbackCapture.js +36 -0
- package/dist/rowFailureReason.js +36 -0
- package/dist/schemaDrift.js +40 -0
- package/dist/scope.js +40 -0
- package/dist/sealedKeys.js +40 -0
- package/dist/stagedSwap.js +164 -0
- package/dist/storageAssetMetadata.js +47 -0
- package/dist/subset.js +90 -0
- package/dist/topo.js +24 -0
- package/dist/typedCodec.js +36 -0
- package/package.json +3 -3
package/dist/ledger.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BundleError as e } from "./errors.js";
|
|
2
|
+
import { Effect as t } from "effect";
|
|
3
|
+
//#region src/ledger.ts
|
|
4
|
+
var n = () => ({
|
|
5
|
+
tables: {},
|
|
6
|
+
assets: {}
|
|
7
|
+
}), r = (e) => t.tryPromise(async () => {
|
|
8
|
+
let t = await (await import("node:fs/promises")).readFile(e, "utf8");
|
|
9
|
+
return JSON.parse(t);
|
|
10
|
+
}).pipe(t.orElseSucceed(n)), i = (n, r) => t.tryPromise({
|
|
11
|
+
try: async () => {
|
|
12
|
+
let e = await import("node:fs/promises"), { randomUUID: t } = await import("node:crypto"), i = `${n}.tmp-${t()}`;
|
|
13
|
+
await e.writeFile(i, JSON.stringify(r)), await e.rename(i, n);
|
|
14
|
+
},
|
|
15
|
+
catch: (t) => new e({
|
|
16
|
+
reason: `ledger write failed: ${String(t?.message ?? t)}`,
|
|
17
|
+
path: n
|
|
18
|
+
})
|
|
19
|
+
}), a = (e, t) => t in e.tables, o = (e, t) => t in e.assets;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { o as assetDone, n as emptyLedger, r as readLedger, a as tableDone, i as writeLedger };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/liveGuard.ts
|
|
2
|
+
var e = (e) => {
|
|
3
|
+
if (e.allowLive || e.liveInstance === null || e.sameTarget === "different") return { refuse: !1 };
|
|
4
|
+
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.";
|
|
5
|
+
return {
|
|
6
|
+
refuse: !0,
|
|
7
|
+
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).`
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { e as assessLiveImport };
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { isSafeBundlePath as e } from "./bundlePaths.js";
|
|
2
|
+
import { Schema as t } from "effect";
|
|
3
|
+
import { StorageAddress as n } from "@voltro/plugin-storage/errors";
|
|
4
|
+
//#region src/manifest.ts
|
|
5
|
+
var r = 2, i = t.Struct({
|
|
6
|
+
name: t.String,
|
|
7
|
+
file: t.String,
|
|
8
|
+
rowCount: t.Number,
|
|
9
|
+
checksum: t.String,
|
|
10
|
+
columnTypes: t.Record(t.String, t.String),
|
|
11
|
+
primaryKey: t.String
|
|
12
|
+
}), a = t.Struct({
|
|
13
|
+
kind: t.Literals([
|
|
14
|
+
"all",
|
|
15
|
+
"tenant",
|
|
16
|
+
"tables"
|
|
17
|
+
]),
|
|
18
|
+
tenantId: t.optional(t.String),
|
|
19
|
+
tables: t.optional(t.Array(t.String)),
|
|
20
|
+
exclude: t.optional(t.Array(t.String))
|
|
21
|
+
}), o = t.Struct({
|
|
22
|
+
count: t.Number,
|
|
23
|
+
totalBytes: t.Number,
|
|
24
|
+
index: t.optional(t.String.pipe(t.check(t.makeFilter(e))))
|
|
25
|
+
}), s = n, c = t.Struct({
|
|
26
|
+
...s.fields,
|
|
27
|
+
sha256: t.String.pipe(t.check(t.isPattern(/^[a-f0-9]{64}$/))),
|
|
28
|
+
size: t.Number.pipe(t.check(t.isInt()), t.check(t.isGreaterThanOrEqualTo(0)), t.check(t.isLessThanOrEqualTo(2 ** 53 - 1))),
|
|
29
|
+
contentType: t.String.pipe(t.check(t.isMinLength(1)), t.check(t.makeFilter((e) => !/[\uD800-\uDFFF]/u.test(e))))
|
|
30
|
+
}), l = t.Struct({
|
|
31
|
+
formatVersion: t.Number,
|
|
32
|
+
createdAt: t.String,
|
|
33
|
+
source: t.Struct({
|
|
34
|
+
dialect: t.String,
|
|
35
|
+
schemaFingerprint: t.String
|
|
36
|
+
}),
|
|
37
|
+
scope: a,
|
|
38
|
+
consistency: t.Literals(["live", "snapshot"]),
|
|
39
|
+
compression: t.Literals([
|
|
40
|
+
"zstd",
|
|
41
|
+
"gzip",
|
|
42
|
+
"none"
|
|
43
|
+
]),
|
|
44
|
+
tables: t.Array(i),
|
|
45
|
+
assets: o,
|
|
46
|
+
fieldKeys: t.optional(t.Struct({
|
|
47
|
+
keyIds: t.Array(t.String),
|
|
48
|
+
unnamed: t.Number
|
|
49
|
+
})),
|
|
50
|
+
masking: t.optional(t.Struct({
|
|
51
|
+
policyId: t.optional(t.String),
|
|
52
|
+
transformed: t.Array(t.String)
|
|
53
|
+
}))
|
|
54
|
+
}), u = t.encodeSync(t.fromJsonString(l)), d = t.decodeUnknownSync(t.fromJsonString(l)), f = "manifest.json", p = "README.md", m = "data", h = "assets", g = "assets/index.ndjson", _ = ".ledger.json";
|
|
55
|
+
//#endregion
|
|
56
|
+
export { h as ASSETS_DIR, g as ASSET_INDEX_FILE, s as AssetAddress, c as AssetEntry, o as AssetSummary, m as DATA_DIR, a as ExportScope, r as FORMAT_VERSION, _ as LEDGER_FILE, f as MANIFEST_FILE, l as Manifest, p as README_FILE, i as TableEntry, d as decodeManifest, u as encodeManifest };
|
package/dist/masking.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createHmac as e } from "node:crypto";
|
|
2
|
+
//#region src/masking.ts
|
|
3
|
+
var t = {
|
|
4
|
+
email: { fake: "email" },
|
|
5
|
+
fullName: { fake: "fullName" },
|
|
6
|
+
firstName: { fake: "firstName" },
|
|
7
|
+
lastName: { fake: "lastName" },
|
|
8
|
+
username: { fake: "username" },
|
|
9
|
+
phone: { fake: "phone" },
|
|
10
|
+
address: { fake: "address" },
|
|
11
|
+
company: { fake: "company" },
|
|
12
|
+
url: { fake: "url" },
|
|
13
|
+
ip: { fake: "ip" },
|
|
14
|
+
creditCard: { fake: "creditCard" },
|
|
15
|
+
date: "dateShift",
|
|
16
|
+
secret: "null",
|
|
17
|
+
freeText: "redact"
|
|
18
|
+
}, n = (e) => {
|
|
19
|
+
let t = {};
|
|
20
|
+
for (let n of e.tables) {
|
|
21
|
+
let e = {};
|
|
22
|
+
for (let t of n.columns) e[t.name] = {
|
|
23
|
+
...t.sensitive ? { sensitive: t.sensitive } : {},
|
|
24
|
+
...t.safe ? { safe: !0 } : {},
|
|
25
|
+
columnType: t.type
|
|
26
|
+
};
|
|
27
|
+
t[n.name] = e;
|
|
28
|
+
}
|
|
29
|
+
return t;
|
|
30
|
+
}, r = (e, n, r, i) => {
|
|
31
|
+
let a = i.columns?.[`${e}.${n}`];
|
|
32
|
+
if (a) return a;
|
|
33
|
+
if (r?.sensitive) {
|
|
34
|
+
let e = r.sensitive.class;
|
|
35
|
+
return i.classes?.[e] ?? t[e] ?? "redact";
|
|
36
|
+
}
|
|
37
|
+
return r?.safe ? i.onSafe ?? "keep" : r?.columnType === "id" || r?.columnType === "reference" ? "keep" : i.onUnclassified ?? "error";
|
|
38
|
+
}, i = (t, n) => e("sha256", t).update(n == null ? "∅" : String(n)).digest(), a = (e, t) => e.readUInt32BE(t * 4 % (e.length - 4)), o = [
|
|
39
|
+
"Ada",
|
|
40
|
+
"Alan",
|
|
41
|
+
"Grace",
|
|
42
|
+
"Linus",
|
|
43
|
+
"Ida",
|
|
44
|
+
"Ken",
|
|
45
|
+
"Barbara",
|
|
46
|
+
"Dennis",
|
|
47
|
+
"Radia",
|
|
48
|
+
"Guido",
|
|
49
|
+
"Margaret",
|
|
50
|
+
"Bjarne"
|
|
51
|
+
], s = [
|
|
52
|
+
"Lovelace",
|
|
53
|
+
"Turing",
|
|
54
|
+
"Hopper",
|
|
55
|
+
"Torvalds",
|
|
56
|
+
"Rhodes",
|
|
57
|
+
"Thompson",
|
|
58
|
+
"Liskov",
|
|
59
|
+
"Ritchie",
|
|
60
|
+
"Perlman",
|
|
61
|
+
"Rossum",
|
|
62
|
+
"Hamilton",
|
|
63
|
+
"Stroustrup"
|
|
64
|
+
], c = [
|
|
65
|
+
"Maple",
|
|
66
|
+
"Oak",
|
|
67
|
+
"Cedar",
|
|
68
|
+
"Pine",
|
|
69
|
+
"Elm",
|
|
70
|
+
"Birch",
|
|
71
|
+
"Willow",
|
|
72
|
+
"Ash"
|
|
73
|
+
], l = [
|
|
74
|
+
"Initech",
|
|
75
|
+
"Hooli",
|
|
76
|
+
"Umbrella",
|
|
77
|
+
"Acme",
|
|
78
|
+
"Globex",
|
|
79
|
+
"Soylent",
|
|
80
|
+
"Stark",
|
|
81
|
+
"Wayne"
|
|
82
|
+
], u = (e, t, n) => e[a(t, n) % e.length], d = (e, t, n) => {
|
|
83
|
+
let r = i(n, `${e}:${String(t)}`), d = a(r, 1) % 1e4;
|
|
84
|
+
switch (e) {
|
|
85
|
+
case "email": return `${u(o, r, 0).toLowerCase()}.${u(s, r, 2).toLowerCase()}${d}@example.com`;
|
|
86
|
+
case "fullName": return `${u(o, r, 0)} ${u(s, r, 1)}`;
|
|
87
|
+
case "firstName": return u(o, r, 0);
|
|
88
|
+
case "lastName": return u(s, r, 1);
|
|
89
|
+
case "username": return `${u(o, r, 0).toLowerCase()}${d}`;
|
|
90
|
+
case "phone": return `+1${String(a(r, 0) % 1e10).padStart(10, "0")}`;
|
|
91
|
+
case "address": return `${a(r, 0) % 9899 + 100} ${u(c, r, 1)} St`;
|
|
92
|
+
case "company": return u(l, r, 0);
|
|
93
|
+
case "url": return `https://example.com/${r.toString("hex").slice(0, 12)}`;
|
|
94
|
+
case "ip": return `${a(r, 0) % 256}.${a(r, 1) % 256}.${a(r, 2) % 256}.${a(r, 3) % 254 + 1}`;
|
|
95
|
+
case "creditCard": return f(`4${r.toString("hex").replace(/\D/g, "").padEnd(14, "0").slice(0, 14)}`);
|
|
96
|
+
default: return `${e}_${r.toString("hex").slice(0, 8)}`;
|
|
97
|
+
}
|
|
98
|
+
}, f = (e) => {
|
|
99
|
+
let t = e.slice(0, 15).split("").map(Number), n = 0;
|
|
100
|
+
t.forEach((e, t) => {
|
|
101
|
+
let r = e;
|
|
102
|
+
(15 - t) % 2 == 1 && (r *= 2, r > 9 && (r -= 9)), n += r;
|
|
103
|
+
});
|
|
104
|
+
let r = (10 - n % 10) % 10;
|
|
105
|
+
return e.slice(0, 15) + String(r);
|
|
106
|
+
}, p = 864e5, m = (e, t) => {
|
|
107
|
+
let n = e instanceof Date ? e.getTime() : Date.parse(String(e));
|
|
108
|
+
if (Number.isNaN(n)) return e;
|
|
109
|
+
let r = a(i(t, "date-shift-offset"), 0) % 730 - 365, o = new Date(n + r * p);
|
|
110
|
+
return e instanceof Date ? o : o.toISOString();
|
|
111
|
+
}, h = (e, t) => {
|
|
112
|
+
if (t.value === null || t.value === void 0) return null;
|
|
113
|
+
if (e === "error") throw Error(`masking: unresolved 'error' action for ${t.table}.${t.column}`);
|
|
114
|
+
if (e === "keep") return t.value;
|
|
115
|
+
if (e === "null") return null;
|
|
116
|
+
if (e === "redact") return t.columnType === "text" || typeof t.value == "string" ? "[redacted]" : null;
|
|
117
|
+
if (e === "hash") return i(t.seed, t.value).toString("hex").slice(0, 16);
|
|
118
|
+
if (e === "dateShift") return m(t.value, t.seed);
|
|
119
|
+
if (typeof e == "object" && "fake" in e) return d(e.fake, t.value, t.seed);
|
|
120
|
+
if (typeof e == "object" && "custom" in e) return e.custom(t);
|
|
121
|
+
if (typeof e == "object" && "json" in e) return g(e, t);
|
|
122
|
+
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 } | { json: { fields, rest? } }.`);
|
|
123
|
+
}, g = (e, t) => {
|
|
124
|
+
let { fields: n, rest: r = "redact" } = e.json, i = typeof t.value == "string" ? _(t.value) : {
|
|
125
|
+
ok: !0,
|
|
126
|
+
value: t.value
|
|
127
|
+
};
|
|
128
|
+
if (!i.ok) return h(r, {
|
|
129
|
+
...t,
|
|
130
|
+
columnType: "text"
|
|
131
|
+
});
|
|
132
|
+
let a = (e, i) => {
|
|
133
|
+
if (e == null) return null;
|
|
134
|
+
if (Array.isArray(e)) return e.map((e, t) => a(e, `${i}[${t}]`));
|
|
135
|
+
if (typeof e == "object") {
|
|
136
|
+
let a = {};
|
|
137
|
+
for (let [o, s] of Object.entries(e)) {
|
|
138
|
+
let e = n[o] ?? r, c = `${i}.${o}`;
|
|
139
|
+
a[o] = typeof e == "object" && "json" in e ? g(e, {
|
|
140
|
+
...t,
|
|
141
|
+
value: s,
|
|
142
|
+
column: c,
|
|
143
|
+
columnType: "json"
|
|
144
|
+
}) : h(e, {
|
|
145
|
+
...t,
|
|
146
|
+
value: s,
|
|
147
|
+
column: c,
|
|
148
|
+
columnType: typeof s == "string" ? "text" : "json"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return a;
|
|
152
|
+
}
|
|
153
|
+
return h(r, {
|
|
154
|
+
...t,
|
|
155
|
+
value: e,
|
|
156
|
+
column: i,
|
|
157
|
+
columnType: typeof e == "string" ? "text" : "json"
|
|
158
|
+
});
|
|
159
|
+
}, o = a(i.value, t.column);
|
|
160
|
+
return typeof t.value == "string" ? JSON.stringify(o) : o;
|
|
161
|
+
}, _ = (e) => {
|
|
162
|
+
try {
|
|
163
|
+
return {
|
|
164
|
+
ok: !0,
|
|
165
|
+
value: JSON.parse(e)
|
|
166
|
+
};
|
|
167
|
+
} catch {
|
|
168
|
+
return { ok: !1 };
|
|
169
|
+
}
|
|
170
|
+
}, v = (e) => {
|
|
171
|
+
if (typeof e == "string") return e === "keep" || e === "null" || e === "redact" || e === "hash" || e === "dateShift" || e === "error";
|
|
172
|
+
if (typeof e != "object" || !e) return !1;
|
|
173
|
+
if ("fake" in e) return typeof e.fake == "string";
|
|
174
|
+
if ("custom" in e) return typeof e.custom == "function";
|
|
175
|
+
if ("json" in e) {
|
|
176
|
+
let t = e.json;
|
|
177
|
+
if (typeof t != "object" || !t) return !1;
|
|
178
|
+
let { fields: n, rest: r } = t;
|
|
179
|
+
return typeof n != "object" || !n ? !1 : Object.values(n).every(v) && (r === void 0 || v(r));
|
|
180
|
+
}
|
|
181
|
+
return !1;
|
|
182
|
+
}, y = (e, t, n) => {
|
|
183
|
+
let i = {}, a = [], o = [];
|
|
184
|
+
for (let s of e) for (let e of s.columns) {
|
|
185
|
+
let c = `${s.name}.${e.name}`, l = r(s.name, e.name, t[s.name]?.[e.name], n);
|
|
186
|
+
l === "error" ? a.push(c) : v(l) ? i[c] = l : o.push({
|
|
187
|
+
column: c,
|
|
188
|
+
action: l
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
actions: i,
|
|
193
|
+
unclassified: a,
|
|
194
|
+
invalid: o
|
|
195
|
+
};
|
|
196
|
+
}, b = [
|
|
197
|
+
{
|
|
198
|
+
name: "email",
|
|
199
|
+
re: /[\w.+-]+@[\w-]+\.[\w.-]+/
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
name: "phone",
|
|
203
|
+
re: /(?:\+?\d[\d\s().-]{8,}\d)/
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: "ipv4",
|
|
207
|
+
re: /\b(?:\d{1,3}\.){3}\d{1,3}\b/
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "creditCard",
|
|
211
|
+
re: /\b(?:\d[ -]?){13,16}\b/
|
|
212
|
+
}
|
|
213
|
+
], x = (e, t, n) => {
|
|
214
|
+
let r = [], i = /* @__PURE__ */ new Set();
|
|
215
|
+
for (let [a, o] of Object.entries(n)) {
|
|
216
|
+
if (!a.startsWith(`${t}.`) || o !== "keep") continue;
|
|
217
|
+
let n = a.slice(t.length + 1);
|
|
218
|
+
for (let a of e) {
|
|
219
|
+
let e = a[n];
|
|
220
|
+
if (typeof e != "string" || e.length === 0) continue;
|
|
221
|
+
let o = b.find((t) => t.re.test(e));
|
|
222
|
+
if (o && !i.has(n)) {
|
|
223
|
+
i.add(n), r.push({
|
|
224
|
+
table: t,
|
|
225
|
+
column: n,
|
|
226
|
+
pattern: o.name,
|
|
227
|
+
sample: e.slice(0, 40)
|
|
228
|
+
});
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return r;
|
|
234
|
+
}, S = (e, t, n, r, i) => {
|
|
235
|
+
let a = {};
|
|
236
|
+
for (let [o, s] of Object.entries(e)) a[o] = h(n[`${t}.${o}`] ?? "keep", {
|
|
237
|
+
value: s,
|
|
238
|
+
table: t,
|
|
239
|
+
column: o,
|
|
240
|
+
seed: r,
|
|
241
|
+
...i?.[o] ? { columnType: i[o] } : {}
|
|
242
|
+
});
|
|
243
|
+
return a;
|
|
244
|
+
};
|
|
245
|
+
//#endregion
|
|
246
|
+
export { t as DEFAULT_CLASS_ACTIONS, h as applyAction, n as classificationFromSnapshot, v as isMaskAction, S as maskRow, y as planMasking, r as resolveAction, x as scanForLeaks };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { classificationFromSnapshot as e, maskRow as t, planMasking as n, scanForLeaks as r } from "./masking.js";
|
|
2
|
+
import { resolveScope as i } from "./scope.js";
|
|
3
|
+
import { topoSortTables as a } from "./topo.js";
|
|
4
|
+
import { Effect as o, Stream as s } from "effect";
|
|
5
|
+
import { streamTable as c } from "@voltro/database";
|
|
6
|
+
//#region src/maskingPreview.ts
|
|
7
|
+
var l = (e) => typeof e == "object" && e ? "fake" in e ? `fake:${e.fake}` : "custom" : String(e), u = (u) => o.gen(function* () {
|
|
8
|
+
let d = u.scope ?? { kind: "all" }, f = yield* i(d, u.snapshot, {
|
|
9
|
+
store: u.store,
|
|
10
|
+
...u.tenantTables ? { tenantTables: u.tenantTables } : {}
|
|
11
|
+
}), p = a(f.tables, u.snapshot), m = u.classification ?? e(u.snapshot), h = u.sampleSize ?? 20, g = p.map((e) => ({
|
|
12
|
+
name: e,
|
|
13
|
+
columns: (u.snapshot.tables.find((t) => t.name === e)?.columns ?? []).map((e) => ({
|
|
14
|
+
name: e.name,
|
|
15
|
+
type: e.type
|
|
16
|
+
}))
|
|
17
|
+
})), _ = n(g, m, u.masking), v = [], y = [];
|
|
18
|
+
for (let e of p) {
|
|
19
|
+
let n = f.predicateFor(e), i = yield* c(u.store, {
|
|
20
|
+
table: e,
|
|
21
|
+
chunkSize: h,
|
|
22
|
+
...n === void 0 ? {} : { where: n }
|
|
23
|
+
}).pipe(s.take(h), s.runCollect, o.map((e) => [...e])), a = i.map((n) => t(n, e, _.actions, u.masking.seed));
|
|
24
|
+
y.push(...r(a, e, _.actions));
|
|
25
|
+
let d = i[0], p = a[0], m = [];
|
|
26
|
+
if (d && p) for (let [t, n] of Object.entries(_.actions)) {
|
|
27
|
+
if (!t.startsWith(`${e}.`) || n === "keep") continue;
|
|
28
|
+
let r = t.slice(e.length + 1);
|
|
29
|
+
m.push({
|
|
30
|
+
column: r,
|
|
31
|
+
action: l(n),
|
|
32
|
+
before: d[r],
|
|
33
|
+
after: p[r]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
v.push({
|
|
37
|
+
table: e,
|
|
38
|
+
samples: m
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
tables: v,
|
|
43
|
+
leaks: y,
|
|
44
|
+
unclassified: _.unclassified
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { u as previewMasking };
|