@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/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,6 +7178,7 @@
|
|
|
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";
|
|
7046
7183
|
const ERR_ABORTED = "The operation was aborted";
|
|
7047
7184
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -7079,6 +7216,7 @@
|
|
|
7079
7216
|
parent,
|
|
7080
7217
|
children: [],
|
|
7081
7218
|
uncompressedSize: params.uncompressedSize || 0,
|
|
7219
|
+
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
7082
7220
|
passThrough: params.passThrough
|
|
7083
7221
|
});
|
|
7084
7222
|
if (parent || !fs.root) {
|
|
@@ -7146,16 +7284,17 @@
|
|
|
7146
7284
|
|
|
7147
7285
|
async getData(writer, options = {}) {
|
|
7148
7286
|
const zipEntry = this;
|
|
7149
|
-
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
|
|
7287
|
+
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data && keepsContentType(writer, zipEntry.data))) {
|
|
7150
7288
|
return zipEntry.data;
|
|
7151
7289
|
} else {
|
|
7152
7290
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
7153
|
-
const
|
|
7154
|
-
await Promise.all([initStream(reader), initStream(writer,
|
|
7155
|
-
const { readable } = reader;
|
|
7291
|
+
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
7292
|
+
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
7156
7293
|
const { signal } = options;
|
|
7294
|
+
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
7295
|
+
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
7157
7296
|
zipEntry.uncompressedSize = reader.size;
|
|
7158
|
-
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal });
|
|
7297
|
+
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal, preventClose, preventAbort: preventClose });
|
|
7159
7298
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7160
7299
|
}
|
|
7161
7300
|
}
|
|
@@ -7286,7 +7425,7 @@
|
|
|
7286
7425
|
Reader: TextReader,
|
|
7287
7426
|
Writer: TextWriter,
|
|
7288
7427
|
options,
|
|
7289
|
-
uncompressedSize: text
|
|
7428
|
+
uncompressedSize: getTextSize(text)
|
|
7290
7429
|
});
|
|
7291
7430
|
}
|
|
7292
7431
|
|
|
@@ -7415,10 +7554,16 @@
|
|
|
7415
7554
|
}
|
|
7416
7555
|
|
|
7417
7556
|
async importZip(reader, options = {}) {
|
|
7418
|
-
|
|
7419
|
-
|
|
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
|
+
}
|
|
7420
7565
|
const importedEntries = [];
|
|
7421
|
-
const entries = await zipReader.getEntries();
|
|
7566
|
+
const entries = await zipReader.getEntries(options);
|
|
7422
7567
|
for (const entry of entries) {
|
|
7423
7568
|
let parent = this;
|
|
7424
7569
|
try {
|
|
@@ -7440,7 +7585,7 @@
|
|
|
7440
7585
|
importedEntries.push(addChild(parent, name, {
|
|
7441
7586
|
data: entry,
|
|
7442
7587
|
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
7443
|
-
uncompressedSize: entry.uncompressedSize,
|
|
7588
|
+
uncompressedSize: options.passThrough ? entry.compressedSize : entry.uncompressedSize,
|
|
7444
7589
|
passThrough: options.passThrough
|
|
7445
7590
|
}));
|
|
7446
7591
|
} else {
|
|
@@ -7482,11 +7627,25 @@
|
|
|
7482
7627
|
}
|
|
7483
7628
|
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
7484
7629
|
const zipWriter = new ZipWriter(writer, options);
|
|
7485
|
-
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry],
|
|
7486
|
-
await zipWriter.close();
|
|
7630
|
+
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
7631
|
+
await zipWriter.close(options.globalComment);
|
|
7487
7632
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7488
7633
|
}
|
|
7489
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
|
+
|
|
7490
7649
|
getChildByName(name) {
|
|
7491
7650
|
const children = this.children;
|
|
7492
7651
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
@@ -7694,6 +7853,10 @@
|
|
|
7694
7853
|
return this.root.exportZip(writer, options);
|
|
7695
7854
|
}
|
|
7696
7855
|
|
|
7856
|
+
getExportedSize(options) {
|
|
7857
|
+
return this.root.getExportedSize(options);
|
|
7858
|
+
}
|
|
7859
|
+
|
|
7697
7860
|
isPasswordProtected() {
|
|
7698
7861
|
return this.root.isPasswordProtected();
|
|
7699
7862
|
}
|
|
@@ -7705,12 +7868,12 @@
|
|
|
7705
7868
|
|
|
7706
7869
|
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
7707
7870
|
|
|
7708
|
-
function getTotalSize(entries,
|
|
7871
|
+
function getTotalSize(entries, getEntrySize) {
|
|
7709
7872
|
let size = 0;
|
|
7710
7873
|
const pendingEntries = Array.from(entries);
|
|
7711
7874
|
while (pendingEntries.length) {
|
|
7712
7875
|
const entry = pendingEntries.pop();
|
|
7713
|
-
size += entry
|
|
7876
|
+
size += getEntrySize(entry) || 0;
|
|
7714
7877
|
for (const child of entry.children) {
|
|
7715
7878
|
pendingEntries.push(child);
|
|
7716
7879
|
}
|
|
@@ -7718,6 +7881,15 @@
|
|
|
7718
7881
|
return size;
|
|
7719
7882
|
}
|
|
7720
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
|
+
|
|
7721
7893
|
function getReadableReader(readable) {
|
|
7722
7894
|
let consumed;
|
|
7723
7895
|
return function () {
|
|
@@ -7740,10 +7912,17 @@
|
|
|
7740
7912
|
|
|
7741
7913
|
async init() {
|
|
7742
7914
|
const zipBlobReader = this;
|
|
7743
|
-
|
|
7744
|
-
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
|
+
}));
|
|
7745
7923
|
zipBlobReader.data = data;
|
|
7746
7924
|
zipBlobReader.blobReader = new BlobReader(data);
|
|
7925
|
+
zipBlobReader.size = data.size;
|
|
7747
7926
|
super.init();
|
|
7748
7927
|
}
|
|
7749
7928
|
|
|
@@ -7757,6 +7936,30 @@
|
|
|
7757
7936
|
return Reader.prototype ? new Reader(data, options) : Reader(data, options);
|
|
7758
7937
|
}
|
|
7759
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
|
+
|
|
7760
7963
|
async function initReaders(entry, options) {
|
|
7761
7964
|
const fileEntries = [];
|
|
7762
7965
|
const pendingEntries = [entry];
|
|
@@ -7789,6 +7992,7 @@
|
|
|
7789
7992
|
}
|
|
7790
7993
|
if (reader.size !== UNDEFINED_VALUE) {
|
|
7791
7994
|
child.uncompressedSize = reader.size;
|
|
7995
|
+
child.undeterminedSize = false;
|
|
7792
7996
|
}
|
|
7793
7997
|
}));
|
|
7794
7998
|
return readers;
|
|
@@ -7838,6 +8042,90 @@
|
|
|
7838
8042
|
return error;
|
|
7839
8043
|
}
|
|
7840
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
|
+
|
|
7841
8129
|
function getUserExtraField(extraField) {
|
|
7842
8130
|
if (extraField) {
|
|
7843
8131
|
const userExtraField = new Map();
|
|
@@ -7853,8 +8141,14 @@
|
|
|
7853
8141
|
}
|
|
7854
8142
|
|
|
7855
8143
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
8144
|
+
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
7856
8145
|
const selectedEntry = entry;
|
|
7857
|
-
const
|
|
8146
|
+
const totalEntries = getTotalSize(entry.children, () => 1);
|
|
8147
|
+
let writtenSize = 0;
|
|
8148
|
+
let writtenEntries = 0;
|
|
8149
|
+
if (onstart) {
|
|
8150
|
+
await callHandler(onstart, totalSize);
|
|
8151
|
+
}
|
|
7858
8152
|
if (options.bufferedWrite) {
|
|
7859
8153
|
await processChildren(entry);
|
|
7860
8154
|
} else {
|
|
@@ -7862,6 +8156,9 @@
|
|
|
7862
8156
|
await addChild(child);
|
|
7863
8157
|
}
|
|
7864
8158
|
}
|
|
8159
|
+
if (onend) {
|
|
8160
|
+
await callHandler(onend, writtenSize);
|
|
8161
|
+
}
|
|
7865
8162
|
|
|
7866
8163
|
async function processChildren(entry) {
|
|
7867
8164
|
const results = await Promise.allSettled(entry.children.map(async child => {
|
|
@@ -7875,81 +8172,23 @@
|
|
|
7875
8172
|
}
|
|
7876
8173
|
|
|
7877
8174
|
async function addChild(child) {
|
|
7878
|
-
const name
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
externalFileAttributes,
|
|
7884
|
-
versionMadeBy,
|
|
7885
|
-
comment,
|
|
7886
|
-
lastModDate,
|
|
7887
|
-
creationDate,
|
|
7888
|
-
lastAccessDate,
|
|
7889
|
-
uncompressedSize,
|
|
7890
|
-
encrypted,
|
|
7891
|
-
zipCrypto,
|
|
7892
|
-
crc32,
|
|
7893
|
-
compressionMethod,
|
|
7894
|
-
extraFieldAES,
|
|
7895
|
-
internalFileAttributes,
|
|
7896
|
-
extraField,
|
|
7897
|
-
uid,
|
|
7898
|
-
gid
|
|
7899
|
-
} = child.data;
|
|
7900
|
-
zipEntryOptions = {
|
|
7901
|
-
externalFileAttributes,
|
|
7902
|
-
versionMadeBy,
|
|
7903
|
-
comment,
|
|
7904
|
-
lastModDate,
|
|
7905
|
-
creationDate,
|
|
7906
|
-
lastAccessDate,
|
|
7907
|
-
internalFileAttributes
|
|
7908
|
-
};
|
|
7909
|
-
const userExtraField = getUserExtraField(extraField);
|
|
7910
|
-
if (userExtraField) {
|
|
7911
|
-
zipEntryOptions.extraField = userExtraField;
|
|
7912
|
-
}
|
|
7913
|
-
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
7914
|
-
Object.assign(zipEntryOptions, {
|
|
7915
|
-
uid,
|
|
7916
|
-
gid,
|
|
7917
|
-
unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
|
|
7918
|
-
});
|
|
7919
|
-
}
|
|
7920
|
-
if (child.passThrough) {
|
|
7921
|
-
let level, encryptionStrength;
|
|
7922
|
-
if (compressionMethod === 0) {
|
|
7923
|
-
level = 0;
|
|
7924
|
-
}
|
|
7925
|
-
if (extraFieldAES) {
|
|
7926
|
-
encryptionStrength = extraFieldAES.strength;
|
|
7927
|
-
}
|
|
7928
|
-
zipEntryOptions = Object.assign(zipEntryOptions, {
|
|
7929
|
-
passThrough: true,
|
|
7930
|
-
encrypted,
|
|
7931
|
-
zipCrypto,
|
|
7932
|
-
crc32,
|
|
7933
|
-
uncompressedSize,
|
|
7934
|
-
level,
|
|
7935
|
-
encryptionStrength,
|
|
7936
|
-
compressionMethod
|
|
7937
|
-
});
|
|
7938
|
-
}
|
|
7939
|
-
}
|
|
7940
|
-
await zipWriter.add(name, readers.get(child), Object.assign({}, options, zipEntryOptions, childOptions, {
|
|
7941
|
-
directory: child.directory,
|
|
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,
|
|
7942
8180
|
onprogress: async indexProgress => {
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
} catch {
|
|
7948
|
-
// ignored
|
|
7949
|
-
}
|
|
8181
|
+
writtenSize += indexProgress - entryWrittenSize;
|
|
8182
|
+
entryWrittenSize = indexProgress;
|
|
8183
|
+
if (onprogress) {
|
|
8184
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
7950
8185
|
}
|
|
7951
8186
|
}
|
|
7952
8187
|
}));
|
|
8188
|
+
writtenEntries++;
|
|
8189
|
+
if (onentryprogress) {
|
|
8190
|
+
await callHandler(onentryprogress, writtenEntries, totalEntries, entryMetadata);
|
|
8191
|
+
}
|
|
7953
8192
|
}
|
|
7954
8193
|
}
|
|
7955
8194
|
|
|
@@ -7977,7 +8216,7 @@
|
|
|
7977
8216
|
})
|
|
7978
8217
|
);
|
|
7979
8218
|
} else if (handle.kind == "directory") {
|
|
7980
|
-
const directoryEntry = parentEntry.addDirectory(handle.name);
|
|
8219
|
+
const directoryEntry = parentEntry.addDirectory(handle.name, options);
|
|
7981
8220
|
addedEntries.push(directoryEntry);
|
|
7982
8221
|
for await (const childHandle of handle.values()) {
|
|
7983
8222
|
await addFile(directoryEntry, childHandle, addedEntries, entryName);
|
|
@@ -7999,15 +8238,29 @@
|
|
|
7999
8238
|
}
|
|
8000
8239
|
|
|
8001
8240
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
8002
|
-
const
|
|
8003
|
-
const writtenSizes = new Map();
|
|
8241
|
+
const { onstart, onprogress, onend } = options;
|
|
8004
8242
|
const abortController = new AbortController();
|
|
8005
8243
|
const { signal } = abortController;
|
|
8006
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));
|
|
8007
8253
|
const exportedEntryNames = [];
|
|
8008
8254
|
let exportAborted = false;
|
|
8255
|
+
let writtenSize = 0;
|
|
8009
8256
|
try {
|
|
8257
|
+
if (onstart) {
|
|
8258
|
+
await callHandler(onstart, totalSize);
|
|
8259
|
+
}
|
|
8010
8260
|
await exportChildren(zipEntry, directoryHandle);
|
|
8261
|
+
if (onend) {
|
|
8262
|
+
await callHandler(onend, writtenSize);
|
|
8263
|
+
}
|
|
8011
8264
|
} catch (error) {
|
|
8012
8265
|
try {
|
|
8013
8266
|
error.exportedEntryNames = exportedEntryNames;
|
|
@@ -8020,6 +8273,25 @@
|
|
|
8020
8273
|
}
|
|
8021
8274
|
return directoryHandle;
|
|
8022
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
|
+
|
|
8023
8295
|
async function exportChildren(entry, parentHandle) {
|
|
8024
8296
|
if (options.concurrent) {
|
|
8025
8297
|
const results = await Promise.allSettled(entry.children.map(child => exportChild(child, parentHandle)));
|
|
@@ -8051,19 +8323,7 @@
|
|
|
8051
8323
|
const fileHandle = await parentHandle.getFileHandle(child.name, { create: true });
|
|
8052
8324
|
const writable = await fileHandle.createWritable();
|
|
8053
8325
|
try {
|
|
8054
|
-
await child.getData({ writable
|
|
8055
|
-
signal,
|
|
8056
|
-
onprogress: async progress => {
|
|
8057
|
-
if (options.onprogress) {
|
|
8058
|
-
writtenSizes.set(child.id, progress);
|
|
8059
|
-
try {
|
|
8060
|
-
await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
|
|
8061
|
-
} catch {
|
|
8062
|
-
// ignored
|
|
8063
|
-
}
|
|
8064
|
-
}
|
|
8065
|
-
}
|
|
8066
|
-
}));
|
|
8326
|
+
await child.getData({ writable: createProgressWritable(writable) }, getDataOptions);
|
|
8067
8327
|
} catch (error) {
|
|
8068
8328
|
throw exportAborted ? new Error(ERR_ABORT_EXPORT) : error;
|
|
8069
8329
|
}
|
|
@@ -8178,6 +8438,7 @@
|
|
|
8178
8438
|
|
|
8179
8439
|
exports.ERR_ABORTED = ERR_ABORTED;
|
|
8180
8440
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
8441
|
+
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8181
8442
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
8182
8443
|
exports.fs = fs;
|
|
8183
8444
|
|