@zip.js/zip.js 2.8.57 → 2.8.58
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/deno.json +1 -1
- package/dist/zip-core-external.js +303 -163
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +303 -163
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +327 -164
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +344 -157
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +327 -164
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +329 -165
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +330 -166
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +305 -165
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +305 -165
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +306 -166
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +329 -165
- package/index-native.min.js +1 -1
- package/index.cjs +330 -166
- package/index.d.cts +113 -9
- package/index.d.ts +113 -9
- package/index.min.js +1 -1
- package/lib/core/constants.js +2 -0
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-fs.js +27 -1
- package/lib/core/zip-reader.js +26 -6
- package/lib/core/zip-writer.js +278 -156
- package/lib/core/zlib-streams-inline.js +1 -1
- package/package.json +1 -1
package/lib/core/zip-writer.js
CHANGED
|
@@ -129,6 +129,7 @@ import {
|
|
|
129
129
|
FILE_ATTR_UNIX_SETUID_MASK,
|
|
130
130
|
FILE_ATTR_UNIX_SETGID_MASK,
|
|
131
131
|
FILE_ATTR_UNIX_STICKY_MASK,
|
|
132
|
+
VERSION_STORE,
|
|
132
133
|
VERSION_DEFLATE,
|
|
133
134
|
VERSION_MADE_BY_MSDOS,
|
|
134
135
|
VERSION_MADE_BY_UNIX,
|
|
@@ -174,6 +175,7 @@ import { concat, getDataView } from "./util/array.js";
|
|
|
174
175
|
import { toCompatibleReadable, streamToBlob } from "./util/compatible-streams.js";
|
|
175
176
|
import {
|
|
176
177
|
PROPERTY_NAME_LAST_MODIFICATION_DATE,
|
|
178
|
+
PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE,
|
|
177
179
|
PROPERTY_NAME_LAST_ACCESS_DATE,
|
|
178
180
|
PROPERTY_NAME_CREATION_DATE,
|
|
179
181
|
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
|
|
@@ -305,153 +307,150 @@ class ZipWriter {
|
|
|
305
307
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
306
308
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
307
309
|
pendingAddFileCalls: new Set(),
|
|
310
|
+
pendingErrors: [],
|
|
308
311
|
bufferedWrites: 0,
|
|
309
312
|
lastFileEntry: UNDEFINED_VALUE
|
|
310
313
|
});
|
|
311
314
|
}
|
|
312
315
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
320
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
321
|
-
await initStream(reader);
|
|
322
|
-
}
|
|
323
|
-
const { ZipReader } = await import("./zip-reader.js");
|
|
324
|
-
const zipReader = new ZipReader(reader);
|
|
325
|
-
const entries = await zipReader.getEntries();
|
|
326
|
-
await zipReader.close();
|
|
327
|
-
await initStream(this.writer);
|
|
328
|
-
const { directoryOffset } = zipReader;
|
|
329
|
-
if (this.addSplitZipSignature) {
|
|
330
|
-
delete this.addSplitZipSignature;
|
|
331
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
332
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
333
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
337
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
338
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
339
|
-
const {
|
|
340
|
-
version,
|
|
341
|
-
rawLastModDate,
|
|
342
|
-
lastAccessDate,
|
|
343
|
-
creationDate,
|
|
344
|
-
rawFilename,
|
|
345
|
-
bitFlag,
|
|
346
|
-
encrypted,
|
|
347
|
-
uncompressedSize,
|
|
348
|
-
compressedSize,
|
|
349
|
-
extraFieldZip64
|
|
350
|
-
} = entry;
|
|
351
|
-
let {
|
|
352
|
-
compressionMethod,
|
|
353
|
-
rawExtraFieldZip64,
|
|
354
|
-
rawExtraFieldAES,
|
|
355
|
-
rawExtraFieldExtendedTimestamp,
|
|
356
|
-
rawExtraFieldNTFS,
|
|
357
|
-
rawExtraFieldUnix,
|
|
358
|
-
rawExtraField,
|
|
359
|
-
} = entry;
|
|
360
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
361
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
362
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
363
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
364
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
365
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
366
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
367
|
-
if (entry.extraFieldAES) {
|
|
368
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
369
|
-
}
|
|
370
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
371
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
372
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
373
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
374
|
-
const {
|
|
375
|
-
headerArray,
|
|
376
|
-
headerView
|
|
377
|
-
} = getHeaderArrayData({
|
|
378
|
-
version,
|
|
379
|
-
bitFlag: bitFlagValue,
|
|
380
|
-
compressionMethod,
|
|
381
|
-
uncompressedSize,
|
|
382
|
-
compressedSize,
|
|
383
|
-
rawLastModDate,
|
|
384
|
-
rawFilename,
|
|
385
|
-
zip64CompressedSize,
|
|
386
|
-
zip64UncompressedSize,
|
|
387
|
-
extraFieldLength
|
|
388
|
-
});
|
|
389
|
-
const { crc32 } = entry;
|
|
390
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
391
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
392
|
-
}
|
|
393
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
394
|
-
Object.assign(entry, {
|
|
395
|
-
zip64UncompressedSize,
|
|
396
|
-
zip64CompressedSize,
|
|
397
|
-
offset,
|
|
398
|
-
diskNumberStart,
|
|
399
|
-
zip64DiskNumberStart: false,
|
|
400
|
-
rawExtraFieldZip64,
|
|
401
|
-
rawExtraFieldAES,
|
|
402
|
-
rawExtraFieldExtendedTimestamp,
|
|
403
|
-
rawExtraFieldNTFS,
|
|
404
|
-
rawExtraFieldUnix,
|
|
405
|
-
rawExtraField,
|
|
406
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
407
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
408
|
-
headerArray,
|
|
409
|
-
headerView
|
|
410
|
-
});
|
|
411
|
-
return [entry.filename, entry];
|
|
412
|
-
}));
|
|
316
|
+
prependZip(reader) {
|
|
317
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
appendZip(reader) {
|
|
321
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
413
322
|
}
|
|
414
323
|
|
|
415
|
-
async
|
|
324
|
+
async appendZipEntries(reader) {
|
|
416
325
|
const zipWriter = this;
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
workers++;
|
|
421
|
-
} else {
|
|
422
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
326
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
327
|
+
while (pendingAddFileCalls.size) {
|
|
328
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
423
329
|
}
|
|
424
|
-
let
|
|
425
|
-
|
|
330
|
+
let resolveAppendZip;
|
|
331
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
332
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
333
|
+
const appendedFilenames = [];
|
|
334
|
+
let releaseLockWriter;
|
|
426
335
|
try {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
336
|
+
reader = new GenericReader(reader);
|
|
337
|
+
await initStream(reader);
|
|
338
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
339
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
340
|
+
await initStream(reader);
|
|
430
341
|
}
|
|
431
|
-
|
|
432
|
-
|
|
342
|
+
const { ZipReader } = await import("./zip-reader.js");
|
|
343
|
+
const zipReader = new ZipReader(reader);
|
|
344
|
+
const entries = await zipReader.getEntries();
|
|
345
|
+
await zipReader.close();
|
|
346
|
+
await initStream(zipWriter.writer);
|
|
347
|
+
const { directoryOffset } = zipReader;
|
|
348
|
+
entries.forEach(({ filename }) => {
|
|
349
|
+
if (filenames.has(filename)) {
|
|
350
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
351
|
+
}
|
|
352
|
+
filenames.add(filename);
|
|
353
|
+
appendedFilenames.push(filename);
|
|
354
|
+
});
|
|
355
|
+
zipWriter.writerLocked = true;
|
|
356
|
+
const { lockWriter } = zipWriter;
|
|
357
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
358
|
+
zipWriter.writerLocked = false;
|
|
359
|
+
resolve();
|
|
360
|
+
});
|
|
361
|
+
await lockWriter;
|
|
362
|
+
if (zipWriter.addSplitZipSignature) {
|
|
363
|
+
delete zipWriter.addSplitZipSignature;
|
|
364
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
365
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
366
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
367
|
+
}
|
|
433
368
|
}
|
|
434
|
-
zipWriter
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
369
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
370
|
+
entries.forEach(entry => {
|
|
371
|
+
const {
|
|
372
|
+
version,
|
|
373
|
+
rawLastModDate,
|
|
374
|
+
rawFilename,
|
|
375
|
+
bitFlag,
|
|
376
|
+
encrypted,
|
|
377
|
+
uncompressedSize,
|
|
378
|
+
compressedSize,
|
|
379
|
+
extraFieldZip64
|
|
380
|
+
} = entry;
|
|
381
|
+
let {
|
|
382
|
+
compressionMethod,
|
|
383
|
+
rawExtraField,
|
|
384
|
+
} = entry;
|
|
385
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
386
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
387
|
+
if (entry.extraFieldAES) {
|
|
388
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
389
|
+
}
|
|
390
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
391
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
392
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
393
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
394
|
+
const {
|
|
395
|
+
headerArray,
|
|
396
|
+
headerView
|
|
397
|
+
} = getHeaderArrayData({
|
|
398
|
+
version,
|
|
399
|
+
bitFlag: bitFlagValue,
|
|
400
|
+
compressionMethod,
|
|
401
|
+
uncompressedSize,
|
|
402
|
+
compressedSize,
|
|
403
|
+
rawLastModDate,
|
|
404
|
+
rawFilename,
|
|
405
|
+
zip64CompressedSize,
|
|
406
|
+
zip64UncompressedSize,
|
|
407
|
+
extraFieldLength
|
|
408
|
+
});
|
|
409
|
+
const { crc32 } = entry;
|
|
410
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
411
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
412
|
+
}
|
|
413
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
414
|
+
Object.assign(entry, {
|
|
415
|
+
zip64UncompressedSize,
|
|
416
|
+
zip64CompressedSize,
|
|
417
|
+
offset,
|
|
418
|
+
diskNumberStart,
|
|
419
|
+
zip64DiskNumberStart: false,
|
|
420
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
421
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
422
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
423
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
424
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
425
|
+
rawExtraField,
|
|
426
|
+
extendedTimestamp: false,
|
|
427
|
+
headerArray,
|
|
428
|
+
headerView
|
|
429
|
+
});
|
|
430
|
+
fileEntries.set(entry.filename, entry);
|
|
431
|
+
});
|
|
439
432
|
} catch (error) {
|
|
440
|
-
|
|
441
|
-
zipWriter.filenames.delete(name);
|
|
442
|
-
}
|
|
433
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
443
434
|
throw error;
|
|
444
435
|
} finally {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
} else {
|
|
450
|
-
workers--;
|
|
436
|
+
resolveAppendZip();
|
|
437
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
438
|
+
if (releaseLockWriter) {
|
|
439
|
+
releaseLockWriter();
|
|
451
440
|
}
|
|
452
441
|
}
|
|
453
442
|
}
|
|
454
443
|
|
|
444
|
+
add(name = "", reader, options = {}) {
|
|
445
|
+
const zipWriter = this;
|
|
446
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
447
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
448
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
449
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
450
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
451
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
452
|
+
}
|
|
453
|
+
|
|
455
454
|
remove(entry) {
|
|
456
455
|
const { filenames, fileEntries } = this;
|
|
457
456
|
// deno-lint-ignore valid-typeof
|
|
@@ -482,6 +481,19 @@ class ZipWriter {
|
|
|
482
481
|
while (pendingAddFileCalls.size) {
|
|
483
482
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
484
483
|
}
|
|
484
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
485
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
486
|
+
if (unobservedWatchers.length) {
|
|
487
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
488
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
489
|
+
const [error] = unobservedErrors;
|
|
490
|
+
try {
|
|
491
|
+
error.entryErrors = unobservedErrors;
|
|
492
|
+
} catch {
|
|
493
|
+
// ignored
|
|
494
|
+
}
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
485
497
|
await closeFile(zipWriter, comment, options);
|
|
486
498
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
487
499
|
if (!preventClose) {
|
|
@@ -516,11 +528,7 @@ class ZipWriterStream {
|
|
|
516
528
|
try {
|
|
517
529
|
await zipWriter.close();
|
|
518
530
|
} catch (error) {
|
|
519
|
-
|
|
520
|
-
await zipWriter.writer.writable.abort(error);
|
|
521
|
-
} catch {
|
|
522
|
-
// ignored
|
|
523
|
-
}
|
|
531
|
+
await abortWritable(zipWriter, error);
|
|
524
532
|
}
|
|
525
533
|
}
|
|
526
534
|
}
|
|
@@ -537,8 +545,90 @@ class ZipWriterStream {
|
|
|
537
545
|
}
|
|
538
546
|
|
|
539
547
|
async close(comment = UNDEFINED_VALUE, options = {}) {
|
|
540
|
-
|
|
541
|
-
|
|
548
|
+
const { zipWriter } = this;
|
|
549
|
+
const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
|
|
550
|
+
const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
|
|
551
|
+
if (entryErrors.length) {
|
|
552
|
+
const [error] = entryErrors;
|
|
553
|
+
try {
|
|
554
|
+
error.entryErrors = entryErrors;
|
|
555
|
+
} catch {
|
|
556
|
+
// ignored
|
|
557
|
+
}
|
|
558
|
+
await abortWritable(zipWriter, error);
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
try {
|
|
562
|
+
return await zipWriter.close(comment, options);
|
|
563
|
+
} catch (error) {
|
|
564
|
+
await abortWritable(zipWriter, error);
|
|
565
|
+
throw error;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
class WatchedPromise extends Promise {
|
|
571
|
+
|
|
572
|
+
then(onFulfilled, onRejected) {
|
|
573
|
+
const { watcher } = this;
|
|
574
|
+
if (watcher) {
|
|
575
|
+
watcher.observed = true;
|
|
576
|
+
}
|
|
577
|
+
return super.then(onFulfilled, onRejected);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
function watchPromiseError(zipWriter, promise) {
|
|
582
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
583
|
+
const watcher = {};
|
|
584
|
+
watchedPromise.watcher = watcher;
|
|
585
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
586
|
+
zipWriter.pendingErrors.push(watcher);
|
|
587
|
+
return watchedPromise;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
591
|
+
if (zipWriter.filenames.size) {
|
|
592
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
593
|
+
}
|
|
594
|
+
await zipWriter.appendZipEntries(reader);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
598
|
+
options = Object.assign({}, options);
|
|
599
|
+
name = name.trim();
|
|
600
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
601
|
+
name += DIRECTORY_SIGNATURE;
|
|
602
|
+
}
|
|
603
|
+
if (zipWriter.filenames.has(name)) {
|
|
604
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
605
|
+
}
|
|
606
|
+
zipWriter.filenames.add(name);
|
|
607
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
608
|
+
workers++;
|
|
609
|
+
} else {
|
|
610
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
611
|
+
}
|
|
612
|
+
try {
|
|
613
|
+
return await addFile(zipWriter, name, reader, options);
|
|
614
|
+
} catch (error) {
|
|
615
|
+
zipWriter.filenames.delete(name);
|
|
616
|
+
throw error;
|
|
617
|
+
} finally {
|
|
618
|
+
const pendingEntry = pendingEntries.shift();
|
|
619
|
+
if (pendingEntry) {
|
|
620
|
+
pendingEntry();
|
|
621
|
+
} else {
|
|
622
|
+
workers--;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
async function abortWritable(zipWriter, error) {
|
|
628
|
+
try {
|
|
629
|
+
await zipWriter.writer.writable.abort(error);
|
|
630
|
+
} catch {
|
|
631
|
+
// ignored
|
|
542
632
|
}
|
|
543
633
|
}
|
|
544
634
|
|
|
@@ -779,11 +869,12 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
779
869
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
780
870
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
781
871
|
}
|
|
782
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
783
|
-
if (version > MAX_16_BITS) {
|
|
872
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
873
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
784
874
|
throw new Error(ERR_INVALID_VERSION);
|
|
785
875
|
}
|
|
786
876
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
877
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
787
878
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
788
879
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
789
880
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -827,7 +918,7 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
827
918
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
828
919
|
dataDescriptor = false;
|
|
829
920
|
}
|
|
830
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
921
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
831
922
|
dataDescriptor = true;
|
|
832
923
|
}
|
|
833
924
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -846,6 +937,7 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
846
937
|
rawComment,
|
|
847
938
|
version,
|
|
848
939
|
lastModDate,
|
|
940
|
+
rawLastModDate,
|
|
849
941
|
lastAccessDate,
|
|
850
942
|
creationDate,
|
|
851
943
|
internalFileAttributes,
|
|
@@ -1121,10 +1213,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1121
1213
|
}
|
|
1122
1214
|
await initStream(fileWriter);
|
|
1123
1215
|
const diskOffset = getDiskOffset(writer);
|
|
1124
|
-
if (zipWriter.addSplitZipSignature) {
|
|
1125
|
-
|
|
1126
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
1127
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
1216
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
1217
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
1128
1218
|
}
|
|
1129
1219
|
if (usdz && !bufferedWrite) {
|
|
1130
1220
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -1151,6 +1241,9 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1151
1241
|
if (bufferedWrite) {
|
|
1152
1242
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
1153
1243
|
await requestLockWriter();
|
|
1244
|
+
if (zipWriter.addSplitZipSignature) {
|
|
1245
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
1246
|
+
}
|
|
1154
1247
|
writingBufferedEntryData = true;
|
|
1155
1248
|
writerSizeBeforeEntry = writer.size;
|
|
1156
1249
|
await skipDiskIfNeeded();
|
|
@@ -1422,6 +1515,7 @@ function getHeaderInfo(options) {
|
|
|
1422
1515
|
const {
|
|
1423
1516
|
rawFilename,
|
|
1424
1517
|
lastModDate,
|
|
1518
|
+
rawLastModDate: rawLastModDateOption,
|
|
1425
1519
|
lastAccessDate,
|
|
1426
1520
|
creationDate,
|
|
1427
1521
|
level,
|
|
@@ -1555,6 +1649,9 @@ function getHeaderInfo(options) {
|
|
|
1555
1649
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
1556
1650
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
1557
1651
|
}
|
|
1652
|
+
if (version === UNDEFINED_VALUE) {
|
|
1653
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
1654
|
+
}
|
|
1558
1655
|
const { codecVersionNeeded } = options;
|
|
1559
1656
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
1560
1657
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -1587,6 +1684,7 @@ function getHeaderInfo(options) {
|
|
|
1587
1684
|
compressionMethod,
|
|
1588
1685
|
uncompressedSize,
|
|
1589
1686
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
1687
|
+
rawLastModDate: rawLastModDateOption,
|
|
1590
1688
|
rawFilename,
|
|
1591
1689
|
zip64CompressedSize,
|
|
1592
1690
|
zip64UncompressedSize,
|
|
@@ -1793,9 +1891,9 @@ function updateLocalHeader({
|
|
|
1793
1891
|
|
|
1794
1892
|
async function closeFile(zipWriter, comment, options) {
|
|
1795
1893
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
1796
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
1894
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
1797
1895
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
1798
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
1896
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
1799
1897
|
}
|
|
1800
1898
|
|
|
1801
1899
|
function createDirectoryRecords(files) {
|
|
@@ -1879,6 +1977,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1879
1977
|
let directoryDiskOffset = 0;
|
|
1880
1978
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
1881
1979
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
1980
|
+
let directoryEndDiskEntriesLength = 0;
|
|
1882
1981
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
1883
1982
|
const {
|
|
1884
1983
|
offset: fileEntryOffset,
|
|
@@ -1908,6 +2007,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1908
2007
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
1909
2008
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
1910
2009
|
directoryDiskOffset = offset;
|
|
2010
|
+
directoryEndDiskEntriesLength = 0;
|
|
1911
2011
|
await writer.closeDisk();
|
|
1912
2012
|
}
|
|
1913
2013
|
if (indexFileEntry == 0) {
|
|
@@ -1943,6 +2043,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1943
2043
|
directoryRecord.writeBytes(rawComment);
|
|
1944
2044
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
1945
2045
|
offset += directoryRecordLength;
|
|
2046
|
+
directoryEndDiskEntriesLength++;
|
|
1946
2047
|
if (options.onprogress) {
|
|
1947
2048
|
try {
|
|
1948
2049
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -1954,6 +2055,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1954
2055
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
1955
2056
|
return {
|
|
1956
2057
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
2058
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
1957
2059
|
directoryArray
|
|
1958
2060
|
};
|
|
1959
2061
|
}
|
|
@@ -1982,16 +2084,20 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
|
1982
2084
|
|
|
1983
2085
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
1984
2086
|
const { writer } = zipWriter;
|
|
1985
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
2087
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
1986
2088
|
let { directoryDataLength } = cdInfo;
|
|
1987
2089
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
1988
2090
|
let diskNumber = directoryStart.diskNumber;
|
|
1989
2091
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
2092
|
+
const commentLength = getLength(comment);
|
|
2093
|
+
if (commentLength > MAX_16_BITS) {
|
|
2094
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
2095
|
+
}
|
|
2096
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
1990
2097
|
let lastDiskNumber = getDiskNumber(writer);
|
|
1991
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
2098
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
1992
2099
|
lastDiskNumber++;
|
|
1993
2100
|
}
|
|
1994
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
1995
2101
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
1996
2102
|
if (zip64 === false) {
|
|
1997
2103
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -1999,15 +2105,12 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
1999
2105
|
zip64 = true;
|
|
2000
2106
|
}
|
|
2001
2107
|
}
|
|
2002
|
-
const commentLength = getLength(comment);
|
|
2003
|
-
if (commentLength > MAX_16_BITS) {
|
|
2004
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
2005
|
-
}
|
|
2006
2108
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
2007
2109
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
2008
2110
|
await writer.closeDisk();
|
|
2009
2111
|
}
|
|
2010
2112
|
lastDiskNumber = getDiskNumber(writer);
|
|
2113
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
2011
2114
|
if (zip64) {
|
|
2012
2115
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
2013
2116
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -2015,7 +2118,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
2015
2118
|
endOfdirectoryRecord.writeUint16(45);
|
|
2016
2119
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
2017
2120
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
2018
|
-
endOfdirectoryRecord.writeUint64(
|
|
2121
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
2019
2122
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
2020
2123
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
2021
2124
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -2028,6 +2131,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
2028
2131
|
lastDiskNumber = MAX_16_BITS;
|
|
2029
2132
|
diskNumber = MAX_16_BITS;
|
|
2030
2133
|
}
|
|
2134
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
2031
2135
|
fileEntriesLength = MAX_16_BITS;
|
|
2032
2136
|
directoryOffset = MAX_32_BITS;
|
|
2033
2137
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -2035,7 +2139,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
2035
2139
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
2036
2140
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
2037
2141
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
2038
|
-
endOfdirectoryRecord.writeUint16(
|
|
2142
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
2039
2143
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
2040
2144
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
2041
2145
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -2134,9 +2238,21 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
|
2134
2238
|
async function copyData(zipWriter, reader, offset, size) {
|
|
2135
2239
|
if (size > 0) {
|
|
2136
2240
|
const { writer } = zipWriter;
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2241
|
+
let copiedLength = 0;
|
|
2242
|
+
try {
|
|
2243
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
2244
|
+
} catch (error) {
|
|
2245
|
+
zipWriter.hasCorruptedEntries = true;
|
|
2246
|
+
try {
|
|
2247
|
+
error.corruptedEntry = true;
|
|
2248
|
+
} catch {
|
|
2249
|
+
// ignored
|
|
2250
|
+
}
|
|
2251
|
+
throw error;
|
|
2252
|
+
} finally {
|
|
2253
|
+
writer.size += copiedLength;
|
|
2254
|
+
zipWriter.offset += copiedLength;
|
|
2255
|
+
}
|
|
2140
2256
|
}
|
|
2141
2257
|
}
|
|
2142
2258
|
|
|
@@ -2161,6 +2277,12 @@ function getSplitZipSignatureArray() {
|
|
|
2161
2277
|
return signatureArray;
|
|
2162
2278
|
}
|
|
2163
2279
|
|
|
2280
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
2281
|
+
delete zipWriter.addSplitZipSignature;
|
|
2282
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
2283
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2164
2286
|
async function writeData(writer, array) {
|
|
2165
2287
|
const { writable } = writer;
|
|
2166
2288
|
const streamWriter = writable.getWriter();
|