@saltcorn/admin-models 1.7.0-alpha.0 → 1.7.0-beta.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/cjs/models/backup-retention.cjs +18 -0
- package/cjs/models/file-globs.cjs +18 -0
- package/cjs/models/zip-extract.cjs +18 -0
- package/cjs/models/zip-format.cjs +18 -0
- package/cjs/models/zip-worker.cjs +18 -0
- package/cjs/models/zip-writer.cjs +18 -0
- package/cjs/models/zip.cjs +18 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/models/backup-retention.d.ts +57 -0
- package/dist/models/backup-retention.d.ts.map +1 -0
- package/dist/models/backup-retention.js +108 -0
- package/dist/models/backup-retention.js.map +1 -0
- package/dist/models/backup.d.ts +4 -1
- package/dist/models/backup.d.ts.map +1 -1
- package/dist/models/backup.js +364 -302
- package/dist/models/backup.js.map +1 -1
- package/dist/models/file-globs.d.ts +34 -0
- package/dist/models/file-globs.d.ts.map +1 -0
- package/dist/models/file-globs.js +47 -0
- package/dist/models/file-globs.js.map +1 -0
- package/dist/models/pack.d.ts +1 -1
- package/dist/models/pack.d.ts.map +1 -1
- package/dist/models/pack.js +26 -1
- package/dist/models/pack.js.map +1 -1
- package/dist/models/tenant.d.ts.map +1 -1
- package/dist/models/tenant.js +2 -0
- package/dist/models/tenant.js.map +1 -1
- package/dist/models/zip-extract.d.ts +14 -0
- package/dist/models/zip-extract.d.ts.map +1 -0
- package/dist/models/zip-extract.js +110 -0
- package/dist/models/zip-extract.js.map +1 -0
- package/dist/models/zip-format.d.ts +57 -0
- package/dist/models/zip-format.d.ts.map +1 -0
- package/dist/models/zip-format.js +106 -0
- package/dist/models/zip-format.js.map +1 -0
- package/dist/models/zip-worker.d.ts +2 -0
- package/dist/models/zip-worker.d.ts.map +1 -0
- package/dist/models/zip-worker.js +177 -0
- package/dist/models/zip-worker.js.map +1 -0
- package/dist/models/zip-writer.d.ts +75 -0
- package/dist/models/zip-writer.d.ts.map +1 -0
- package/dist/models/zip-writer.js +321 -0
- package/dist/models/zip-writer.js.map +1 -0
- package/dist/models/zip.d.ts +101 -0
- package/dist/models/zip.d.ts.map +1 -0
- package/dist/models/zip.js +211 -0
- package/dist/models/zip.js.map +1 -0
- package/dist/tests/backup-retention.test.d.ts +2 -0
- package/dist/tests/backup-retention.test.d.ts.map +1 -0
- package/dist/tests/backup-retention.test.js +134 -0
- package/dist/tests/backup-retention.test.js.map +1 -0
- package/dist/tests/backup.test.js +186 -2
- package/dist/tests/backup.test.js.map +1 -1
- package/dist/tests/file-globs.test.d.ts +2 -0
- package/dist/tests/file-globs.test.d.ts.map +1 -0
- package/dist/tests/file-globs.test.js +66 -0
- package/dist/tests/file-globs.test.js.map +1 -0
- package/dist/tests/pack.test.js +14 -3
- package/dist/tests/pack.test.js.map +1 -1
- package/dist/tests/random.test.js +3 -3
- package/dist/tests/random.test.js.map +1 -1
- package/dist/tests/tenant.test.js +7 -7
- package/dist/tests/tenant.test.js.map +1 -1
- package/dist/tests/zip.test.d.ts +2 -0
- package/dist/tests/zip.test.d.ts.map +1 -0
- package/dist/tests/zip.test.js +319 -0
- package/dist/tests/zip.test.js.map +1 -0
- package/package.json +15 -9
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A streaming ZIP writer.
|
|
3
|
+
*
|
|
4
|
+
* Entries are compressed and written out as they are added, so the archive is
|
|
5
|
+
* never held in memory: a backup of a 50 GB file store needs no more memory
|
|
6
|
+
* than a few buffers, whatever its size. Deflation runs on libuv's thread
|
|
7
|
+
* pool (zlib's streaming API), and the whole writer is driven from the zip
|
|
8
|
+
* worker thread, so nothing here competes with the server's event loop.
|
|
9
|
+
*
|
|
10
|
+
* Sizes and CRCs are not known until an entry has been written, so entries
|
|
11
|
+
* carry a data descriptor (general purpose bit 3) instead. Entries larger
|
|
12
|
+
* than ZIP64_THRESHOLD are written in zip64 format, which lifts the 4 GiB
|
|
13
|
+
* limit on entry and archive size.
|
|
14
|
+
*
|
|
15
|
+
* @category saltcorn-admin-models
|
|
16
|
+
* @module models/zip-writer
|
|
17
|
+
*/
|
|
18
|
+
import { createDeflateRaw } from "zlib";
|
|
19
|
+
import { createReadStream } from "fs";
|
|
20
|
+
import { stat } from "fs/promises";
|
|
21
|
+
import { randomBytes } from "crypto";
|
|
22
|
+
import { Readable } from "stream";
|
|
23
|
+
import { once } from "events";
|
|
24
|
+
import { CENTRAL_HEADER_SIZE, CENTRAL_SIG, DESCRIPTOR_SIG, EOCD_SIG, EOCD_SIZE, FLAG_DESCRIPTOR, FLAG_ENCRYPTED, FLAG_UTF8, LOCAL_HEADER_SIZE, LOCAL_SIG, METHOD_DEFLATED, METHOD_STORED, UINT16_MAX, UINT32_MAX, ZIP64_EOCD_SIG, ZIP64_EOCD_SIZE, ZIP64_EXTRA_ID, ZIP64_LOCATOR_SIG, ZIP64_LOCATOR_SIZE, ZIP64_THRESHOLD, ZipCrypto, crc32, dosDateTime, writeUInt64, } from "./zip-format.js";
|
|
25
|
+
export class ZipStreamWriter {
|
|
26
|
+
constructor(out, options = {}) {
|
|
27
|
+
this.offset = 0;
|
|
28
|
+
this.entries = [];
|
|
29
|
+
this.names = new Set();
|
|
30
|
+
this.out = out;
|
|
31
|
+
this.password = options.password || undefined;
|
|
32
|
+
this.level = options.level ?? 5;
|
|
33
|
+
this.zip64Threshold = options.zip64Threshold ?? ZIP64_THRESHOLD;
|
|
34
|
+
this.probeLimit = options.probeLimit ?? 32 * 1024 * 1024;
|
|
35
|
+
}
|
|
36
|
+
/** Write to the output, respecting its backpressure */
|
|
37
|
+
async put(buf) {
|
|
38
|
+
if (!this.out.write(buf))
|
|
39
|
+
await once(this.out, "drain");
|
|
40
|
+
this.offset += buf.length;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Zip entry names are always forward-slash separated and never absolute.
|
|
44
|
+
* A duplicate name would make the archive ambiguous, so it is an error.
|
|
45
|
+
*/
|
|
46
|
+
entryName(name, isDirectory) {
|
|
47
|
+
let clean = name.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
48
|
+
if (isDirectory && !clean.endsWith("/"))
|
|
49
|
+
clean += "/";
|
|
50
|
+
if (this.names.has(clean))
|
|
51
|
+
throw new Error(`Duplicate zip entry: ${clean}`);
|
|
52
|
+
this.names.add(clean);
|
|
53
|
+
return Buffer.from(clean, "utf8");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The local file header. When an entry is zip64 the header carries a
|
|
57
|
+
* zip64 extra field with placeholder sizes, which is what tells a reader
|
|
58
|
+
* that the trailing data descriptor has 8-byte sizes.
|
|
59
|
+
*/
|
|
60
|
+
localHeader(entry) {
|
|
61
|
+
const extraSize = entry.zip64 ? 20 : 0;
|
|
62
|
+
const buf = Buffer.alloc(LOCAL_HEADER_SIZE + entry.name.length + extraSize);
|
|
63
|
+
buf.writeUInt32LE(LOCAL_SIG, 0);
|
|
64
|
+
buf.writeUInt16LE(entry.zip64 ? 45 : 20, 4);
|
|
65
|
+
buf.writeUInt16LE(entry.flags, 6);
|
|
66
|
+
buf.writeUInt16LE(entry.method, 8);
|
|
67
|
+
buf.writeUInt16LE(entry.time, 10);
|
|
68
|
+
buf.writeUInt16LE(entry.date, 12);
|
|
69
|
+
// crc and sizes follow in the data descriptor, except for entries
|
|
70
|
+
// written whole (directories), which have nothing to describe
|
|
71
|
+
buf.writeUInt32LE(entry.crc, 14);
|
|
72
|
+
buf.writeUInt32LE(entry.zip64 ? UINT32_MAX : entry.compressedSize, 18);
|
|
73
|
+
buf.writeUInt32LE(entry.zip64 ? UINT32_MAX : entry.uncompressedSize, 22);
|
|
74
|
+
buf.writeUInt16LE(entry.name.length, 26);
|
|
75
|
+
buf.writeUInt16LE(extraSize, 28);
|
|
76
|
+
entry.name.copy(buf, LOCAL_HEADER_SIZE);
|
|
77
|
+
if (entry.zip64) {
|
|
78
|
+
const at = LOCAL_HEADER_SIZE + entry.name.length;
|
|
79
|
+
buf.writeUInt16LE(ZIP64_EXTRA_ID, at);
|
|
80
|
+
buf.writeUInt16LE(16, at + 2);
|
|
81
|
+
writeUInt64(buf, entry.uncompressedSize, at + 4);
|
|
82
|
+
writeUInt64(buf, entry.compressedSize, at + 12);
|
|
83
|
+
}
|
|
84
|
+
return buf;
|
|
85
|
+
}
|
|
86
|
+
/** The data descriptor written after an entry's data */
|
|
87
|
+
dataDescriptor(entry) {
|
|
88
|
+
const buf = Buffer.alloc(entry.zip64 ? 24 : 16);
|
|
89
|
+
buf.writeUInt32LE(DESCRIPTOR_SIG, 0);
|
|
90
|
+
buf.writeUInt32LE(entry.crc, 4);
|
|
91
|
+
if (entry.zip64) {
|
|
92
|
+
writeUInt64(buf, entry.compressedSize, 8);
|
|
93
|
+
writeUInt64(buf, entry.uncompressedSize, 16);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
buf.writeUInt32LE(entry.compressedSize, 8);
|
|
97
|
+
buf.writeUInt32LE(entry.uncompressedSize, 12);
|
|
98
|
+
}
|
|
99
|
+
return buf;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Add an entry whose contents come from a stream.
|
|
103
|
+
*
|
|
104
|
+
* Whether an entry is zip64 has to be settled before any of its data is
|
|
105
|
+
* written, so a source of unknown length is read ahead of up to
|
|
106
|
+
* `probeLimit` bytes to find out which it is.
|
|
107
|
+
*
|
|
108
|
+
* @param options.sizeHint how large the source is known to be, if it is
|
|
109
|
+
*/
|
|
110
|
+
async addStream(name, source, options = {}) {
|
|
111
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
112
|
+
const probed = [];
|
|
113
|
+
let zip64;
|
|
114
|
+
if (options.sizeHint !== undefined)
|
|
115
|
+
zip64 = options.sizeHint >= this.zip64Threshold;
|
|
116
|
+
else {
|
|
117
|
+
let seen = 0;
|
|
118
|
+
let ended = false;
|
|
119
|
+
while (seen <= this.probeLimit) {
|
|
120
|
+
const next = await iterator.next();
|
|
121
|
+
if (next.done) {
|
|
122
|
+
ended = true;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
probed.push(next.value);
|
|
126
|
+
seen += next.value.length;
|
|
127
|
+
}
|
|
128
|
+
zip64 = !ended || seen >= this.zip64Threshold;
|
|
129
|
+
}
|
|
130
|
+
const { time, date } = dosDateTime(options.mtime ?? new Date());
|
|
131
|
+
const entry = {
|
|
132
|
+
name: this.entryName(name, false),
|
|
133
|
+
flags: FLAG_DESCRIPTOR | FLAG_UTF8 | (this.password ? FLAG_ENCRYPTED : 0),
|
|
134
|
+
method: METHOD_DEFLATED,
|
|
135
|
+
time,
|
|
136
|
+
date,
|
|
137
|
+
crc: 0,
|
|
138
|
+
compressedSize: 0,
|
|
139
|
+
uncompressedSize: 0,
|
|
140
|
+
offset: this.offset,
|
|
141
|
+
mode: options.mode ?? 0o644,
|
|
142
|
+
isDirectory: false,
|
|
143
|
+
zip64,
|
|
144
|
+
};
|
|
145
|
+
await this.put(this.localHeader(entry));
|
|
146
|
+
const crypto = this.password ? new ZipCrypto(this.password) : null;
|
|
147
|
+
if (crypto) {
|
|
148
|
+
// the 12 byte encryption header. Its last byte is a check byte the
|
|
149
|
+
// reader compares against - the high byte of the modification time,
|
|
150
|
+
// because with a data descriptor the CRC is not known yet
|
|
151
|
+
const salt = randomBytes(12);
|
|
152
|
+
salt[11] = (time >>> 8) & 0xff;
|
|
153
|
+
await this.put(crypto.encrypt(salt));
|
|
154
|
+
entry.compressedSize += 12;
|
|
155
|
+
}
|
|
156
|
+
const deflate = createDeflateRaw({ level: this.level });
|
|
157
|
+
let feedError;
|
|
158
|
+
const feed = (async () => {
|
|
159
|
+
const consume = async (buf) => {
|
|
160
|
+
entry.crc = crc32(buf, entry.crc);
|
|
161
|
+
entry.uncompressedSize += buf.length;
|
|
162
|
+
if (!deflate.write(buf))
|
|
163
|
+
await once(deflate, "drain");
|
|
164
|
+
};
|
|
165
|
+
// whatever the format probe already read, then the rest of the source
|
|
166
|
+
for (const buf of probed)
|
|
167
|
+
await consume(buf);
|
|
168
|
+
while (true) {
|
|
169
|
+
const next = await iterator.next();
|
|
170
|
+
if (next.done)
|
|
171
|
+
break;
|
|
172
|
+
await consume(next.value);
|
|
173
|
+
}
|
|
174
|
+
deflate.end();
|
|
175
|
+
})().catch((e) => {
|
|
176
|
+
feedError = e;
|
|
177
|
+
// unblock the consumer below, which would otherwise wait for an end
|
|
178
|
+
// that is never coming
|
|
179
|
+
deflate.destroy(e);
|
|
180
|
+
});
|
|
181
|
+
try {
|
|
182
|
+
for await (const chunk of deflate) {
|
|
183
|
+
const data = crypto
|
|
184
|
+
? crypto.encrypt(chunk)
|
|
185
|
+
: chunk;
|
|
186
|
+
entry.compressedSize += data.length;
|
|
187
|
+
await this.put(data);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
await feed;
|
|
192
|
+
}
|
|
193
|
+
if (feedError)
|
|
194
|
+
throw feedError;
|
|
195
|
+
if (!entry.zip64 &&
|
|
196
|
+
(entry.compressedSize > UINT32_MAX || entry.uncompressedSize > UINT32_MAX))
|
|
197
|
+
throw new Error(`Zip entry ${name} grew past 4GB while it was being written`);
|
|
198
|
+
await this.put(this.dataDescriptor(entry));
|
|
199
|
+
this.entries.push(entry);
|
|
200
|
+
}
|
|
201
|
+
/** Add an entry from content held in memory */
|
|
202
|
+
async addBuffer(name, data, options = {}) {
|
|
203
|
+
await this.addStream(name, Readable.from([data]), {
|
|
204
|
+
...options,
|
|
205
|
+
sizeHint: data.length,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/** Add an entry read from a file on disk. The file is streamed. */
|
|
209
|
+
async addFile(name, localPath) {
|
|
210
|
+
const stats = await stat(localPath);
|
|
211
|
+
await this.addStream(name, createReadStream(localPath), {
|
|
212
|
+
sizeHint: stats.size,
|
|
213
|
+
mode: stats.mode & 0o7777,
|
|
214
|
+
mtime: stats.mtime,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/** Add a directory entry */
|
|
218
|
+
async addDirectory(name, options = {}) {
|
|
219
|
+
const { time, date } = dosDateTime(options.mtime ?? new Date());
|
|
220
|
+
const entry = {
|
|
221
|
+
name: this.entryName(name, true),
|
|
222
|
+
flags: FLAG_UTF8,
|
|
223
|
+
method: METHOD_STORED,
|
|
224
|
+
time,
|
|
225
|
+
date,
|
|
226
|
+
crc: 0,
|
|
227
|
+
compressedSize: 0,
|
|
228
|
+
uncompressedSize: 0,
|
|
229
|
+
offset: this.offset,
|
|
230
|
+
mode: options.mode ?? 0o755,
|
|
231
|
+
isDirectory: true,
|
|
232
|
+
zip64: false,
|
|
233
|
+
};
|
|
234
|
+
await this.put(this.localHeader(entry));
|
|
235
|
+
this.entries.push(entry);
|
|
236
|
+
}
|
|
237
|
+
/** The central directory record of one entry */
|
|
238
|
+
centralHeader(entry) {
|
|
239
|
+
// only the values that do not fit go into the zip64 extra field, in the
|
|
240
|
+
// order the format prescribes
|
|
241
|
+
const zip64Fields = [];
|
|
242
|
+
if (entry.uncompressedSize > UINT32_MAX)
|
|
243
|
+
zip64Fields.push(entry.uncompressedSize);
|
|
244
|
+
if (entry.compressedSize > UINT32_MAX)
|
|
245
|
+
zip64Fields.push(entry.compressedSize);
|
|
246
|
+
if (entry.offset > UINT32_MAX)
|
|
247
|
+
zip64Fields.push(entry.offset);
|
|
248
|
+
const extraSize = zip64Fields.length ? 4 + zip64Fields.length * 8 : 0;
|
|
249
|
+
const buf = Buffer.alloc(CENTRAL_HEADER_SIZE + entry.name.length + extraSize);
|
|
250
|
+
buf.writeUInt32LE(CENTRAL_SIG, 0);
|
|
251
|
+
buf.writeUInt16LE((3 << 8) | 45, 4); // made by unix
|
|
252
|
+
buf.writeUInt16LE(extraSize ? 45 : 20, 6);
|
|
253
|
+
buf.writeUInt16LE(entry.flags, 8);
|
|
254
|
+
buf.writeUInt16LE(entry.method, 10);
|
|
255
|
+
buf.writeUInt16LE(entry.time, 12);
|
|
256
|
+
buf.writeUInt16LE(entry.date, 14);
|
|
257
|
+
buf.writeUInt32LE(entry.crc, 16);
|
|
258
|
+
buf.writeUInt32LE(Math.min(entry.compressedSize, UINT32_MAX), 20);
|
|
259
|
+
buf.writeUInt32LE(Math.min(entry.uncompressedSize, UINT32_MAX), 24);
|
|
260
|
+
buf.writeUInt16LE(entry.name.length, 28);
|
|
261
|
+
buf.writeUInt16LE(extraSize, 30);
|
|
262
|
+
buf.writeUInt16LE(0, 32); // comment length
|
|
263
|
+
buf.writeUInt16LE(0, 34); // disk number
|
|
264
|
+
buf.writeUInt16LE(0, 36); // internal attributes
|
|
265
|
+
buf.writeUInt32LE(((entry.mode & 0xffff) << 16) | (entry.isDirectory ? 0x10 : 0), 38);
|
|
266
|
+
buf.writeUInt32LE(Math.min(entry.offset, UINT32_MAX), 42);
|
|
267
|
+
entry.name.copy(buf, CENTRAL_HEADER_SIZE);
|
|
268
|
+
if (extraSize) {
|
|
269
|
+
const at = CENTRAL_HEADER_SIZE + entry.name.length;
|
|
270
|
+
buf.writeUInt16LE(ZIP64_EXTRA_ID, at);
|
|
271
|
+
buf.writeUInt16LE(extraSize - 4, at + 2);
|
|
272
|
+
zip64Fields.forEach((v, i) => writeUInt64(buf, v, at + 4 + i * 8));
|
|
273
|
+
}
|
|
274
|
+
return buf;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Write the central directory and the end of central directory records.
|
|
278
|
+
* The writer cannot be used afterwards.
|
|
279
|
+
*/
|
|
280
|
+
async finalize() {
|
|
281
|
+
const centralStart = this.offset;
|
|
282
|
+
for (const entry of this.entries)
|
|
283
|
+
await this.put(this.centralHeader(entry));
|
|
284
|
+
const centralSize = this.offset - centralStart;
|
|
285
|
+
const needsZip64 = this.entries.length > UINT16_MAX ||
|
|
286
|
+
centralStart > UINT32_MAX ||
|
|
287
|
+
centralSize > UINT32_MAX;
|
|
288
|
+
if (needsZip64) {
|
|
289
|
+
const zip64Eocd = Buffer.alloc(ZIP64_EOCD_SIZE);
|
|
290
|
+
zip64Eocd.writeUInt32LE(ZIP64_EOCD_SIG, 0);
|
|
291
|
+
writeUInt64(zip64Eocd, ZIP64_EOCD_SIZE - 12, 4);
|
|
292
|
+
zip64Eocd.writeUInt16LE((3 << 8) | 45, 12);
|
|
293
|
+
zip64Eocd.writeUInt16LE(45, 14);
|
|
294
|
+
zip64Eocd.writeUInt32LE(0, 16); // this disk
|
|
295
|
+
zip64Eocd.writeUInt32LE(0, 20); // disk with central directory
|
|
296
|
+
writeUInt64(zip64Eocd, this.entries.length, 24);
|
|
297
|
+
writeUInt64(zip64Eocd, this.entries.length, 32);
|
|
298
|
+
writeUInt64(zip64Eocd, centralSize, 40);
|
|
299
|
+
writeUInt64(zip64Eocd, centralStart, 48);
|
|
300
|
+
const eocdOffset = this.offset;
|
|
301
|
+
await this.put(zip64Eocd);
|
|
302
|
+
const locator = Buffer.alloc(ZIP64_LOCATOR_SIZE);
|
|
303
|
+
locator.writeUInt32LE(ZIP64_LOCATOR_SIG, 0);
|
|
304
|
+
locator.writeUInt32LE(0, 4);
|
|
305
|
+
writeUInt64(locator, eocdOffset, 8);
|
|
306
|
+
locator.writeUInt32LE(1, 16);
|
|
307
|
+
await this.put(locator);
|
|
308
|
+
}
|
|
309
|
+
const eocd = Buffer.alloc(EOCD_SIZE);
|
|
310
|
+
eocd.writeUInt32LE(EOCD_SIG, 0);
|
|
311
|
+
eocd.writeUInt16LE(0, 4);
|
|
312
|
+
eocd.writeUInt16LE(0, 6);
|
|
313
|
+
eocd.writeUInt16LE(Math.min(this.entries.length, UINT16_MAX), 8);
|
|
314
|
+
eocd.writeUInt16LE(Math.min(this.entries.length, UINT16_MAX), 10);
|
|
315
|
+
eocd.writeUInt32LE(Math.min(centralSize, UINT32_MAX), 12);
|
|
316
|
+
eocd.writeUInt32LE(Math.min(centralStart, UINT32_MAX), 16);
|
|
317
|
+
eocd.writeUInt16LE(0, 20); // comment length
|
|
318
|
+
await this.put(eocd);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=zip-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-writer.js","sourceRoot":"","sources":["../../models/zip-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Readable } from "stream";
|
|
2
|
+
/** Request sent from the main thread to the zip worker. */
|
|
3
|
+
export type ZipRequest = {
|
|
4
|
+
id: number;
|
|
5
|
+
cmd: "beginFile";
|
|
6
|
+
path: string;
|
|
7
|
+
password?: string;
|
|
8
|
+
} | {
|
|
9
|
+
id: number;
|
|
10
|
+
cmd: "beginStream";
|
|
11
|
+
password?: string;
|
|
12
|
+
} | {
|
|
13
|
+
id: number;
|
|
14
|
+
cmd: "addBuffer";
|
|
15
|
+
entryName: string;
|
|
16
|
+
data: Uint8Array;
|
|
17
|
+
} | {
|
|
18
|
+
id: number;
|
|
19
|
+
cmd: "addLocalFile";
|
|
20
|
+
entryName: string;
|
|
21
|
+
localPath: string;
|
|
22
|
+
} | {
|
|
23
|
+
id: number;
|
|
24
|
+
cmd: "addDirectory";
|
|
25
|
+
entryName: string;
|
|
26
|
+
} | {
|
|
27
|
+
id: number;
|
|
28
|
+
cmd: "beginEntry";
|
|
29
|
+
entryName: string;
|
|
30
|
+
} | {
|
|
31
|
+
id: number;
|
|
32
|
+
cmd: "entryChunk";
|
|
33
|
+
data: Uint8Array;
|
|
34
|
+
} | {
|
|
35
|
+
id: number;
|
|
36
|
+
cmd: "endEntry";
|
|
37
|
+
} | {
|
|
38
|
+
id: number;
|
|
39
|
+
cmd: "finish";
|
|
40
|
+
};
|
|
41
|
+
/** Reply sent from the zip worker back to the main thread. */
|
|
42
|
+
export type ZipResponse = {
|
|
43
|
+
id: number;
|
|
44
|
+
ok: true;
|
|
45
|
+
result?: any;
|
|
46
|
+
} | {
|
|
47
|
+
id: number;
|
|
48
|
+
ok: false;
|
|
49
|
+
error: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Builds a zip file, one entry at a time, on a worker thread.
|
|
53
|
+
*
|
|
54
|
+
* `finish` completes the archive and shuts the worker down; the builder
|
|
55
|
+
* cannot be used afterwards.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ZipBuilder {
|
|
58
|
+
private worker;
|
|
59
|
+
private closed;
|
|
60
|
+
/** set when the archive is streamed to the caller rather than to a file */
|
|
61
|
+
readonly stream?: Readable;
|
|
62
|
+
private constructor();
|
|
63
|
+
private static begin;
|
|
64
|
+
/**
|
|
65
|
+
* Build an archive at a path on disk. It is written where it belongs -
|
|
66
|
+
* writing it elsewhere and moving it would fail across filesystems.
|
|
67
|
+
*
|
|
68
|
+
* @param password if non-empty, entries are encrypted with the traditional
|
|
69
|
+
* zip password scheme, as the system `zip -P` did
|
|
70
|
+
*/
|
|
71
|
+
static toFile(path: string, password?: string): Promise<ZipBuilder>;
|
|
72
|
+
/**
|
|
73
|
+
* Build an archive into a readable stream, for destinations written over
|
|
74
|
+
* the network (S3, SFTP) or straight to a browser, so that no copy is made
|
|
75
|
+
* on the local disk. Read `stream` while adding entries: the archive is
|
|
76
|
+
* produced as it is consumed.
|
|
77
|
+
*/
|
|
78
|
+
static toStream(password?: string): Promise<ZipBuilder>;
|
|
79
|
+
/** Add an entry from content held in memory */
|
|
80
|
+
addBuffer(entryName: string, data: Buffer): Promise<void>;
|
|
81
|
+
/** Add an entry from a file on disk. The worker streams it. */
|
|
82
|
+
addLocalFile(entryName: string, localPath: string): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Add an entry from a stream of content produced in the main thread, for
|
|
85
|
+
* content too large to want as one buffer - a table dump, say. Each chunk
|
|
86
|
+
* is acknowledged before the next is sent, so the producer runs no faster
|
|
87
|
+
* than the archive is written.
|
|
88
|
+
*/
|
|
89
|
+
addStream(entryName: string, source: Readable): Promise<void>;
|
|
90
|
+
/** Add a directory entry. A trailing slash is added if missing. */
|
|
91
|
+
addDirectory(entryName: string): Promise<void>;
|
|
92
|
+
/** Complete the archive and close the worker */
|
|
93
|
+
finish(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Abandon a half-built archive and close the worker. Any consumer of
|
|
96
|
+
* `stream` is failed too, so a partial archive is never mistaken for a
|
|
97
|
+
* complete one.
|
|
98
|
+
*/
|
|
99
|
+
discard(cause?: any): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=zip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip.d.ts","sourceRoot":"","sources":["../../models/zip.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAe,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE/C,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACrE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACnD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,CAAC;AAElC,8DAA8D;AAC9D,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,GACtC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAgH7C;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAkB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAE3B,OAAO;mBAKc,KAAK;IAgB1B;;;;;;OAMG;WACU,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAMzE;;;;;OAKG;WACU,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQ7D,+CAA+C;IACzC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,+DAA+D;IACzD,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE,mEAAmE;IAC7D,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,gDAAgD;IAC1C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAW7B;;;;OAIG;IACG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ1C"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Building a zip file on a worker thread.
|
|
3
|
+
*
|
|
4
|
+
* Zipping is CPU-bound, so doing it on the main thread would block the event
|
|
5
|
+
* loop for the whole duration of a backup, which is why this used to shell
|
|
6
|
+
* out to the system `zip` executable. A worker thread gives the same
|
|
7
|
+
* non-blocking behaviour without depending on anything being installed on the
|
|
8
|
+
* host. (Reading is a different matter - see zip-extract.ts.)
|
|
9
|
+
*
|
|
10
|
+
* The archive is streamed, never assembled in memory: entries are compressed
|
|
11
|
+
* and written out as they are added (see zip-writer.ts), so a backup of a
|
|
12
|
+
* file store far larger than RAM works. Content generated in the main thread
|
|
13
|
+
* (pack.json, table dumps, config) is handed over a buffer at a time, while
|
|
14
|
+
* files already on disk are only named - the worker streams them itself.
|
|
15
|
+
*
|
|
16
|
+
* @category saltcorn-admin-models
|
|
17
|
+
* @module models/zip
|
|
18
|
+
*/
|
|
19
|
+
import { Worker } from "worker_threads";
|
|
20
|
+
import { PassThrough } from "stream";
|
|
21
|
+
const workerURL = new URL("./zip-worker.js", import.meta.url);
|
|
22
|
+
/**
|
|
23
|
+
* A worker thread running zip-worker.js, with a promise-per-message
|
|
24
|
+
* request/response protocol on top of it.
|
|
25
|
+
*/
|
|
26
|
+
class ZipWorker {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.seq = 0;
|
|
29
|
+
this.pending = new Map();
|
|
30
|
+
this.worker = new Worker(workerURL);
|
|
31
|
+
this.worker.on("message", (msg) => {
|
|
32
|
+
if (msg?.type === "chunk")
|
|
33
|
+
return this.takeChunk(msg.data);
|
|
34
|
+
if (msg?.type === "chunkEnd")
|
|
35
|
+
return this.sink?.end();
|
|
36
|
+
const waiter = this.pending.get(msg.id);
|
|
37
|
+
if (!waiter)
|
|
38
|
+
return;
|
|
39
|
+
this.pending.delete(msg.id);
|
|
40
|
+
if (msg.ok)
|
|
41
|
+
waiter.resolve(msg.result);
|
|
42
|
+
else
|
|
43
|
+
waiter.reject(new Error(msg.error));
|
|
44
|
+
});
|
|
45
|
+
this.worker.on("error", (e) => this.fail(e));
|
|
46
|
+
this.worker.on("exit", (code) => {
|
|
47
|
+
if (this.pending.size)
|
|
48
|
+
this.fail(new Error(`zip worker stopped with exit code ${code}`));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Take a chunk of the archive and acknowledge it once the consumer has
|
|
53
|
+
* room for more. The worker sends the next chunk only after the
|
|
54
|
+
* acknowledgement, so a slow upload slows the whole pipeline down rather
|
|
55
|
+
* than filling memory.
|
|
56
|
+
*/
|
|
57
|
+
takeChunk(data) {
|
|
58
|
+
const sink = this.sink;
|
|
59
|
+
if (!sink || sink.destroyed)
|
|
60
|
+
return this.abandon(new Error("Zip output stream was closed"));
|
|
61
|
+
const ack = () => this.worker.postMessage({ cmd: "chunkAck" });
|
|
62
|
+
if (sink.write(Buffer.from(data.buffer, data.byteOffset, data.byteLength)))
|
|
63
|
+
ack();
|
|
64
|
+
else
|
|
65
|
+
sink.once("drain", ack);
|
|
66
|
+
}
|
|
67
|
+
fail(e) {
|
|
68
|
+
this.dead = e;
|
|
69
|
+
for (const waiter of this.pending.values())
|
|
70
|
+
waiter.reject(e);
|
|
71
|
+
this.pending.clear();
|
|
72
|
+
this.sink?.destroy(e);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The output went away - a failed upload, a browser that closed the
|
|
76
|
+
* connection. Stop the worker rather than leaving it blocked forever on an
|
|
77
|
+
* acknowledgement that is never coming.
|
|
78
|
+
*/
|
|
79
|
+
abandon(e) {
|
|
80
|
+
if (this.dead)
|
|
81
|
+
return;
|
|
82
|
+
this.fail(e);
|
|
83
|
+
this.worker.terminate();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Send a request and wait for its reply.
|
|
87
|
+
*
|
|
88
|
+
* Content buffers are copied, not transferred. Transferring would save the
|
|
89
|
+
* copy, but the buffer belongs to whoever passed it in: a producer that
|
|
90
|
+
* fills and reuses one buffer - which a Readable is free to do - would find
|
|
91
|
+
* it detached under it, and would go on writing zero-length chunks with no
|
|
92
|
+
* error anywhere. The copy is a memcpy against a deflate; it does not show.
|
|
93
|
+
*/
|
|
94
|
+
send(req) {
|
|
95
|
+
if (this.dead)
|
|
96
|
+
return Promise.reject(this.dead);
|
|
97
|
+
const id = ++this.seq;
|
|
98
|
+
const message = { ...req, id };
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
this.pending.set(id, { resolve, reject });
|
|
101
|
+
this.worker.postMessage(message);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/** Start collecting the archive bytes the worker sends us */
|
|
105
|
+
openSink() {
|
|
106
|
+
const sink = new PassThrough();
|
|
107
|
+
// a consumer that fails takes the sink down with it; keep a listener of
|
|
108
|
+
// our own so that never becomes an unhandled error event, and stop
|
|
109
|
+
// producing bytes nobody is going to read
|
|
110
|
+
sink.on("error", (e) => this.abandon(e));
|
|
111
|
+
this.sink = sink;
|
|
112
|
+
return sink;
|
|
113
|
+
}
|
|
114
|
+
async close() {
|
|
115
|
+
await this.worker.terminate();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Builds a zip file, one entry at a time, on a worker thread.
|
|
120
|
+
*
|
|
121
|
+
* `finish` completes the archive and shuts the worker down; the builder
|
|
122
|
+
* cannot be used afterwards.
|
|
123
|
+
*/
|
|
124
|
+
export class ZipBuilder {
|
|
125
|
+
constructor(worker, stream) {
|
|
126
|
+
this.closed = false;
|
|
127
|
+
this.worker = worker;
|
|
128
|
+
this.stream = stream;
|
|
129
|
+
}
|
|
130
|
+
static async begin(start, stream) {
|
|
131
|
+
const worker = new ZipWorker();
|
|
132
|
+
const readable = stream?.(worker);
|
|
133
|
+
const builder = new ZipBuilder(worker, readable);
|
|
134
|
+
try {
|
|
135
|
+
await start(worker);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
await builder.discard(e);
|
|
139
|
+
throw e;
|
|
140
|
+
}
|
|
141
|
+
return builder;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Build an archive at a path on disk. It is written where it belongs -
|
|
145
|
+
* writing it elsewhere and moving it would fail across filesystems.
|
|
146
|
+
*
|
|
147
|
+
* @param password if non-empty, entries are encrypted with the traditional
|
|
148
|
+
* zip password scheme, as the system `zip -P` did
|
|
149
|
+
*/
|
|
150
|
+
static async toFile(path, password) {
|
|
151
|
+
return await ZipBuilder.begin((worker) => worker.send({ cmd: "beginFile", path, password: password || undefined }));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Build an archive into a readable stream, for destinations written over
|
|
155
|
+
* the network (S3, SFTP) or straight to a browser, so that no copy is made
|
|
156
|
+
* on the local disk. Read `stream` while adding entries: the archive is
|
|
157
|
+
* produced as it is consumed.
|
|
158
|
+
*/
|
|
159
|
+
static async toStream(password) {
|
|
160
|
+
return await ZipBuilder.begin((worker) => worker.send({ cmd: "beginStream", password: password || undefined }), (worker) => worker.openSink());
|
|
161
|
+
}
|
|
162
|
+
/** Add an entry from content held in memory */
|
|
163
|
+
async addBuffer(entryName, data) {
|
|
164
|
+
await this.worker.send({ cmd: "addBuffer", entryName, data });
|
|
165
|
+
}
|
|
166
|
+
/** Add an entry from a file on disk. The worker streams it. */
|
|
167
|
+
async addLocalFile(entryName, localPath) {
|
|
168
|
+
await this.worker.send({ cmd: "addLocalFile", entryName, localPath });
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Add an entry from a stream of content produced in the main thread, for
|
|
172
|
+
* content too large to want as one buffer - a table dump, say. Each chunk
|
|
173
|
+
* is acknowledged before the next is sent, so the producer runs no faster
|
|
174
|
+
* than the archive is written.
|
|
175
|
+
*/
|
|
176
|
+
async addStream(entryName, source) {
|
|
177
|
+
await this.worker.send({ cmd: "beginEntry", entryName });
|
|
178
|
+
for await (const chunk of source)
|
|
179
|
+
await this.worker.send({ cmd: "entryChunk", data: chunk });
|
|
180
|
+
await this.worker.send({ cmd: "endEntry" });
|
|
181
|
+
}
|
|
182
|
+
/** Add a directory entry. A trailing slash is added if missing. */
|
|
183
|
+
async addDirectory(entryName) {
|
|
184
|
+
await this.worker.send({ cmd: "addDirectory", entryName });
|
|
185
|
+
}
|
|
186
|
+
/** Complete the archive and close the worker */
|
|
187
|
+
async finish() {
|
|
188
|
+
try {
|
|
189
|
+
await this.worker.send({ cmd: "finish" });
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
await this.discard(e);
|
|
193
|
+
throw e;
|
|
194
|
+
}
|
|
195
|
+
this.closed = true;
|
|
196
|
+
await this.worker.close();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Abandon a half-built archive and close the worker. Any consumer of
|
|
200
|
+
* `stream` is failed too, so a partial archive is never mistaken for a
|
|
201
|
+
* complete one.
|
|
202
|
+
*/
|
|
203
|
+
async discard(cause) {
|
|
204
|
+
if (this.closed)
|
|
205
|
+
return;
|
|
206
|
+
this.closed = true;
|
|
207
|
+
this.stream?.destroy(cause instanceof Error ? cause : new Error("Zip archive abandoned"));
|
|
208
|
+
await this.worker.close();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=zip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip.js","sourceRoot":"","sources":["../../models/zip.ts"],"names":[],"mappings":"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"}
|