@zip.js/zip.js 2.8.50 → 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 +460 -171
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +461 -170
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +460 -171
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +463 -170
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +463 -170
- 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 +463 -170
- package/index-native.min.js +1 -1
- package/index.cjs +463 -170
- package/index.d.cts +320 -9
- package/index.d.ts +320 -9
- 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 +289 -131
- 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/dist/zip-fs-core.js
CHANGED
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
const FILE_ATTR_MSDOS_ARCHIVE_MASK = 0x20;
|
|
90
90
|
const FILE_ATTR_UNIX_TYPE_MASK = 0o170000;
|
|
91
91
|
const FILE_ATTR_UNIX_TYPE_DIR = 0o040000;
|
|
92
|
+
const FILE_ATTR_UNIX_TYPE_SYMLINK = 0o120000;
|
|
93
|
+
const FILE_ATTR_UNIX_TYPE_FILE = 0o100000;
|
|
92
94
|
const FILE_ATTR_UNIX_EXECUTABLE_MASK = 0o111;
|
|
93
95
|
const FILE_ATTR_UNIX_DEFAULT_MASK = 0o644;
|
|
94
96
|
const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
|
|
@@ -257,8 +259,6 @@
|
|
|
257
259
|
*/
|
|
258
260
|
|
|
259
261
|
|
|
260
|
-
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
261
|
-
|
|
262
262
|
function toCompatibleReadable(readable) {
|
|
263
263
|
if (readable instanceof ReadableStream) {
|
|
264
264
|
return readable;
|
|
@@ -281,12 +281,9 @@
|
|
|
281
281
|
|
|
282
282
|
function streamToBlob(readable, contentType) {
|
|
283
283
|
readable = toCompatibleReadable(readable);
|
|
284
|
+
const blobOptions = contentType ? { type: contentType } : {};
|
|
284
285
|
if (responseSupportsGlobalReadable()) {
|
|
285
|
-
|
|
286
|
-
if (contentType) {
|
|
287
|
-
options.headers = [[HTTP_HEADER_CONTENT_TYPE, contentType]];
|
|
288
|
-
}
|
|
289
|
-
return new Response(readable, options).blob();
|
|
286
|
+
return new Response(readable).blob().then(blob => contentType ? new Blob([blob], blobOptions) : blob);
|
|
290
287
|
}
|
|
291
288
|
const chunks = [];
|
|
292
289
|
return readable
|
|
@@ -295,7 +292,7 @@
|
|
|
295
292
|
chunks.push(chunk);
|
|
296
293
|
}
|
|
297
294
|
}))
|
|
298
|
-
.then(() => new Blob(chunks,
|
|
295
|
+
.then(() => new Blob(chunks, blobOptions));
|
|
299
296
|
}
|
|
300
297
|
|
|
301
298
|
function responseSupportsGlobalReadable() {
|
|
@@ -396,8 +393,10 @@
|
|
|
396
393
|
async pull(controller) {
|
|
397
394
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
398
395
|
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
399
|
-
|
|
400
|
-
|
|
396
|
+
if (data.length) {
|
|
397
|
+
controller.enqueue(data);
|
|
398
|
+
}
|
|
399
|
+
if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
401
400
|
controller.close();
|
|
402
401
|
} else {
|
|
403
402
|
chunkOffset += chunkSize;
|
|
@@ -475,6 +474,7 @@
|
|
|
475
474
|
constructor(contentType) {
|
|
476
475
|
super();
|
|
477
476
|
Object.assign(this, {
|
|
477
|
+
contentType,
|
|
478
478
|
data: "data:" + (contentType || "") + ";base64,",
|
|
479
479
|
pending: []
|
|
480
480
|
});
|
|
@@ -576,6 +576,7 @@
|
|
|
576
576
|
return transformStream.writable;
|
|
577
577
|
}
|
|
578
578
|
});
|
|
579
|
+
writer.contentType = contentType;
|
|
579
580
|
writer.blob = streamToBlob(transformStream.readable, contentType);
|
|
580
581
|
writer.blob.catch(() => { });
|
|
581
582
|
}
|
|
@@ -592,6 +593,26 @@
|
|
|
592
593
|
}
|
|
593
594
|
}
|
|
594
595
|
|
|
596
|
+
function getTextSize(text) {
|
|
597
|
+
let size = 0;
|
|
598
|
+
for (let indexCharacter = 0; indexCharacter < text.length; indexCharacter++) {
|
|
599
|
+
const characterCode = text.charCodeAt(indexCharacter);
|
|
600
|
+
if (characterCode < 0x80) {
|
|
601
|
+
size += 1;
|
|
602
|
+
} else if (characterCode < 0x800) {
|
|
603
|
+
size += 2;
|
|
604
|
+
} else if (characterCode < 0xd800 || characterCode >= 0xe000) {
|
|
605
|
+
size += 3;
|
|
606
|
+
} else if (characterCode < 0xdc00 && (text.charCodeAt(indexCharacter + 1) & 0xfc00) == 0xdc00) {
|
|
607
|
+
size += 4;
|
|
608
|
+
indexCharacter++;
|
|
609
|
+
} else {
|
|
610
|
+
size += 3;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
return size;
|
|
614
|
+
}
|
|
615
|
+
|
|
595
616
|
class TextWriter extends BlobWriter {
|
|
596
617
|
|
|
597
618
|
constructor(encoding) {
|
|
@@ -1248,6 +1269,10 @@
|
|
|
1248
1269
|
}
|
|
1249
1270
|
}
|
|
1250
1271
|
|
|
1272
|
+
function ownsWritable(writer) {
|
|
1273
|
+
return Boolean(writer && writer.getData);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1251
1276
|
function isHttpFamily(url) {
|
|
1252
1277
|
const { baseURI } = getConfiguration();
|
|
1253
1278
|
const { protocol } = new URL(url, baseURI);
|
|
@@ -3783,6 +3808,8 @@
|
|
|
3783
3808
|
const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
|
|
3784
3809
|
const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes";
|
|
3785
3810
|
const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes";
|
|
3811
|
+
const PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES = "internalFileAttribute";
|
|
3812
|
+
const PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttribute";
|
|
3786
3813
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw";
|
|
3787
3814
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes";
|
|
3788
3815
|
const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
|
|
@@ -3793,6 +3820,7 @@
|
|
|
3793
3820
|
const PROPERTY_NAME_ZIPCRYPTO = "zipCrypto";
|
|
3794
3821
|
const PROPERTY_NAME_DIRECTORY = "directory";
|
|
3795
3822
|
const PROPERTY_NAME_EXECUTABLE = "executable";
|
|
3823
|
+
const PROPERTY_NAME_SYMLINK = "symlink";
|
|
3796
3824
|
const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
|
|
3797
3825
|
const PROPERTY_NAME_SIGNATURE = "signature";
|
|
3798
3826
|
const PROPERTY_NAME_CRC32 = "crc32";
|
|
@@ -3836,6 +3864,8 @@
|
|
|
3836
3864
|
PROPERTY_NAME_DISK_NUMBER_START,
|
|
3837
3865
|
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
|
|
3838
3866
|
PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
|
|
3867
|
+
PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES,
|
|
3868
|
+
PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES,
|
|
3839
3869
|
PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW,
|
|
3840
3870
|
PROPERTY_NAME_MSDOS_ATTRIBUTES,
|
|
3841
3871
|
PROPERTY_NAME_MS_DOS_COMPATIBLE,
|
|
@@ -3846,6 +3876,7 @@
|
|
|
3846
3876
|
PROPERTY_NAME_ZIPCRYPTO,
|
|
3847
3877
|
PROPERTY_NAME_DIRECTORY,
|
|
3848
3878
|
PROPERTY_NAME_EXECUTABLE,
|
|
3879
|
+
PROPERTY_NAME_SYMLINK,
|
|
3849
3880
|
PROPERTY_NAME_COMPRESSION_METHOD,
|
|
3850
3881
|
PROPERTY_NAME_SIGNATURE,
|
|
3851
3882
|
PROPERTY_NAME_CRC32,
|
|
@@ -4308,15 +4339,18 @@
|
|
|
4308
4339
|
const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK);
|
|
4309
4340
|
const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK);
|
|
4310
4341
|
const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
|
|
4311
|
-
const
|
|
4342
|
+
const unixType = fileEntry.unixMode === UNDEFINED_VALUE ? unixExternalUpper : fileEntry.unixMode;
|
|
4343
|
+
const symlink = (unixType & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK;
|
|
4344
|
+
const executable = !symlink && ((fileEntry.unixMode !== UNDEFINED_VALUE)
|
|
4312
4345
|
? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
|
|
4313
|
-
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
|
|
4346
|
+
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
|
|
4314
4347
|
const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4315
4348
|
const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4316
4349
|
Object.assign(fileEntry, {
|
|
4317
4350
|
setuid,
|
|
4318
4351
|
setgid,
|
|
4319
4352
|
sticky,
|
|
4353
|
+
symlink,
|
|
4320
4354
|
unixExternalUpper,
|
|
4321
4355
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
4322
4356
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
@@ -4382,6 +4416,10 @@
|
|
|
4382
4416
|
}
|
|
4383
4417
|
|
|
4384
4418
|
async close() {
|
|
4419
|
+
const { reader } = this;
|
|
4420
|
+
if (!reader.readUint8Array && reader.readable && !reader.readable.locked) {
|
|
4421
|
+
await reader.readable.cancel();
|
|
4422
|
+
}
|
|
4385
4423
|
}
|
|
4386
4424
|
}
|
|
4387
4425
|
|
|
@@ -4566,7 +4604,7 @@
|
|
|
4566
4604
|
throw error;
|
|
4567
4605
|
}
|
|
4568
4606
|
} finally {
|
|
4569
|
-
const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
4607
|
+
const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
4570
4608
|
if (!preventClose && writable && !writable.locked) {
|
|
4571
4609
|
const writableWriter = writable.getWriter();
|
|
4572
4610
|
if (abortError) {
|
|
@@ -4810,8 +4848,8 @@
|
|
|
4810
4848
|
return;
|
|
4811
4849
|
}
|
|
4812
4850
|
const extraFieldView = getDataView(extraField.data);
|
|
4813
|
-
const lastAccessDate = new Date(getUint32(extraFieldView, 0) * 1000);
|
|
4814
|
-
const lastModDate = new Date(getUint32(extraFieldView, 4) * 1000);
|
|
4851
|
+
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
4852
|
+
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
4815
4853
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
4816
4854
|
if (extraField.data.length >= 12) {
|
|
4817
4855
|
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
@@ -5240,6 +5278,7 @@
|
|
|
5240
5278
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5241
5279
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5242
5280
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5281
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5243
5282
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
5244
5283
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5245
5284
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -5249,6 +5288,7 @@
|
|
|
5249
5288
|
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
5250
5289
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
5251
5290
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
5291
|
+
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
5252
5292
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
5253
5293
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
5254
5294
|
const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
|
|
@@ -5456,7 +5496,7 @@
|
|
|
5456
5496
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5457
5497
|
}
|
|
5458
5498
|
await closeFile(zipWriter, comment, options);
|
|
5459
|
-
const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5499
|
+
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5460
5500
|
if (!preventClose) {
|
|
5461
5501
|
await writable.getWriter().close();
|
|
5462
5502
|
}
|
|
@@ -5553,7 +5593,7 @@
|
|
|
5553
5593
|
if (versionMadeBy > MAX_16_BITS) {
|
|
5554
5594
|
throw new Error(ERR_INVALID_VERSION);
|
|
5555
5595
|
}
|
|
5556
|
-
let externalFileAttributes =
|
|
5596
|
+
let externalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES);
|
|
5557
5597
|
const externalFileAttributesProvided = externalFileAttributes !== UNDEFINED_VALUE;
|
|
5558
5598
|
if (!externalFileAttributesProvided) {
|
|
5559
5599
|
externalFileAttributes = 0;
|
|
@@ -5601,7 +5641,9 @@
|
|
|
5601
5641
|
}
|
|
5602
5642
|
if (!externalFileAttributesProvided || unixModeProvided) {
|
|
5603
5643
|
if (directory) {
|
|
5604
|
-
unixMode
|
|
5644
|
+
unixMode = (unixMode & ~FILE_ATTR_UNIX_TYPE_MASK) | FILE_ATTR_UNIX_TYPE_DIR;
|
|
5645
|
+
} else if (!(unixMode & FILE_ATTR_UNIX_TYPE_MASK)) {
|
|
5646
|
+
unixMode |= FILE_ATTR_UNIX_TYPE_FILE;
|
|
5605
5647
|
}
|
|
5606
5648
|
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_16_BITS);
|
|
5607
5649
|
}
|
|
@@ -5654,15 +5696,12 @@
|
|
|
5654
5696
|
const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
5655
5697
|
const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
5656
5698
|
const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
5657
|
-
const internalFileAttributes =
|
|
5699
|
+
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
5658
5700
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
5664
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
5665
|
-
}
|
|
5701
|
+
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
5702
|
+
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
5703
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
5704
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
5666
5705
|
}
|
|
5667
5706
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
5668
5707
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
@@ -5775,14 +5814,24 @@
|
|
|
5775
5814
|
}
|
|
5776
5815
|
|
|
5777
5816
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
5817
|
+
if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
5818
|
+
throw new Error(ERR_UNDEFINED_READER);
|
|
5819
|
+
}
|
|
5820
|
+
let contentSize;
|
|
5821
|
+
if (reader) {
|
|
5822
|
+
reader = new GenericReader(reader);
|
|
5823
|
+
await initStream(reader);
|
|
5824
|
+
({ size: contentSize } = reader);
|
|
5825
|
+
}
|
|
5826
|
+
return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
|
|
5827
|
+
}
|
|
5828
|
+
|
|
5829
|
+
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
5778
5830
|
const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
5779
5831
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
5780
5832
|
let maximumCompressedSize = 0;
|
|
5781
5833
|
let uncompressedSize = 0;
|
|
5782
|
-
if (passThrough) {
|
|
5783
|
-
if (!reader) {
|
|
5784
|
-
throw new Error(ERR_UNDEFINED_READER);
|
|
5785
|
-
}
|
|
5834
|
+
if (passThrough && hasContent) {
|
|
5786
5835
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
5787
5836
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
5788
5837
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -5790,29 +5839,30 @@
|
|
|
5790
5839
|
}
|
|
5791
5840
|
const zip64Enabled = zip64 === true;
|
|
5792
5841
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
5793
|
-
|
|
5794
|
-
|
|
5842
|
+
if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
|
|
5843
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
5844
|
+
}
|
|
5845
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
|
|
5846
|
+
if (!hasContent) {
|
|
5795
5847
|
level = 0;
|
|
5796
5848
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
5797
5849
|
}
|
|
5798
5850
|
const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
5799
|
-
if (
|
|
5800
|
-
reader = new GenericReader(reader);
|
|
5801
|
-
await initStream(reader);
|
|
5851
|
+
if (hasContent) {
|
|
5802
5852
|
if (!passThrough) {
|
|
5803
|
-
if (
|
|
5853
|
+
if (contentSize === UNDEFINED_VALUE) {
|
|
5804
5854
|
dataDescriptor = true;
|
|
5805
5855
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
5806
5856
|
zip64 = true;
|
|
5807
5857
|
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
5808
5858
|
}
|
|
5809
5859
|
} else {
|
|
5810
|
-
options.uncompressedSize = uncompressedSize =
|
|
5811
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
5860
|
+
options.uncompressedSize = uncompressedSize = contentSize;
|
|
5861
|
+
maximumCompressedSize = (isCompressed(compressionMethod, level) ? getMaximumCompressedSize(uncompressedSize) : uncompressedSize) + encryptionOverhead;
|
|
5812
5862
|
}
|
|
5813
5863
|
} else {
|
|
5814
5864
|
options.uncompressedSize = uncompressedSize;
|
|
5815
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
5865
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
5816
5866
|
}
|
|
5817
5867
|
}
|
|
5818
5868
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
@@ -5826,7 +5876,7 @@
|
|
|
5826
5876
|
}
|
|
5827
5877
|
zip64 = zip64 || false;
|
|
5828
5878
|
return {
|
|
5829
|
-
|
|
5879
|
+
maximumCompressedSize,
|
|
5830
5880
|
resolvedOptions: {
|
|
5831
5881
|
dataDescriptor,
|
|
5832
5882
|
zip64,
|
|
@@ -5840,6 +5890,78 @@
|
|
|
5840
5890
|
};
|
|
5841
5891
|
}
|
|
5842
5892
|
|
|
5893
|
+
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
5894
|
+
const zipWriter = { options: writerOptions, config: getConfiguration() };
|
|
5895
|
+
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
5896
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5897
|
+
}
|
|
5898
|
+
const commentLength = getLength(comment);
|
|
5899
|
+
if (commentLength > MAX_16_BITS) {
|
|
5900
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
5901
|
+
}
|
|
5902
|
+
const usdz = writerOptions[OPTION_USDZ];
|
|
5903
|
+
const files = new Map();
|
|
5904
|
+
let layoutDependsOnWriteOrder = Boolean(usdz);
|
|
5905
|
+
let offset = 0;
|
|
5906
|
+
for (const entry of entries) {
|
|
5907
|
+
let { name } = entry;
|
|
5908
|
+
const { size } = entry;
|
|
5909
|
+
const options = Object.assign({}, entry.options);
|
|
5910
|
+
name = name.trim();
|
|
5911
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
5912
|
+
name += DIRECTORY_SIGNATURE;
|
|
5913
|
+
}
|
|
5914
|
+
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
5915
|
+
({ name } = attributesInfo);
|
|
5916
|
+
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
5917
|
+
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
5918
|
+
!metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
|
|
5919
|
+
metadata.level = 0;
|
|
5920
|
+
}
|
|
5921
|
+
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
5922
|
+
if (hasContent && size === UNDEFINED_VALUE) {
|
|
5923
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5924
|
+
}
|
|
5925
|
+
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
5926
|
+
if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
5927
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5928
|
+
}
|
|
5929
|
+
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
|
|
5930
|
+
const headerInfo = getHeaderInfo(entryOptions);
|
|
5931
|
+
const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
|
|
5932
|
+
const entryInfo = {
|
|
5933
|
+
headerInfo,
|
|
5934
|
+
metadataSize: getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray)
|
|
5935
|
+
};
|
|
5936
|
+
if (usdz) {
|
|
5937
|
+
appendExtraFieldUSDZ(entryInfo, offset);
|
|
5938
|
+
}
|
|
5939
|
+
const compressedSize = hasContent ? maximumCompressedSize : 0;
|
|
5940
|
+
if (offset >= MAX_32_BITS) {
|
|
5941
|
+
layoutDependsOnWriteOrder = true;
|
|
5942
|
+
}
|
|
5943
|
+
files.set(name, Object.assign({}, entryOptions, headerInfo, {
|
|
5944
|
+
offset,
|
|
5945
|
+
diskNumberStart: 0,
|
|
5946
|
+
compressedSize
|
|
5947
|
+
}));
|
|
5948
|
+
offset += entryInfo.metadataSize + compressedSize;
|
|
5949
|
+
}
|
|
5950
|
+
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
5951
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5952
|
+
}
|
|
5953
|
+
const directoryDataLength = createDirectoryRecords(files);
|
|
5954
|
+
let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
|
|
5955
|
+
if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
|
|
5956
|
+
if (zip64 === false) {
|
|
5957
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
5958
|
+
} else {
|
|
5959
|
+
zip64 = true;
|
|
5960
|
+
}
|
|
5961
|
+
}
|
|
5962
|
+
return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
5963
|
+
}
|
|
5964
|
+
|
|
5843
5965
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
5844
5966
|
const {
|
|
5845
5967
|
files,
|
|
@@ -6211,9 +6333,7 @@
|
|
|
6211
6333
|
crc32
|
|
6212
6334
|
} = options;
|
|
6213
6335
|
let { version, compressionMethod } = options;
|
|
6214
|
-
const compressed = !directory && (compressionMethod
|
|
6215
|
-
? (level === UNDEFINED_VALUE || level > 0)
|
|
6216
|
-
: compressionMethod !== COMPRESSION_METHOD_STORE);
|
|
6336
|
+
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
6217
6337
|
let rawLocalExtraFieldZip64;
|
|
6218
6338
|
const uncompressedFile = passThrough || !compressed;
|
|
6219
6339
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
@@ -6900,6 +7020,16 @@
|
|
|
6900
7020
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
6901
7021
|
}
|
|
6902
7022
|
|
|
7023
|
+
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7024
|
+
const value = getAliasedValue(options, name, deprecatedName);
|
|
7025
|
+
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
7026
|
+
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7027
|
+
}
|
|
7028
|
+
|
|
7029
|
+
function getAliasedValue(options, name, deprecatedName) {
|
|
7030
|
+
return options[name] === UNDEFINED_VALUE ? options[deprecatedName] : options[name];
|
|
7031
|
+
}
|
|
7032
|
+
|
|
6903
7033
|
function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
6904
7034
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
6905
7035
|
}
|
|
@@ -6912,6 +7042,12 @@
|
|
|
6912
7042
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
6913
7043
|
}
|
|
6914
7044
|
|
|
7045
|
+
function isCompressed(compressionMethod, level) {
|
|
7046
|
+
return compressionMethod === UNDEFINED_VALUE
|
|
7047
|
+
? (level === UNDEFINED_VALUE || level > 0)
|
|
7048
|
+
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7049
|
+
}
|
|
7050
|
+
|
|
6915
7051
|
function setUint8(view, offset, value) {
|
|
6916
7052
|
view.setUint8(offset, value);
|
|
6917
7053
|
}
|
|
@@ -7042,7 +7178,10 @@
|
|
|
7042
7178
|
|
|
7043
7179
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
7044
7180
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
7181
|
+
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
7045
7182
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
7183
|
+
const ERR_ABORTED = "The operation was aborted";
|
|
7184
|
+
const ABORT_ERROR_NAME = "AbortError";
|
|
7046
7185
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
7047
7186
|
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
7048
7187
|
EXTRAFIELD_TYPE_ZIP64,
|
|
@@ -7077,6 +7216,7 @@
|
|
|
7077
7216
|
parent,
|
|
7078
7217
|
children: [],
|
|
7079
7218
|
uncompressedSize: params.uncompressedSize || 0,
|
|
7219
|
+
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
7080
7220
|
passThrough: params.passThrough
|
|
7081
7221
|
});
|
|
7082
7222
|
if (parent || !fs.root) {
|
|
@@ -7144,16 +7284,17 @@
|
|
|
7144
7284
|
|
|
7145
7285
|
async getData(writer, options = {}) {
|
|
7146
7286
|
const zipEntry = this;
|
|
7147
|
-
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
|
|
7287
|
+
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data && keepsContentType(writer, zipEntry.data))) {
|
|
7148
7288
|
return zipEntry.data;
|
|
7149
7289
|
} else {
|
|
7150
7290
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
7151
|
-
const
|
|
7152
|
-
await Promise.all([initStream(reader), initStream(writer,
|
|
7153
|
-
const { readable } = reader;
|
|
7291
|
+
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
7292
|
+
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
7154
7293
|
const { signal } = options;
|
|
7294
|
+
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
7295
|
+
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
7155
7296
|
zipEntry.uncompressedSize = reader.size;
|
|
7156
|
-
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal });
|
|
7297
|
+
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal, preventClose, preventAbort: preventClose });
|
|
7157
7298
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7158
7299
|
}
|
|
7159
7300
|
}
|
|
@@ -7284,7 +7425,7 @@
|
|
|
7284
7425
|
Reader: TextReader,
|
|
7285
7426
|
Writer: TextWriter,
|
|
7286
7427
|
options,
|
|
7287
|
-
uncompressedSize: text
|
|
7428
|
+
uncompressedSize: getTextSize(text)
|
|
7288
7429
|
});
|
|
7289
7430
|
}
|
|
7290
7431
|
|
|
@@ -7413,10 +7554,16 @@
|
|
|
7413
7554
|
}
|
|
7414
7555
|
|
|
7415
7556
|
async importZip(reader, options = {}) {
|
|
7416
|
-
|
|
7417
|
-
|
|
7557
|
+
let zipReader;
|
|
7558
|
+
if (reader && typeof reader.getEntries == FUNCTION_TYPE) {
|
|
7559
|
+
zipReader = reader;
|
|
7560
|
+
options = Object.assign({}, zipReader.options, options);
|
|
7561
|
+
} else {
|
|
7562
|
+
await initStream(reader);
|
|
7563
|
+
zipReader = new ZipReader(reader, options);
|
|
7564
|
+
}
|
|
7418
7565
|
const importedEntries = [];
|
|
7419
|
-
const entries = await zipReader.getEntries();
|
|
7566
|
+
const entries = await zipReader.getEntries(options);
|
|
7420
7567
|
for (const entry of entries) {
|
|
7421
7568
|
let parent = this;
|
|
7422
7569
|
try {
|
|
@@ -7438,7 +7585,7 @@
|
|
|
7438
7585
|
importedEntries.push(addChild(parent, name, {
|
|
7439
7586
|
data: entry,
|
|
7440
7587
|
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
7441
|
-
uncompressedSize: entry.uncompressedSize,
|
|
7588
|
+
uncompressedSize: options.passThrough ? entry.compressedSize : entry.uncompressedSize,
|
|
7442
7589
|
passThrough: options.passThrough
|
|
7443
7590
|
}));
|
|
7444
7591
|
} else {
|
|
@@ -7480,11 +7627,25 @@
|
|
|
7480
7627
|
}
|
|
7481
7628
|
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
7482
7629
|
const zipWriter = new ZipWriter(writer, options);
|
|
7483
|
-
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry],
|
|
7484
|
-
await zipWriter.close();
|
|
7630
|
+
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
7631
|
+
await zipWriter.close(options.globalComment);
|
|
7485
7632
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7486
7633
|
}
|
|
7487
7634
|
|
|
7635
|
+
getExportedSize(options = {}) {
|
|
7636
|
+
const zipEntry = this;
|
|
7637
|
+
options = Object.assign({}, options);
|
|
7638
|
+
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
7639
|
+
options.bufferedWrite = true;
|
|
7640
|
+
}
|
|
7641
|
+
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
7642
|
+
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
7643
|
+
return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
|
|
7644
|
+
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
7645
|
+
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
7646
|
+
}), writeOrderGuaranteed, options.globalComment);
|
|
7647
|
+
}
|
|
7648
|
+
|
|
7488
7649
|
getChildByName(name) {
|
|
7489
7650
|
const children = this.children;
|
|
7490
7651
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
@@ -7495,6 +7656,10 @@
|
|
|
7495
7656
|
}
|
|
7496
7657
|
}
|
|
7497
7658
|
|
|
7659
|
+
getChildren(options = {}) {
|
|
7660
|
+
return collectChildren(this, options.recursive);
|
|
7661
|
+
}
|
|
7662
|
+
|
|
7498
7663
|
isPasswordProtected() {
|
|
7499
7664
|
const children = this.children;
|
|
7500
7665
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
@@ -7586,6 +7751,10 @@
|
|
|
7586
7751
|
return this.root.getChildByName(name);
|
|
7587
7752
|
}
|
|
7588
7753
|
|
|
7754
|
+
getChildren(options) {
|
|
7755
|
+
return this.root.getChildren(options);
|
|
7756
|
+
}
|
|
7757
|
+
|
|
7589
7758
|
addDirectory(name, options) {
|
|
7590
7759
|
return this.root.addDirectory(name, options);
|
|
7591
7760
|
}
|
|
@@ -7684,6 +7853,10 @@
|
|
|
7684
7853
|
return this.root.exportZip(writer, options);
|
|
7685
7854
|
}
|
|
7686
7855
|
|
|
7856
|
+
getExportedSize(options) {
|
|
7857
|
+
return this.root.getExportedSize(options);
|
|
7858
|
+
}
|
|
7859
|
+
|
|
7687
7860
|
isPasswordProtected() {
|
|
7688
7861
|
return this.root.isPasswordProtected();
|
|
7689
7862
|
}
|
|
@@ -7695,12 +7868,12 @@
|
|
|
7695
7868
|
|
|
7696
7869
|
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
7697
7870
|
|
|
7698
|
-
function getTotalSize(entries,
|
|
7871
|
+
function getTotalSize(entries, getEntrySize) {
|
|
7699
7872
|
let size = 0;
|
|
7700
7873
|
const pendingEntries = Array.from(entries);
|
|
7701
7874
|
while (pendingEntries.length) {
|
|
7702
7875
|
const entry = pendingEntries.pop();
|
|
7703
|
-
size += entry
|
|
7876
|
+
size += getEntrySize(entry) || 0;
|
|
7704
7877
|
for (const child of entry.children) {
|
|
7705
7878
|
pendingEntries.push(child);
|
|
7706
7879
|
}
|
|
@@ -7708,6 +7881,15 @@
|
|
|
7708
7881
|
return size;
|
|
7709
7882
|
}
|
|
7710
7883
|
|
|
7884
|
+
function getUncompressedSize(entry) {
|
|
7885
|
+
return entry.uncompressedSize;
|
|
7886
|
+
}
|
|
7887
|
+
|
|
7888
|
+
function getExtractedSize(entry, passThrough) {
|
|
7889
|
+
const { data } = entry;
|
|
7890
|
+
return passThrough && data instanceof Entry ? data.compressedSize : entry.uncompressedSize;
|
|
7891
|
+
}
|
|
7892
|
+
|
|
7711
7893
|
function getReadableReader(readable) {
|
|
7712
7894
|
let consumed;
|
|
7713
7895
|
return function () {
|
|
@@ -7730,10 +7912,17 @@
|
|
|
7730
7912
|
|
|
7731
7913
|
async init() {
|
|
7732
7914
|
const zipBlobReader = this;
|
|
7733
|
-
|
|
7734
|
-
const
|
|
7915
|
+
const readerOptions = Object.assign({}, options, zipBlobReader.options);
|
|
7916
|
+
const { checkOverlappingEntry, checkOverlappingEntryOnly } = readerOptions;
|
|
7917
|
+
const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign(readerOptions, {
|
|
7918
|
+
checkPasswordOnly: false,
|
|
7919
|
+
checkOverlappingEntry: checkOverlappingEntryOnly || checkOverlappingEntry,
|
|
7920
|
+
checkOverlappingEntryOnly: false,
|
|
7921
|
+
preventClose: false
|
|
7922
|
+
}));
|
|
7735
7923
|
zipBlobReader.data = data;
|
|
7736
7924
|
zipBlobReader.blobReader = new BlobReader(data);
|
|
7925
|
+
zipBlobReader.size = data.size;
|
|
7737
7926
|
super.init();
|
|
7738
7927
|
}
|
|
7739
7928
|
|
|
@@ -7747,6 +7936,30 @@
|
|
|
7747
7936
|
return Reader.prototype ? new Reader(data, options) : Reader(data, options);
|
|
7748
7937
|
}
|
|
7749
7938
|
|
|
7939
|
+
function keepsContentType(writer, data) {
|
|
7940
|
+
const { contentType } = writer;
|
|
7941
|
+
if (contentType === UNDEFINED_VALUE) {
|
|
7942
|
+
return true;
|
|
7943
|
+
} else if (writer.constructor == BlobWriter) {
|
|
7944
|
+
return data.type == contentType;
|
|
7945
|
+
} else if (writer.constructor == Data64URIWriter) {
|
|
7946
|
+
return data.startsWith(writer.data);
|
|
7947
|
+
} else {
|
|
7948
|
+
return true;
|
|
7949
|
+
}
|
|
7950
|
+
}
|
|
7951
|
+
|
|
7952
|
+
function createProgressReadable(zipEntry, reader, options, signal) {
|
|
7953
|
+
const { onstart, onprogress, onend } = options;
|
|
7954
|
+
const { readable } = reader;
|
|
7955
|
+
const coreReaderReportsProgress = zipEntry.data instanceof Entry;
|
|
7956
|
+
if (coreReaderReportsProgress || (!onstart && !onprogress && !onend)) {
|
|
7957
|
+
return readable;
|
|
7958
|
+
} else {
|
|
7959
|
+
return toCompatibleReadable(readable).pipeThrough(new ProgressWatcherStream({ onstart, onprogress, onend, size: reader.size }), { signal });
|
|
7960
|
+
}
|
|
7961
|
+
}
|
|
7962
|
+
|
|
7750
7963
|
async function initReaders(entry, options) {
|
|
7751
7964
|
const fileEntries = [];
|
|
7752
7965
|
const pendingEntries = [entry];
|
|
@@ -7779,6 +7992,7 @@
|
|
|
7779
7992
|
}
|
|
7780
7993
|
if (reader.size !== UNDEFINED_VALUE) {
|
|
7781
7994
|
child.uncompressedSize = reader.size;
|
|
7995
|
+
child.undeterminedSize = false;
|
|
7782
7996
|
}
|
|
7783
7997
|
}));
|
|
7784
7998
|
return readers;
|
|
@@ -7828,6 +8042,90 @@
|
|
|
7828
8042
|
return error;
|
|
7829
8043
|
}
|
|
7830
8044
|
|
|
8045
|
+
function getChildEntryOptions(child, selectedEntry, options) {
|
|
8046
|
+
const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
|
|
8047
|
+
const childOptions = child.options || {};
|
|
8048
|
+
let zipEntryMetadata = {};
|
|
8049
|
+
let passThroughOptions = {};
|
|
8050
|
+
if (child.data instanceof Entry) {
|
|
8051
|
+
const {
|
|
8052
|
+
externalFileAttributes,
|
|
8053
|
+
versionMadeBy,
|
|
8054
|
+
comment,
|
|
8055
|
+
lastModDate,
|
|
8056
|
+
creationDate,
|
|
8057
|
+
lastAccessDate,
|
|
8058
|
+
uncompressedSize,
|
|
8059
|
+
encrypted,
|
|
8060
|
+
zipCrypto,
|
|
8061
|
+
crc32,
|
|
8062
|
+
compressionMethod,
|
|
8063
|
+
extraFieldAES,
|
|
8064
|
+
internalFileAttributes,
|
|
8065
|
+
extraField,
|
|
8066
|
+
uid,
|
|
8067
|
+
gid
|
|
8068
|
+
} = child.data;
|
|
8069
|
+
zipEntryMetadata = {
|
|
8070
|
+
externalFileAttributes,
|
|
8071
|
+
versionMadeBy,
|
|
8072
|
+
comment,
|
|
8073
|
+
lastModDate,
|
|
8074
|
+
creationDate,
|
|
8075
|
+
lastAccessDate,
|
|
8076
|
+
internalFileAttributes
|
|
8077
|
+
};
|
|
8078
|
+
const userExtraField = getUserExtraField(extraField);
|
|
8079
|
+
if (userExtraField) {
|
|
8080
|
+
zipEntryMetadata.extraField = userExtraField;
|
|
8081
|
+
}
|
|
8082
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
8083
|
+
Object.assign(zipEntryMetadata, {
|
|
8084
|
+
uid,
|
|
8085
|
+
gid,
|
|
8086
|
+
unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
|
|
8087
|
+
});
|
|
8088
|
+
}
|
|
8089
|
+
if (isPassThrough(child, options)) {
|
|
8090
|
+
let level, encryptionStrength;
|
|
8091
|
+
if (compressionMethod === 0) {
|
|
8092
|
+
level = 0;
|
|
8093
|
+
}
|
|
8094
|
+
if (extraFieldAES) {
|
|
8095
|
+
encryptionStrength = extraFieldAES.strength;
|
|
8096
|
+
}
|
|
8097
|
+
passThroughOptions = {
|
|
8098
|
+
passThrough: true,
|
|
8099
|
+
encrypted,
|
|
8100
|
+
zipCrypto,
|
|
8101
|
+
crc32,
|
|
8102
|
+
uncompressedSize,
|
|
8103
|
+
level,
|
|
8104
|
+
encryptionStrength,
|
|
8105
|
+
compressionMethod
|
|
8106
|
+
};
|
|
8107
|
+
}
|
|
8108
|
+
}
|
|
8109
|
+
const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
|
|
8110
|
+
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
8111
|
+
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
8112
|
+
}
|
|
8113
|
+
return { name, entryOptions };
|
|
8114
|
+
}
|
|
8115
|
+
|
|
8116
|
+
function getDeterminedSize(child, passThrough) {
|
|
8117
|
+
const { reader } = child;
|
|
8118
|
+
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
8119
|
+
return reader.size;
|
|
8120
|
+
}
|
|
8121
|
+
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
8122
|
+
}
|
|
8123
|
+
|
|
8124
|
+
function isPassThrough(child, options) {
|
|
8125
|
+
const { readerOptions } = options;
|
|
8126
|
+
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
8127
|
+
}
|
|
8128
|
+
|
|
7831
8129
|
function getUserExtraField(extraField) {
|
|
7832
8130
|
if (extraField) {
|
|
7833
8131
|
const userExtraField = new Map();
|
|
@@ -7843,104 +8141,53 @@
|
|
|
7843
8141
|
}
|
|
7844
8142
|
|
|
7845
8143
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
8144
|
+
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
7846
8145
|
const selectedEntry = entry;
|
|
7847
|
-
const
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
await
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
throw errorResult.reason;
|
|
7859
|
-
}
|
|
7860
|
-
} else {
|
|
7861
|
-
for (const child of entry.children) {
|
|
7862
|
-
await processChild(child);
|
|
7863
|
-
}
|
|
7864
|
-
}
|
|
8146
|
+
const totalEntries = getTotalSize(entry.children, () => 1);
|
|
8147
|
+
let writtenSize = 0;
|
|
8148
|
+
let writtenEntries = 0;
|
|
8149
|
+
if (onstart) {
|
|
8150
|
+
await callHandler(onstart, totalSize);
|
|
8151
|
+
}
|
|
8152
|
+
if (options.bufferedWrite) {
|
|
8153
|
+
await processChildren(entry);
|
|
8154
|
+
} else {
|
|
8155
|
+
for (const child of entry.getChildren({ recursive: true })) {
|
|
8156
|
+
await addChild(child);
|
|
7865
8157
|
}
|
|
8158
|
+
}
|
|
8159
|
+
if (onend) {
|
|
8160
|
+
await callHandler(onend, writtenSize);
|
|
8161
|
+
}
|
|
7866
8162
|
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
} = child.data;
|
|
7890
|
-
zipEntryOptions = {
|
|
7891
|
-
externalFileAttributes,
|
|
7892
|
-
versionMadeBy,
|
|
7893
|
-
comment,
|
|
7894
|
-
lastModDate,
|
|
7895
|
-
creationDate,
|
|
7896
|
-
lastAccessDate,
|
|
7897
|
-
internalFileAttributes
|
|
7898
|
-
};
|
|
7899
|
-
const userExtraField = getUserExtraField(extraField);
|
|
7900
|
-
if (userExtraField) {
|
|
7901
|
-
zipEntryOptions.extraField = userExtraField;
|
|
7902
|
-
}
|
|
7903
|
-
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
7904
|
-
Object.assign(zipEntryOptions, {
|
|
7905
|
-
uid,
|
|
7906
|
-
gid,
|
|
7907
|
-
unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
|
|
7908
|
-
});
|
|
7909
|
-
}
|
|
7910
|
-
if (child.passThrough) {
|
|
7911
|
-
let level, encryptionStrength;
|
|
7912
|
-
if (compressionMethod === 0) {
|
|
7913
|
-
level = 0;
|
|
7914
|
-
}
|
|
7915
|
-
if (extraFieldAES) {
|
|
7916
|
-
encryptionStrength = extraFieldAES.strength;
|
|
7917
|
-
}
|
|
7918
|
-
zipEntryOptions = Object.assign(zipEntryOptions, {
|
|
7919
|
-
passThrough: true,
|
|
7920
|
-
encrypted,
|
|
7921
|
-
zipCrypto,
|
|
7922
|
-
crc32,
|
|
7923
|
-
uncompressedSize,
|
|
7924
|
-
level,
|
|
7925
|
-
encryptionStrength,
|
|
7926
|
-
compressionMethod
|
|
7927
|
-
});
|
|
8163
|
+
async function processChildren(entry) {
|
|
8164
|
+
const results = await Promise.allSettled(entry.children.map(async child => {
|
|
8165
|
+
await addChild(child);
|
|
8166
|
+
await processChildren(child);
|
|
8167
|
+
}));
|
|
8168
|
+
const errorResult = results.find(result => result.status == "rejected");
|
|
8169
|
+
if (errorResult) {
|
|
8170
|
+
throw errorResult.reason;
|
|
8171
|
+
}
|
|
8172
|
+
}
|
|
8173
|
+
|
|
8174
|
+
async function addChild(child) {
|
|
8175
|
+
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
8176
|
+
let entryWrittenSize = 0;
|
|
8177
|
+
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
8178
|
+
onstart: UNDEFINED_VALUE,
|
|
8179
|
+
onend: UNDEFINED_VALUE,
|
|
8180
|
+
onprogress: async indexProgress => {
|
|
8181
|
+
writtenSize += indexProgress - entryWrittenSize;
|
|
8182
|
+
entryWrittenSize = indexProgress;
|
|
8183
|
+
if (onprogress) {
|
|
8184
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
7928
8185
|
}
|
|
7929
8186
|
}
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
entryOffsets.set(name, indexProgress);
|
|
7935
|
-
try {
|
|
7936
|
-
await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
|
|
7937
|
-
} catch {
|
|
7938
|
-
// ignored
|
|
7939
|
-
}
|
|
7940
|
-
}
|
|
7941
|
-
}
|
|
7942
|
-
}));
|
|
7943
|
-
await process(zipWriter, child);
|
|
8187
|
+
}));
|
|
8188
|
+
writtenEntries++;
|
|
8189
|
+
if (onentryprogress) {
|
|
8190
|
+
await callHandler(onentryprogress, writtenEntries, totalEntries, entryMetadata);
|
|
7944
8191
|
}
|
|
7945
8192
|
}
|
|
7946
8193
|
}
|
|
@@ -7969,7 +8216,7 @@
|
|
|
7969
8216
|
})
|
|
7970
8217
|
);
|
|
7971
8218
|
} else if (handle.kind == "directory") {
|
|
7972
|
-
const directoryEntry = parentEntry.addDirectory(handle.name);
|
|
8219
|
+
const directoryEntry = parentEntry.addDirectory(handle.name, options);
|
|
7973
8220
|
addedEntries.push(directoryEntry);
|
|
7974
8221
|
for await (const childHandle of handle.values()) {
|
|
7975
8222
|
await addFile(directoryEntry, childHandle, addedEntries, entryName);
|
|
@@ -7991,14 +8238,29 @@
|
|
|
7991
8238
|
}
|
|
7992
8239
|
|
|
7993
8240
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
7994
|
-
const
|
|
7995
|
-
const writtenSizes = new Map();
|
|
8241
|
+
const { onstart, onprogress, onend } = options;
|
|
7996
8242
|
const abortController = new AbortController();
|
|
7997
8243
|
const { signal } = abortController;
|
|
7998
8244
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
8245
|
+
const getDataOptions = Object.assign({}, options, options.readerOptions, {
|
|
8246
|
+
signal,
|
|
8247
|
+
onstart: UNDEFINED_VALUE,
|
|
8248
|
+
onprogress: UNDEFINED_VALUE,
|
|
8249
|
+
onend: UNDEFINED_VALUE,
|
|
8250
|
+
preventClose: false
|
|
8251
|
+
});
|
|
8252
|
+
const totalSize = getTotalSize([zipEntry], entry => getExtractedSize(entry, getDataOptions.passThrough));
|
|
7999
8253
|
const exportedEntryNames = [];
|
|
8254
|
+
let exportAborted = false;
|
|
8255
|
+
let writtenSize = 0;
|
|
8000
8256
|
try {
|
|
8257
|
+
if (onstart) {
|
|
8258
|
+
await callHandler(onstart, totalSize);
|
|
8259
|
+
}
|
|
8001
8260
|
await exportChildren(zipEntry, directoryHandle);
|
|
8261
|
+
if (onend) {
|
|
8262
|
+
await callHandler(onend, writtenSize);
|
|
8263
|
+
}
|
|
8002
8264
|
} catch (error) {
|
|
8003
8265
|
try {
|
|
8004
8266
|
error.exportedEntryNames = exportedEntryNames;
|
|
@@ -8011,6 +8273,25 @@
|
|
|
8011
8273
|
}
|
|
8012
8274
|
return directoryHandle;
|
|
8013
8275
|
|
|
8276
|
+
function createProgressWritable(writable) {
|
|
8277
|
+
const writer = writable.getWriter();
|
|
8278
|
+
return new WritableStream({
|
|
8279
|
+
async write(chunk) {
|
|
8280
|
+
await writer.write(chunk);
|
|
8281
|
+
writtenSize += chunk.length;
|
|
8282
|
+
if (onprogress) {
|
|
8283
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
8284
|
+
}
|
|
8285
|
+
},
|
|
8286
|
+
close() {
|
|
8287
|
+
return writer.close();
|
|
8288
|
+
},
|
|
8289
|
+
abort(reason) {
|
|
8290
|
+
return writer.abort(reason);
|
|
8291
|
+
}
|
|
8292
|
+
});
|
|
8293
|
+
}
|
|
8294
|
+
|
|
8014
8295
|
async function exportChildren(entry, parentHandle) {
|
|
8015
8296
|
if (options.concurrent) {
|
|
8016
8297
|
const results = await Promise.allSettled(entry.children.map(child => exportChild(child, parentHandle)));
|
|
@@ -8029,10 +8310,10 @@
|
|
|
8029
8310
|
|
|
8030
8311
|
async function exportChild(child, parentHandle) {
|
|
8031
8312
|
if (signal.aborted) {
|
|
8032
|
-
if (isExportAborted(signal.reason)) {
|
|
8313
|
+
if (exportAborted || isExportAborted(signal.reason)) {
|
|
8033
8314
|
return;
|
|
8034
8315
|
}
|
|
8035
|
-
throw signal.reason;
|
|
8316
|
+
throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
|
|
8036
8317
|
}
|
|
8037
8318
|
try {
|
|
8038
8319
|
if (child.directory) {
|
|
@@ -8041,22 +8322,15 @@
|
|
|
8041
8322
|
} else {
|
|
8042
8323
|
const fileHandle = await parentHandle.getFileHandle(child.name, { create: true });
|
|
8043
8324
|
const writable = await fileHandle.createWritable();
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
try {
|
|
8050
|
-
await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
|
|
8051
|
-
} catch {
|
|
8052
|
-
// ignored
|
|
8053
|
-
}
|
|
8054
|
-
}
|
|
8055
|
-
}
|
|
8056
|
-
}));
|
|
8325
|
+
try {
|
|
8326
|
+
await child.getData({ writable: createProgressWritable(writable) }, getDataOptions);
|
|
8327
|
+
} catch (error) {
|
|
8328
|
+
throw exportAborted ? new Error(ERR_ABORT_EXPORT) : error;
|
|
8329
|
+
}
|
|
8057
8330
|
exportedEntryNames.push(child.getRelativeName(zipEntry));
|
|
8058
8331
|
}
|
|
8059
8332
|
} catch (error) {
|
|
8333
|
+
exportAborted = true;
|
|
8060
8334
|
abortController.abort(new Error(ERR_ABORT_EXPORT));
|
|
8061
8335
|
try {
|
|
8062
8336
|
if (error.entryName === UNDEFINED_VALUE) {
|
|
@@ -8128,6 +8402,21 @@
|
|
|
8128
8402
|
fs.root = new ZipDirectoryEntry(fs);
|
|
8129
8403
|
}
|
|
8130
8404
|
|
|
8405
|
+
function collectChildren(directory, recursive) {
|
|
8406
|
+
const children = [];
|
|
8407
|
+
const pendingDirectories = [directory];
|
|
8408
|
+
let directoryIndex = 0;
|
|
8409
|
+
while (directoryIndex < pendingDirectories.length) {
|
|
8410
|
+
for (const child of pendingDirectories[directoryIndex++].children) {
|
|
8411
|
+
children.push(child);
|
|
8412
|
+
if (recursive) {
|
|
8413
|
+
pendingDirectories.push(child);
|
|
8414
|
+
}
|
|
8415
|
+
}
|
|
8416
|
+
}
|
|
8417
|
+
return children;
|
|
8418
|
+
}
|
|
8419
|
+
|
|
8131
8420
|
function registerEntries(fs, entry) {
|
|
8132
8421
|
const pendingEntries = [entry];
|
|
8133
8422
|
while (pendingEntries.length) {
|
|
@@ -8147,7 +8436,9 @@
|
|
|
8147
8436
|
}
|
|
8148
8437
|
}
|
|
8149
8438
|
|
|
8439
|
+
exports.ERR_ABORTED = ERR_ABORTED;
|
|
8150
8440
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
8441
|
+
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8151
8442
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
8152
8443
|
exports.fs = fs;
|
|
8153
8444
|
|