swarm-deploy 0.1.0 → 0.2.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 +44 -0
- package/README.md +680 -49
- package/RELEASING.md +2 -2
- package/SECURITY.md +2 -3
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +79 -22
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +19 -29
- package/dist/client.js +46 -55
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +4 -0
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -1
- package/dist/files.d.ts +13 -28
- package/dist/files.js +13 -78
- package/dist/files.js.map +1 -1
- package/dist/hooks-module.d.ts +9 -0
- package/dist/hooks-module.js +118 -0
- package/dist/hooks-module.js.map +1 -0
- package/dist/hooks.d.ts +69 -0
- package/dist/hooks.js +88 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/release.d.ts +26 -0
- package/dist/release.js +419 -0
- package/dist/release.js.map +1 -0
- package/dist/server.d.ts +86 -0
- package/dist/server.js +405 -53
- package/dist/server.js.map +1 -1
- package/dist/storage/commit-journal.d.ts +39 -2
- package/dist/storage/commit-journal.js +140 -2
- package/dist/storage/commit-journal.js.map +1 -1
- package/dist/storage/commit-store.d.ts +69 -8
- package/dist/storage/commit-store.js +374 -22
- package/dist/storage/commit-store.js.map +1 -1
- package/dist/storage/layout.js +7 -1
- package/dist/storage/layout.js.map +1 -1
- package/dist/storage/link-store.d.ts +70 -0
- package/dist/storage/link-store.js +363 -0
- package/dist/storage/link-store.js.map +1 -0
- package/dist/storage/recovery.d.ts +2 -1
- package/dist/storage/recovery.js +8 -1
- package/dist/storage/recovery.js.map +1 -1
- package/dist/storage/retention.d.ts +41 -21
- package/dist/storage/retention.js +162 -8
- package/dist/storage/retention.js.map +1 -1
- package/dist/storage/tar-session-store.d.ts +36 -5
- package/dist/storage/tar-session-store.js +283 -55
- package/dist/storage/tar-session-store.js.map +1 -1
- package/dist/storage/tree-fs.d.ts +44 -0
- package/dist/storage/tree-fs.js +580 -0
- package/dist/storage/tree-fs.js.map +1 -0
- package/dist/storage/tree-staging.d.ts +9 -0
- package/dist/storage/tree-staging.js +64 -0
- package/dist/storage/tree-staging.js.map +1 -0
- package/dist/storage/types.d.ts +15 -0
- package/dist/symlinks.d.ts +36 -0
- package/dist/symlinks.js +128 -0
- package/dist/symlinks.js.map +1 -0
- package/dist/tar-protocol/controls.d.ts +25 -0
- package/dist/tar-protocol/controls.js +108 -2
- package/dist/tar-protocol/controls.js.map +1 -1
- package/dist/tar-protocol/direct-wire.d.ts +3 -3
- package/dist/tar-protocol/direct-wire.js +2 -2
- package/dist/tar-protocol/direct-wire.js.map +1 -1
- package/dist/tar-protocol/manifest.d.ts +13 -1
- package/dist/tar-protocol/manifest.js +26 -1
- package/dist/tar-protocol/manifest.js.map +1 -1
- package/dist/tar-protocol/tree-extract.d.ts +37 -0
- package/dist/tar-protocol/tree-extract.js +240 -0
- package/dist/tar-protocol/tree-extract.js.map +1 -0
- package/dist/tar-protocol/tree-manifest.d.ts +45 -0
- package/dist/tar-protocol/tree-manifest.js +277 -0
- package/dist/tar-protocol/tree-manifest.js.map +1 -0
- package/dist/tar-protocol/tree-path.d.ts +15 -0
- package/dist/tar-protocol/tree-path.js +68 -0
- package/dist/tar-protocol/tree-path.js.map +1 -0
- package/dist/tar-protocol/tree.d.ts +68 -0
- package/dist/tar-protocol/tree.js +269 -0
- package/dist/tar-protocol/tree.js.map +1 -0
- package/dist/tar-protocol/ustar.d.ts +14 -0
- package/dist/tar-protocol/ustar.js +81 -1
- package/dist/tar-protocol/ustar.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/package.json +3 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TREE_TRANSFER_DOMAIN = void 0;
|
|
7
|
+
exports.computeTreeTransferId = computeTreeTransferId;
|
|
8
|
+
exports.buildTreeManifest = buildTreeManifest;
|
|
9
|
+
exports.regenerateTreeTarSuffix = regenerateTreeTarSuffix;
|
|
10
|
+
exports.treeMetadataFromManifest = treeMetadataFromManifest;
|
|
11
|
+
exports.assertTreeMetadataTransferId = assertTreeMetadataTransferId;
|
|
12
|
+
const b4a_1 = __importDefault(require("b4a"));
|
|
13
|
+
const _fs_1 = __importDefault(require("#fs"));
|
|
14
|
+
const _path_1 = __importDefault(require("#path"));
|
|
15
|
+
const sodium_native_1 = __importDefault(require("sodium-native"));
|
|
16
|
+
const abort_js_1 = require("../abort.js");
|
|
17
|
+
const errors_js_1 = require("../errors.js");
|
|
18
|
+
const files_js_1 = require("../files.js");
|
|
19
|
+
const layout_js_1 = require("../storage/layout.js");
|
|
20
|
+
const controls_js_1 = require("./controls.js");
|
|
21
|
+
const hash_js_1 = require("./hash.js");
|
|
22
|
+
const manifest_js_1 = require("./manifest.js");
|
|
23
|
+
const tree_js_1 = require("./tree.js");
|
|
24
|
+
const ustar_js_1 = require("./ustar.js");
|
|
25
|
+
exports.TREE_TRANSFER_DOMAIN = 'swarm-deploy/direct-tree/v1';
|
|
26
|
+
const READ_BYTES = 64 * 1024;
|
|
27
|
+
function invalid(message, cause = null) {
|
|
28
|
+
return new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.PROTOCOL_INVALID, message, cause);
|
|
29
|
+
}
|
|
30
|
+
function assertClientKey(key) {
|
|
31
|
+
if (!b4a_1.default.isBuffer(key) || key.byteLength !== 32)
|
|
32
|
+
throw invalid('Invalid client public key');
|
|
33
|
+
}
|
|
34
|
+
function canonicalName(directoryPath) {
|
|
35
|
+
const name = (0, files_js_1.validateBasename)(_path_1.default.basename(_path_1.default.resolve(directoryPath)));
|
|
36
|
+
if ((0, files_js_1.isReservedHistoryName)(name)) {
|
|
37
|
+
throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.INVALID_FILENAME, 'Reserved artifact name');
|
|
38
|
+
}
|
|
39
|
+
return name;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The authenticated identity of a directory offer. It is domain separated from
|
|
43
|
+
* the file transfer ID and commits to every metadata field plus the pinned USTAR
|
|
44
|
+
* constants and tree limits that shape the archive.
|
|
45
|
+
*/
|
|
46
|
+
function computeTreeTransferId(clientPublicKey, immutable) {
|
|
47
|
+
assertClientKey(clientPublicKey);
|
|
48
|
+
for (const [label, value] of [
|
|
49
|
+
['tree entry count', immutable.entryCount],
|
|
50
|
+
['tree payload size', immutable.payloadBytes],
|
|
51
|
+
['TAR size', immutable.tarSize]
|
|
52
|
+
]) {
|
|
53
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
|
|
54
|
+
throw invalid(`Invalid ${label}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!b4a_1.default.isBuffer(immutable.treeSha256) || immutable.treeSha256.byteLength !== 32) {
|
|
58
|
+
throw invalid('Invalid tree digest');
|
|
59
|
+
}
|
|
60
|
+
if (!b4a_1.default.isBuffer(immutable.tarSha256) || immutable.tarSha256.byteLength !== 32) {
|
|
61
|
+
throw invalid('Invalid TAR digest');
|
|
62
|
+
}
|
|
63
|
+
const hash = new hash_js_1.SodiumSha256();
|
|
64
|
+
(0, tree_js_1.hashField)(hash, 'domain', exports.TREE_TRANSFER_DOMAIN);
|
|
65
|
+
(0, tree_js_1.hashField)(hash, 'clientPublicKey', clientPublicKey);
|
|
66
|
+
(0, tree_js_1.hashField)(hash, 'kind', 'directory');
|
|
67
|
+
(0, tree_js_1.hashField)(hash, 'name', immutable.name);
|
|
68
|
+
if (immutable.sourceParent !== undefined) {
|
|
69
|
+
(0, controls_js_1.assertSourceParent)(immutable.sourceParent);
|
|
70
|
+
(0, tree_js_1.hashField)(hash, 'sourceParent', immutable.sourceParent);
|
|
71
|
+
}
|
|
72
|
+
(0, tree_js_1.hashField)(hash, 'entryCount', immutable.entryCount);
|
|
73
|
+
(0, tree_js_1.hashField)(hash, 'payloadBytes', immutable.payloadBytes);
|
|
74
|
+
(0, tree_js_1.hashField)(hash, 'treeSha256', immutable.treeSha256);
|
|
75
|
+
(0, tree_js_1.hashField)(hash, 'tarSize', immutable.tarSize);
|
|
76
|
+
(0, tree_js_1.hashField)(hash, 'tarSha256', immutable.tarSha256);
|
|
77
|
+
(0, tree_js_1.hashField)(hash, 'fileMode', ustar_js_1.TAR_MODE);
|
|
78
|
+
(0, tree_js_1.hashField)(hash, 'directoryMode', ustar_js_1.TAR_DIRECTORY_MODE);
|
|
79
|
+
(0, tree_js_1.hashField)(hash, 'uid', ustar_js_1.TAR_UID);
|
|
80
|
+
(0, tree_js_1.hashField)(hash, 'gid', ustar_js_1.TAR_GID);
|
|
81
|
+
(0, tree_js_1.hashField)(hash, 'mtimeMs', ustar_js_1.TAR_MTIME_MS);
|
|
82
|
+
(0, tree_js_1.hashField)(hash, 'uname', ustar_js_1.TAR_UNAME);
|
|
83
|
+
(0, tree_js_1.hashField)(hash, 'gname', ustar_js_1.TAR_GNAME);
|
|
84
|
+
(0, tree_js_1.hashField)(hash, 'maxDepth', tree_js_1.MAX_TREE_DEPTH);
|
|
85
|
+
(0, tree_js_1.hashField)(hash, 'maxEntries', tree_js_1.MAX_TREE_ENTRIES);
|
|
86
|
+
(0, tree_js_1.hashField)(hash, 'pax', 'none');
|
|
87
|
+
return hash.digest();
|
|
88
|
+
}
|
|
89
|
+
/** Streams one file's payload, proving it is the snapshotted inode at open and at the end. */
|
|
90
|
+
async function* readEntryPayload(entry, signal) {
|
|
91
|
+
let handle = null;
|
|
92
|
+
try {
|
|
93
|
+
handle = await _fs_1.default.promises.open(entry.absolutePath, (0, layout_js_1.safeFileOpenFlags)('read'));
|
|
94
|
+
(0, tree_js_1.assertSameTreeIdentity)(entry.identity, await handle.stat(), 'Tree entry changed while opening');
|
|
95
|
+
let position = 0;
|
|
96
|
+
while (position < entry.size) {
|
|
97
|
+
(0, abort_js_1.throwIfAborted)(signal);
|
|
98
|
+
const chunk = b4a_1.default.alloc(Math.min(READ_BYTES, entry.size - position));
|
|
99
|
+
const read = await handle.read(chunk, 0, chunk.byteLength, position);
|
|
100
|
+
const count = typeof read === 'number' ? read : read.bytesRead;
|
|
101
|
+
if (count !== chunk.byteLength) {
|
|
102
|
+
throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.FILE_BUSY, 'Tree entry was truncated');
|
|
103
|
+
}
|
|
104
|
+
position += count;
|
|
105
|
+
yield chunk;
|
|
106
|
+
}
|
|
107
|
+
(0, tree_js_1.assertSameTreeIdentity)(entry.identity, await handle.stat(), 'Tree entry changed during TAR generation');
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error instanceof errors_js_1.SwarmDeployError)
|
|
111
|
+
throw error;
|
|
112
|
+
throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.FILE_BUSY, 'Unable to safely read tree entry', error);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
if (handle)
|
|
116
|
+
await handle.close().catch(() => { });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Yields the exact deterministic archive, hashing each entry payload in order. */
|
|
120
|
+
async function* generateTreeTar(snapshot, digests, signal) {
|
|
121
|
+
for (const entry of snapshot.entries) {
|
|
122
|
+
(0, abort_js_1.throwIfAborted)(signal);
|
|
123
|
+
yield (0, ustar_js_1.canonicalUstarTreeHeader)((0, tree_js_1.tarEntryName)(entry), entry.kind, entry.size);
|
|
124
|
+
if (entry.kind === 'directory') {
|
|
125
|
+
digests.push({ entry: { kind: entry.kind, path: entry.path, size: 0 } });
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const hash = new hash_js_1.SodiumSha256();
|
|
129
|
+
for await (const chunk of readEntryPayload(entry, signal)) {
|
|
130
|
+
hash.update(chunk);
|
|
131
|
+
yield chunk;
|
|
132
|
+
}
|
|
133
|
+
digests.push({
|
|
134
|
+
entry: { kind: entry.kind, path: entry.path, size: entry.size },
|
|
135
|
+
sha256: hash.digest()
|
|
136
|
+
});
|
|
137
|
+
const padding = (ustar_js_1.TAR_BLOCK_BYTES - (entry.size % ustar_js_1.TAR_BLOCK_BYTES)) % ustar_js_1.TAR_BLOCK_BYTES;
|
|
138
|
+
if (padding > 0)
|
|
139
|
+
yield b4a_1.default.alloc(padding);
|
|
140
|
+
}
|
|
141
|
+
yield b4a_1.default.alloc(2 * ustar_js_1.TAR_BLOCK_BYTES);
|
|
142
|
+
}
|
|
143
|
+
async function buildTreeManifest(directoryPath, clientPublicKey, { signal = null, includeSourceParent = true } = {}) {
|
|
144
|
+
assertClientKey(clientPublicKey);
|
|
145
|
+
const resolved = _path_1.default.resolve(directoryPath);
|
|
146
|
+
const name = canonicalName(resolved);
|
|
147
|
+
const sourceParent = includeSourceParent === false ? undefined : (0, manifest_js_1.deriveSourceParent)(resolved);
|
|
148
|
+
const snapshot = await (0, tree_js_1.snapshotTree)(resolved, { signal });
|
|
149
|
+
(0, tree_js_1.assertCanonicalTreeEntries)(snapshot.entries);
|
|
150
|
+
const digests = [];
|
|
151
|
+
const tarHash = new hash_js_1.SodiumSha256();
|
|
152
|
+
let tarSize = 0;
|
|
153
|
+
for await (const chunk of generateTreeTar(snapshot, digests, signal)) {
|
|
154
|
+
tarHash.update(chunk);
|
|
155
|
+
tarSize += chunk.byteLength;
|
|
156
|
+
}
|
|
157
|
+
await (0, tree_js_1.revalidateTreeSnapshot)(snapshot, { signal });
|
|
158
|
+
if (tarSize !== (0, ustar_js_1.deterministicTreeTarSize)(snapshot.entries)) {
|
|
159
|
+
throw invalid('Noncanonical deterministic TAR length');
|
|
160
|
+
}
|
|
161
|
+
const treeSha256 = (0, tree_js_1.treeDigest)(digests);
|
|
162
|
+
const tarSha256 = tarHash.digest();
|
|
163
|
+
const transferId = computeTreeTransferId(clientPublicKey, {
|
|
164
|
+
name,
|
|
165
|
+
...(sourceParent === undefined ? {} : { sourceParent }),
|
|
166
|
+
entryCount: snapshot.entryCount,
|
|
167
|
+
payloadBytes: snapshot.payloadBytes,
|
|
168
|
+
treeSha256,
|
|
169
|
+
tarSize,
|
|
170
|
+
tarSha256
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
kind: 'directory',
|
|
174
|
+
path: resolved,
|
|
175
|
+
name,
|
|
176
|
+
...(sourceParent === undefined ? {} : { sourceParent }),
|
|
177
|
+
entryCount: snapshot.entryCount,
|
|
178
|
+
payloadBytes: snapshot.payloadBytes,
|
|
179
|
+
treeSha256,
|
|
180
|
+
tarSize,
|
|
181
|
+
tarSha256,
|
|
182
|
+
transferId,
|
|
183
|
+
snapshot
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
async function regenerateTreeTarSuffix(manifest, offset, write, { signal = null, expectedPrefixSha256 = null } = {}) {
|
|
187
|
+
if (!manifest || typeof manifest !== 'object')
|
|
188
|
+
throw invalid('Invalid tree manifest');
|
|
189
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > manifest.tarSize) {
|
|
190
|
+
throw invalid('Invalid TAR resume offset');
|
|
191
|
+
}
|
|
192
|
+
if (typeof write !== 'function')
|
|
193
|
+
throw invalid('Invalid TAR suffix writer');
|
|
194
|
+
if (expectedPrefixSha256 !== null &&
|
|
195
|
+
(!b4a_1.default.isBuffer(expectedPrefixSha256) || expectedPrefixSha256.byteLength !== 32)) {
|
|
196
|
+
throw invalid('Invalid expected prefix digest');
|
|
197
|
+
}
|
|
198
|
+
const digests = [];
|
|
199
|
+
const tarHash = new hash_js_1.SodiumSha256();
|
|
200
|
+
const prefixHash = new hash_js_1.SodiumSha256();
|
|
201
|
+
let position = 0;
|
|
202
|
+
let bytesSent = 0;
|
|
203
|
+
let prefixSha256 = offset === 0 ? prefixHash.digest() : null;
|
|
204
|
+
let resetRequired = prefixSha256 !== null &&
|
|
205
|
+
expectedPrefixSha256 !== null &&
|
|
206
|
+
!sodium_native_1.default.sodium_memcmp(prefixSha256, expectedPrefixSha256);
|
|
207
|
+
for await (const chunk of generateTreeTar(manifest.snapshot, digests, signal)) {
|
|
208
|
+
(0, abort_js_1.throwIfAborted)(signal);
|
|
209
|
+
tarHash.update(chunk);
|
|
210
|
+
const end = position + chunk.byteLength;
|
|
211
|
+
if (position < offset) {
|
|
212
|
+
const prefixEnd = Math.min(chunk.byteLength, offset - position);
|
|
213
|
+
prefixHash.update(chunk.subarray(0, prefixEnd));
|
|
214
|
+
if (end >= offset) {
|
|
215
|
+
prefixSha256 = prefixHash.digest();
|
|
216
|
+
if (expectedPrefixSha256 && !sodium_native_1.default.sodium_memcmp(prefixSha256, expectedPrefixSha256)) {
|
|
217
|
+
resetRequired = true;
|
|
218
|
+
}
|
|
219
|
+
if (!resetRequired && prefixEnd < chunk.byteLength) {
|
|
220
|
+
const suffix = chunk.subarray(prefixEnd);
|
|
221
|
+
await write(suffix);
|
|
222
|
+
bytesSent += suffix.byteLength;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (!resetRequired) {
|
|
227
|
+
await write(chunk);
|
|
228
|
+
bytesSent += chunk.byteLength;
|
|
229
|
+
}
|
|
230
|
+
position = end;
|
|
231
|
+
}
|
|
232
|
+
await (0, tree_js_1.revalidateTreeSnapshot)(manifest.snapshot, { signal });
|
|
233
|
+
if (position !== manifest.tarSize ||
|
|
234
|
+
(!resetRequired && bytesSent !== manifest.tarSize - offset)) {
|
|
235
|
+
throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.FILE_BUSY, 'Regenerated TAR length changed');
|
|
236
|
+
}
|
|
237
|
+
if (!(0, hash_js_1.digestMatches)((0, tree_js_1.treeDigest)(digests), manifest.treeSha256) ||
|
|
238
|
+
!(0, hash_js_1.digestMatches)(tarHash.digest(), manifest.tarSha256)) {
|
|
239
|
+
throw new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.FILE_BUSY, 'Tree changed during TAR regeneration');
|
|
240
|
+
}
|
|
241
|
+
if (prefixSha256 === null)
|
|
242
|
+
throw invalid('Unable to hash TAR prefix');
|
|
243
|
+
if (resetRequired)
|
|
244
|
+
return { status: 'RESET_REQUIRED', prefixSha256, bytesSent: 0 };
|
|
245
|
+
return { status: 'MATCH', prefixSha256, bytesSent };
|
|
246
|
+
}
|
|
247
|
+
function treeMetadataFromManifest(manifest, reset = false) {
|
|
248
|
+
return {
|
|
249
|
+
v: controls_js_1.CONTROL_VERSION,
|
|
250
|
+
kind: 'directory',
|
|
251
|
+
name: manifest.name,
|
|
252
|
+
...(manifest.sourceParent === undefined ? {} : { sourceParent: manifest.sourceParent }),
|
|
253
|
+
entryCount: manifest.entryCount,
|
|
254
|
+
payloadBytes: manifest.payloadBytes,
|
|
255
|
+
treeSha256: b4a_1.default.toString(manifest.treeSha256, 'hex'),
|
|
256
|
+
tarSize: manifest.tarSize,
|
|
257
|
+
tarSha256: b4a_1.default.toString(manifest.tarSha256, 'hex'),
|
|
258
|
+
transferId: b4a_1.default.toString(manifest.transferId, 'hex'),
|
|
259
|
+
reset
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function assertTreeMetadataTransferId(clientPublicKey, offeredMetadata) {
|
|
263
|
+
const metadata = (0, controls_js_1.decodeTreeMetadataRecord)((0, controls_js_1.encodeTreeMetadataRecord)(offeredMetadata));
|
|
264
|
+
const expected = computeTreeTransferId(clientPublicKey, {
|
|
265
|
+
name: metadata.name,
|
|
266
|
+
...(metadata.sourceParent === undefined ? {} : { sourceParent: metadata.sourceParent }),
|
|
267
|
+
entryCount: metadata.entryCount,
|
|
268
|
+
payloadBytes: metadata.payloadBytes,
|
|
269
|
+
treeSha256: b4a_1.default.from(metadata.treeSha256, 'hex'),
|
|
270
|
+
tarSize: metadata.tarSize,
|
|
271
|
+
tarSha256: b4a_1.default.from(metadata.tarSha256, 'hex')
|
|
272
|
+
});
|
|
273
|
+
if (!sodium_native_1.default.sodium_memcmp(expected, b4a_1.default.from(metadata.transferId, 'hex'))) {
|
|
274
|
+
throw invalid('Noncanonical tree transfer ID');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=tree-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-manifest.js","sourceRoot":"","sources":["../../src/tar-protocol/tree-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ArtifactKind } from '../types.js';
|
|
2
|
+
export declare const MAX_TREE_DEPTH = 32;
|
|
3
|
+
export declare const MAX_TREE_ENTRIES = 10000;
|
|
4
|
+
export declare const MAX_TREE_NAME_BYTES = 100;
|
|
5
|
+
export interface TreePathEntryLike {
|
|
6
|
+
kind: ArtifactKind;
|
|
7
|
+
path: string;
|
|
8
|
+
}
|
|
9
|
+
/** The exact TAR name field for an entry: directories carry a trailing `/`. */
|
|
10
|
+
export declare function tarEntryName(entry: Pick<TreePathEntryLike, 'kind' | 'path'>): string;
|
|
11
|
+
export declare function assertTreeEntryPath(value: unknown, kind: ArtifactKind): string;
|
|
12
|
+
/** Bytewise order. A parent is a proper prefix, so it always sorts first. */
|
|
13
|
+
export declare function compareTreePaths(left: string, right: string): number;
|
|
14
|
+
/** Normalizes a canonical TAR stored name to a tree entry path and validates components. */
|
|
15
|
+
export declare function assertTreeStoredName(storedName: string, kind: ArtifactKind): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MAX_TREE_NAME_BYTES = exports.MAX_TREE_ENTRIES = exports.MAX_TREE_DEPTH = void 0;
|
|
7
|
+
exports.tarEntryName = tarEntryName;
|
|
8
|
+
exports.assertTreeEntryPath = assertTreeEntryPath;
|
|
9
|
+
exports.compareTreePaths = compareTreePaths;
|
|
10
|
+
exports.assertTreeStoredName = assertTreeStoredName;
|
|
11
|
+
const b4a_1 = __importDefault(require("b4a"));
|
|
12
|
+
const errors_js_1 = require("../errors.js");
|
|
13
|
+
const files_js_1 = require("../files.js");
|
|
14
|
+
exports.MAX_TREE_DEPTH = 32;
|
|
15
|
+
exports.MAX_TREE_ENTRIES = 10_000;
|
|
16
|
+
exports.MAX_TREE_NAME_BYTES = 100;
|
|
17
|
+
function unsafeName(message) {
|
|
18
|
+
return new errors_js_1.SwarmDeployError(errors_js_1.ERRORS.INVALID_FILENAME, message);
|
|
19
|
+
}
|
|
20
|
+
/** The exact TAR name field for an entry: directories carry a trailing `/`. */
|
|
21
|
+
function tarEntryName(entry) {
|
|
22
|
+
return entry.kind === 'directory' ? `${entry.path}/` : entry.path;
|
|
23
|
+
}
|
|
24
|
+
function assertTreeEntryPath(value, kind) {
|
|
25
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
26
|
+
throw unsafeName('Invalid tree entry path');
|
|
27
|
+
if (value.includes('\\') || value.includes('\u0000'))
|
|
28
|
+
throw unsafeName('Invalid tree entry path');
|
|
29
|
+
const components = value.split('/');
|
|
30
|
+
if (components.length > exports.MAX_TREE_DEPTH)
|
|
31
|
+
throw unsafeName('Tree entry path is too deep');
|
|
32
|
+
for (const component of components) {
|
|
33
|
+
if (component.length === 0)
|
|
34
|
+
throw unsafeName('Invalid tree entry path');
|
|
35
|
+
(0, files_js_1.validateBasename)(component);
|
|
36
|
+
if ((0, files_js_1.isReservedHistoryName)(component))
|
|
37
|
+
throw unsafeName('Reserved tree entry path');
|
|
38
|
+
}
|
|
39
|
+
const stored = b4a_1.default.from(tarEntryName({ kind, path: value }));
|
|
40
|
+
if (stored.byteLength > exports.MAX_TREE_NAME_BYTES)
|
|
41
|
+
throw unsafeName('Tree entry path is too long');
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
/** Bytewise order. A parent is a proper prefix, so it always sorts first. */
|
|
45
|
+
function compareTreePaths(left, right) {
|
|
46
|
+
return b4a_1.default.compare(b4a_1.default.from(left), b4a_1.default.from(right));
|
|
47
|
+
}
|
|
48
|
+
/** Normalizes a canonical TAR stored name to a tree entry path and validates components. */
|
|
49
|
+
function assertTreeStoredName(storedName, kind) {
|
|
50
|
+
if (typeof storedName !== 'string')
|
|
51
|
+
throw unsafeName('Invalid tree entry path');
|
|
52
|
+
if (storedName.includes('\u0000') || storedName.includes('\\') || storedName.startsWith('/')) {
|
|
53
|
+
throw unsafeName('Invalid tree entry path');
|
|
54
|
+
}
|
|
55
|
+
const encoded = b4a_1.default.from(storedName);
|
|
56
|
+
if (encoded.byteLength === 0 || encoded.byteLength > exports.MAX_TREE_NAME_BYTES) {
|
|
57
|
+
throw unsafeName('Tree entry path is too long');
|
|
58
|
+
}
|
|
59
|
+
if (kind === 'directory') {
|
|
60
|
+
if (!storedName.endsWith('/'))
|
|
61
|
+
throw unsafeName('Invalid tree entry path');
|
|
62
|
+
return assertTreeEntryPath(storedName.slice(0, -1), 'directory');
|
|
63
|
+
}
|
|
64
|
+
if (storedName.endsWith('/'))
|
|
65
|
+
throw unsafeName('Invalid tree entry path');
|
|
66
|
+
return assertTreeEntryPath(storedName, 'file');
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tree-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-path.js","sourceRoot":"","sources":["../../src/tar-protocol/tree-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from '#fs';
|
|
2
|
+
import { type AbortSignalLike } from '../abort.js';
|
|
3
|
+
import { SwarmDeployError } from '../errors.js';
|
|
4
|
+
import type { ArtifactKind } from '../types.js';
|
|
5
|
+
import { SodiumSha256 } from './hash.js';
|
|
6
|
+
export { assertTreeEntryPath, assertTreeStoredName, compareTreePaths, MAX_TREE_DEPTH, MAX_TREE_ENTRIES, MAX_TREE_NAME_BYTES, tarEntryName } from './tree-path.js';
|
|
7
|
+
export declare const TREE_DIGEST_DOMAIN = "swarm-deploy/tree/v1";
|
|
8
|
+
export interface TreeEntry {
|
|
9
|
+
kind: ArtifactKind;
|
|
10
|
+
/** Relative POSIX path inside the artifact, with no leading or trailing `/`. */
|
|
11
|
+
path: string;
|
|
12
|
+
/** Regular-file byte length; always `0` for a directory. */
|
|
13
|
+
size: number;
|
|
14
|
+
}
|
|
15
|
+
export interface TreeIdentity {
|
|
16
|
+
dev: number | bigint;
|
|
17
|
+
ino: number | bigint;
|
|
18
|
+
size: number;
|
|
19
|
+
mtimeMs: number;
|
|
20
|
+
}
|
|
21
|
+
export interface TreeSnapshotEntry extends TreeEntry {
|
|
22
|
+
absolutePath: string;
|
|
23
|
+
identity: TreeIdentity;
|
|
24
|
+
}
|
|
25
|
+
export interface TreeSnapshot {
|
|
26
|
+
rootPath: string;
|
|
27
|
+
root: TreeIdentity;
|
|
28
|
+
entries: TreeSnapshotEntry[];
|
|
29
|
+
entryCount: number;
|
|
30
|
+
payloadBytes: number;
|
|
31
|
+
}
|
|
32
|
+
export interface TreeDigestEntry {
|
|
33
|
+
entry: TreeEntry;
|
|
34
|
+
/** Required for a file entry and forbidden for a directory entry. */
|
|
35
|
+
sha256?: Uint8Array;
|
|
36
|
+
}
|
|
37
|
+
export interface TreeSnapshotOptions {
|
|
38
|
+
signal?: AbortSignalLike | null;
|
|
39
|
+
}
|
|
40
|
+
export declare function assertCanonicalTreeEntries(entries: readonly TreeEntry[]): void;
|
|
41
|
+
/** Length-prefixed, labelled field framing shared by tree digests and tree transfer IDs. */
|
|
42
|
+
export declare function hashField(hash: SodiumSha256, label: string, value: Uint8Array | string | number): void;
|
|
43
|
+
export declare function treeDigest(entries: readonly TreeDigestEntry[]): Buffer;
|
|
44
|
+
/** Minimal stat surface used to classify one tree member. */
|
|
45
|
+
export interface TreeEntryStatLike {
|
|
46
|
+
isSymbolicLink(): boolean;
|
|
47
|
+
isDirectory(): boolean;
|
|
48
|
+
isFile(): boolean;
|
|
49
|
+
nlink?: number;
|
|
50
|
+
}
|
|
51
|
+
export declare function classifyTreeEntry(stat: TreeEntryStatLike): ArtifactKind;
|
|
52
|
+
/** Stable error for unreadable directory listings during snapshot walks. */
|
|
53
|
+
export declare function treeDirectoryReadError(): SwarmDeployError;
|
|
54
|
+
/** Maps revalidation failures to FILE_BUSY while preserving ABORTED. */
|
|
55
|
+
export declare function normalizeRevalidateFailure(error: unknown): never;
|
|
56
|
+
/**
|
|
57
|
+
* Walks `rootPath` recursively and returns the canonical entry list with one
|
|
58
|
+
* snapshotted identity per entry. Any unsafe or non-regular member rejects the
|
|
59
|
+
* whole directory; nothing is ever silently dropped.
|
|
60
|
+
*/
|
|
61
|
+
export declare function snapshotTree(rootPath: string, { signal }?: TreeSnapshotOptions): Promise<TreeSnapshot>;
|
|
62
|
+
export declare function assertSameTreeIdentity(expected: TreeIdentity, actual: fs.Stats, message: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Reproves every snapshotted identity and re-walks the source tree before a resume
|
|
65
|
+
* regenerates the archive. Any mutation, disappearance, unreadable path, collision,
|
|
66
|
+
* limit breach, or newly unsafe member becomes FILE_BUSY; ABORTED is preserved.
|
|
67
|
+
*/
|
|
68
|
+
export declare function revalidateTreeSnapshot(snapshot: TreeSnapshot, { signal }?: TreeSnapshotOptions): Promise<void>;
|