@voltro/data-transfer 0.86.0 → 0.88.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 +5484 -0
- package/THIRD-PARTY-NOTICES.md +2503 -690
- package/dist/assetAdmission.js +91 -0
- package/dist/assets.js +62 -42
- package/dist/blobStorage.js +55 -32
- package/dist/bundleArchive.js +249 -105
- package/dist/bundleCrypto.js +1 -2
- package/dist/bundlePaths.js +3 -0
- package/dist/casAssetPhase.js +78 -35
- package/dist/compress.js +4 -5
- package/dist/consistency.js +1 -2
- package/dist/crossDialect.js +1 -2
- package/dist/driftClassification.js +1 -2
- package/dist/environmentLocal.js +267 -4
- package/dist/errors.js +13 -7
- package/dist/exporter.js +146 -133
- package/dist/filesystemAdmission.js +32 -0
- package/dist/importer.js +326 -287
- package/dist/index.d.ts +200 -46
- package/dist/index.js +28 -26
- package/dist/ledger.js +1 -2
- package/dist/liveGuard.js +1 -2
- package/dist/manifest.js +45 -42
- package/dist/masking.js +1 -2
- package/dist/maskingPreview.js +1 -2
- package/dist/nativeDump.js +134 -86
- package/dist/ndjson.js +1 -2
- package/dist/physicalRequest.js +9 -0
- package/dist/profile.js +1 -2
- package/dist/progress.js +1 -2
- package/dist/readme.js +1 -2
- package/dist/replacePreflight.js +1 -2
- package/dist/rollbackCapture.js +1 -2
- package/dist/rowFailureReason.js +1 -2
- package/dist/schemaDrift.js +1 -2
- package/dist/scope.js +1 -2
- package/dist/sealedKeys.js +39 -0
- package/dist/stagedSwap.js +1 -2
- package/dist/storageAssetMetadata.js +46 -0
- package/dist/subset.js +1 -2
- package/dist/topo.js +1 -2
- package/dist/typedCodec.js +1 -2
- package/package.json +4 -4
package/dist/exporter.js
CHANGED
|
@@ -1,257 +1,270 @@
|
|
|
1
1
|
import { snapshotPrelude as e } from "./consistency.js";
|
|
2
2
|
import { classificationFromSnapshot as t, maskRow as n, planMasking as r } from "./masking.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
import { emptyTally as i, mergeTally as a, tallyRow as o } from "./sealedKeys.js";
|
|
4
|
+
import { BundleError as s, MaskingError as c, ScopeError as l } from "./errors.js";
|
|
5
|
+
import { computeSubsetIds as u, subsetToScope as d } from "./subset.js";
|
|
6
|
+
import { resolveScope as f } from "./scope.js";
|
|
7
|
+
import { ASSETS_DIR as p, ASSET_INDEX_FILE as m, DATA_DIR as h, LEDGER_FILE as g, MANIFEST_FILE as _, README_FILE as v, encodeManifest as y } from "./manifest.js";
|
|
8
|
+
import { captureAssetsToCas as b } from "./casAssetPhase.js";
|
|
9
|
+
import { compressionExt as x, makeCompressor as S, pickCompression as C } from "./compress.js";
|
|
10
|
+
import { buildReadme as w } from "./readme.js";
|
|
11
|
+
import { reportProgress as T, withTableSpan as E } from "./progress.js";
|
|
12
|
+
import { readLedger as D, tableDone as O, writeLedger as k } from "./ledger.js";
|
|
13
|
+
import { rowsToNdjson as A } from "./ndjson.js";
|
|
14
|
+
import { topoSortTables as j } from "./topo.js";
|
|
15
|
+
import { Cause as M, Effect as N, Exit as P, Schedule as F, Stream as I } from "effect";
|
|
16
|
+
import { streamTable as L } from "@voltro/database";
|
|
17
|
+
import { fingerprintSchema as R } from "@voltro/database/sql";
|
|
18
|
+
// src/exporter.ts
|
|
19
|
+
var z = (e) => {
|
|
19
20
|
let t = e, n = [];
|
|
20
21
|
typeof t?._tag == "string" && t._tag !== "" && n.push(t._tag);
|
|
21
22
|
let r = typeof t?.message == "string" ? t.message.trim() : "";
|
|
22
|
-
if (r === "" ? t?.cause !== void 0 && t.cause !== null && n.push(
|
|
23
|
+
if (r === "" ? t?.cause !== void 0 && t.cause !== null && n.push(z(t.cause)) : n.push(r), n.length === 0) {
|
|
23
24
|
let t = String(e ?? "").trim();
|
|
24
|
-
return t === "" || t === "[object Object]" ?
|
|
25
|
+
return t === "" || t === "[object Object]" ? B(e) : t;
|
|
25
26
|
}
|
|
26
27
|
return n.join(": ");
|
|
27
|
-
},
|
|
28
|
+
}, B = (e) => {
|
|
28
29
|
try {
|
|
29
30
|
let t = JSON.stringify(e);
|
|
30
31
|
return t === void 0 || t === "{}" ? "unknown error (no message, cause or tag)" : t;
|
|
31
32
|
} catch {
|
|
32
33
|
return "unknown error (not serialisable)";
|
|
33
34
|
}
|
|
34
|
-
},
|
|
35
|
+
}, V = (e, t) => {
|
|
35
36
|
let n = e.tables.find((e) => e.name === t), r = {};
|
|
36
37
|
for (let e of n?.columns ?? []) e.generatedAs === void 0 && (r[e.name] = e.type);
|
|
37
38
|
return r;
|
|
38
|
-
},
|
|
39
|
+
}, H = (e, t) => (e.tables.find((e) => e.name === t)?.columns ?? []).filter((e) => e.generatedAs !== void 0).map((e) => e.name), U = (e, t) => {
|
|
39
40
|
if (t.length === 0) return e;
|
|
40
41
|
let n = { ...e };
|
|
41
42
|
for (let e of t) delete n[e];
|
|
42
43
|
return n;
|
|
43
|
-
},
|
|
44
|
+
}, W = (e, t) => {
|
|
44
45
|
let n = e.tables.find((e) => e.name === t);
|
|
45
46
|
if (n === void 0) return { refusal: `${t}: not in the schema snapshot, so its primary key is unknown.` };
|
|
46
47
|
let r = n.columns.find((e) => e.type === "id");
|
|
47
48
|
if (r !== void 0) return { column: r.name };
|
|
48
49
|
let i = n.indexes.find((e) => e.name === `${t}_pkey`)?.columns ?? n.primaryKey ?? [];
|
|
49
50
|
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.` };
|
|
50
|
-
},
|
|
51
|
+
}, G = (e, t, n) => N.tryPromise({
|
|
51
52
|
try: async () => {
|
|
52
|
-
let { createWriteStream: r } = 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: l } = await import("node:stream"), u = a("sha256"), d = 0,
|
|
53
|
+
let { createWriteStream: r } = 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: l } = await import("node:stream"), u = a("sha256"), d = 0, f = new l({ transform(e, t, n) {
|
|
53
54
|
u.update(e);
|
|
54
55
|
let r = e;
|
|
55
56
|
for (let e = 0; e < r.length; e++) r[e] === 10 && d++;
|
|
56
57
|
n(null, e);
|
|
57
|
-
} }),
|
|
58
|
+
} }), p = c.fromWeb(I.toReadableStream(e)), m = `${t}.tmp-${o()}`;
|
|
58
59
|
try {
|
|
59
|
-
await s(
|
|
60
|
+
await s(p, f, S(n), r(m)), await i.rename(m, t);
|
|
60
61
|
} catch (e) {
|
|
61
|
-
throw await i.rm(
|
|
62
|
+
throw await i.rm(m, { force: !0 }).catch(() => {}), e;
|
|
62
63
|
}
|
|
63
64
|
return {
|
|
64
65
|
rowCount: d,
|
|
65
66
|
checksum: u.digest("hex")
|
|
66
67
|
};
|
|
67
68
|
},
|
|
68
|
-
catch: (e) => new
|
|
69
|
-
reason: `write table failed: ${
|
|
69
|
+
catch: (e) => new s({
|
|
70
|
+
reason: `write table failed: ${z(e)}`,
|
|
70
71
|
path: t
|
|
71
72
|
})
|
|
72
|
-
}),
|
|
73
|
+
}), K = (e, t) => N.tryPromise({
|
|
73
74
|
try: async () => {
|
|
74
75
|
await (await import("node:fs/promises")).appendFile(e, `${t}\n`);
|
|
75
76
|
},
|
|
76
|
-
catch: (t) => new
|
|
77
|
-
reason: `append failed: ${
|
|
77
|
+
catch: (t) => new s({
|
|
78
|
+
reason: `append failed: ${z(t)}`,
|
|
78
79
|
path: e
|
|
79
80
|
})
|
|
80
|
-
}),
|
|
81
|
-
let r = [],
|
|
82
|
-
for (let
|
|
83
|
-
let
|
|
84
|
-
if ("refusal" in
|
|
85
|
-
let
|
|
86
|
-
if (
|
|
87
|
-
let e = t.ledger.tables[
|
|
88
|
-
|
|
81
|
+
}), q = (e, t) => N.gen(function* () {
|
|
82
|
+
let r = [], s = t.ordered.length;
|
|
83
|
+
for (let c = 0; c < t.ordered.length; c++) {
|
|
84
|
+
let u = t.ordered[c], d = V(t.snapshot, u), f = W(t.snapshot, u);
|
|
85
|
+
if ("refusal" in f) return yield* N.fail(new l({ reason: `export: ${f.refusal}` }));
|
|
86
|
+
let p = f.column, m = `${h}/${u}.ndjson${x(t.compression)}`;
|
|
87
|
+
if (O(t.ledger, u)) {
|
|
88
|
+
let e = t.ledger.tables[u];
|
|
89
|
+
e.sealed !== void 0 && a(t.sealed, e.sealed), T(t.onProgress, {
|
|
89
90
|
phase: "export",
|
|
90
|
-
table:
|
|
91
|
-
index:
|
|
92
|
-
tableCount:
|
|
91
|
+
table: u,
|
|
92
|
+
index: c,
|
|
93
|
+
tableCount: s,
|
|
93
94
|
event: "done",
|
|
94
95
|
rowsDone: e.rowCount,
|
|
95
96
|
total: e.rowCount
|
|
96
97
|
}), r.push({
|
|
97
|
-
name:
|
|
98
|
-
file:
|
|
98
|
+
name: u,
|
|
99
|
+
file: m,
|
|
99
100
|
rowCount: e.rowCount,
|
|
100
101
|
checksum: e.checksum,
|
|
101
|
-
columnTypes:
|
|
102
|
-
primaryKey:
|
|
102
|
+
columnTypes: d,
|
|
103
|
+
primaryKey: p
|
|
103
104
|
});
|
|
104
105
|
continue;
|
|
105
106
|
}
|
|
106
|
-
|
|
107
|
+
T(t.onProgress, {
|
|
107
108
|
phase: "export",
|
|
108
|
-
table:
|
|
109
|
-
index:
|
|
110
|
-
tableCount:
|
|
109
|
+
table: u,
|
|
110
|
+
index: c,
|
|
111
|
+
tableCount: s,
|
|
111
112
|
event: "start",
|
|
112
113
|
rowsDone: 0
|
|
113
114
|
});
|
|
114
|
-
let
|
|
115
|
-
table:
|
|
116
|
-
pk:
|
|
115
|
+
let g = t.resolved.predicateFor(u), _ = L(e, {
|
|
116
|
+
table: u,
|
|
117
|
+
pk: p,
|
|
117
118
|
chunkSize: t.chunkSize,
|
|
118
119
|
retry: t.retry,
|
|
119
|
-
...
|
|
120
|
-
}),
|
|
121
|
-
t.ledger.tables[
|
|
122
|
-
rowCount:
|
|
123
|
-
checksum:
|
|
124
|
-
|
|
120
|
+
...g === void 0 ? {} : { where: g }
|
|
121
|
+
}), v = H(t.snapshot, u), y = v.length === 0 ? _ : _.pipe(I.map((e) => U(e, v))), b = t.mask ? y.pipe(I.map((e) => n(e, u, t.mask.actions, t.mask.seed, d))) : y, S = i(), C = b.pipe(I.map((e) => (o(e, S), e))), { rowCount: w, checksum: D } = yield* E("export", u, c, s, (e) => e.rowCount, G(A(C, d), t.bundleFile(m), t.compression));
|
|
122
|
+
t.ledger.tables[u] = {
|
|
123
|
+
rowCount: w,
|
|
124
|
+
checksum: D,
|
|
125
|
+
sealed: S
|
|
126
|
+
}, a(t.sealed, S), yield* k(t.ledgerPath, t.ledger), T(t.onProgress, {
|
|
125
127
|
phase: "export",
|
|
126
|
-
table:
|
|
127
|
-
index:
|
|
128
|
-
tableCount:
|
|
128
|
+
table: u,
|
|
129
|
+
index: c,
|
|
130
|
+
tableCount: s,
|
|
129
131
|
event: "done",
|
|
130
|
-
rowsDone:
|
|
131
|
-
total:
|
|
132
|
+
rowsDone: w,
|
|
133
|
+
total: w
|
|
132
134
|
}), r.push({
|
|
133
|
-
name:
|
|
134
|
-
file:
|
|
135
|
-
rowCount:
|
|
136
|
-
checksum:
|
|
137
|
-
columnTypes:
|
|
138
|
-
primaryKey:
|
|
135
|
+
name: u,
|
|
136
|
+
file: m,
|
|
137
|
+
rowCount: w,
|
|
138
|
+
checksum: D,
|
|
139
|
+
columnTypes: d,
|
|
140
|
+
primaryKey: p
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
return r;
|
|
142
|
-
}),
|
|
144
|
+
}), J = (e) => ({
|
|
143
145
|
_tag: "RawSqlFragment",
|
|
144
146
|
strings: [e],
|
|
145
147
|
values: []
|
|
146
|
-
}),
|
|
148
|
+
}), Y = (t, n, r) => N.tryPromise({
|
|
147
149
|
try: () => t.transactional(async (t) => {
|
|
148
|
-
if (t.raw) for (let r of e(n)) await t.raw(
|
|
149
|
-
let i = await
|
|
150
|
-
if (
|
|
150
|
+
if (t.raw) for (let r of e(n)) await t.raw(J(r));
|
|
151
|
+
let i = await N.runPromiseExit(r(t));
|
|
152
|
+
if (P.isFailure(i)) throw Error(M.pretty(i.cause));
|
|
151
153
|
return i.value;
|
|
152
154
|
}),
|
|
153
|
-
catch: (e) => e instanceof
|
|
154
|
-
}),
|
|
155
|
-
let n = e.scope ?? { kind: "all" },
|
|
156
|
-
yield*
|
|
155
|
+
catch: (e) => e instanceof s ? e : new s({ reason: `snapshot export failed: ${z(e)}` })
|
|
156
|
+
}), X = (e) => N.gen(function* () {
|
|
157
|
+
let n = e.scope ?? { kind: "all" }, a = C(e.compression), o = e.chunkSize ?? 1e3, l = e.retryTimes ?? 5, x = F.max([F.exponential("50 millis").pipe(F.jittered), F.recurs(l)]), S = yield* N.promise(() => import("node:path")), T = (t) => S.join(e.outDir, t);
|
|
158
|
+
yield* N.tryPromise({
|
|
157
159
|
try: async () => {
|
|
158
160
|
let t = await import("node:fs/promises");
|
|
159
|
-
await t.mkdir(T(
|
|
161
|
+
await t.mkdir(T(h), { recursive: !0 }), e.assets && await t.mkdir(T(p), { recursive: !0 });
|
|
160
162
|
},
|
|
161
|
-
catch: (t) => new
|
|
162
|
-
reason: `mkdir failed: ${
|
|
163
|
+
catch: (t) => new s({
|
|
164
|
+
reason: `mkdir failed: ${z(t)}`,
|
|
163
165
|
path: e.outDir
|
|
164
166
|
})
|
|
165
167
|
});
|
|
166
|
-
let
|
|
168
|
+
let E = T(g), O = yield* D(E), A = e.subset ? d(yield* u(e.store, e.snapshot, e.subset), e.snapshot) : yield* f(n, e.snapshot, {
|
|
167
169
|
store: e.store,
|
|
168
170
|
...e.tenantTables ? { tenantTables: e.tenantTables } : {}
|
|
169
|
-
}),
|
|
171
|
+
}), M = j(A.tables, e.snapshot), P = e.consistency ?? "live", I, L;
|
|
170
172
|
if (e.masking) {
|
|
171
|
-
let n = e.classification ?? t(e.snapshot), i =
|
|
173
|
+
let n = e.classification ?? t(e.snapshot), i = M.map((t) => ({
|
|
172
174
|
name: t,
|
|
173
175
|
columns: (e.snapshot.tables.find((e) => e.name === t)?.columns ?? []).map((e) => ({
|
|
174
176
|
name: e.name,
|
|
175
177
|
type: e.type
|
|
176
178
|
}))
|
|
177
|
-
})),
|
|
178
|
-
if (
|
|
179
|
-
unclassified:
|
|
180
|
-
...
|
|
179
|
+
})), a = r(i, n, e.masking);
|
|
180
|
+
if (a.unclassified.length > 0 || a.invalid.length > 0) return yield* N.fail(new c({
|
|
181
|
+
unclassified: a.unclassified,
|
|
182
|
+
...a.invalid.length > 0 ? { invalidActions: a.invalid.map((e) => `${e.column}: ${JSON.stringify(e.action)}`) } : {}
|
|
181
183
|
}));
|
|
182
|
-
|
|
183
|
-
actions:
|
|
184
|
+
L = {
|
|
185
|
+
actions: a.actions,
|
|
184
186
|
seed: e.masking.seed
|
|
185
187
|
};
|
|
186
|
-
let
|
|
187
|
-
|
|
188
|
+
let o = Object.entries(a.actions).filter(([, e]) => e !== "keep").map(([e]) => e);
|
|
189
|
+
I = {
|
|
188
190
|
...e.masking.id ? { policyId: e.masking.id } : {},
|
|
189
|
-
transformed:
|
|
191
|
+
transformed: o
|
|
190
192
|
};
|
|
191
193
|
}
|
|
192
|
-
let
|
|
194
|
+
let B = i(), V = {
|
|
195
|
+
sealed: B,
|
|
193
196
|
snapshot: e.snapshot,
|
|
194
|
-
ordered:
|
|
195
|
-
resolved:
|
|
196
|
-
compression:
|
|
197
|
-
chunkSize:
|
|
198
|
-
retry:
|
|
199
|
-
ledger:
|
|
200
|
-
ledgerPath:
|
|
197
|
+
ordered: M,
|
|
198
|
+
resolved: A,
|
|
199
|
+
compression: a,
|
|
200
|
+
chunkSize: o,
|
|
201
|
+
retry: x,
|
|
202
|
+
ledger: O,
|
|
203
|
+
ledgerPath: E,
|
|
201
204
|
bundleFile: T,
|
|
202
|
-
...
|
|
205
|
+
...L ? { mask: L } : {},
|
|
203
206
|
...e.onProgress ? { onProgress: e.onProgress } : {}
|
|
204
|
-
},
|
|
207
|
+
}, H = P === "snapshot" ? yield* Y(e.store, e.dialect, (e) => q(e, V)) : yield* q(e.store, V), U = 0, W = 0;
|
|
205
208
|
if (e.assets) {
|
|
206
|
-
let t = T(
|
|
207
|
-
source:
|
|
208
|
-
|
|
209
|
+
let t = T(m), n = yield* b({
|
|
210
|
+
source: {
|
|
211
|
+
...e.assets,
|
|
212
|
+
list: () => e.assets.list({
|
|
213
|
+
dir: e.outDir,
|
|
214
|
+
tables: H,
|
|
215
|
+
compression: a
|
|
216
|
+
})
|
|
217
|
+
},
|
|
218
|
+
assetsDir: T(p),
|
|
209
219
|
progress: {
|
|
210
|
-
done: (e) => e in
|
|
211
|
-
mark: (e, n) => (
|
|
220
|
+
done: (e) => e in O.assets,
|
|
221
|
+
mark: (e, n) => (O.assets[e] = !0, K(t, JSON.stringify(n)).pipe(N.andThen(k(E, O))))
|
|
212
222
|
}
|
|
213
223
|
});
|
|
214
|
-
|
|
224
|
+
U = n.count, W = n.totalBytes, n.missing.length > 0 && (yield* N.logWarning(`${n.missing.length} of ${n.missing.length + n.count} blob reference(s) point at objects the storage provider does not have; they are NOT in this bundle and no import can bring them back. e.g. ${n.missing.slice(0, 3).map((e) => `'${e}'`).join(", ")}` + (n.missing.length > 3 ? `, and ${n.missing.length - 3} more` : "")));
|
|
215
225
|
}
|
|
216
226
|
let G = {
|
|
217
|
-
formatVersion:
|
|
227
|
+
formatVersion: 2,
|
|
218
228
|
createdAt: e.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
219
229
|
source: {
|
|
220
230
|
dialect: e.dialect,
|
|
221
|
-
schemaFingerprint:
|
|
231
|
+
schemaFingerprint: R(e.snapshot)
|
|
222
232
|
},
|
|
223
233
|
scope: n,
|
|
224
234
|
consistency: P,
|
|
225
|
-
compression:
|
|
226
|
-
tables:
|
|
227
|
-
assets:
|
|
228
|
-
count:
|
|
229
|
-
totalBytes:
|
|
230
|
-
index:
|
|
235
|
+
compression: a,
|
|
236
|
+
tables: H,
|
|
237
|
+
assets: U > 0 ? {
|
|
238
|
+
count: U,
|
|
239
|
+
totalBytes: W,
|
|
240
|
+
index: m
|
|
231
241
|
} : {
|
|
232
242
|
count: 0,
|
|
233
243
|
totalBytes: 0
|
|
234
244
|
},
|
|
235
|
-
...
|
|
245
|
+
...I ? { masking: I } : {},
|
|
246
|
+
fieldKeys: {
|
|
247
|
+
keyIds: Object.entries(B.byKey).filter(([, e]) => e > 0).map(([e]) => e).sort(),
|
|
248
|
+
unnamed: B.unnamed
|
|
249
|
+
}
|
|
236
250
|
};
|
|
237
|
-
return yield*
|
|
251
|
+
return yield* N.tryPromise({
|
|
238
252
|
try: async () => {
|
|
239
|
-
await (await import("node:fs/promises")).writeFile(T(
|
|
253
|
+
await (await import("node:fs/promises")).writeFile(T(_), y(G));
|
|
240
254
|
},
|
|
241
|
-
catch: (e) => new
|
|
242
|
-
reason: `manifest write failed: ${
|
|
243
|
-
path:
|
|
255
|
+
catch: (e) => new s({
|
|
256
|
+
reason: `manifest write failed: ${z(e)}`,
|
|
257
|
+
path: _
|
|
244
258
|
})
|
|
245
|
-
}), yield*
|
|
259
|
+
}), yield* N.tryPromise({
|
|
246
260
|
try: async () => {
|
|
247
261
|
let e = await import("node:fs/promises"), t = await import("node:os");
|
|
248
|
-
await e.writeFile(T(
|
|
262
|
+
await e.writeFile(T(v), w(G, { hostname: t.hostname() }));
|
|
249
263
|
},
|
|
250
|
-
catch: (e) => new
|
|
251
|
-
reason: `readme write failed: ${
|
|
252
|
-
path:
|
|
264
|
+
catch: (e) => new s({
|
|
265
|
+
reason: `readme write failed: ${z(e)}`,
|
|
266
|
+
path: v
|
|
253
267
|
})
|
|
254
268
|
}), G;
|
|
255
269
|
});
|
|
256
|
-
|
|
257
|
-
export { q as runExport };
|
|
270
|
+
export { X as runExport };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { constants as e } from "node:fs";
|
|
2
|
+
import { copyFile as t, lstat as n, mkdir as r, mkdtemp as i, rename as a, rm as o } from "node:fs/promises";
|
|
3
|
+
import { dirname as s, join as c, parse as l, resolve as u, sep as d } from "node:path";
|
|
4
|
+
// src/filesystemAdmission.ts
|
|
5
|
+
var f = async (e, t) => {
|
|
6
|
+
let r = u(e), i = l(r).root, a = r.slice(i.length).split(d).filter(Boolean), o = i;
|
|
7
|
+
for (let e = 0; e < a.length; e++) {
|
|
8
|
+
o = c(o, a[e]);
|
|
9
|
+
let r;
|
|
10
|
+
try {
|
|
11
|
+
r = await n(o);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
if (typeof e == "object" && e && "code" in e && e.code === "ENOENT") return;
|
|
14
|
+
throw e;
|
|
15
|
+
}
|
|
16
|
+
if (r.isSymbolicLink()) throw Error("bundle path contains a symbolic link");
|
|
17
|
+
if (e === a.length - 1 && t === "file" ? !r.isFile() : !r.isDirectory()) throw Error("bundle path has an incompatible filesystem entry");
|
|
18
|
+
}
|
|
19
|
+
}, p = async (n, l) => {
|
|
20
|
+
await f(l, "file"), await r(s(l), { recursive: !0 }), await f(l, "file");
|
|
21
|
+
let u = await i(c(s(l), ".voltro-unpack-"));
|
|
22
|
+
try {
|
|
23
|
+
let r = c(u, "file");
|
|
24
|
+
await t(n, r, e.COPYFILE_EXCL), await f(l, "file"), await a(r, l);
|
|
25
|
+
} finally {
|
|
26
|
+
await o(u, {
|
|
27
|
+
recursive: !0,
|
|
28
|
+
force: !0
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
export { f as admitFilesystemPath, p as publishBundleFile };
|