@zip.js/zip.js 2.8.51 → 2.8.52
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/README.md +8 -3
- package/deno.json +1 -1
- package/dist/zip-core-external.js +88 -44
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +89 -43
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +408 -148
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +408 -147
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +408 -148
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +410 -147
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +410 -147
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +89 -43
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +89 -43
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +89 -43
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +410 -147
- package/index-native.min.js +1 -1
- package/index.cjs +410 -147
- package/index.d.cts +278 -10
- package/index.d.ts +278 -10
- package/index.min.js +1 -1
- package/lib/core/codec-worker.js +2 -0
- package/lib/core/constants.js +4 -0
- package/lib/core/io.js +32 -2
- package/lib/core/util/compatible-streams.js +3 -8
- package/lib/core/zip-entry.js +8 -0
- package/lib/core/zip-fs.js +236 -107
- package/lib/core/zip-reader.js +15 -6
- package/lib/core/zip-writer.js +135 -29
- package/lib/zip-core-writer.js +2 -0
- package/package.json +5 -5
package/index-native.cjs
CHANGED
|
@@ -84,6 +84,8 @@ const FILE_ATTR_MSDOS_SYSTEM_MASK = 0x04;
|
|
|
84
84
|
const FILE_ATTR_MSDOS_ARCHIVE_MASK = 0x20;
|
|
85
85
|
const FILE_ATTR_UNIX_TYPE_MASK = 0o170000;
|
|
86
86
|
const FILE_ATTR_UNIX_TYPE_DIR = 0o040000;
|
|
87
|
+
const FILE_ATTR_UNIX_TYPE_SYMLINK = 0o120000;
|
|
88
|
+
const FILE_ATTR_UNIX_TYPE_FILE = 0o100000;
|
|
87
89
|
const FILE_ATTR_UNIX_EXECUTABLE_MASK = 0o111;
|
|
88
90
|
const FILE_ATTR_UNIX_DEFAULT_MASK = 0o644;
|
|
89
91
|
const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
|
|
@@ -1775,8 +1777,6 @@ function getInt32(number) {
|
|
|
1775
1777
|
*/
|
|
1776
1778
|
|
|
1777
1779
|
|
|
1778
|
-
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
1779
|
-
|
|
1780
1780
|
function toCompatibleReadable(readable) {
|
|
1781
1781
|
if (readable instanceof ReadableStream) {
|
|
1782
1782
|
return readable;
|
|
@@ -1799,12 +1799,9 @@ function toCompatibleReadable(readable) {
|
|
|
1799
1799
|
|
|
1800
1800
|
function streamToBlob(readable, contentType) {
|
|
1801
1801
|
readable = toCompatibleReadable(readable);
|
|
1802
|
+
const blobOptions = contentType ? { type: contentType } : {};
|
|
1802
1803
|
if (responseSupportsGlobalReadable()) {
|
|
1803
|
-
|
|
1804
|
-
if (contentType) {
|
|
1805
|
-
options.headers = [[HTTP_HEADER_CONTENT_TYPE, contentType]];
|
|
1806
|
-
}
|
|
1807
|
-
return new Response(readable, options).blob();
|
|
1804
|
+
return new Response(readable).blob().then(blob => contentType ? new Blob([blob], blobOptions) : blob);
|
|
1808
1805
|
}
|
|
1809
1806
|
const chunks = [];
|
|
1810
1807
|
return readable
|
|
@@ -1813,7 +1810,7 @@ function streamToBlob(readable, contentType) {
|
|
|
1813
1810
|
chunks.push(chunk);
|
|
1814
1811
|
}
|
|
1815
1812
|
}))
|
|
1816
|
-
.then(() => new Blob(chunks,
|
|
1813
|
+
.then(() => new Blob(chunks, blobOptions));
|
|
1817
1814
|
}
|
|
1818
1815
|
|
|
1819
1816
|
function responseSupportsGlobalReadable() {
|
|
@@ -3344,8 +3341,10 @@ class Reader extends Stream {
|
|
|
3344
3341
|
async pull(controller) {
|
|
3345
3342
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
3346
3343
|
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
3347
|
-
|
|
3348
|
-
|
|
3344
|
+
if (data.length) {
|
|
3345
|
+
controller.enqueue(data);
|
|
3346
|
+
}
|
|
3347
|
+
if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
3349
3348
|
controller.close();
|
|
3350
3349
|
} else {
|
|
3351
3350
|
chunkOffset += chunkSize;
|
|
@@ -3423,6 +3422,7 @@ class Data64URIWriter extends Writer {
|
|
|
3423
3422
|
constructor(contentType) {
|
|
3424
3423
|
super();
|
|
3425
3424
|
Object.assign(this, {
|
|
3425
|
+
contentType,
|
|
3426
3426
|
data: "data:" + (contentType || "") + ";base64,",
|
|
3427
3427
|
pending: []
|
|
3428
3428
|
});
|
|
@@ -3524,6 +3524,7 @@ class BlobWriter extends Stream {
|
|
|
3524
3524
|
return transformStream.writable;
|
|
3525
3525
|
}
|
|
3526
3526
|
});
|
|
3527
|
+
writer.contentType = contentType;
|
|
3527
3528
|
writer.blob = streamToBlob(transformStream.readable, contentType);
|
|
3528
3529
|
writer.blob.catch(() => { });
|
|
3529
3530
|
}
|
|
@@ -3540,6 +3541,26 @@ class TextReader extends BlobReader {
|
|
|
3540
3541
|
}
|
|
3541
3542
|
}
|
|
3542
3543
|
|
|
3544
|
+
function getTextSize(text) {
|
|
3545
|
+
let size = 0;
|
|
3546
|
+
for (let indexCharacter = 0; indexCharacter < text.length; indexCharacter++) {
|
|
3547
|
+
const characterCode = text.charCodeAt(indexCharacter);
|
|
3548
|
+
if (characterCode < 0x80) {
|
|
3549
|
+
size += 1;
|
|
3550
|
+
} else if (characterCode < 0x800) {
|
|
3551
|
+
size += 2;
|
|
3552
|
+
} else if (characterCode < 0xd800 || characterCode >= 0xe000) {
|
|
3553
|
+
size += 3;
|
|
3554
|
+
} else if (characterCode < 0xdc00 && (text.charCodeAt(indexCharacter + 1) & 0xfc00) == 0xdc00) {
|
|
3555
|
+
size += 4;
|
|
3556
|
+
indexCharacter++;
|
|
3557
|
+
} else {
|
|
3558
|
+
size += 3;
|
|
3559
|
+
}
|
|
3560
|
+
}
|
|
3561
|
+
return size;
|
|
3562
|
+
}
|
|
3563
|
+
|
|
3543
3564
|
class TextWriter extends BlobWriter {
|
|
3544
3565
|
|
|
3545
3566
|
constructor(encoding) {
|
|
@@ -4203,6 +4224,10 @@ class GenericWriter {
|
|
|
4203
4224
|
}
|
|
4204
4225
|
}
|
|
4205
4226
|
|
|
4227
|
+
function ownsWritable(writer) {
|
|
4228
|
+
return Boolean(writer && writer.getData);
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4206
4231
|
function isHttpFamily(url) {
|
|
4207
4232
|
const { baseURI } = getConfiguration();
|
|
4208
4233
|
const { protocol } = new URL(url, baseURI);
|
|
@@ -4347,6 +4372,8 @@ const PROPERTY_NAME_CREATION_DATE = "creationDate";
|
|
|
4347
4372
|
const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
|
|
4348
4373
|
const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes";
|
|
4349
4374
|
const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes";
|
|
4375
|
+
const PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES = "internalFileAttribute";
|
|
4376
|
+
const PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttribute";
|
|
4350
4377
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw";
|
|
4351
4378
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes";
|
|
4352
4379
|
const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
|
|
@@ -4357,6 +4384,7 @@ const PROPERTY_NAME_VERSION_MADE_BY = "versionMadeBy";
|
|
|
4357
4384
|
const PROPERTY_NAME_ZIPCRYPTO = "zipCrypto";
|
|
4358
4385
|
const PROPERTY_NAME_DIRECTORY = "directory";
|
|
4359
4386
|
const PROPERTY_NAME_EXECUTABLE = "executable";
|
|
4387
|
+
const PROPERTY_NAME_SYMLINK = "symlink";
|
|
4360
4388
|
const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
|
|
4361
4389
|
const PROPERTY_NAME_SIGNATURE = "signature";
|
|
4362
4390
|
const PROPERTY_NAME_CRC32 = "crc32";
|
|
@@ -4400,6 +4428,8 @@ const PROPERTY_NAMES = [
|
|
|
4400
4428
|
PROPERTY_NAME_DISK_NUMBER_START,
|
|
4401
4429
|
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
|
|
4402
4430
|
PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
|
|
4431
|
+
PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES,
|
|
4432
|
+
PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES,
|
|
4403
4433
|
PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW,
|
|
4404
4434
|
PROPERTY_NAME_MSDOS_ATTRIBUTES,
|
|
4405
4435
|
PROPERTY_NAME_MS_DOS_COMPATIBLE,
|
|
@@ -4410,6 +4440,7 @@ const PROPERTY_NAMES = [
|
|
|
4410
4440
|
PROPERTY_NAME_ZIPCRYPTO,
|
|
4411
4441
|
PROPERTY_NAME_DIRECTORY,
|
|
4412
4442
|
PROPERTY_NAME_EXECUTABLE,
|
|
4443
|
+
PROPERTY_NAME_SYMLINK,
|
|
4413
4444
|
PROPERTY_NAME_COMPRESSION_METHOD,
|
|
4414
4445
|
PROPERTY_NAME_SIGNATURE,
|
|
4415
4446
|
PROPERTY_NAME_CRC32,
|
|
@@ -4872,15 +4903,18 @@ class ZipReader {
|
|
|
4872
4903
|
const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK);
|
|
4873
4904
|
const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK);
|
|
4874
4905
|
const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
|
|
4875
|
-
const
|
|
4906
|
+
const unixType = fileEntry.unixMode === UNDEFINED_VALUE ? unixExternalUpper : fileEntry.unixMode;
|
|
4907
|
+
const symlink = (unixType & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK;
|
|
4908
|
+
const executable = !symlink && ((fileEntry.unixMode !== UNDEFINED_VALUE)
|
|
4876
4909
|
? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
|
|
4877
|
-
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
|
|
4910
|
+
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
|
|
4878
4911
|
const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4879
4912
|
const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4880
4913
|
Object.assign(fileEntry, {
|
|
4881
4914
|
setuid,
|
|
4882
4915
|
setgid,
|
|
4883
4916
|
sticky,
|
|
4917
|
+
symlink,
|
|
4884
4918
|
unixExternalUpper,
|
|
4885
4919
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
4886
4920
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
@@ -4946,6 +4980,10 @@ class ZipReader {
|
|
|
4946
4980
|
}
|
|
4947
4981
|
|
|
4948
4982
|
async close() {
|
|
4983
|
+
const { reader } = this;
|
|
4984
|
+
if (!reader.readUint8Array && reader.readable && !reader.readable.locked) {
|
|
4985
|
+
await reader.readable.cancel();
|
|
4986
|
+
}
|
|
4949
4987
|
}
|
|
4950
4988
|
}
|
|
4951
4989
|
|
|
@@ -5170,7 +5208,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5170
5208
|
throw error;
|
|
5171
5209
|
}
|
|
5172
5210
|
} finally {
|
|
5173
|
-
const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
5211
|
+
const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
5174
5212
|
if (!preventClose && writable && !writable.locked) {
|
|
5175
5213
|
const writableWriter = writable.getWriter();
|
|
5176
5214
|
if (abortError) {
|
|
@@ -5414,8 +5452,8 @@ function readExtraFieldUnixDates(extraField, directory) {
|
|
|
5414
5452
|
return;
|
|
5415
5453
|
}
|
|
5416
5454
|
const extraFieldView = getDataView(extraField.data);
|
|
5417
|
-
const lastAccessDate = new Date(getUint32(extraFieldView, 0) * 1000);
|
|
5418
|
-
const lastModDate = new Date(getUint32(extraFieldView, 4) * 1000);
|
|
5455
|
+
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
5456
|
+
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
5419
5457
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
5420
5458
|
if (extraField.data.length >= 12) {
|
|
5421
5459
|
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
@@ -5846,6 +5884,7 @@ const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
|
5846
5884
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5847
5885
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5848
5886
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5887
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5849
5888
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
5850
5889
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5851
5890
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -5855,6 +5894,7 @@ const MIN_NTFS_TIME = BigInt(0);
|
|
|
5855
5894
|
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
5856
5895
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
5857
5896
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
5897
|
+
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
5858
5898
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
5859
5899
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
5860
5900
|
const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
|
|
@@ -6062,7 +6102,7 @@ class ZipWriter {
|
|
|
6062
6102
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6063
6103
|
}
|
|
6064
6104
|
await closeFile(zipWriter, comment, options);
|
|
6065
|
-
const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6105
|
+
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6066
6106
|
if (!preventClose) {
|
|
6067
6107
|
await writable.getWriter().close();
|
|
6068
6108
|
}
|
|
@@ -6221,7 +6261,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6221
6261
|
if (versionMadeBy > MAX_16_BITS) {
|
|
6222
6262
|
throw new Error(ERR_INVALID_VERSION);
|
|
6223
6263
|
}
|
|
6224
|
-
let externalFileAttributes =
|
|
6264
|
+
let externalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES);
|
|
6225
6265
|
const externalFileAttributesProvided = externalFileAttributes !== UNDEFINED_VALUE;
|
|
6226
6266
|
if (!externalFileAttributesProvided) {
|
|
6227
6267
|
externalFileAttributes = 0;
|
|
@@ -6269,7 +6309,9 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6269
6309
|
}
|
|
6270
6310
|
if (!externalFileAttributesProvided || unixModeProvided) {
|
|
6271
6311
|
if (directory) {
|
|
6272
|
-
unixMode
|
|
6312
|
+
unixMode = (unixMode & ~FILE_ATTR_UNIX_TYPE_MASK) | FILE_ATTR_UNIX_TYPE_DIR;
|
|
6313
|
+
} else if (!(unixMode & FILE_ATTR_UNIX_TYPE_MASK)) {
|
|
6314
|
+
unixMode |= FILE_ATTR_UNIX_TYPE_FILE;
|
|
6273
6315
|
}
|
|
6274
6316
|
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_16_BITS);
|
|
6275
6317
|
}
|
|
@@ -6322,15 +6364,12 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
6322
6364
|
const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6323
6365
|
const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6324
6366
|
const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6325
|
-
const internalFileAttributes =
|
|
6367
|
+
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6326
6368
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
6332
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
6333
|
-
}
|
|
6369
|
+
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6370
|
+
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6371
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
6372
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
6334
6373
|
}
|
|
6335
6374
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
6336
6375
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
@@ -6443,14 +6482,24 @@ function serializeExtraField(extraField) {
|
|
|
6443
6482
|
}
|
|
6444
6483
|
|
|
6445
6484
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
6485
|
+
if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
6486
|
+
throw new Error(ERR_UNDEFINED_READER);
|
|
6487
|
+
}
|
|
6488
|
+
let contentSize;
|
|
6489
|
+
if (reader) {
|
|
6490
|
+
reader = new GenericReader(reader);
|
|
6491
|
+
await initStream(reader);
|
|
6492
|
+
({ size: contentSize } = reader);
|
|
6493
|
+
}
|
|
6494
|
+
return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
|
|
6495
|
+
}
|
|
6496
|
+
|
|
6497
|
+
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
6446
6498
|
const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
6447
6499
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
6448
6500
|
let maximumCompressedSize = 0;
|
|
6449
6501
|
let uncompressedSize = 0;
|
|
6450
|
-
if (passThrough) {
|
|
6451
|
-
if (!reader) {
|
|
6452
|
-
throw new Error(ERR_UNDEFINED_READER);
|
|
6453
|
-
}
|
|
6502
|
+
if (passThrough && hasContent) {
|
|
6454
6503
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
6455
6504
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
6456
6505
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -6458,29 +6507,30 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
6458
6507
|
}
|
|
6459
6508
|
const zip64Enabled = zip64 === true;
|
|
6460
6509
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
6461
|
-
|
|
6462
|
-
|
|
6510
|
+
if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
|
|
6511
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
6512
|
+
}
|
|
6513
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
|
|
6514
|
+
if (!hasContent) {
|
|
6463
6515
|
level = 0;
|
|
6464
6516
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
6465
6517
|
}
|
|
6466
6518
|
const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
6467
|
-
if (
|
|
6468
|
-
reader = new GenericReader(reader);
|
|
6469
|
-
await initStream(reader);
|
|
6519
|
+
if (hasContent) {
|
|
6470
6520
|
if (!passThrough) {
|
|
6471
|
-
if (
|
|
6521
|
+
if (contentSize === UNDEFINED_VALUE) {
|
|
6472
6522
|
dataDescriptor = true;
|
|
6473
6523
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
6474
6524
|
zip64 = true;
|
|
6475
6525
|
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
6476
6526
|
}
|
|
6477
6527
|
} else {
|
|
6478
|
-
options.uncompressedSize = uncompressedSize =
|
|
6479
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
6528
|
+
options.uncompressedSize = uncompressedSize = contentSize;
|
|
6529
|
+
maximumCompressedSize = (isCompressed(compressionMethod, level) ? getMaximumCompressedSize(uncompressedSize) : uncompressedSize) + encryptionOverhead;
|
|
6480
6530
|
}
|
|
6481
6531
|
} else {
|
|
6482
6532
|
options.uncompressedSize = uncompressedSize;
|
|
6483
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
6533
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
6484
6534
|
}
|
|
6485
6535
|
}
|
|
6486
6536
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
@@ -6494,7 +6544,7 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
6494
6544
|
}
|
|
6495
6545
|
zip64 = zip64 || false;
|
|
6496
6546
|
return {
|
|
6497
|
-
|
|
6547
|
+
maximumCompressedSize,
|
|
6498
6548
|
resolvedOptions: {
|
|
6499
6549
|
dataDescriptor,
|
|
6500
6550
|
zip64,
|
|
@@ -6508,6 +6558,78 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
6508
6558
|
};
|
|
6509
6559
|
}
|
|
6510
6560
|
|
|
6561
|
+
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
6562
|
+
const zipWriter = { options: writerOptions, config: getConfiguration() };
|
|
6563
|
+
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
6564
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6565
|
+
}
|
|
6566
|
+
const commentLength = getLength(comment);
|
|
6567
|
+
if (commentLength > MAX_16_BITS) {
|
|
6568
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
6569
|
+
}
|
|
6570
|
+
const usdz = writerOptions[OPTION_USDZ];
|
|
6571
|
+
const files = new Map();
|
|
6572
|
+
let layoutDependsOnWriteOrder = Boolean(usdz);
|
|
6573
|
+
let offset = 0;
|
|
6574
|
+
for (const entry of entries) {
|
|
6575
|
+
let { name } = entry;
|
|
6576
|
+
const { size } = entry;
|
|
6577
|
+
const options = Object.assign({}, entry.options);
|
|
6578
|
+
name = name.trim();
|
|
6579
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6580
|
+
name += DIRECTORY_SIGNATURE;
|
|
6581
|
+
}
|
|
6582
|
+
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
6583
|
+
({ name } = attributesInfo);
|
|
6584
|
+
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
6585
|
+
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
6586
|
+
!metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
|
|
6587
|
+
metadata.level = 0;
|
|
6588
|
+
}
|
|
6589
|
+
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
6590
|
+
if (hasContent && size === UNDEFINED_VALUE) {
|
|
6591
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6592
|
+
}
|
|
6593
|
+
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
6594
|
+
if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
6595
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6596
|
+
}
|
|
6597
|
+
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
|
|
6598
|
+
const headerInfo = getHeaderInfo(entryOptions);
|
|
6599
|
+
const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
|
|
6600
|
+
const entryInfo = {
|
|
6601
|
+
headerInfo,
|
|
6602
|
+
metadataSize: getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray)
|
|
6603
|
+
};
|
|
6604
|
+
if (usdz) {
|
|
6605
|
+
appendExtraFieldUSDZ(entryInfo, offset);
|
|
6606
|
+
}
|
|
6607
|
+
const compressedSize = hasContent ? maximumCompressedSize : 0;
|
|
6608
|
+
if (offset >= MAX_32_BITS) {
|
|
6609
|
+
layoutDependsOnWriteOrder = true;
|
|
6610
|
+
}
|
|
6611
|
+
files.set(name, Object.assign({}, entryOptions, headerInfo, {
|
|
6612
|
+
offset,
|
|
6613
|
+
diskNumberStart: 0,
|
|
6614
|
+
compressedSize
|
|
6615
|
+
}));
|
|
6616
|
+
offset += entryInfo.metadataSize + compressedSize;
|
|
6617
|
+
}
|
|
6618
|
+
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
6619
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6620
|
+
}
|
|
6621
|
+
const directoryDataLength = createDirectoryRecords(files);
|
|
6622
|
+
let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
|
|
6623
|
+
if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
|
|
6624
|
+
if (zip64 === false) {
|
|
6625
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
6626
|
+
} else {
|
|
6627
|
+
zip64 = true;
|
|
6628
|
+
}
|
|
6629
|
+
}
|
|
6630
|
+
return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
6631
|
+
}
|
|
6632
|
+
|
|
6511
6633
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
6512
6634
|
const {
|
|
6513
6635
|
files,
|
|
@@ -6879,9 +7001,7 @@ function getHeaderInfo(options) {
|
|
|
6879
7001
|
crc32
|
|
6880
7002
|
} = options;
|
|
6881
7003
|
let { version, compressionMethod } = options;
|
|
6882
|
-
const compressed = !directory && (compressionMethod
|
|
6883
|
-
? (level === UNDEFINED_VALUE || level > 0)
|
|
6884
|
-
: compressionMethod !== COMPRESSION_METHOD_STORE);
|
|
7004
|
+
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
6885
7005
|
let rawLocalExtraFieldZip64;
|
|
6886
7006
|
const uncompressedFile = passThrough || !compressed;
|
|
6887
7007
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
@@ -7568,6 +7688,16 @@ function getOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
7568
7688
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7569
7689
|
}
|
|
7570
7690
|
|
|
7691
|
+
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7692
|
+
const value = getAliasedValue(options, name, deprecatedName);
|
|
7693
|
+
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
7694
|
+
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7695
|
+
}
|
|
7696
|
+
|
|
7697
|
+
function getAliasedValue(options, name, deprecatedName) {
|
|
7698
|
+
return options[name] === UNDEFINED_VALUE ? options[deprecatedName] : options[name];
|
|
7699
|
+
}
|
|
7700
|
+
|
|
7571
7701
|
function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
7572
7702
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
7573
7703
|
}
|
|
@@ -7580,6 +7710,12 @@ function getMaximumCompressedSize(uncompressedSize) {
|
|
|
7580
7710
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
7581
7711
|
}
|
|
7582
7712
|
|
|
7713
|
+
function isCompressed(compressionMethod, level) {
|
|
7714
|
+
return compressionMethod === UNDEFINED_VALUE
|
|
7715
|
+
? (level === UNDEFINED_VALUE || level > 0)
|
|
7716
|
+
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7717
|
+
}
|
|
7718
|
+
|
|
7583
7719
|
function setUint8(view, offset, value) {
|
|
7584
7720
|
view.setUint8(offset, value);
|
|
7585
7721
|
}
|
|
@@ -8228,6 +8364,7 @@ setDefaultConfiguration({
|
|
|
8228
8364
|
|
|
8229
8365
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
8230
8366
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
8367
|
+
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
8231
8368
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
8232
8369
|
const ERR_ABORTED = "The operation was aborted";
|
|
8233
8370
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -8265,6 +8402,7 @@ class ZipEntry {
|
|
|
8265
8402
|
parent,
|
|
8266
8403
|
children: [],
|
|
8267
8404
|
uncompressedSize: params.uncompressedSize || 0,
|
|
8405
|
+
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
8268
8406
|
passThrough: params.passThrough
|
|
8269
8407
|
});
|
|
8270
8408
|
if (parent || !fs.root) {
|
|
@@ -8332,16 +8470,17 @@ class ZipFileEntry extends ZipEntry {
|
|
|
8332
8470
|
|
|
8333
8471
|
async getData(writer, options = {}) {
|
|
8334
8472
|
const zipEntry = this;
|
|
8335
|
-
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
|
|
8473
|
+
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data && keepsContentType(writer, zipEntry.data))) {
|
|
8336
8474
|
return zipEntry.data;
|
|
8337
8475
|
} else {
|
|
8338
8476
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
8339
|
-
const
|
|
8340
|
-
await Promise.all([initStream(reader), initStream(writer,
|
|
8341
|
-
const { readable } = reader;
|
|
8477
|
+
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
8478
|
+
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
8342
8479
|
const { signal } = options;
|
|
8480
|
+
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
8481
|
+
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
8343
8482
|
zipEntry.uncompressedSize = reader.size;
|
|
8344
|
-
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal });
|
|
8483
|
+
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal, preventClose, preventAbort: preventClose });
|
|
8345
8484
|
return writer.getData ? writer.getData() : writer.writable;
|
|
8346
8485
|
}
|
|
8347
8486
|
}
|
|
@@ -8472,7 +8611,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8472
8611
|
Reader: TextReader,
|
|
8473
8612
|
Writer: TextWriter,
|
|
8474
8613
|
options,
|
|
8475
|
-
uncompressedSize: text
|
|
8614
|
+
uncompressedSize: getTextSize(text)
|
|
8476
8615
|
});
|
|
8477
8616
|
}
|
|
8478
8617
|
|
|
@@ -8601,10 +8740,16 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8601
8740
|
}
|
|
8602
8741
|
|
|
8603
8742
|
async importZip(reader, options = {}) {
|
|
8604
|
-
|
|
8605
|
-
|
|
8743
|
+
let zipReader;
|
|
8744
|
+
if (reader && typeof reader.getEntries == FUNCTION_TYPE) {
|
|
8745
|
+
zipReader = reader;
|
|
8746
|
+
options = Object.assign({}, zipReader.options, options);
|
|
8747
|
+
} else {
|
|
8748
|
+
await initStream(reader);
|
|
8749
|
+
zipReader = new ZipReader(reader, options);
|
|
8750
|
+
}
|
|
8606
8751
|
const importedEntries = [];
|
|
8607
|
-
const entries = await zipReader.getEntries();
|
|
8752
|
+
const entries = await zipReader.getEntries(options);
|
|
8608
8753
|
for (const entry of entries) {
|
|
8609
8754
|
let parent = this;
|
|
8610
8755
|
try {
|
|
@@ -8626,7 +8771,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8626
8771
|
importedEntries.push(addChild(parent, name, {
|
|
8627
8772
|
data: entry,
|
|
8628
8773
|
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
8629
|
-
uncompressedSize: entry.uncompressedSize,
|
|
8774
|
+
uncompressedSize: options.passThrough ? entry.compressedSize : entry.uncompressedSize,
|
|
8630
8775
|
passThrough: options.passThrough
|
|
8631
8776
|
}));
|
|
8632
8777
|
} else {
|
|
@@ -8668,11 +8813,25 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8668
8813
|
}
|
|
8669
8814
|
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
8670
8815
|
const zipWriter = new ZipWriter(writer, options);
|
|
8671
|
-
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry],
|
|
8672
|
-
await zipWriter.close();
|
|
8816
|
+
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
8817
|
+
await zipWriter.close(options.globalComment);
|
|
8673
8818
|
return writer.getData ? writer.getData() : writer.writable;
|
|
8674
8819
|
}
|
|
8675
8820
|
|
|
8821
|
+
getExportedSize(options = {}) {
|
|
8822
|
+
const zipEntry = this;
|
|
8823
|
+
options = Object.assign({}, options);
|
|
8824
|
+
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
8825
|
+
options.bufferedWrite = true;
|
|
8826
|
+
}
|
|
8827
|
+
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
8828
|
+
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
8829
|
+
return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
|
|
8830
|
+
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
8831
|
+
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
8832
|
+
}), writeOrderGuaranteed, options.globalComment);
|
|
8833
|
+
}
|
|
8834
|
+
|
|
8676
8835
|
getChildByName(name) {
|
|
8677
8836
|
const children = this.children;
|
|
8678
8837
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
@@ -8880,6 +9039,10 @@ class FS {
|
|
|
8880
9039
|
return this.root.exportZip(writer, options);
|
|
8881
9040
|
}
|
|
8882
9041
|
|
|
9042
|
+
getExportedSize(options) {
|
|
9043
|
+
return this.root.getExportedSize(options);
|
|
9044
|
+
}
|
|
9045
|
+
|
|
8883
9046
|
isPasswordProtected() {
|
|
8884
9047
|
return this.root.isPasswordProtected();
|
|
8885
9048
|
}
|
|
@@ -8891,12 +9054,12 @@ class FS {
|
|
|
8891
9054
|
|
|
8892
9055
|
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
8893
9056
|
|
|
8894
|
-
function getTotalSize(entries,
|
|
9057
|
+
function getTotalSize(entries, getEntrySize) {
|
|
8895
9058
|
let size = 0;
|
|
8896
9059
|
const pendingEntries = Array.from(entries);
|
|
8897
9060
|
while (pendingEntries.length) {
|
|
8898
9061
|
const entry = pendingEntries.pop();
|
|
8899
|
-
size += entry
|
|
9062
|
+
size += getEntrySize(entry) || 0;
|
|
8900
9063
|
for (const child of entry.children) {
|
|
8901
9064
|
pendingEntries.push(child);
|
|
8902
9065
|
}
|
|
@@ -8904,6 +9067,15 @@ function getTotalSize(entries, propertyName) {
|
|
|
8904
9067
|
return size;
|
|
8905
9068
|
}
|
|
8906
9069
|
|
|
9070
|
+
function getUncompressedSize(entry) {
|
|
9071
|
+
return entry.uncompressedSize;
|
|
9072
|
+
}
|
|
9073
|
+
|
|
9074
|
+
function getExtractedSize(entry, passThrough) {
|
|
9075
|
+
const { data } = entry;
|
|
9076
|
+
return passThrough && data instanceof Entry ? data.compressedSize : entry.uncompressedSize;
|
|
9077
|
+
}
|
|
9078
|
+
|
|
8907
9079
|
function getReadableReader(readable) {
|
|
8908
9080
|
let consumed;
|
|
8909
9081
|
return function () {
|
|
@@ -8926,10 +9098,17 @@ function getZipBlobReader(options) {
|
|
|
8926
9098
|
|
|
8927
9099
|
async init() {
|
|
8928
9100
|
const zipBlobReader = this;
|
|
8929
|
-
|
|
8930
|
-
const
|
|
9101
|
+
const readerOptions = Object.assign({}, options, zipBlobReader.options);
|
|
9102
|
+
const { checkOverlappingEntry, checkOverlappingEntryOnly } = readerOptions;
|
|
9103
|
+
const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign(readerOptions, {
|
|
9104
|
+
checkPasswordOnly: false,
|
|
9105
|
+
checkOverlappingEntry: checkOverlappingEntryOnly || checkOverlappingEntry,
|
|
9106
|
+
checkOverlappingEntryOnly: false,
|
|
9107
|
+
preventClose: false
|
|
9108
|
+
}));
|
|
8931
9109
|
zipBlobReader.data = data;
|
|
8932
9110
|
zipBlobReader.blobReader = new BlobReader(data);
|
|
9111
|
+
zipBlobReader.size = data.size;
|
|
8933
9112
|
super.init();
|
|
8934
9113
|
}
|
|
8935
9114
|
|
|
@@ -8943,6 +9122,30 @@ function createReader(Reader, data, options) {
|
|
|
8943
9122
|
return Reader.prototype ? new Reader(data, options) : Reader(data, options);
|
|
8944
9123
|
}
|
|
8945
9124
|
|
|
9125
|
+
function keepsContentType(writer, data) {
|
|
9126
|
+
const { contentType } = writer;
|
|
9127
|
+
if (contentType === UNDEFINED_VALUE) {
|
|
9128
|
+
return true;
|
|
9129
|
+
} else if (writer.constructor == BlobWriter) {
|
|
9130
|
+
return data.type == contentType;
|
|
9131
|
+
} else if (writer.constructor == Data64URIWriter) {
|
|
9132
|
+
return data.startsWith(writer.data);
|
|
9133
|
+
} else {
|
|
9134
|
+
return true;
|
|
9135
|
+
}
|
|
9136
|
+
}
|
|
9137
|
+
|
|
9138
|
+
function createProgressReadable(zipEntry, reader, options, signal) {
|
|
9139
|
+
const { onstart, onprogress, onend } = options;
|
|
9140
|
+
const { readable } = reader;
|
|
9141
|
+
const coreReaderReportsProgress = zipEntry.data instanceof Entry;
|
|
9142
|
+
if (coreReaderReportsProgress || (!onstart && !onprogress && !onend)) {
|
|
9143
|
+
return readable;
|
|
9144
|
+
} else {
|
|
9145
|
+
return toCompatibleReadable(readable).pipeThrough(new ProgressWatcherStream({ onstart, onprogress, onend, size: reader.size }), { signal });
|
|
9146
|
+
}
|
|
9147
|
+
}
|
|
9148
|
+
|
|
8946
9149
|
async function initReaders(entry, options) {
|
|
8947
9150
|
const fileEntries = [];
|
|
8948
9151
|
const pendingEntries = [entry];
|
|
@@ -8975,6 +9178,7 @@ async function initReaders(entry, options) {
|
|
|
8975
9178
|
}
|
|
8976
9179
|
if (reader.size !== UNDEFINED_VALUE) {
|
|
8977
9180
|
child.uncompressedSize = reader.size;
|
|
9181
|
+
child.undeterminedSize = false;
|
|
8978
9182
|
}
|
|
8979
9183
|
}));
|
|
8980
9184
|
return readers;
|
|
@@ -9024,6 +9228,90 @@ function aggregateEntryErrors(errors) {
|
|
|
9024
9228
|
return error;
|
|
9025
9229
|
}
|
|
9026
9230
|
|
|
9231
|
+
function getChildEntryOptions(child, selectedEntry, options) {
|
|
9232
|
+
const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
|
|
9233
|
+
const childOptions = child.options || {};
|
|
9234
|
+
let zipEntryMetadata = {};
|
|
9235
|
+
let passThroughOptions = {};
|
|
9236
|
+
if (child.data instanceof Entry) {
|
|
9237
|
+
const {
|
|
9238
|
+
externalFileAttributes,
|
|
9239
|
+
versionMadeBy,
|
|
9240
|
+
comment,
|
|
9241
|
+
lastModDate,
|
|
9242
|
+
creationDate,
|
|
9243
|
+
lastAccessDate,
|
|
9244
|
+
uncompressedSize,
|
|
9245
|
+
encrypted,
|
|
9246
|
+
zipCrypto,
|
|
9247
|
+
crc32,
|
|
9248
|
+
compressionMethod,
|
|
9249
|
+
extraFieldAES,
|
|
9250
|
+
internalFileAttributes,
|
|
9251
|
+
extraField,
|
|
9252
|
+
uid,
|
|
9253
|
+
gid
|
|
9254
|
+
} = child.data;
|
|
9255
|
+
zipEntryMetadata = {
|
|
9256
|
+
externalFileAttributes,
|
|
9257
|
+
versionMadeBy,
|
|
9258
|
+
comment,
|
|
9259
|
+
lastModDate,
|
|
9260
|
+
creationDate,
|
|
9261
|
+
lastAccessDate,
|
|
9262
|
+
internalFileAttributes
|
|
9263
|
+
};
|
|
9264
|
+
const userExtraField = getUserExtraField(extraField);
|
|
9265
|
+
if (userExtraField) {
|
|
9266
|
+
zipEntryMetadata.extraField = userExtraField;
|
|
9267
|
+
}
|
|
9268
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
9269
|
+
Object.assign(zipEntryMetadata, {
|
|
9270
|
+
uid,
|
|
9271
|
+
gid,
|
|
9272
|
+
unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
|
|
9273
|
+
});
|
|
9274
|
+
}
|
|
9275
|
+
if (isPassThrough(child, options)) {
|
|
9276
|
+
let level, encryptionStrength;
|
|
9277
|
+
if (compressionMethod === 0) {
|
|
9278
|
+
level = 0;
|
|
9279
|
+
}
|
|
9280
|
+
if (extraFieldAES) {
|
|
9281
|
+
encryptionStrength = extraFieldAES.strength;
|
|
9282
|
+
}
|
|
9283
|
+
passThroughOptions = {
|
|
9284
|
+
passThrough: true,
|
|
9285
|
+
encrypted,
|
|
9286
|
+
zipCrypto,
|
|
9287
|
+
crc32,
|
|
9288
|
+
uncompressedSize,
|
|
9289
|
+
level,
|
|
9290
|
+
encryptionStrength,
|
|
9291
|
+
compressionMethod
|
|
9292
|
+
};
|
|
9293
|
+
}
|
|
9294
|
+
}
|
|
9295
|
+
const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
|
|
9296
|
+
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
9297
|
+
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
9298
|
+
}
|
|
9299
|
+
return { name, entryOptions };
|
|
9300
|
+
}
|
|
9301
|
+
|
|
9302
|
+
function getDeterminedSize(child, passThrough) {
|
|
9303
|
+
const { reader } = child;
|
|
9304
|
+
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
9305
|
+
return reader.size;
|
|
9306
|
+
}
|
|
9307
|
+
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
9308
|
+
}
|
|
9309
|
+
|
|
9310
|
+
function isPassThrough(child, options) {
|
|
9311
|
+
const { readerOptions } = options;
|
|
9312
|
+
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
9313
|
+
}
|
|
9314
|
+
|
|
9027
9315
|
function getUserExtraField(extraField) {
|
|
9028
9316
|
if (extraField) {
|
|
9029
9317
|
const userExtraField = new Map();
|
|
@@ -9039,8 +9327,14 @@ function getUserExtraField(extraField) {
|
|
|
9039
9327
|
}
|
|
9040
9328
|
|
|
9041
9329
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
9330
|
+
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
9042
9331
|
const selectedEntry = entry;
|
|
9043
|
-
const
|
|
9332
|
+
const totalEntries = getTotalSize(entry.children, () => 1);
|
|
9333
|
+
let writtenSize = 0;
|
|
9334
|
+
let writtenEntries = 0;
|
|
9335
|
+
if (onstart) {
|
|
9336
|
+
await callHandler(onstart, totalSize);
|
|
9337
|
+
}
|
|
9044
9338
|
if (options.bufferedWrite) {
|
|
9045
9339
|
await processChildren(entry);
|
|
9046
9340
|
} else {
|
|
@@ -9048,6 +9342,9 @@ async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
|
9048
9342
|
await addChild(child);
|
|
9049
9343
|
}
|
|
9050
9344
|
}
|
|
9345
|
+
if (onend) {
|
|
9346
|
+
await callHandler(onend, writtenSize);
|
|
9347
|
+
}
|
|
9051
9348
|
|
|
9052
9349
|
async function processChildren(entry) {
|
|
9053
9350
|
const results = await Promise.allSettled(entry.children.map(async child => {
|
|
@@ -9061,81 +9358,23 @@ async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
|
9061
9358
|
}
|
|
9062
9359
|
|
|
9063
9360
|
async function addChild(child) {
|
|
9064
|
-
const name
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
externalFileAttributes,
|
|
9070
|
-
versionMadeBy,
|
|
9071
|
-
comment,
|
|
9072
|
-
lastModDate,
|
|
9073
|
-
creationDate,
|
|
9074
|
-
lastAccessDate,
|
|
9075
|
-
uncompressedSize,
|
|
9076
|
-
encrypted,
|
|
9077
|
-
zipCrypto,
|
|
9078
|
-
crc32,
|
|
9079
|
-
compressionMethod,
|
|
9080
|
-
extraFieldAES,
|
|
9081
|
-
internalFileAttributes,
|
|
9082
|
-
extraField,
|
|
9083
|
-
uid,
|
|
9084
|
-
gid
|
|
9085
|
-
} = child.data;
|
|
9086
|
-
zipEntryOptions = {
|
|
9087
|
-
externalFileAttributes,
|
|
9088
|
-
versionMadeBy,
|
|
9089
|
-
comment,
|
|
9090
|
-
lastModDate,
|
|
9091
|
-
creationDate,
|
|
9092
|
-
lastAccessDate,
|
|
9093
|
-
internalFileAttributes
|
|
9094
|
-
};
|
|
9095
|
-
const userExtraField = getUserExtraField(extraField);
|
|
9096
|
-
if (userExtraField) {
|
|
9097
|
-
zipEntryOptions.extraField = userExtraField;
|
|
9098
|
-
}
|
|
9099
|
-
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
9100
|
-
Object.assign(zipEntryOptions, {
|
|
9101
|
-
uid,
|
|
9102
|
-
gid,
|
|
9103
|
-
unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
|
|
9104
|
-
});
|
|
9105
|
-
}
|
|
9106
|
-
if (child.passThrough) {
|
|
9107
|
-
let level, encryptionStrength;
|
|
9108
|
-
if (compressionMethod === 0) {
|
|
9109
|
-
level = 0;
|
|
9110
|
-
}
|
|
9111
|
-
if (extraFieldAES) {
|
|
9112
|
-
encryptionStrength = extraFieldAES.strength;
|
|
9113
|
-
}
|
|
9114
|
-
zipEntryOptions = Object.assign(zipEntryOptions, {
|
|
9115
|
-
passThrough: true,
|
|
9116
|
-
encrypted,
|
|
9117
|
-
zipCrypto,
|
|
9118
|
-
crc32,
|
|
9119
|
-
uncompressedSize,
|
|
9120
|
-
level,
|
|
9121
|
-
encryptionStrength,
|
|
9122
|
-
compressionMethod
|
|
9123
|
-
});
|
|
9124
|
-
}
|
|
9125
|
-
}
|
|
9126
|
-
await zipWriter.add(name, readers.get(child), Object.assign({}, options, zipEntryOptions, childOptions, {
|
|
9127
|
-
directory: child.directory,
|
|
9361
|
+
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
9362
|
+
let entryWrittenSize = 0;
|
|
9363
|
+
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
9364
|
+
onstart: UNDEFINED_VALUE,
|
|
9365
|
+
onend: UNDEFINED_VALUE,
|
|
9128
9366
|
onprogress: async indexProgress => {
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
} catch {
|
|
9134
|
-
// ignored
|
|
9135
|
-
}
|
|
9367
|
+
writtenSize += indexProgress - entryWrittenSize;
|
|
9368
|
+
entryWrittenSize = indexProgress;
|
|
9369
|
+
if (onprogress) {
|
|
9370
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
9136
9371
|
}
|
|
9137
9372
|
}
|
|
9138
9373
|
}));
|
|
9374
|
+
writtenEntries++;
|
|
9375
|
+
if (onentryprogress) {
|
|
9376
|
+
await callHandler(onentryprogress, writtenEntries, totalEntries, entryMetadata);
|
|
9377
|
+
}
|
|
9139
9378
|
}
|
|
9140
9379
|
}
|
|
9141
9380
|
|
|
@@ -9163,7 +9402,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
|
|
|
9163
9402
|
})
|
|
9164
9403
|
);
|
|
9165
9404
|
} else if (handle.kind == "directory") {
|
|
9166
|
-
const directoryEntry = parentEntry.addDirectory(handle.name);
|
|
9405
|
+
const directoryEntry = parentEntry.addDirectory(handle.name, options);
|
|
9167
9406
|
addedEntries.push(directoryEntry);
|
|
9168
9407
|
for await (const childHandle of handle.values()) {
|
|
9169
9408
|
await addFile(directoryEntry, childHandle, addedEntries, entryName);
|
|
@@ -9185,15 +9424,29 @@ function addFileSystemHandle(zipEntry, handle, options) {
|
|
|
9185
9424
|
}
|
|
9186
9425
|
|
|
9187
9426
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
9188
|
-
const
|
|
9189
|
-
const writtenSizes = new Map();
|
|
9427
|
+
const { onstart, onprogress, onend } = options;
|
|
9190
9428
|
const abortController = new AbortController();
|
|
9191
9429
|
const { signal } = abortController;
|
|
9192
9430
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
9431
|
+
const getDataOptions = Object.assign({}, options, options.readerOptions, {
|
|
9432
|
+
signal,
|
|
9433
|
+
onstart: UNDEFINED_VALUE,
|
|
9434
|
+
onprogress: UNDEFINED_VALUE,
|
|
9435
|
+
onend: UNDEFINED_VALUE,
|
|
9436
|
+
preventClose: false
|
|
9437
|
+
});
|
|
9438
|
+
const totalSize = getTotalSize([zipEntry], entry => getExtractedSize(entry, getDataOptions.passThrough));
|
|
9193
9439
|
const exportedEntryNames = [];
|
|
9194
9440
|
let exportAborted = false;
|
|
9441
|
+
let writtenSize = 0;
|
|
9195
9442
|
try {
|
|
9443
|
+
if (onstart) {
|
|
9444
|
+
await callHandler(onstart, totalSize);
|
|
9445
|
+
}
|
|
9196
9446
|
await exportChildren(zipEntry, directoryHandle);
|
|
9447
|
+
if (onend) {
|
|
9448
|
+
await callHandler(onend, writtenSize);
|
|
9449
|
+
}
|
|
9197
9450
|
} catch (error) {
|
|
9198
9451
|
try {
|
|
9199
9452
|
error.exportedEntryNames = exportedEntryNames;
|
|
@@ -9206,6 +9459,25 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
|
9206
9459
|
}
|
|
9207
9460
|
return directoryHandle;
|
|
9208
9461
|
|
|
9462
|
+
function createProgressWritable(writable) {
|
|
9463
|
+
const writer = writable.getWriter();
|
|
9464
|
+
return new WritableStream({
|
|
9465
|
+
async write(chunk) {
|
|
9466
|
+
await writer.write(chunk);
|
|
9467
|
+
writtenSize += chunk.length;
|
|
9468
|
+
if (onprogress) {
|
|
9469
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
9470
|
+
}
|
|
9471
|
+
},
|
|
9472
|
+
close() {
|
|
9473
|
+
return writer.close();
|
|
9474
|
+
},
|
|
9475
|
+
abort(reason) {
|
|
9476
|
+
return writer.abort(reason);
|
|
9477
|
+
}
|
|
9478
|
+
});
|
|
9479
|
+
}
|
|
9480
|
+
|
|
9209
9481
|
async function exportChildren(entry, parentHandle) {
|
|
9210
9482
|
if (options.concurrent) {
|
|
9211
9483
|
const results = await Promise.allSettled(entry.children.map(child => exportChild(child, parentHandle)));
|
|
@@ -9237,19 +9509,7 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
|
9237
9509
|
const fileHandle = await parentHandle.getFileHandle(child.name, { create: true });
|
|
9238
9510
|
const writable = await fileHandle.createWritable();
|
|
9239
9511
|
try {
|
|
9240
|
-
await child.getData({ writable
|
|
9241
|
-
signal,
|
|
9242
|
-
onprogress: async progress => {
|
|
9243
|
-
if (options.onprogress) {
|
|
9244
|
-
writtenSizes.set(child.id, progress);
|
|
9245
|
-
try {
|
|
9246
|
-
await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
|
|
9247
|
-
} catch {
|
|
9248
|
-
// ignored
|
|
9249
|
-
}
|
|
9250
|
-
}
|
|
9251
|
-
}
|
|
9252
|
-
}));
|
|
9512
|
+
await child.getData({ writable: createProgressWritable(writable) }, getDataOptions);
|
|
9253
9513
|
} catch (error) {
|
|
9254
9514
|
throw exportAborted ? new Error(ERR_ABORT_EXPORT) : error;
|
|
9255
9515
|
}
|
|
@@ -9493,6 +9753,7 @@ exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
|
|
|
9493
9753
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
9494
9754
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
9495
9755
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9756
|
+
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
9496
9757
|
exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
|
|
9497
9758
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
9498
9759
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|
|
@@ -9510,11 +9771,13 @@ exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
|
|
|
9510
9771
|
exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
|
|
9511
9772
|
exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
|
|
9512
9773
|
exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
|
|
9774
|
+
exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
|
|
9513
9775
|
exports.ERR_UNSAFE_FILENAME = ERR_UNSAFE_FILENAME;
|
|
9514
9776
|
exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION$1;
|
|
9515
9777
|
exports.ERR_UNSUPPORTED_CONTEXT = ERR_UNSUPPORTED_CONTEXT;
|
|
9516
9778
|
exports.ERR_UNSUPPORTED_CRYPTO_API = ERR_UNSUPPORTED_CRYPTO_API;
|
|
9517
9779
|
exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
|
|
9780
|
+
exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
|
|
9518
9781
|
exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
|
|
9519
9782
|
exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
|
|
9520
9783
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|