@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.
@@ -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
- const options = {};
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, contentType ? { type: contentType } : {}));
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
- controller.enqueue(data);
400
- if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
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 executable = (fileEntry.unixMode !== UNDEFINED_VALUE)
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 = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES);
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 |= FILE_ATTR_UNIX_TYPE_DIR;
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 = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
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
- let password, rawPassword;
5660
- if (!passThrough) {
5661
- password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
5662
- rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
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
- const encryptedEntry = Boolean(reader) && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
5794
- if (!reader) {
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 (reader) {
5800
- reader = new GenericReader(reader);
5801
- await initStream(reader);
5851
+ if (hasContent) {
5802
5852
  if (!passThrough) {
5803
- if (reader.size === UNDEFINED_VALUE) {
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 = reader.size;
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
- reader,
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 === UNDEFINED_VALUE
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 uncompressedSize = zipEntry.data ? zipEntry.data.uncompressedSize : reader.size;
7154
- await Promise.all([initStream(reader), initStream(writer, uncompressedSize)]);
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.length
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
- await initStream(reader);
7419
- const zipReader = new ZipReader(reader, options);
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], "uncompressedSize"), options, readers);
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, propertyName) {
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[propertyName] || 0;
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
- zipBlobReader.size = zipBlobReader.entry.uncompressedSize;
7744
- const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign({}, options, zipBlobReader.options));
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 entryOffsets = new Map();
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 = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
7879
- const childOptions = child.options || {};
7880
- let zipEntryOptions = {};
7881
- if (child.data instanceof Entry) {
7882
- const {
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
- if (options.onprogress) {
7944
- entryOffsets.set(name, indexProgress);
7945
- try {
7946
- await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
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 totalSize = getTotalSize([zipEntry], "uncompressedSize");
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 }, Object.assign({}, options, {
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