@zip.js/zip.js 2.11.4 → 2.13.0

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.
Files changed (52) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +549 -139
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +559 -136
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +615 -260
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +628 -257
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +615 -260
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +630 -259
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +631 -260
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +561 -138
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +561 -138
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +562 -139
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +630 -259
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +631 -260
  27. package/index.d.cts +474 -59
  28. package/index.d.ts +474 -59
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-worker-web.js +72 -22
  31. package/lib/core/codec-worker.js +18 -5
  32. package/lib/core/configuration.js +20 -5
  33. package/lib/core/constants.js +2 -0
  34. package/lib/core/io.js +13 -5
  35. package/lib/core/options.js +16 -0
  36. package/lib/core/streams/codec-stream.js +6 -0
  37. package/lib/core/util/error.js +35 -0
  38. package/lib/core/util/warnings.js +42 -0
  39. package/lib/core/version.js +1 -1
  40. package/lib/core/web-worker-base.js +46 -9
  41. package/lib/core/web-worker-inline-native.js +1 -1
  42. package/lib/core/web-worker-inline-wasm.js +1 -1
  43. package/lib/core/zip-entry.js +49 -1
  44. package/lib/core/zip-fs.js +45 -133
  45. package/lib/core/zip-reader.js +115 -52
  46. package/lib/core/zip-writer.js +244 -57
  47. package/lib/zip-core-base.js +9 -3
  48. package/lib/zip-core-reader.js +2 -0
  49. package/lib/zip-core-writer.js +6 -1
  50. package/lib/zip-module-wasm-base.js +2 -2
  51. package/package.json +5 -3
  52. package/worker-message-property-names.js +1 -1
@@ -125,6 +125,7 @@ const NUMBER_TYPE = "number";
125
125
  const BOOLEAN_TYPE = "boolean";
126
126
 
127
127
  const EMPTY_UINT8_ARRAY = new Uint8Array();
128
+ const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
128
129
 
129
130
  /*
130
131
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -169,6 +170,7 @@ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
169
170
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
170
171
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
171
172
  const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
173
+ const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
172
174
  const OPTION_CHECK_SIGNATURE = "checkSignature";
173
175
  const OPTION_CHECK_CRC32 = "checkCrc32";
174
176
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -199,15 +201,18 @@ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
199
201
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
200
202
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
201
203
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
204
+ const OPTION_ENTRY = "entry";
202
205
  const TEXT_TYPE_FILENAME = "filename";
203
206
  const TEXT_TYPE_COMMENT = "comment";
204
207
  const STRICTNESS_STRICT = "strict";
205
208
  const STRICTNESS_BALANCED = "balanced";
206
209
  const STRICTNESS_TOLERANT = "tolerant";
210
+ const PASS_THROUGH_COMPRESSED = "compressed";
207
211
 
208
212
  const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
209
213
  const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
210
214
  const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
215
+ const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
211
216
  const ERR_ABORTED = "The operation was aborted";
212
217
  const ABORT_ERROR_NAME = "AbortError";
213
218
 
@@ -237,6 +242,13 @@ function checkPasswordOption(password, rawPassword) {
237
242
  }
238
243
  }
239
244
 
245
+ function checkPassThroughOption(passThrough) {
246
+ if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
247
+ throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
248
+ }
249
+ return passThrough;
250
+ }
251
+
240
252
  function checkInteger(value, maxValue, errorMessage) {
241
253
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
242
254
  throw new Error(errorMessage);
@@ -286,6 +298,8 @@ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
286
298
  const MINIMUM_CHUNK_SIZE = 64;
287
299
  const MINIMUM_PROPERTY_VALUE = 1;
288
300
  const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
301
+ const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
302
+ const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
289
303
  let maxWorkers = 2;
290
304
  try {
291
305
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -310,9 +324,9 @@ const DEFAULT_CONFIGURATION = {
310
324
  };
311
325
 
312
326
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
327
+ const PROPERTY_NAME_BASE_URI = "baseURI";
313
328
 
314
- const STRING_PROPERTY_NAMES = [
315
- "baseURI",
329
+ const URI_PROPERTY_NAMES = [
316
330
  "wasmURI",
317
331
  "workerURI"
318
332
  ];
@@ -336,7 +350,8 @@ const FUNCTION_PROPERTY_NAMES = [
336
350
  "DecompressionStreamFallback"
337
351
  ];
338
352
  const CONFIGURABLE_PROPERTY_NAMES = [
339
- ...STRING_PROPERTY_NAMES,
353
+ PROPERTY_NAME_BASE_URI,
354
+ ...URI_PROPERTY_NAMES,
340
355
  ...BOOLEAN_PROPERTY_NAMES,
341
356
  ...NUMBER_PROPERTY_NAMES,
342
357
  ...FUNCTION_PROPERTY_NAMES
@@ -380,6 +395,14 @@ function checkPropertyValue(propertyName, propertyValue) {
380
395
  }
381
396
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
382
397
  checkFunctionOption(propertyValue);
398
+ } else if (propertyName == PROPERTY_NAME_BASE_URI) {
399
+ if (propertyValue && typeof propertyValue != STRING_TYPE) {
400
+ throw new Error(ERR_INVALID_BASE_URI);
401
+ }
402
+ } else if (URI_PROPERTY_NAMES.includes(propertyName)) {
403
+ if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
404
+ throw new Error(ERR_INVALID_URI);
405
+ }
383
406
  }
384
407
  return propertyValue;
385
408
  }
@@ -493,6 +516,39 @@ function getDataView(array) {
493
516
  return new DataView(array.buffer, array.byteOffset, array.byteLength);
494
517
  }
495
518
 
519
+ /*
520
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
521
+
522
+ Redistribution and use in source and binary forms, with or without
523
+ modification, are permitted provided that the following conditions are met:
524
+
525
+ 1. Redistributions of source code must retain the above copyright notice,
526
+ this list of conditions and the following disclaimer.
527
+
528
+ 2. Redistributions in binary form must reproduce the above copyright
529
+ notice, this list of conditions and the following disclaimer in
530
+ the documentation and/or other materials provided with the distribution.
531
+
532
+ 3. The names of the authors may not be used to endorse or promote products
533
+ derived from this software without specific prior written permission.
534
+
535
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
536
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
537
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
538
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
539
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
540
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
541
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
542
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
543
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
544
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
545
+ */
546
+
547
+
548
+ function isErrorObject(error) {
549
+ return Boolean(error) && typeof error == "object";
550
+ }
551
+
496
552
  /*
497
553
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
498
554
 
@@ -2632,6 +2688,7 @@ class ChunkStream extends TransformStream {
2632
2688
  constructor(chunkSize) {
2633
2689
  const pendingChunks = [];
2634
2690
  let pendingLength = 0;
2691
+ let outputSize = 0;
2635
2692
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2636
2693
  chunkSize = DEFAULT_CHUNK_SIZE;
2637
2694
  }
@@ -2640,15 +2697,20 @@ class ChunkStream extends TransformStream {
2640
2697
  pendingChunks.push(chunk);
2641
2698
  pendingLength += chunk.length;
2642
2699
  while (pendingLength > chunkSize) {
2700
+ outputSize += chunkSize;
2643
2701
  controller.enqueue(shiftChunk());
2644
2702
  }
2645
2703
  },
2646
2704
  flush(controller) {
2647
2705
  if (pendingLength) {
2706
+ outputSize += pendingLength;
2648
2707
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2649
2708
  }
2650
2709
  }
2651
2710
  });
2711
+ Object.defineProperty(this, "outputSize", {
2712
+ get: () => outputSize
2713
+ });
2652
2714
 
2653
2715
  function shiftChunk() {
2654
2716
  const result = new Uint8Array(chunkSize);
@@ -2758,7 +2820,9 @@ function disableWebWorker(workerData) {
2758
2820
 
2759
2821
  class CodecWorker {
2760
2822
 
2761
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
2823
+ constructor(workerData, { readable, writable }, workerOptions, onTaskFinished) {
2824
+ const { options, config, streamOptions, useWebWorkers, transferStreams, workerURI } = workerOptions;
2825
+ let { createWorker } = workerOptions;
2762
2826
  const { signal } = streamOptions;
2763
2827
  if (createWorkerFailed) {
2764
2828
  createWorker = UNDEFINED_VALUE;
@@ -2771,6 +2835,7 @@ class CodecWorker {
2771
2835
  .pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
2772
2836
  writable,
2773
2837
  options: Object.assign({}, options),
2838
+ workerOptions,
2774
2839
  workerURI,
2775
2840
  createWorker,
2776
2841
  transferStreams,
@@ -2852,8 +2917,8 @@ function createWorkerInterface(workerData, config) {
2852
2917
  };
2853
2918
  }
2854
2919
 
2855
- async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2856
- let codecStream;
2920
+ async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
2921
+ let codecStream, chunkStream;
2857
2922
  try {
2858
2923
  if (options.compressed && !options.format) {
2859
2924
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2876,9 +2941,10 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2876
2941
  }
2877
2942
  }
2878
2943
  codecStream = new CodecStream(options, config);
2944
+ chunkStream = new ChunkStream(getChunkSize(config));
2879
2945
  await readable
2880
2946
  .pipeThrough(codecStream)
2881
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2947
+ .pipeThrough(chunkStream)
2882
2948
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2883
2949
  const {
2884
2950
  crc32,
@@ -2892,7 +2958,15 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2892
2958
  };
2893
2959
  } catch (error) {
2894
2960
  if (codecStream) {
2895
- error.outputSize = codecStream.outputSize;
2961
+ const outputSize = chunkStream ? chunkStream.outputSize : 0;
2962
+ workerOptions.outputSize = outputSize;
2963
+ if (isErrorObject(error)) {
2964
+ try {
2965
+ error.outputSize = outputSize;
2966
+ } catch {
2967
+ // ignored
2968
+ }
2969
+ }
2896
2970
  }
2897
2971
  throw error;
2898
2972
  } finally {
@@ -3001,11 +3075,23 @@ async function runWebWorker(workerData, config) {
3001
3075
  let resolveResult, rejectResult;
3002
3076
  const result = new Promise((resolve, reject) => {
3003
3077
  resolveResult = resolve;
3004
- rejectResult = reject;
3078
+ rejectResult = error => {
3079
+ const { outputSize, workerOptions } = workerData;
3080
+ workerOptions.outputSize = outputSize;
3081
+ if (isErrorObject(error) && error.outputSize === UNDEFINED_VALUE) {
3082
+ try {
3083
+ error.outputSize = outputSize;
3084
+ } catch {
3085
+ // ignored
3086
+ }
3087
+ }
3088
+ reject(error);
3089
+ };
3005
3090
  });
3006
3091
  Object.assign(workerData, {
3007
3092
  reader: null,
3008
3093
  writer: null,
3094
+ outputSize: 0,
3009
3095
  resolveResult,
3010
3096
  rejectResult,
3011
3097
  result
@@ -3266,21 +3352,15 @@ function sendMessage(message, { worker, writer, transferStreams, workerAlive })
3266
3352
  }
3267
3353
 
3268
3354
  async function onMessage({ data }, workerData) {
3269
- const { type, value, messageId, result, error } = data;
3355
+ const { type, value, messageId, result, error, errorValue } = data;
3270
3356
  const { reader, writer, resolveResult, rejectResult, onTaskFinished, generation } = workerData;
3271
3357
  const stale = () => workerData.generation != generation;
3272
3358
  try {
3273
3359
  if (error) {
3274
- const { message, stack, code, name, outputSize, cause, codecImportFailed } = error;
3275
- const responseError = new Error(message);
3276
- Object.assign(responseError, { stack, code, name, outputSize });
3277
- if (cause) {
3278
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3279
- }
3280
- if (codecImportFailed) {
3281
- responseError.codecImportFailed = true;
3360
+ if (error.outputSize !== UNDEFINED_VALUE) {
3361
+ workerData.outputSize = error.outputSize;
3282
3362
  }
3283
- close(responseError);
3363
+ fail(getResponseError(error, errorValue));
3284
3364
  } else {
3285
3365
  if (type == MESSAGE_PULL) {
3286
3366
  const { value, done } = await reader.read();
@@ -3289,39 +3369,82 @@ async function onMessage({ data }, workerData) {
3289
3369
  }
3290
3370
  }
3291
3371
  if (type == MESSAGE_DATA) {
3372
+ const chunk = new Uint8Array(value);
3292
3373
  await writer.ready;
3293
- await writer.write(new Uint8Array(value));
3374
+ await writer.write(chunk);
3375
+ workerData.outputSize += chunk.length;
3294
3376
  if (!stale()) {
3295
3377
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3296
3378
  }
3297
3379
  }
3298
3380
  if (type == MESSAGE_CLOSE) {
3299
- close(null, result);
3381
+ succeed(result);
3300
3382
  }
3301
3383
  }
3302
3384
  } catch (error) {
3303
3385
  if (!stale()) {
3304
3386
  terminateWorker$1(workerData);
3305
- close(error);
3387
+ fail(error);
3306
3388
  }
3307
3389
  }
3308
3390
 
3309
- function close(error, result) {
3310
- if (stale()) {
3311
- return;
3312
- }
3313
- if (error) {
3391
+ function fail(error) {
3392
+ if (!stale()) {
3314
3393
  rejectResult(error);
3315
- } else {
3394
+ releaseWriter();
3395
+ if (!(isErrorObject(error) && error.codecImportFailed)) {
3396
+ onTaskFinished();
3397
+ }
3398
+ }
3399
+ }
3400
+
3401
+ function succeed(result) {
3402
+ if (!stale()) {
3316
3403
  resolveResult(result);
3404
+ releaseWriter();
3405
+ onTaskFinished();
3317
3406
  }
3407
+ }
3408
+
3409
+ function releaseWriter() {
3318
3410
  if (writer) {
3319
3411
  writer.releaseLock();
3320
3412
  }
3321
- if (!(error && error.codecImportFailed)) {
3322
- onTaskFinished();
3413
+ }
3414
+ }
3415
+
3416
+ function getResponseError(errorData, errorValue) {
3417
+ const { message, stack, code, name, outputSize, cause, codecImportFailed } = errorData;
3418
+ let responseError;
3419
+ if (errorValue) {
3420
+ responseError = errorValue.value;
3421
+ } else {
3422
+ responseError = Object.assign(new Error(message), { stack, code, name });
3423
+ if (cause) {
3424
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3323
3425
  }
3324
3426
  }
3427
+ if (isErrorObject(responseError)) {
3428
+ try {
3429
+ if (outputSize !== UNDEFINED_VALUE) {
3430
+ responseError.outputSize = outputSize;
3431
+ }
3432
+ if (codecImportFailed) {
3433
+ responseError.codecImportFailed = true;
3434
+ }
3435
+ if (errorValue) {
3436
+ if (responseError.name !== name) {
3437
+ responseError.name = name;
3438
+ }
3439
+ if (responseError.code !== code) {
3440
+ responseError.code = code;
3441
+ }
3442
+ }
3443
+ } catch {
3444
+ // ignored
3445
+ }
3446
+ }
3447
+ return responseError;
3325
3448
  }
3326
3449
 
3327
3450
  /*
@@ -3598,10 +3721,13 @@ function decode(value, encoding, ignoreBOM) {
3598
3721
 
3599
3722
 
3600
3723
  const ERR_HTTP_STATUS = "HTTP error ";
3724
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3725
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3601
3726
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3602
3727
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3603
3728
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3604
3729
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3730
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3605
3731
 
3606
3732
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3607
3733
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3793,6 +3919,7 @@ class BlobReader extends Reader {
3793
3919
  const reader = this;
3794
3920
  const { sourceBlob, size } = reader;
3795
3921
  const { offset = 0, size: readSize = size - offset } = options || {};
3922
+ // deno-lint-ignore valid-typeof
3796
3923
  if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3797
3924
  if (!offset && readSize >= size) {
3798
3925
  return toCompatibleReadable(sourceBlob.stream());
@@ -4199,7 +4326,7 @@ async function getContentLength(httpReader, sendRequest, getRequestData) {
4199
4326
 
4200
4327
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4201
4328
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4202
- if (response.status < 400) {
4329
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4203
4330
  return response;
4204
4331
  } else {
4205
4332
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4210,7 +4337,7 @@ function sendXMLHttpRequest(method, { url }, headers) {
4210
4337
  return new Promise((resolve, reject) => {
4211
4338
  const request = new XMLHttpRequest();
4212
4339
  request.addEventListener("load", () => {
4213
- if (request.status < 400) {
4340
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4214
4341
  const headers = [];
4215
4342
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4216
4343
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4514,8 +4641,10 @@ class GenericWriter {
4514
4641
  writable: toCompatibleWritable(writer)
4515
4642
  };
4516
4643
  }
4517
- if (writer.size === UNDEFINED_VALUE) {
4518
- writer.size = 0;
4644
+ try {
4645
+ writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
4646
+ } catch {
4647
+ throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
4519
4648
  }
4520
4649
  return writer;
4521
4650
  }
@@ -4563,6 +4692,45 @@ function createReadable(reader, options) {
4563
4692
  }
4564
4693
  }
4565
4694
 
4695
+ /*
4696
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
4697
+
4698
+ Redistribution and use in source and binary forms, with or without
4699
+ modification, are permitted provided that the following conditions are met:
4700
+
4701
+ 1. Redistributions of source code must retain the above copyright notice,
4702
+ this list of conditions and the following disclaimer.
4703
+
4704
+ 2. Redistributions in binary form must reproduce the above copyright
4705
+ notice, this list of conditions and the following disclaimer in
4706
+ the documentation and/or other materials provided with the distribution.
4707
+
4708
+ 3. The names of the authors may not be used to endorse or promote products
4709
+ derived from this software without specific prior written permission.
4710
+
4711
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4712
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4713
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4714
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4715
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4716
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4717
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4718
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4719
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4720
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4721
+ */
4722
+
4723
+
4724
+ function addWarning(warnings, reason, filename) {
4725
+ if (!warnings.some(warning => warning.reason == reason)) {
4726
+ const warning = { reason };
4727
+ if (filename !== UNDEFINED_VALUE) {
4728
+ warning.filename = filename;
4729
+ }
4730
+ warnings.push(warning);
4731
+ }
4732
+ }
4733
+
4566
4734
  /*
4567
4735
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4568
4736
 
@@ -4591,6 +4759,7 @@ function createReadable(reader, options) {
4591
4759
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4592
4760
  */
4593
4761
 
4762
+
4594
4763
  const PROPERTY_NAME_FILENAME = "filename";
4595
4764
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4596
4765
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4715,6 +4884,38 @@ class Entry {
4715
4884
 
4716
4885
  }
4717
4886
 
4887
+ const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
4888
+ EXTRAFIELD_TYPE_ZIP64,
4889
+ EXTRAFIELD_TYPE_AES,
4890
+ EXTRAFIELD_TYPE_NTFS,
4891
+ EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
4892
+ EXTRAFIELD_TYPE_UNICODE_PATH,
4893
+ EXTRAFIELD_TYPE_UNICODE_COMMENT,
4894
+ EXTRAFIELD_TYPE_USDZ,
4895
+ EXTRAFIELD_TYPE_INFOZIP,
4896
+ EXTRAFIELD_TYPE_UNIX,
4897
+ EXTRAFIELD_TYPE_UNIX_TYPE1,
4898
+ EXTRAFIELD_TYPE_PKWARE_UNIX
4899
+ ]);
4900
+
4901
+ function getUserExtraField(extraField) {
4902
+ if (extraField) {
4903
+ const userExtraField = new Map();
4904
+ extraField.forEach((field, type) => {
4905
+ if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
4906
+ userExtraField.set(type, field.data);
4907
+ }
4908
+ });
4909
+ if (userExtraField.size) {
4910
+ return userExtraField;
4911
+ }
4912
+ }
4913
+ }
4914
+
4915
+ function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
4916
+ return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
4917
+ }
4918
+
4718
4919
  /*
4719
4920
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4720
4921
 
@@ -4774,6 +4975,8 @@ const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
4774
4975
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4775
4976
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4776
4977
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4978
+ const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
4979
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
4777
4980
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4778
4981
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4779
4982
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4844,7 +5047,7 @@ class ZipReader {
4844
5047
  }
4845
5048
  }
4846
5049
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4847
- throwAmbiguousArchive("multiple end of central directory records");
5050
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4848
5051
  }
4849
5052
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4850
5053
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5142,7 +5345,8 @@ class ZipReader {
5142
5345
  const writer = new TransformStream();
5143
5346
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5144
5347
  arrayBufferPromise.catch(() => { });
5145
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5348
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5349
+ Object.assign({}, options, { preventClose: false }));
5146
5350
  return arrayBufferPromise;
5147
5351
  };
5148
5352
  offset = endOffset;
@@ -5223,49 +5427,101 @@ class ZipReader {
5223
5427
  await reader.readable.cancel();
5224
5428
  }
5225
5429
  }
5430
+
5431
+ [SYMBOL_ASYNC_DISPOSE]() {
5432
+ return this.close();
5433
+ }
5226
5434
  }
5227
5435
 
5228
5436
  class ZipReaderStream {
5229
5437
 
5230
5438
  constructor(options = {}) {
5231
- const { readable, writable } = new TransformStream();
5232
- const gen = new ZipReader(readable, options).getEntriesGenerator();
5439
+ let sourceController;
5440
+ const { readable, writable } = new TransformStream({
5441
+ start(controller) {
5442
+ sourceController = controller;
5443
+ }
5444
+ });
5445
+ const zipReader = new ZipReader(readable, options);
5446
+ const gen = zipReader.getEntriesGenerator();
5447
+ const pendingEntries = new Set();
5233
5448
  this.readable = new ReadableStream({
5234
5449
  async pull(controller) {
5235
5450
  const { done, value } = await gen.next();
5236
5451
  if (done)
5237
5452
  return controller.close();
5238
- const entryReadable = (function () {
5239
- const { readable, writable } = new TransformStream();
5240
- if (value.getData) {
5241
- getData();
5242
- return readable;
5243
- }
5244
-
5245
- async function getData() {
5246
- try {
5247
- await value.getData(writable);
5248
- } catch (error) {
5249
- try {
5250
- await writable.abort(error);
5251
- } catch {
5252
- // ignored
5253
- }
5254
- }
5255
- }
5256
- })();
5453
+ const entryStream = createEntryStream(value, pendingEntries);
5257
5454
  const chunk = {
5258
5455
  ...value,
5259
- readable: entryReadable
5456
+ readable: entryStream.readable
5260
5457
  };
5261
5458
  delete chunk.getData;
5459
+ Object.defineProperties(chunk, {
5460
+ localDirectory: {
5461
+ get: () => value.localDirectory,
5462
+ enumerable: true
5463
+ },
5464
+ warnings: {
5465
+ get: () => value.warnings,
5466
+ enumerable: true
5467
+ }
5468
+ });
5262
5469
  controller.enqueue(chunk);
5470
+ },
5471
+ async cancel(reason) {
5472
+ const entryStreams = Array.from(pendingEntries);
5473
+ pendingEntries.clear();
5474
+ sourceController.error(reason);
5475
+ await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
5476
+ await Promise.allSettled([gen.return(), zipReader.close()]);
5263
5477
  }
5264
5478
  });
5265
5479
  this.writable = writable;
5266
5480
  }
5267
5481
  }
5268
5482
 
5483
+ function createEntryStream(entry, pendingEntries) {
5484
+ const { readable, writable } = new TransformStream();
5485
+ let dataReader;
5486
+ const entryStream = {
5487
+ cancel: async reason => {
5488
+ pendingEntries.delete(entryStream);
5489
+ await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
5490
+ }
5491
+ };
5492
+ entryStream.readable = new ReadableStream({
5493
+ async pull(controller) {
5494
+ if (!dataReader) {
5495
+ dataReader = readable.getReader();
5496
+ pendingEntries.add(entryStream);
5497
+ getData();
5498
+ }
5499
+ const { done, value } = await dataReader.read();
5500
+ if (done) {
5501
+ controller.close();
5502
+ } else {
5503
+ controller.enqueue(value);
5504
+ }
5505
+ },
5506
+ cancel: reason => entryStream.cancel(reason)
5507
+ }, { highWaterMark: 0 });
5508
+ return entryStream;
5509
+
5510
+ async function getData() {
5511
+ try {
5512
+ await entry.getData(writable, { preventClose: false });
5513
+ } catch (error) {
5514
+ try {
5515
+ await writable.abort(error);
5516
+ } catch {
5517
+ // ignored
5518
+ }
5519
+ } finally {
5520
+ pendingEntries.delete(entryStream);
5521
+ }
5522
+ }
5523
+ }
5524
+
5269
5525
  async function isZipFile(reader, options = {}) {
5270
5526
  reader = new GenericReader(reader);
5271
5527
  await initStream(reader);
@@ -5325,7 +5581,9 @@ let ZipEntry$1 = class ZipEntry {
5325
5581
  const dataView = getDataView(dataArray);
5326
5582
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5327
5583
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5328
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5584
+ const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
5585
+ const passThroughCompression = Boolean(passThrough);
5586
+ const passThroughEncryption = passThrough === true;
5329
5587
  checkPasswordOption(password, rawPassword);
5330
5588
  password = password && password.length && password;
5331
5589
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5346,7 +5604,9 @@ let ZipEntry$1 = class ZipEntry {
5346
5604
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5347
5605
  const entryStrictness = getStrictness(options, zipEntry.options);
5348
5606
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5349
- const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5607
+ const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
5608
+ const checkLocalFilename = getCheckLocalFilename(
5609
+ checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
5350
5610
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5351
5611
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5352
5612
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5377,16 +5637,17 @@ let ZipEntry$1 = class ZipEntry {
5377
5637
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5378
5638
  fileEntry.gid = gid;
5379
5639
  }
5380
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5640
+ const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5641
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5381
5642
  const zipCrypto = encrypted && !extraFieldAES;
5382
- if (!passThrough) {
5643
+ if (!passThroughEncryption) {
5383
5644
  fileEntry.zipCrypto = zipCrypto;
5384
5645
  }
5385
5646
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5386
5647
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5387
5648
  }
5388
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5389
- if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThrough) {
5649
+ const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5650
+ if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
5390
5651
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5391
5652
  }
5392
5653
  if (encrypted) {
@@ -5403,15 +5664,16 @@ let ZipEntry$1 = class ZipEntry {
5403
5664
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5404
5665
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5405
5666
  throwIfAborted(signal);
5406
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5407
5667
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5408
5668
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5409
5669
  if (checkOverlappingEntryOnly) {
5410
5670
  checkOverlappingEntry = true;
5411
5671
  }
5412
5672
  const { onstart, onprogress, onend } = options;
5413
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5414
- const outputSize = passThrough ? compressedSize : uncompressedSize;
5673
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
5674
+ const outputSize = passThroughCompression ?
5675
+ compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
5676
+ uncompressedSize;
5415
5677
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5416
5678
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5417
5679
  if (deflate64) {
@@ -5420,7 +5682,7 @@ let ZipEntry$1 = class ZipEntry {
5420
5682
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5421
5683
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5422
5684
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5423
- checkCrc32Option) && !passThrough &&
5685
+ checkCrc32Option) && !passThroughCompression &&
5424
5686
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5425
5687
  const workerOptions = {
5426
5688
  options: {
@@ -5464,7 +5726,7 @@ let ZipEntry$1 = class ZipEntry {
5464
5726
  readRanges
5465
5727
  });
5466
5728
  }
5467
- let writable, abortError;
5729
+ let writable, abortError, aborted;
5468
5730
  try {
5469
5731
  if (!checkOverlappingEntryOnly) {
5470
5732
  if (checkPasswordOnly) {
@@ -5474,24 +5736,28 @@ let ZipEntry$1 = class ZipEntry {
5474
5736
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5475
5737
  ({ writable } = writer);
5476
5738
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5477
- writer.size += writtenSize;
5478
5739
  if (writtenSize != outputSize) {
5479
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5740
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5480
5741
  }
5742
+ writer.size += writtenSize;
5481
5743
  }
5482
5744
  } catch (error) {
5483
- if (error.outputSize !== UNDEFINED_VALUE) {
5745
+ const { outputSize: failedOutputSize } = workerOptions;
5746
+ if (failedOutputSize !== UNDEFINED_VALUE) {
5747
+ writer.size += failedOutputSize;
5748
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
5484
5749
  writer.size += error.outputSize;
5485
5750
  }
5486
- if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
5751
+ if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
5487
5752
  abortError = error;
5753
+ aborted = true;
5488
5754
  throw error;
5489
5755
  }
5490
5756
  } finally {
5491
5757
  const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
5492
5758
  if (!preventClose && writable && !writable.locked) {
5493
5759
  const writableWriter = writable.getWriter();
5494
- if (abortError) {
5760
+ if (aborted) {
5495
5761
  try {
5496
5762
  await writableWriter.abort(abortError);
5497
5763
  } catch {
@@ -6143,7 +6409,7 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
6143
6409
  if (checkLocalFilename && !maskedLocalDirectory &&
6144
6410
  (rawLocalFilename.length != rawFilename.length ||
6145
6411
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6146
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6412
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6147
6413
  }
6148
6414
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6149
6415
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6168,16 +6434,6 @@ function reportAmbiguity(reject, warnings, reason) {
6168
6434
  }
6169
6435
  }
6170
6436
 
6171
- function addWarning(warnings, reason, filename) {
6172
- if (!warnings.some(warning => warning.reason == reason)) {
6173
- const warning = { reason };
6174
- if (filename !== UNDEFINED_VALUE) {
6175
- warning.filename = filename;
6176
- }
6177
- warnings.push(warning);
6178
- }
6179
- }
6180
-
6181
6437
  function throwAmbiguousArchive(reason) {
6182
6438
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6183
6439
  error.reason = reason;
@@ -6257,7 +6513,9 @@ var zipReader = /*#__PURE__*/Object.freeze({
6257
6513
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6258
6514
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6259
6515
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6516
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6260
6517
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6518
+ WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6261
6519
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6262
6520
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6263
6521
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6310,7 +6568,7 @@ const ERR_INVALID_VERSION = "Version exceeds 65535";
6310
6568
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6311
6569
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6312
6570
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6313
- const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6571
+ const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
6314
6572
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6315
6573
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6316
6574
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6322,6 +6580,7 @@ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
6322
6580
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6323
6581
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6324
6582
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6583
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6325
6584
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6326
6585
  const ERR_UNDEFINED_READER = "Undefined reader";
6327
6586
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6335,14 +6594,21 @@ const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be intege
6335
6594
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6336
6595
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6337
6596
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6597
+ const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
6598
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
6599
+ const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
6600
+ const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
6338
6601
 
6339
6602
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6340
6603
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6341
6604
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6342
6605
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6606
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6607
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6343
6608
  const VENDOR_VERSION_AE_1 = 1;
6344
- const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6609
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6345
6610
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6611
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6346
6612
  const MAX_LEVEL = 9;
6347
6613
 
6348
6614
  let workers = 0;
@@ -6369,9 +6635,11 @@ class ZipWriter {
6369
6635
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6370
6636
  pendingAddFileCalls: new Set(),
6371
6637
  pendingErrors: [],
6638
+ warnings: [],
6372
6639
  bufferedWrites: 0,
6373
6640
  directWrites: 0,
6374
- lastFileEntry: UNDEFINED_VALUE
6641
+ lastFileEntry: UNDEFINED_VALUE,
6642
+ archiveClosed: false
6375
6643
  });
6376
6644
  }
6377
6645
 
@@ -6536,6 +6804,9 @@ class ZipWriter {
6536
6804
  const zipWriter = this;
6537
6805
  const { pendingAddFileCalls, writer } = this;
6538
6806
  const { writable } = writer;
6807
+ if (zipWriter.archiveClosed) {
6808
+ return getWriterData(writer);
6809
+ }
6539
6810
  if (!(comment instanceof Uint8Array)) {
6540
6811
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6541
6812
  }
@@ -6546,7 +6817,7 @@ class ZipWriter {
6546
6817
  await Promise.allSettled(Array.from(pendingAddFileCalls));
6547
6818
  }
6548
6819
  await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
6549
- const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
6820
+ const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.failed && !watcher.observed);
6550
6821
  if (unobservedWatchers.length) {
6551
6822
  const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
6552
6823
  unobservedWatchers.forEach(watcher => watcher.observed = true);
@@ -6559,11 +6830,16 @@ class ZipWriter {
6559
6830
  throw error;
6560
6831
  }
6561
6832
  await closeFile(zipWriter, comment, options);
6833
+ zipWriter.archiveClosed = true;
6562
6834
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6563
6835
  if (!preventClose) {
6564
6836
  await writable.getWriter().close();
6565
6837
  }
6566
- return writer.getData ? writer.getData() : writable;
6838
+ return getWriterData(writer);
6839
+ }
6840
+
6841
+ [SYMBOL_ASYNC_DISPOSE]() {
6842
+ return this.close();
6567
6843
  }
6568
6844
  }
6569
6845
 
@@ -6642,11 +6918,16 @@ class WatchedPromise extends Promise {
6642
6918
  }
6643
6919
  }
6644
6920
 
6921
+ function getWriterData(writer) {
6922
+ return writer.getData ? writer.getData() : writer.writable;
6923
+ }
6924
+
6645
6925
  function watchPromiseError(zipWriter, promise) {
6646
6926
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6647
6927
  const watcher = {};
6648
6928
  watchedPromise.watcher = watcher;
6649
- watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
6929
+ watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
6930
+ error => Object.assign(watcher, { failed: true, error }));
6650
6931
  zipWriter.pendingErrors.push(watcher);
6651
6932
  return watchedPromise;
6652
6933
  }
@@ -6660,6 +6941,14 @@ async function prependZipEntries(zipWriter, reader) {
6660
6941
 
6661
6942
  async function addFileEntry(zipWriter, name, reader, options) {
6662
6943
  options = Object.assign({}, options);
6944
+ const entry = options[OPTION_ENTRY];
6945
+ if (entry !== UNDEFINED_VALUE) {
6946
+ const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
6947
+ checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
6948
+ getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
6949
+ delete options[OPTION_ENTRY];
6950
+ options = Object.assign(entryOptions, passThroughOptions, options);
6951
+ }
6663
6952
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6664
6953
  name += DIRECTORY_SIGNATURE;
6665
6954
  }
@@ -6724,21 +7013,33 @@ async function addFile(zipWriter, name, reader, options) {
6724
7013
  try {
6725
7014
  const { resolvedOptions } = metadataInfo;
6726
7015
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6727
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
7016
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6728
7017
  resolvedOptions.level = 0;
7018
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6729
7019
  }
6730
7020
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6731
7021
  ({ reader } = sizesInfo);
6732
7022
  const diskOffset = getDiskOffset(zipWriter.writer);
6733
7023
  const diskNumber = getDiskNumber(zipWriter.writer);
7024
+ let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
7025
+ const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
7026
+ if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
7027
+ crc32 = UNDEFINED_VALUE;
7028
+ }
7029
+ if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
7030
+ throw new Error(ERR_UNDEFINED_CRC32);
7031
+ }
6734
7032
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6735
7033
  signature: options[PROPERTY_NAME_SIGNATURE],
6736
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
7034
+ crc32,
6737
7035
  offset: zipWriter.offset - diskOffset,
6738
7036
  diskNumberStart: diskNumber,
6739
7037
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6740
7038
  });
6741
7039
  const headerInfo = getHeaderInfo(options);
7040
+ if (headerInfo.lastModDateClamped) {
7041
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
7042
+ }
6742
7043
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6743
7044
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6744
7045
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6765,6 +7066,95 @@ async function addFile(zipWriter, name, reader, options) {
6765
7066
  return new Entry(fileEntry);
6766
7067
  }
6767
7068
 
7069
+ function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
7070
+ if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
7071
+ throw new Error(ERR_INVALID_ENTRY);
7072
+ }
7073
+ const {
7074
+ externalFileAttributes,
7075
+ versionMadeBy,
7076
+ comment,
7077
+ lastModDate,
7078
+ rawLastModDate,
7079
+ creationDate,
7080
+ lastAccessDate,
7081
+ uncompressedSize,
7082
+ encrypted,
7083
+ zipCrypto,
7084
+ crc32,
7085
+ compressionMethod,
7086
+ extraFieldAES,
7087
+ extraFieldUnix,
7088
+ internalFileAttributes,
7089
+ extraField,
7090
+ bitFlag,
7091
+ directory,
7092
+ uid,
7093
+ gid
7094
+ } = entry;
7095
+ const entryOptions = {
7096
+ externalFileAttributes,
7097
+ versionMadeBy,
7098
+ comment,
7099
+ lastModDate,
7100
+ creationDate,
7101
+ lastAccessDate,
7102
+ internalFileAttributes,
7103
+ directory
7104
+ };
7105
+ if (bitFlag && bitFlag.languageEncodingFlag) {
7106
+ entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
7107
+ }
7108
+ const userExtraField = getUserExtraField(extraField);
7109
+ if (userExtraField) {
7110
+ entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
7111
+ }
7112
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
7113
+ Object.assign(entryOptions, {
7114
+ uid,
7115
+ gid,
7116
+ unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
7117
+ });
7118
+ }
7119
+ const passThroughOptions = {};
7120
+ if (passThrough && !directory) {
7121
+ Object.assign(passThroughOptions, {
7122
+ uncompressedSize,
7123
+ crc32,
7124
+ compressionMethod
7125
+ });
7126
+ if (passThrough !== PASS_THROUGH_COMPRESSED) {
7127
+ Object.assign(passThroughOptions, {
7128
+ encrypted,
7129
+ zipCrypto,
7130
+ encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
7131
+ });
7132
+ }
7133
+ if (bitFlag) {
7134
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
7135
+ passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
7136
+ }
7137
+ if (lastModDateOverride === UNDEFINED_VALUE) {
7138
+ passThroughOptions.rawLastModDate = rawLastModDate;
7139
+ } else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
7140
+ lastModDateOverride instanceof Date &&
7141
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
7142
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
7143
+ }
7144
+ }
7145
+ return { entryOptions, passThroughOptions };
7146
+ }
7147
+
7148
+ function getDosTimeHighByte(lastModDate) {
7149
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
7150
+ if (dosLastModDate < MIN_DATE) {
7151
+ dosLastModDate = MIN_DATE;
7152
+ } else if (dosLastModDate > MAX_DATE) {
7153
+ dosLastModDate = MAX_DATE;
7154
+ }
7155
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
7156
+ }
7157
+
6768
7158
  function resolveAttributes(zipWriter, name, options) {
6769
7159
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6770
7160
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6779,7 +7169,7 @@ function resolveAttributes(zipWriter, name, options) {
6779
7169
  checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6780
7170
  checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6781
7171
  checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6782
- if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
7172
+ if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6783
7173
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6784
7174
  }
6785
7175
  if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
@@ -6787,7 +7177,7 @@ function resolveAttributes(zipWriter, name, options) {
6787
7177
  throw new Error(ERR_INVALID_UNIX_ID_SIZE);
6788
7178
  }
6789
7179
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6790
- unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
7180
+ unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
6791
7181
  }
6792
7182
  let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6793
7183
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
@@ -6918,7 +7308,9 @@ function resolveMetadata(zipWriter, name, options) {
6918
7308
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6919
7309
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6920
7310
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6921
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
7311
+ const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7312
+ const passThroughCompression = Boolean(passThrough);
7313
+ const passThroughEncryption = passThrough === true;
6922
7314
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6923
7315
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6924
7316
  checkPasswordOption(password, rawPassword);
@@ -6934,10 +7326,11 @@ function resolveMetadata(zipWriter, name, options) {
6934
7326
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6935
7327
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6936
7328
  throwIfAborted(signal);
6937
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7329
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7330
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6938
7331
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6939
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6940
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7332
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7333
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6941
7334
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6942
7335
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6943
7336
  }
@@ -6951,15 +7344,15 @@ function resolveMetadata(zipWriter, name, options) {
6951
7344
  level = 0;
6952
7345
  }
6953
7346
  }
6954
- if (passThrough) {
6955
- level = UNDEFINED_VALUE;
7347
+ if (passThroughCompression) {
7348
+ level = toNumber(options[OPTION_LEVEL]);
6956
7349
  }
6957
7350
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6958
7351
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6959
7352
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6960
7353
  dataDescriptor = false;
6961
7354
  }
6962
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7355
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6963
7356
  dataDescriptor = true;
6964
7357
  }
6965
7358
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6983,7 +7376,8 @@ function resolveMetadata(zipWriter, name, options) {
6983
7376
  lastAccessDate,
6984
7377
  creationDate,
6985
7378
  internalFileAttributes,
6986
- passThrough,
7379
+ passThroughCompression,
7380
+ passThroughEncryption,
6987
7381
  password,
6988
7382
  rawPassword,
6989
7383
  encryptionStrength,
@@ -7044,7 +7438,7 @@ function serializeExtraField(extraField) {
7044
7438
  }
7045
7439
 
7046
7440
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
7047
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7441
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7048
7442
  throw new Error(ERR_UNDEFINED_READER);
7049
7443
  }
7050
7444
  let contentSize;
@@ -7060,12 +7454,12 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
7060
7454
  }
7061
7455
 
7062
7456
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7063
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7457
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7064
7458
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7065
7459
  let maximumCompressedSize = 0;
7066
7460
  let uncompressedSize = 0;
7067
7461
  let unknownSize = false;
7068
- if (passThrough && hasContent) {
7462
+ if (passThroughCompression && hasContent) {
7069
7463
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7070
7464
  if (uncompressedSize === UNDEFINED_VALUE) {
7071
7465
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7076,17 +7470,17 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7076
7470
  }
7077
7471
  const zip64Enabled = zip64 === true;
7078
7472
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7079
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7473
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7080
7474
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7081
7475
  }
7082
- const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
7476
+ const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
7083
7477
  if (!hasContent) {
7084
7478
  level = 0;
7085
7479
  compressionMethod = COMPRESSION_METHOD_STORE;
7086
7480
  }
7087
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7481
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7088
7482
  if (hasContent) {
7089
- if (!passThrough) {
7483
+ if (!passThroughCompression) {
7090
7484
  if (contentSize === UNDEFINED_VALUE) {
7091
7485
  dataDescriptor = true;
7092
7486
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7099,10 +7493,12 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7099
7493
  }
7100
7494
  } else {
7101
7495
  options.uncompressedSize = uncompressedSize;
7102
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7496
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7497
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7498
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7103
7499
  }
7104
7500
  }
7105
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7501
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7106
7502
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7107
7503
  dataDescriptor = false;
7108
7504
  }
@@ -7151,6 +7547,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7151
7547
  const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
7152
7548
  let offset = initialOffset;
7153
7549
  let minimumEntrySize = INFINITY_VALUE;
7550
+ const entrySizes = [];
7551
+ const entriesAlreadyZip64 = new Set();
7154
7552
  for (const entry of entries) {
7155
7553
  let { name } = entry;
7156
7554
  const { size } = entry;
@@ -7162,7 +7560,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7162
7560
  ({ name } = attributesInfo);
7163
7561
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
7164
7562
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
7165
- !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
7563
+ !metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
7166
7564
  metadata.level = 0;
7167
7565
  }
7168
7566
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -7170,7 +7568,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7170
7568
  throw new Error(ERR_UNDETERMINED_SIZE);
7171
7569
  }
7172
7570
  const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
7173
- if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
7571
+ if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
7174
7572
  throw new Error(ERR_UNDETERMINED_SIZE);
7175
7573
  }
7176
7574
  const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
@@ -7190,10 +7588,15 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7190
7588
  compressedSize
7191
7589
  }));
7192
7590
  const entrySize = entryInfo.metadataSize + compressedSize;
7591
+ entrySizes.push(entrySize);
7592
+ entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
7593
+ entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
7193
7594
  minimumEntrySize = Math.min(minimumEntrySize, entrySize);
7194
7595
  offset += entrySize;
7195
7596
  }
7196
- const layoutDependsOnWriteOrder = files.size > 1 && (usdz || offset - minimumEntrySize >= MAX_32_BITS);
7597
+ const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
7598
+ (offset - minimumEntrySize >= MAX_32_BITS &&
7599
+ (entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
7197
7600
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
7198
7601
  throw new Error(ERR_UNDETERMINED_SIZE);
7199
7602
  }
@@ -7211,6 +7614,20 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7211
7614
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7212
7615
  }
7213
7616
 
7617
+ function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
7618
+ const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
7619
+ let position = initialOffset;
7620
+ let count = 0;
7621
+ for (const entrySize of ordered) {
7622
+ if (position >= MAX_32_BITS) {
7623
+ break;
7624
+ }
7625
+ position += entrySize;
7626
+ count++;
7627
+ }
7628
+ return count;
7629
+ }
7630
+
7214
7631
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7215
7632
  const {
7216
7633
  fileEntries,
@@ -7386,6 +7803,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7386
7803
  localExtraFieldZip64Length,
7387
7804
  rawExtraFieldExtendedTimestamp,
7388
7805
  extraFieldExtendedTimestampFlag,
7806
+ extraFieldExtendedTimestampTime,
7389
7807
  rawExtraFieldNTFS,
7390
7808
  rawExtraFieldUnix,
7391
7809
  rawExtraFieldAES,
@@ -7398,6 +7816,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7398
7816
  password,
7399
7817
  rawPassword,
7400
7818
  level,
7819
+ useUnicodeFileNames,
7401
7820
  zip64,
7402
7821
  zip64Enabled,
7403
7822
  zip64UncompressedSize,
@@ -7432,7 +7851,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7432
7851
  msdosAttributesRaw,
7433
7852
  msdosAttributes,
7434
7853
  useCompressionStream,
7435
- passThrough,
7854
+ passThroughCompression,
7855
+ passThroughEncryption,
7436
7856
  format,
7437
7857
  codecURI
7438
7858
  } = options;
@@ -7443,9 +7863,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7443
7863
  zip64Enabled,
7444
7864
  directory: Boolean(directory),
7445
7865
  executable: Boolean(executable),
7446
- filenameUTF8: true,
7866
+ filenameUTF8: Boolean(useUnicodeFileNames),
7447
7867
  rawFilename,
7448
- commentUTF8: true,
7868
+ commentUTF8: Boolean(useUnicodeFileNames),
7449
7869
  rawComment,
7450
7870
  rawExtraFieldZip64,
7451
7871
  localExtraFieldZip64Length,
@@ -7476,7 +7896,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7476
7896
  uncompressedSize
7477
7897
  } = options;
7478
7898
  let compressedSize = 0;
7479
- if (!passThrough) {
7899
+ if (!passThroughCompression) {
7480
7900
  uncompressedSize = 0;
7481
7901
  }
7482
7902
  const { writable } = writer;
@@ -7493,9 +7913,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7493
7913
  encryptionStrength,
7494
7914
  zipCrypto: encrypted && zipCrypto,
7495
7915
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7496
- computeCrc32: !passThrough,
7497
- compressed: compressed && !passThrough,
7498
- encrypted: encrypted && !passThrough,
7916
+ computeCrc32: !passThroughCompression,
7917
+ compressed: compressed && !passThroughCompression,
7918
+ encrypted: encrypted && !passThroughEncryption,
7499
7919
  useWebWorkers,
7500
7920
  useCompressionStream,
7501
7921
  transferStreams,
@@ -7510,7 +7930,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7510
7930
  const result = await runWorker({ readable, writable }, workerOptions);
7511
7931
  compressedSize = result.outputSize;
7512
7932
  writer.size += compressedSize;
7513
- if (!passThrough) {
7933
+ if (!passThroughCompression) {
7514
7934
  uncompressedSize = result.inputSize;
7515
7935
  if (!encrypted || zipCrypto) {
7516
7936
  crc32 = result.crc32;
@@ -7521,7 +7941,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7521
7941
  throw new Error(ERR_UNSUPPORTED_FORMAT);
7522
7942
  }
7523
7943
  } catch (error) {
7524
- if (error.outputSize !== UNDEFINED_VALUE) {
7944
+ const { outputSize: failedOutputSize } = workerOptions;
7945
+ if (failedOutputSize !== UNDEFINED_VALUE) {
7946
+ writer.size += failedOutputSize;
7947
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
7525
7948
  writer.size += error.outputSize;
7526
7949
  }
7527
7950
  throw error;
@@ -7553,8 +7976,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7553
7976
  headerArray,
7554
7977
  headerView,
7555
7978
  signature: crc32,
7556
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7979
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7557
7980
  extraFieldExtendedTimestampFlag,
7981
+ extraFieldExtendedTimestampTime,
7558
7982
  zip64UncompressedSize,
7559
7983
  zip64CompressedSize
7560
7984
  });
@@ -7579,7 +8003,7 @@ function getHeaderInfo(options) {
7579
8003
  encryptionStrength,
7580
8004
  extendedTimestamp,
7581
8005
  ntfsTimestamp,
7582
- passThrough,
8006
+ passThroughCompression,
7583
8007
  encrypted,
7584
8008
  zip64UncompressedSize,
7585
8009
  zip64CompressedSize,
@@ -7590,7 +8014,7 @@ function getHeaderInfo(options) {
7590
8014
  let { version, compressionMethod } = options;
7591
8015
  const compressed = !directory && isCompressed(compressionMethod, level);
7592
8016
  let rawLocalExtraFieldZip64;
7593
- const uncompressedFile = passThrough || !compressed;
8017
+ const uncompressedFile = passThroughCompression || !compressed;
7594
8018
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7595
8019
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7596
8020
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7602,8 +8026,8 @@ function getHeaderInfo(options) {
7602
8026
  if (zip64ExtraFieldComplete) {
7603
8027
  extraFieldZip64.writeUint64(uncompressedSize);
7604
8028
  if (uncompressedFile) {
7605
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7606
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
8029
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
8030
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7607
8031
  }
7608
8032
  }
7609
8033
  } else {
@@ -7622,6 +8046,7 @@ function getHeaderInfo(options) {
7622
8046
  let rawExtraFieldNTFS;
7623
8047
  let rawExtraFieldExtendedTimestamp;
7624
8048
  let extraFieldExtendedTimestampFlag;
8049
+ let extraFieldExtendedTimestampTime;
7625
8050
  if (extendedTimestamp) {
7626
8051
  const lastModTimeUnix = getTimeUnix(lastModDate);
7627
8052
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7629,6 +8054,7 @@ function getHeaderInfo(options) {
7629
8054
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7630
8055
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7631
8056
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
8057
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7632
8058
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7633
8059
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7634
8060
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7671,7 +8097,7 @@ function getHeaderInfo(options) {
7671
8097
  let rawExtraFieldUnix;
7672
8098
  try {
7673
8099
  const { uid, gid, unixExtraFieldType } = options;
7674
- if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
8100
+ if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7675
8101
  const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7676
8102
  const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7677
8103
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
@@ -7712,7 +8138,7 @@ function getHeaderInfo(options) {
7712
8138
  }
7713
8139
  if (encrypted && !zipCrypto) {
7714
8140
  version = version > VERSION_AES ? version : VERSION_AES;
7715
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
8141
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7716
8142
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7717
8143
  }
7718
8144
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7774,12 +8200,14 @@ function getHeaderInfo(options) {
7774
8200
  headerArray,
7775
8201
  headerView,
7776
8202
  lastModDate: storedLastModDate,
8203
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7777
8204
  rawLastModDate,
7778
8205
  encrypted,
7779
8206
  compressed,
7780
8207
  version,
7781
8208
  compressionMethod,
7782
8209
  extraFieldExtendedTimestampFlag,
8210
+ extraFieldExtendedTimestampTime,
7783
8211
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7784
8212
  localExtraFieldZip64Length,
7785
8213
  rawExtraFieldExtendedTimestamp,
@@ -7882,7 +8310,7 @@ function setEntryInfo({
7882
8310
  }, {
7883
8311
  zip64,
7884
8312
  zipCrypto,
7885
- passThrough,
8313
+ passThroughCompression,
7886
8314
  dataDescriptor
7887
8315
  }) {
7888
8316
  const {
@@ -7893,7 +8321,7 @@ function setEntryInfo({
7893
8321
  dataDescriptorView,
7894
8322
  dataDescriptorOffset
7895
8323
  } = dataDescriptorInfo;
7896
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8324
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7897
8325
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7898
8326
  if (dataDescriptor) {
7899
8327
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7924,9 +8352,9 @@ function updateLocalHeader({
7924
8352
  uncompressedSize,
7925
8353
  zip64UncompressedSize,
7926
8354
  zip64CompressedSize
7927
- }, localHeaderView, { dataDescriptor, passThrough }) {
8355
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7928
8356
  if (!dataDescriptor) {
7929
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8357
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7930
8358
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7931
8359
  }
7932
8360
  if (!zip64CompressedSize) {
@@ -7963,9 +8391,8 @@ function createDirectoryRecords(files) {
7963
8391
  rawExtraFieldUnix,
7964
8392
  rawExtraField,
7965
8393
  rawCentralExtraField,
7966
- extendedTimestamp,
7967
8394
  extraFieldExtendedTimestampFlag,
7968
- lastModDate,
8395
+ extraFieldExtendedTimestampTime,
7969
8396
  zip64Enabled,
7970
8397
  uncompressedSize,
7971
8398
  compressedSize
@@ -8008,16 +8435,15 @@ function createDirectoryRecords(files) {
8008
8435
  fileEntry.zip64Offset = zip64Offset;
8009
8436
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
8010
8437
  let rawExtraFieldTimestamp;
8011
- const lastModTimeUnix = getTimeUnix(lastModDate);
8012
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8438
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8439
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8440
+ } else {
8013
8441
  const extraFieldTimestamp = createRecordWriter(9);
8014
8442
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
8015
8443
  extraFieldTimestamp.writeUint16(5);
8016
8444
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
8017
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8445
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
8018
8446
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
8019
- } else {
8020
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8021
8447
  }
8022
8448
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
8023
8449
  const extraFieldLength = getLength(
@@ -8517,6 +8943,11 @@ function getHeaderArrayData({
8517
8943
  };
8518
8944
  }
8519
8945
 
8946
+ function isPrintableASCIIText(rawText) {
8947
+ return rawText.every(characterCode =>
8948
+ characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
8949
+ }
8950
+
8520
8951
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8521
8952
  let bitFlag = 0;
8522
8953
  if (useUnicodeFileNames) {
@@ -8678,7 +9109,7 @@ function formatSupported(StreamClass, format) {
8678
9109
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8679
9110
  */
8680
9111
 
8681
- const VERSION = "2.11.4";
9112
+ const VERSION = "2.13.0";
8682
9113
 
8683
9114
  /*
8684
9115
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9498,9 +9929,9 @@ setDefaultConfiguration({
9498
9929
  DecompressionStreamFallback: DecompressionStreamZlib
9499
9930
  });
9500
9931
 
9501
- function terminateWorkersAndModule() {
9932
+ async function terminateWorkersAndModule() {
9933
+ await terminateWorkers();
9502
9934
  modulePromise = null;
9503
- terminateWorkers();
9504
9935
  resetWasmModule();
9505
9936
  }
9506
9937
 
@@ -9541,7 +9972,10 @@ configureExternalAssets();
9541
9972
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
9542
9973
  const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
9543
9974
  const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
9544
- const ERR_ANCESTOR_ENTRY = "Entry is a ancestor of target entry";
9975
+ const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
9976
+ const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
9977
+ const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
9978
+ const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
9545
9979
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
9546
9980
  const DUPLICATES_THROW = "throw";
9547
9981
  const DUPLICATES_KEEP_FIRST = "keep-first";
@@ -9549,22 +9983,8 @@ const DUPLICATES_KEEP_LAST = "keep-last";
9549
9983
  const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
9550
9984
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9551
9985
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9552
- const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
9986
+ const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
9553
9987
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
9554
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
9555
- const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
9556
- EXTRAFIELD_TYPE_ZIP64,
9557
- EXTRAFIELD_TYPE_AES,
9558
- EXTRAFIELD_TYPE_NTFS,
9559
- EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
9560
- EXTRAFIELD_TYPE_UNICODE_PATH,
9561
- EXTRAFIELD_TYPE_UNICODE_COMMENT,
9562
- EXTRAFIELD_TYPE_USDZ,
9563
- EXTRAFIELD_TYPE_INFOZIP,
9564
- EXTRAFIELD_TYPE_UNIX,
9565
- EXTRAFIELD_TYPE_UNIX_TYPE1,
9566
- EXTRAFIELD_TYPE_PKWARE_UNIX
9567
- ]);
9568
9988
 
9569
9989
  class ZipEntry {
9570
9990
 
@@ -9696,7 +10116,7 @@ class ZipFileEntry extends ZipEntry {
9696
10116
  }));
9697
10117
  return true;
9698
10118
  } catch (error) {
9699
- if (error.message == ERR_INVALID_PASSWORD) {
10119
+ if (isErrorObject(error) && error.message == ERR_INVALID_PASSWORD) {
9700
10120
  return false;
9701
10121
  } else {
9702
10122
  throw error;
@@ -9936,6 +10356,7 @@ class ZipDirectoryEntry extends ZipEntry {
9936
10356
  await initStream(reader);
9937
10357
  zipReader = new ZipReader(reader, options);
9938
10358
  }
10359
+ checkPassThroughValue(options.passThrough);
9939
10360
  const duplicates = checkDuplicatesOption(options.duplicates);
9940
10361
  const importedEntries = [];
9941
10362
  const entries = await zipReader.getEntries(options);
@@ -10026,18 +10447,25 @@ class ZipDirectoryEntry extends ZipEntry {
10026
10447
 
10027
10448
  async exportZip(writer, options = {}) {
10028
10449
  const zipEntry = this;
10450
+ const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
10029
10451
  options = Object.assign({}, options);
10030
- if (options.bufferedWrite === UNDEFINED_VALUE) {
10452
+ if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
10031
10453
  options.bufferedWrite = true;
10032
10454
  }
10033
- const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
10034
- const zipWriter = new ZipWriter(writer, options);
10455
+ const [readers] = await Promise.all([
10456
+ initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
10457
+ zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
10458
+ ]);
10459
+ const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
10035
10460
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
10461
+ if (zipWriterProvided) {
10462
+ return zipWriter;
10463
+ }
10036
10464
  await zipWriter.close(options.globalComment);
10037
10465
  return writer.getData ? writer.getData() : writer.writable;
10038
10466
  }
10039
10467
 
10040
- getExportedSize(options = {}) {
10468
+ async getExportedSize(options = {}) {
10041
10469
  const zipEntry = this;
10042
10470
  options = Object.assign({}, options);
10043
10471
  checkReaderOptions(options.readerOptions);
@@ -10052,7 +10480,7 @@ class ZipDirectoryEntry extends ZipEntry {
10052
10480
  const writeOrderGuaranteed = !options.bufferedWrite ||
10053
10481
  (entries.every(entry => entry.options.keepOrder !== false) &&
10054
10482
  children.every(child => isImplicitDirectory(child) || !child.children.length));
10055
- return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10483
+ return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10056
10484
  }
10057
10485
 
10058
10486
  getChildByName(name) {
@@ -10113,7 +10541,7 @@ class ZipFS {
10113
10541
 
10114
10542
  move(entry, destination) {
10115
10543
  if (entry == this.root) {
10116
- throw new Error("Root directory cannot be moved");
10544
+ throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
10117
10545
  } else {
10118
10546
  if (destination.directory) {
10119
10547
  if (!destination.isDescendantOf(entry)) {
@@ -10134,7 +10562,7 @@ class ZipFS {
10134
10562
  throw new Error(ERR_ANCESTOR_ENTRY);
10135
10563
  }
10136
10564
  } else {
10137
- throw new Error("Target entry is not a directory");
10565
+ throw new Error(ERR_TARGET_NOT_DIRECTORY);
10138
10566
  }
10139
10567
  }
10140
10568
  }
@@ -10447,70 +10875,11 @@ function getChildEntryOptions(child, selectedEntry, options) {
10447
10875
  let zipEntryMetadata = {};
10448
10876
  let passThroughOptions = {};
10449
10877
  if (child.data instanceof Entry) {
10450
- const {
10451
- externalFileAttributes,
10452
- versionMadeBy,
10453
- comment,
10454
- lastModDate,
10455
- rawLastModDate,
10456
- creationDate,
10457
- lastAccessDate,
10458
- uncompressedSize,
10459
- encrypted,
10460
- zipCrypto,
10461
- crc32,
10462
- compressionMethod,
10463
- extraFieldAES,
10464
- internalFileAttributes,
10465
- extraField,
10466
- bitFlag,
10467
- uid,
10468
- gid
10469
- } = child.data;
10470
- zipEntryMetadata = {
10471
- externalFileAttributes,
10472
- versionMadeBy,
10473
- comment,
10474
- lastModDate,
10475
- creationDate,
10476
- lastAccessDate,
10477
- internalFileAttributes
10478
- };
10479
- const userExtraField = getUserExtraField(extraField);
10480
- if (userExtraField) {
10481
- zipEntryMetadata.extraField = userExtraField;
10482
- }
10483
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
10484
- Object.assign(zipEntryMetadata, {
10485
- uid,
10486
- gid,
10487
- unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
10488
- });
10489
- }
10490
- if (isPassThrough(child, options)) {
10491
- let encryptionStrength;
10492
- if (extraFieldAES) {
10493
- encryptionStrength = extraFieldAES.strength;
10494
- }
10495
- passThroughOptions = {
10496
- passThrough: true,
10497
- encrypted,
10498
- zipCrypto,
10499
- crc32,
10500
- uncompressedSize,
10501
- encryptionStrength,
10502
- compressionMethod
10503
- };
10504
- if (bitFlag) {
10505
- passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
10506
- }
10507
- const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10508
- if (lastModDateOverride === UNDEFINED_VALUE) {
10509
- passThroughOptions.rawLastModDate = rawLastModDate;
10510
- } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
10511
- getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
10512
- throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
10513
- }
10878
+ const passThrough = isPassThrough(child, options);
10879
+ const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10880
+ ({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
10881
+ if (passThrough) {
10882
+ passThroughOptions.passThrough = true;
10514
10883
  }
10515
10884
  }
10516
10885
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -10520,16 +10889,6 @@ function getChildEntryOptions(child, selectedEntry, options) {
10520
10889
  return { name, entryOptions };
10521
10890
  }
10522
10891
 
10523
- function getDosTimeHighByte(lastModDate) {
10524
- let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
10525
- if (dosLastModDate < MIN_DATE) {
10526
- dosLastModDate = MIN_DATE;
10527
- } else if (dosLastModDate > MAX_DATE) {
10528
- dosLastModDate = MAX_DATE;
10529
- }
10530
- return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
10531
- }
10532
-
10533
10892
  function getDeterminedSize(child, passThrough) {
10534
10893
  const { reader } = child;
10535
10894
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10542,9 +10901,18 @@ function checkReaderOptions(readerOptions) {
10542
10901
  if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10543
10902
  throw new Error(ERR_INVALID_READER_OPTIONS);
10544
10903
  }
10904
+ if (readerOptions) {
10905
+ checkPassThroughValue(readerOptions.passThrough);
10906
+ }
10545
10907
  return readerOptions;
10546
10908
  }
10547
10909
 
10910
+ function checkPassThroughValue(passThrough) {
10911
+ if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
10912
+ throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
10913
+ }
10914
+ }
10915
+
10548
10916
  function replaceContent(zipEntry, params) {
10549
10917
  const { uncompressedSize } = params;
10550
10918
  Object.assign(zipEntry, params, {
@@ -10573,20 +10941,6 @@ function isImplicitDirectory(child) {
10573
10941
  return child.directory && child.data === null;
10574
10942
  }
10575
10943
 
10576
- function getUserExtraField(extraField) {
10577
- if (extraField) {
10578
- const userExtraField = new Map();
10579
- extraField.forEach((field, type) => {
10580
- if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
10581
- userExtraField.set(type, field.data);
10582
- }
10583
- });
10584
- if (userExtraField.size) {
10585
- return userExtraField;
10586
- }
10587
- }
10588
- }
10589
-
10590
10944
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
10591
10945
  const { onstart, onprogress, onend, onentryprogress } = options;
10592
10946
  const selectedEntry = entry;
@@ -10689,6 +11043,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
10689
11043
 
10690
11044
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10691
11045
  const { onstart, onprogress, onend } = options;
11046
+ checkPassThroughValue(options.passThrough);
10692
11047
  const readerOptions = checkReaderOptions(options.readerOptions);
10693
11048
  const abortController = new AbortController();
10694
11049
  const { signal } = abortController;
@@ -10764,7 +11119,7 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10764
11119
  if (exportAborted || isExportAborted(signal.reason)) {
10765
11120
  return;
10766
11121
  }
10767
- throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
11122
+ throwIfAborted(signal);
10768
11123
  }
10769
11124
  try {
10770
11125
  if (child.directory) {
@@ -10897,7 +11252,7 @@ function addChild(parent, name, params, directory) {
10897
11252
  }
10898
11253
  return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
10899
11254
  } else {
10900
- throw new Error("Parent entry is not a directory");
11255
+ throw new Error(ERR_PARENT_NOT_DIRECTORY);
10901
11256
  }
10902
11257
  }
10903
11258
 
@@ -10938,4 +11293,4 @@ function getPathParent(parent, path, movedEntry) {
10938
11293
  return parent;
10939
11294
  }
10940
11295
 
10941
- export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_DUPLICATE_IMPORTED_ENTRY, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_DUPLICATES, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_READER, ERR_INVALID_READER_OPTIONS, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_COMPRESSED_PATCHED_DATA, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipDirectoryEntry, ZipEntry, ZipFS, ZipFileEntry, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };
11296
+ export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_ANCESTOR_ENTRY, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_DUPLICATE_IMPORTED_ENTRY, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_DUPLICATES, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_READER_OPTIONS, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_PARENT_NOT_DIRECTORY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_ROOT_DIRECTORY_NOT_MOVABLE, ERR_SPLIT_ZIP_FILE, ERR_TARGET_NOT_DIRECTORY, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_PASS_THROUGH_VALUE, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipDirectoryEntry, ZipEntry, ZipFS, ZipFileEntry, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };