@zip.js/zip.js 2.11.4 → 2.12.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 (50) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +427 -110
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +437 -107
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +492 -230
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +505 -227
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +492 -230
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +507 -229
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +508 -230
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +439 -109
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +439 -109
  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 +440 -110
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +507 -229
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +508 -230
  27. package/index.d.cts +468 -59
  28. package/index.d.ts +468 -59
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-worker-web.js +10 -2
  31. package/lib/core/codec-worker.js +4 -3
  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/warnings.js +42 -0
  38. package/lib/core/version.js +1 -1
  39. package/lib/core/web-worker-base.js +4 -3
  40. package/lib/core/web-worker-inline-native.js +1 -1
  41. package/lib/core/web-worker-inline-wasm.js +1 -1
  42. package/lib/core/zip-entry.js +49 -1
  43. package/lib/core/zip-fs.js +43 -132
  44. package/lib/core/zip-reader.js +106 -48
  45. package/lib/core/zip-writer.js +236 -54
  46. package/lib/zip-core-base.js +9 -3
  47. package/lib/zip-core-reader.js +2 -0
  48. package/lib/zip-core-writer.js +6 -1
  49. package/lib/zip-module-wasm-base.js +2 -2
  50. package/package.json +5 -3
package/index-native.cjs CHANGED
@@ -128,6 +128,7 @@ const NUMBER_TYPE = "number";
128
128
  const BOOLEAN_TYPE = "boolean";
129
129
 
130
130
  const EMPTY_UINT8_ARRAY = new Uint8Array();
131
+ const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
131
132
 
132
133
  /*
133
134
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -172,6 +173,7 @@ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
172
173
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
173
174
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
174
175
  const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
176
+ const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
175
177
  const OPTION_CHECK_SIGNATURE = "checkSignature";
176
178
  const OPTION_CHECK_CRC32 = "checkCrc32";
177
179
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -202,15 +204,18 @@ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
202
204
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
203
205
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
204
206
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
207
+ const OPTION_ENTRY = "entry";
205
208
  const TEXT_TYPE_FILENAME = "filename";
206
209
  const TEXT_TYPE_COMMENT = "comment";
207
210
  const STRICTNESS_STRICT = "strict";
208
211
  const STRICTNESS_BALANCED = "balanced";
209
212
  const STRICTNESS_TOLERANT = "tolerant";
213
+ const PASS_THROUGH_COMPRESSED = "compressed";
210
214
 
211
215
  const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
212
216
  const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
213
217
  const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
218
+ const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
214
219
  const ERR_ABORTED = "The operation was aborted";
215
220
  const ABORT_ERROR_NAME = "AbortError";
216
221
 
@@ -240,6 +245,13 @@ function checkPasswordOption(password, rawPassword) {
240
245
  }
241
246
  }
242
247
 
248
+ function checkPassThroughOption(passThrough) {
249
+ if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
250
+ throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
251
+ }
252
+ return passThrough;
253
+ }
254
+
243
255
  function checkInteger(value, maxValue, errorMessage) {
244
256
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
245
257
  throw new Error(errorMessage);
@@ -289,6 +301,8 @@ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
289
301
  const MINIMUM_CHUNK_SIZE = 64;
290
302
  const MINIMUM_PROPERTY_VALUE = 1;
291
303
  const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
304
+ const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
305
+ const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
292
306
  let maxWorkers = 2;
293
307
  try {
294
308
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -313,9 +327,9 @@ const DEFAULT_CONFIGURATION = {
313
327
  };
314
328
 
315
329
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
330
+ const PROPERTY_NAME_BASE_URI = "baseURI";
316
331
 
317
- const STRING_PROPERTY_NAMES = [
318
- "baseURI",
332
+ const URI_PROPERTY_NAMES = [
319
333
  "wasmURI",
320
334
  "workerURI"
321
335
  ];
@@ -339,7 +353,8 @@ const FUNCTION_PROPERTY_NAMES = [
339
353
  "DecompressionStreamFallback"
340
354
  ];
341
355
  const CONFIGURABLE_PROPERTY_NAMES = [
342
- ...STRING_PROPERTY_NAMES,
356
+ PROPERTY_NAME_BASE_URI,
357
+ ...URI_PROPERTY_NAMES,
343
358
  ...BOOLEAN_PROPERTY_NAMES,
344
359
  ...NUMBER_PROPERTY_NAMES,
345
360
  ...FUNCTION_PROPERTY_NAMES
@@ -383,6 +398,14 @@ function checkPropertyValue(propertyName, propertyValue) {
383
398
  }
384
399
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
385
400
  checkFunctionOption(propertyValue);
401
+ } else if (propertyName == PROPERTY_NAME_BASE_URI) {
402
+ if (propertyValue && typeof propertyValue != STRING_TYPE) {
403
+ throw new Error(ERR_INVALID_BASE_URI);
404
+ }
405
+ } else if (URI_PROPERTY_NAMES.includes(propertyName)) {
406
+ if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
407
+ throw new Error(ERR_INVALID_URI);
408
+ }
386
409
  }
387
410
  return propertyValue;
388
411
  }
@@ -416,7 +439,7 @@ function resetConfiguration() {
416
439
  Object.assign(config, DEFAULT_CONFIGURATION);
417
440
  }
418
441
 
419
- const o=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],t=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],e=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],s=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],r=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],n=new Uint8Array(288);n.fill(8,0,144),n.fill(9,144,256),n.fill(7,256,280),n.fill(8,280,288);const i=new Uint8Array(30).fill(5);function A(o){const t=new Uint16Array(16);for(const e of o)t[e]++;t[0]=0;const e=new Uint16Array(17);for(let o=1;o<=15;o++)e[o+1]=e[o]+t[o];const s=new Uint16Array(o.length);for(let t=0;t<o.length;t++)o[t]&&(s[e[o[t]]++]=t);return {o:t,symbols:s}}const g$1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=(O=()=>function(g){let c=0,O=0,B=0,f=new Uint8Array(1024),C=0,u=0;for(;!u;){u=w(1);const o=w(2);if(0==o)m();else if(1==o)d(A(n),A(i));else {if(2!=o)throw new Error("invalid deflate block type");d(...p());}}return f.subarray(0,C);function q(){if(c>=g.length)throw new Error("unexpected end of deflate data");return g[c++]}function w(o){for(;B<o;)O|=q()<<B,B+=8;const t=O&(1<<o)-1;return O>>>=o,B-=o,t}function m(){O=0,B=0;const o=q()|q()<<8;c+=2,z(C+o);for(let t=0;t<o;t++)f[C++]=q();}function d(r,n){let i=F(r);for(;256!=i;){if(i<256)z(C+1),f[C++]=i;else {const r=i-257,A=o[r]+w(t[r]),g=F(n),c=e[g]+w(s[g]);z(C+A);const O=C-c;for(let o=0;o<A;o++)f[C++]=f[O+o];}i=F(r);}}function p(){const o=w(5)+257,t=w(5)+1,e=w(4)+4,s=new Uint8Array(19);for(let o=0;o<e;o++)s[r[o]]=w(3);const n=A(s),i=new Uint8Array(o+t);let g=0;for(;g<i.length;){const o=F(n);if(o<16)i[g++]=o;else if(16==o){const o=i[g-1];let t=w(2)+3;for(;t--;)i[g++]=o;}else g+=17==o?w(3)+3:w(7)+11;}return [A(i.subarray(0,o)),A(i.subarray(o))]}function F(o){const{o:t,symbols:e}=o;let s=0,r=0,n=0;for(let o=1;o<=15;o++){s|=w(1);const i=t[o];if(s-r<i)return e[n+(s-r)];n+=i,r=r+i<<1,s<<=1;}throw new Error("invalid huffman code")}function z(o){if(f.length<o){let t=2*f.length;for(;t<o;)t*=2;const e=new Uint8Array(t);e.set(f.subarray(0,C)),f=e;}}}(function(o){const t=(o=String(o).replace(/[^A-Za-z0-9+/=]/g,"")).length,e=[];for(let s=0;s<t;s+=4){const t=g$1.indexOf(o[s])<<18|g$1.indexOf(o[s+1])<<12|(63&g$1.indexOf(o[s+2]))<<6|63&g$1.indexOf(o[s+3]);e.push(t>>16&255),"="!==o[s+2]&&e.push(t>>8&255),"="!==o[s+3]&&e.push(255&t);}return new Uint8Array(e)}("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")),o=>o({workerURI:o=>{const t="text/javascript";let e=O();if("string"==typeof e&&(e=(new TextEncoder).encode(e)),o){const o=new Blob([e],{type:t});return URL.createObjectURL(o)}return "data:"+t+";base64,"+function(o){let t="";const e=o.length;let s=0;for(;s+2<e;s+=3){const e=o[s]<<16|o[s+1]<<8|o[s+2];t+=g$1[e>>18&63]+g$1[e>>12&63]+g$1[e>>6&63]+g$1[63&e];}const r=e-s;if(1===r){const e=o[s]<<16;t+=g$1[e>>18&63]+g$1[e>>12&63]+"==";}else if(2===r){const e=o[s]<<16|o[s+1]<<8;t+=g$1[e>>18&63]+g$1[e>>12&63]+g$1[e>>6&63]+"=";}return t}(e)}}));var O;
442
+ const r=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],e=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],c=new Uint8Array(288);c.fill(8,0,144),c.fill(9,144,256),c.fill(7,256,280),c.fill(8,280,288);const n=new Uint8Array(30).fill(5);function B(r){const o=new Uint16Array(16);for(const s of r)o[s]++;o[0]=0;const s=new Uint16Array(17);for(let r=1;r<=15;r++)s[r+1]=s[r]+o[r];const e=new Uint16Array(r.length);for(let o=0;o<r.length;o++)r[o]&&(e[s[r[o]]++]=o);return {o:o,symbols:e}}const A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",f=(w=()=>function(A){let f=0,w=0,K=0,g=new Uint8Array(1024),O=0,T=0;for(;!T;){T=W(1);const r=W(2);if(0==r)i();else if(1==r)z(B(c),B(n));else {if(2!=r)throw new Error("invalid deflate block type");z(...D());}}return g.subarray(0,O);function l(){if(f>=A.length)throw new Error("unexpected end of deflate data");return A[f++]}function W(r){for(;K<r;)w|=l()<<K,K+=8;const o=w&(1<<r)-1;return w>>>=r,K-=r,o}function i(){w=0,K=0;const r=l()|l()<<8;f+=2,u(O+r);for(let o=0;o<r;o++)g[O++]=l();}function z(t,c){let n=E(t);for(;256!=n;){if(n<256)u(O+1),g[O++]=n;else {const t=n-257,B=r[t]+W(o[t]),A=E(c),f=s[A]+W(e[A]);u(O+B);const w=O-f;for(let r=0;r<B;r++)g[O++]=g[w+r];}n=E(t);}}function D(){const r=W(5)+257,o=W(5)+1,s=W(4)+4,e=new Uint8Array(19);for(let r=0;r<s;r++)e[t[r]]=W(3);const c=B(e),n=new Uint8Array(r+o);let A=0;for(;A<n.length;){const r=E(c);if(r<16)n[A++]=r;else if(16==r){const r=n[A-1];let o=W(2)+3;for(;o--;)n[A++]=r;}else A+=17==r?W(3)+3:W(7)+11;}return [B(n.subarray(0,r)),B(n.subarray(r))]}function E(r){const{o:o,symbols:s}=r;let e=0,t=0,c=0;for(let r=1;r<=15;r++){e|=W(1);const n=o[r];if(e-t<n)return s[c+(e-t)];c+=n,t=t+n<<1,e<<=1;}throw new Error("invalid huffman code")}function u(r){if(g.length<r){let o=2*g.length;for(;o<r;)o*=2;const s=new Uint8Array(o);s.set(g.subarray(0,O)),g=s;}}}(function(r){const o=(r=String(r).replace(/[^A-Za-z0-9+/=]/g,"")).length,s=[];for(let e=0;e<o;e+=4){const o=A.indexOf(r[e])<<18|A.indexOf(r[e+1])<<12|(63&A.indexOf(r[e+2]))<<6|63&A.indexOf(r[e+3]);s.push(o>>16&255),"="!==r[e+2]&&s.push(o>>8&255),"="!==r[e+3]&&s.push(255&o);}return new Uint8Array(s)}("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")),r=>r({workerURI:r=>{const o="text/javascript";let s=w();if("string"==typeof s&&(s=(new TextEncoder).encode(s)),r){const r=new Blob([s],{type:o});return URL.createObjectURL(r)}return "data:"+o+";base64,"+function(r){let o="";const s=r.length;let e=0;for(;e+2<s;e+=3){const s=r[e]<<16|r[e+1]<<8|r[e+2];o+=A[s>>18&63]+A[s>>12&63]+A[s>>6&63]+A[63&s];}const t=s-e;if(1===t){const s=r[e]<<16;o+=A[s>>18&63]+A[s>>12&63]+"==";}else if(2===t){const s=r[e]<<16|r[e+1]<<8;o+=A[s>>18&63]+A[s>>12&63]+A[s>>6&63]+"=";}return o}(s)}}));var w;
420
443
 
421
444
  /*
422
445
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -2601,6 +2624,7 @@ class ChunkStream extends TransformStream {
2601
2624
  constructor(chunkSize) {
2602
2625
  const pendingChunks = [];
2603
2626
  let pendingLength = 0;
2627
+ let outputSize = 0;
2604
2628
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2605
2629
  chunkSize = DEFAULT_CHUNK_SIZE;
2606
2630
  }
@@ -2609,15 +2633,20 @@ class ChunkStream extends TransformStream {
2609
2633
  pendingChunks.push(chunk);
2610
2634
  pendingLength += chunk.length;
2611
2635
  while (pendingLength > chunkSize) {
2636
+ outputSize += chunkSize;
2612
2637
  controller.enqueue(shiftChunk());
2613
2638
  }
2614
2639
  },
2615
2640
  flush(controller) {
2616
2641
  if (pendingLength) {
2642
+ outputSize += pendingLength;
2617
2643
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2618
2644
  }
2619
2645
  }
2620
2646
  });
2647
+ Object.defineProperty(this, "outputSize", {
2648
+ get: () => outputSize
2649
+ });
2621
2650
 
2622
2651
  function shiftChunk() {
2623
2652
  const result = new Uint8Array(chunkSize);
@@ -2818,7 +2847,7 @@ function createWorkerInterface(workerData, config) {
2818
2847
  }
2819
2848
 
2820
2849
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2821
- let codecStream;
2850
+ let codecStream, chunkStream;
2822
2851
  try {
2823
2852
  if (options.compressed && !options.format) {
2824
2853
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2841,9 +2870,10 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2841
2870
  }
2842
2871
  }
2843
2872
  codecStream = new CodecStream(options, config);
2873
+ chunkStream = new ChunkStream(getChunkSize(config));
2844
2874
  await readable
2845
2875
  .pipeThrough(codecStream)
2846
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2876
+ .pipeThrough(chunkStream)
2847
2877
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2848
2878
  const {
2849
2879
  crc32,
@@ -2857,7 +2887,7 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2857
2887
  };
2858
2888
  } catch (error) {
2859
2889
  if (codecStream) {
2860
- error.outputSize = codecStream.outputSize;
2890
+ error.outputSize = chunkStream ? chunkStream.outputSize : 0;
2861
2891
  }
2862
2892
  throw error;
2863
2893
  } finally {
@@ -2966,11 +2996,17 @@ async function runWebWorker(workerData, config) {
2966
2996
  let resolveResult, rejectResult;
2967
2997
  const result = new Promise((resolve, reject) => {
2968
2998
  resolveResult = resolve;
2969
- rejectResult = reject;
2999
+ rejectResult = error => {
3000
+ if (error && error.outputSize === UNDEFINED_VALUE) {
3001
+ error.outputSize = workerData.outputSize;
3002
+ }
3003
+ reject(error);
3004
+ };
2970
3005
  });
2971
3006
  Object.assign(workerData, {
2972
3007
  reader: null,
2973
3008
  writer: null,
3009
+ outputSize: 0,
2974
3010
  resolveResult,
2975
3011
  rejectResult,
2976
3012
  result
@@ -3254,8 +3290,10 @@ async function onMessage({ data }, workerData) {
3254
3290
  }
3255
3291
  }
3256
3292
  if (type == MESSAGE_DATA) {
3293
+ const chunk = new Uint8Array(value);
3257
3294
  await writer.ready;
3258
- await writer.write(new Uint8Array(value));
3295
+ await writer.write(chunk);
3296
+ workerData.outputSize += chunk.length;
3259
3297
  if (!stale()) {
3260
3298
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3261
3299
  }
@@ -3563,10 +3601,13 @@ function decode(value, encoding, ignoreBOM) {
3563
3601
 
3564
3602
 
3565
3603
  const ERR_HTTP_STATUS = "HTTP error ";
3604
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3605
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3566
3606
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3567
3607
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3568
3608
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3569
3609
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3610
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3570
3611
 
3571
3612
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3572
3613
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3758,6 +3799,7 @@ class BlobReader extends Reader {
3758
3799
  const reader = this;
3759
3800
  const { sourceBlob, size } = reader;
3760
3801
  const { offset = 0, size: readSize = size - offset } = options || {};
3802
+ // deno-lint-ignore valid-typeof
3761
3803
  if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3762
3804
  if (!offset && readSize >= size) {
3763
3805
  return toCompatibleReadable(sourceBlob.stream());
@@ -4164,7 +4206,7 @@ async function getContentLength(httpReader, sendRequest, getRequestData) {
4164
4206
 
4165
4207
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4166
4208
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4167
- if (response.status < 400) {
4209
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4168
4210
  return response;
4169
4211
  } else {
4170
4212
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4175,7 +4217,7 @@ function sendXMLHttpRequest(method, { url }, headers) {
4175
4217
  return new Promise((resolve, reject) => {
4176
4218
  const request = new XMLHttpRequest();
4177
4219
  request.addEventListener("load", () => {
4178
- if (request.status < 400) {
4220
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4179
4221
  const headers = [];
4180
4222
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4181
4223
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4479,8 +4521,10 @@ class GenericWriter {
4479
4521
  writable: toCompatibleWritable(writer)
4480
4522
  };
4481
4523
  }
4482
- if (writer.size === UNDEFINED_VALUE) {
4483
- writer.size = 0;
4524
+ try {
4525
+ writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
4526
+ } catch {
4527
+ throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
4484
4528
  }
4485
4529
  return writer;
4486
4530
  }
@@ -4528,6 +4572,45 @@ function createReadable(reader, options) {
4528
4572
  }
4529
4573
  }
4530
4574
 
4575
+ /*
4576
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
4577
+
4578
+ Redistribution and use in source and binary forms, with or without
4579
+ modification, are permitted provided that the following conditions are met:
4580
+
4581
+ 1. Redistributions of source code must retain the above copyright notice,
4582
+ this list of conditions and the following disclaimer.
4583
+
4584
+ 2. Redistributions in binary form must reproduce the above copyright
4585
+ notice, this list of conditions and the following disclaimer in
4586
+ the documentation and/or other materials provided with the distribution.
4587
+
4588
+ 3. The names of the authors may not be used to endorse or promote products
4589
+ derived from this software without specific prior written permission.
4590
+
4591
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4592
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4593
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4594
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4595
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4596
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4597
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4598
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4599
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4600
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4601
+ */
4602
+
4603
+
4604
+ function addWarning(warnings, reason, filename) {
4605
+ if (!warnings.some(warning => warning.reason == reason)) {
4606
+ const warning = { reason };
4607
+ if (filename !== UNDEFINED_VALUE) {
4608
+ warning.filename = filename;
4609
+ }
4610
+ warnings.push(warning);
4611
+ }
4612
+ }
4613
+
4531
4614
  /*
4532
4615
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4533
4616
 
@@ -4556,6 +4639,7 @@ function createReadable(reader, options) {
4556
4639
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4557
4640
  */
4558
4641
 
4642
+
4559
4643
  const PROPERTY_NAME_FILENAME = "filename";
4560
4644
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4561
4645
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4680,6 +4764,38 @@ class Entry {
4680
4764
 
4681
4765
  }
4682
4766
 
4767
+ const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
4768
+ EXTRAFIELD_TYPE_ZIP64,
4769
+ EXTRAFIELD_TYPE_AES,
4770
+ EXTRAFIELD_TYPE_NTFS,
4771
+ EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
4772
+ EXTRAFIELD_TYPE_UNICODE_PATH,
4773
+ EXTRAFIELD_TYPE_UNICODE_COMMENT,
4774
+ EXTRAFIELD_TYPE_USDZ,
4775
+ EXTRAFIELD_TYPE_INFOZIP,
4776
+ EXTRAFIELD_TYPE_UNIX,
4777
+ EXTRAFIELD_TYPE_UNIX_TYPE1,
4778
+ EXTRAFIELD_TYPE_PKWARE_UNIX
4779
+ ]);
4780
+
4781
+ function getUserExtraField(extraField) {
4782
+ if (extraField) {
4783
+ const userExtraField = new Map();
4784
+ extraField.forEach((field, type) => {
4785
+ if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
4786
+ userExtraField.set(type, field.data);
4787
+ }
4788
+ });
4789
+ if (userExtraField.size) {
4790
+ return userExtraField;
4791
+ }
4792
+ }
4793
+ }
4794
+
4795
+ function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
4796
+ return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
4797
+ }
4798
+
4683
4799
  /*
4684
4800
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4685
4801
 
@@ -4739,6 +4855,8 @@ const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
4739
4855
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4740
4856
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4741
4857
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4858
+ const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
4859
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
4742
4860
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4743
4861
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4744
4862
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4809,7 +4927,7 @@ class ZipReader {
4809
4927
  }
4810
4928
  }
4811
4929
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4812
- throwAmbiguousArchive("multiple end of central directory records");
4930
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4813
4931
  }
4814
4932
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4815
4933
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5107,7 +5225,8 @@ class ZipReader {
5107
5225
  const writer = new TransformStream();
5108
5226
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5109
5227
  arrayBufferPromise.catch(() => { });
5110
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5228
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5229
+ Object.assign({}, options, { preventClose: false }));
5111
5230
  return arrayBufferPromise;
5112
5231
  };
5113
5232
  offset = endOffset;
@@ -5188,49 +5307,101 @@ class ZipReader {
5188
5307
  await reader.readable.cancel();
5189
5308
  }
5190
5309
  }
5310
+
5311
+ [SYMBOL_ASYNC_DISPOSE]() {
5312
+ return this.close();
5313
+ }
5191
5314
  }
5192
5315
 
5193
5316
  class ZipReaderStream {
5194
5317
 
5195
5318
  constructor(options = {}) {
5196
- const { readable, writable } = new TransformStream();
5197
- const gen = new ZipReader(readable, options).getEntriesGenerator();
5319
+ let sourceController;
5320
+ const { readable, writable } = new TransformStream({
5321
+ start(controller) {
5322
+ sourceController = controller;
5323
+ }
5324
+ });
5325
+ const zipReader = new ZipReader(readable, options);
5326
+ const gen = zipReader.getEntriesGenerator();
5327
+ const pendingEntries = new Set();
5198
5328
  this.readable = new ReadableStream({
5199
5329
  async pull(controller) {
5200
5330
  const { done, value } = await gen.next();
5201
5331
  if (done)
5202
5332
  return controller.close();
5203
- const entryReadable = (function () {
5204
- const { readable, writable } = new TransformStream();
5205
- if (value.getData) {
5206
- getData();
5207
- return readable;
5208
- }
5209
-
5210
- async function getData() {
5211
- try {
5212
- await value.getData(writable);
5213
- } catch (error) {
5214
- try {
5215
- await writable.abort(error);
5216
- } catch {
5217
- // ignored
5218
- }
5219
- }
5220
- }
5221
- })();
5333
+ const entryStream = createEntryStream(value, pendingEntries);
5222
5334
  const chunk = {
5223
5335
  ...value,
5224
- readable: entryReadable
5336
+ readable: entryStream.readable
5225
5337
  };
5226
5338
  delete chunk.getData;
5339
+ Object.defineProperties(chunk, {
5340
+ localDirectory: {
5341
+ get: () => value.localDirectory,
5342
+ enumerable: true
5343
+ },
5344
+ warnings: {
5345
+ get: () => value.warnings,
5346
+ enumerable: true
5347
+ }
5348
+ });
5227
5349
  controller.enqueue(chunk);
5350
+ },
5351
+ async cancel(reason) {
5352
+ const entryStreams = Array.from(pendingEntries);
5353
+ pendingEntries.clear();
5354
+ sourceController.error(reason);
5355
+ await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
5356
+ await Promise.allSettled([gen.return(), zipReader.close()]);
5228
5357
  }
5229
5358
  });
5230
5359
  this.writable = writable;
5231
5360
  }
5232
5361
  }
5233
5362
 
5363
+ function createEntryStream(entry, pendingEntries) {
5364
+ const { readable, writable } = new TransformStream();
5365
+ let dataReader;
5366
+ const entryStream = {
5367
+ cancel: async reason => {
5368
+ pendingEntries.delete(entryStream);
5369
+ await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
5370
+ }
5371
+ };
5372
+ entryStream.readable = new ReadableStream({
5373
+ async pull(controller) {
5374
+ if (!dataReader) {
5375
+ dataReader = readable.getReader();
5376
+ pendingEntries.add(entryStream);
5377
+ getData();
5378
+ }
5379
+ const { done, value } = await dataReader.read();
5380
+ if (done) {
5381
+ controller.close();
5382
+ } else {
5383
+ controller.enqueue(value);
5384
+ }
5385
+ },
5386
+ cancel: reason => entryStream.cancel(reason)
5387
+ }, { highWaterMark: 0 });
5388
+ return entryStream;
5389
+
5390
+ async function getData() {
5391
+ try {
5392
+ await entry.getData(writable, { preventClose: false });
5393
+ } catch (error) {
5394
+ try {
5395
+ await writable.abort(error);
5396
+ } catch {
5397
+ // ignored
5398
+ }
5399
+ } finally {
5400
+ pendingEntries.delete(entryStream);
5401
+ }
5402
+ }
5403
+ }
5404
+
5234
5405
  async function isZipFile(reader, options = {}) {
5235
5406
  reader = new GenericReader(reader);
5236
5407
  await initStream(reader);
@@ -5290,7 +5461,9 @@ let ZipEntry$1 = class ZipEntry {
5290
5461
  const dataView = getDataView(dataArray);
5291
5462
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5292
5463
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5293
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5464
+ const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
5465
+ const passThroughCompression = Boolean(passThrough);
5466
+ const passThroughEncryption = passThrough === true;
5294
5467
  checkPasswordOption(password, rawPassword);
5295
5468
  password = password && password.length && password;
5296
5469
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5311,7 +5484,9 @@ let ZipEntry$1 = class ZipEntry {
5311
5484
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5312
5485
  const entryStrictness = getStrictness(options, zipEntry.options);
5313
5486
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5314
- const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5487
+ const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
5488
+ const checkLocalFilename = getCheckLocalFilename(
5489
+ checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
5315
5490
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5316
5491
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5317
5492
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5342,16 +5517,17 @@ let ZipEntry$1 = class ZipEntry {
5342
5517
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5343
5518
  fileEntry.gid = gid;
5344
5519
  }
5345
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5520
+ const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5521
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5346
5522
  const zipCrypto = encrypted && !extraFieldAES;
5347
- if (!passThrough) {
5523
+ if (!passThroughEncryption) {
5348
5524
  fileEntry.zipCrypto = zipCrypto;
5349
5525
  }
5350
5526
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5351
5527
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5352
5528
  }
5353
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5354
- if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThrough) {
5529
+ const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5530
+ if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
5355
5531
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5356
5532
  }
5357
5533
  if (encrypted) {
@@ -5368,15 +5544,16 @@ let ZipEntry$1 = class ZipEntry {
5368
5544
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5369
5545
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5370
5546
  throwIfAborted(signal);
5371
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5372
5547
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5373
5548
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5374
5549
  if (checkOverlappingEntryOnly) {
5375
5550
  checkOverlappingEntry = true;
5376
5551
  }
5377
5552
  const { onstart, onprogress, onend } = options;
5378
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5379
- const outputSize = passThrough ? compressedSize : uncompressedSize;
5553
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
5554
+ const outputSize = passThroughCompression ?
5555
+ compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
5556
+ uncompressedSize;
5380
5557
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5381
5558
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5382
5559
  if (deflate64) {
@@ -5385,7 +5562,7 @@ let ZipEntry$1 = class ZipEntry {
5385
5562
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5386
5563
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5387
5564
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5388
- checkCrc32Option) && !passThrough &&
5565
+ checkCrc32Option) && !passThroughCompression &&
5389
5566
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5390
5567
  const workerOptions = {
5391
5568
  options: {
@@ -5439,10 +5616,10 @@ let ZipEntry$1 = class ZipEntry {
5439
5616
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5440
5617
  ({ writable } = writer);
5441
5618
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5442
- writer.size += writtenSize;
5443
5619
  if (writtenSize != outputSize) {
5444
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5620
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5445
5621
  }
5622
+ writer.size += writtenSize;
5446
5623
  }
5447
5624
  } catch (error) {
5448
5625
  if (error.outputSize !== UNDEFINED_VALUE) {
@@ -6108,7 +6285,7 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
6108
6285
  if (checkLocalFilename && !maskedLocalDirectory &&
6109
6286
  (rawLocalFilename.length != rawFilename.length ||
6110
6287
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6111
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6288
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6112
6289
  }
6113
6290
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6114
6291
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6133,16 +6310,6 @@ function reportAmbiguity(reject, warnings, reason) {
6133
6310
  }
6134
6311
  }
6135
6312
 
6136
- function addWarning(warnings, reason, filename) {
6137
- if (!warnings.some(warning => warning.reason == reason)) {
6138
- const warning = { reason };
6139
- if (filename !== UNDEFINED_VALUE) {
6140
- warning.filename = filename;
6141
- }
6142
- warnings.push(warning);
6143
- }
6144
- }
6145
-
6146
6313
  function throwAmbiguousArchive(reason) {
6147
6314
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6148
6315
  error.reason = reason;
@@ -6222,7 +6389,9 @@ var zipReader = /*#__PURE__*/Object.freeze({
6222
6389
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6223
6390
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6224
6391
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6392
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6225
6393
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6394
+ WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6226
6395
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6227
6396
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6228
6397
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6275,7 +6444,7 @@ const ERR_INVALID_VERSION = "Version exceeds 65535";
6275
6444
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6276
6445
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6277
6446
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6278
- const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6447
+ const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
6279
6448
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6280
6449
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6281
6450
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6287,6 +6456,7 @@ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
6287
6456
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6288
6457
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6289
6458
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6459
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6290
6460
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6291
6461
  const ERR_UNDEFINED_READER = "Undefined reader";
6292
6462
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6300,14 +6470,21 @@ const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be intege
6300
6470
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6301
6471
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6302
6472
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6473
+ const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
6474
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
6475
+ const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
6476
+ const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
6303
6477
 
6304
6478
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6305
6479
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6306
6480
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6307
6481
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6482
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6483
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6308
6484
  const VENDOR_VERSION_AE_1 = 1;
6309
- const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6485
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6310
6486
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6487
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6311
6488
  const MAX_LEVEL = 9;
6312
6489
 
6313
6490
  let workers = 0;
@@ -6334,9 +6511,11 @@ class ZipWriter {
6334
6511
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6335
6512
  pendingAddFileCalls: new Set(),
6336
6513
  pendingErrors: [],
6514
+ warnings: [],
6337
6515
  bufferedWrites: 0,
6338
6516
  directWrites: 0,
6339
- lastFileEntry: UNDEFINED_VALUE
6517
+ lastFileEntry: UNDEFINED_VALUE,
6518
+ archiveClosed: false
6340
6519
  });
6341
6520
  }
6342
6521
 
@@ -6501,6 +6680,9 @@ class ZipWriter {
6501
6680
  const zipWriter = this;
6502
6681
  const { pendingAddFileCalls, writer } = this;
6503
6682
  const { writable } = writer;
6683
+ if (zipWriter.archiveClosed) {
6684
+ return getWriterData(writer);
6685
+ }
6504
6686
  if (!(comment instanceof Uint8Array)) {
6505
6687
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6506
6688
  }
@@ -6524,11 +6706,16 @@ class ZipWriter {
6524
6706
  throw error;
6525
6707
  }
6526
6708
  await closeFile(zipWriter, comment, options);
6709
+ zipWriter.archiveClosed = true;
6527
6710
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6528
6711
  if (!preventClose) {
6529
6712
  await writable.getWriter().close();
6530
6713
  }
6531
- return writer.getData ? writer.getData() : writable;
6714
+ return getWriterData(writer);
6715
+ }
6716
+
6717
+ [SYMBOL_ASYNC_DISPOSE]() {
6718
+ return this.close();
6532
6719
  }
6533
6720
  }
6534
6721
 
@@ -6607,6 +6794,10 @@ class WatchedPromise extends Promise {
6607
6794
  }
6608
6795
  }
6609
6796
 
6797
+ function getWriterData(writer) {
6798
+ return writer.getData ? writer.getData() : writer.writable;
6799
+ }
6800
+
6610
6801
  function watchPromiseError(zipWriter, promise) {
6611
6802
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6612
6803
  const watcher = {};
@@ -6625,6 +6816,14 @@ async function prependZipEntries(zipWriter, reader) {
6625
6816
 
6626
6817
  async function addFileEntry(zipWriter, name, reader, options) {
6627
6818
  options = Object.assign({}, options);
6819
+ const entry = options[OPTION_ENTRY];
6820
+ if (entry !== UNDEFINED_VALUE) {
6821
+ const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
6822
+ checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
6823
+ getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
6824
+ delete options[OPTION_ENTRY];
6825
+ options = Object.assign(entryOptions, passThroughOptions, options);
6826
+ }
6628
6827
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6629
6828
  name += DIRECTORY_SIGNATURE;
6630
6829
  }
@@ -6689,21 +6888,33 @@ async function addFile(zipWriter, name, reader, options) {
6689
6888
  try {
6690
6889
  const { resolvedOptions } = metadataInfo;
6691
6890
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6692
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6891
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6693
6892
  resolvedOptions.level = 0;
6893
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6694
6894
  }
6695
6895
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6696
6896
  ({ reader } = sizesInfo);
6697
6897
  const diskOffset = getDiskOffset(zipWriter.writer);
6698
6898
  const diskNumber = getDiskNumber(zipWriter.writer);
6899
+ let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
6900
+ const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
6901
+ if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
6902
+ crc32 = UNDEFINED_VALUE;
6903
+ }
6904
+ if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
6905
+ throw new Error(ERR_UNDEFINED_CRC32);
6906
+ }
6699
6907
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6700
6908
  signature: options[PROPERTY_NAME_SIGNATURE],
6701
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6909
+ crc32,
6702
6910
  offset: zipWriter.offset - diskOffset,
6703
6911
  diskNumberStart: diskNumber,
6704
6912
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6705
6913
  });
6706
6914
  const headerInfo = getHeaderInfo(options);
6915
+ if (headerInfo.lastModDateClamped) {
6916
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
6917
+ }
6707
6918
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6708
6919
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6709
6920
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6730,6 +6941,95 @@ async function addFile(zipWriter, name, reader, options) {
6730
6941
  return new Entry(fileEntry);
6731
6942
  }
6732
6943
 
6944
+ function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
6945
+ if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
6946
+ throw new Error(ERR_INVALID_ENTRY);
6947
+ }
6948
+ const {
6949
+ externalFileAttributes,
6950
+ versionMadeBy,
6951
+ comment,
6952
+ lastModDate,
6953
+ rawLastModDate,
6954
+ creationDate,
6955
+ lastAccessDate,
6956
+ uncompressedSize,
6957
+ encrypted,
6958
+ zipCrypto,
6959
+ crc32,
6960
+ compressionMethod,
6961
+ extraFieldAES,
6962
+ extraFieldUnix,
6963
+ internalFileAttributes,
6964
+ extraField,
6965
+ bitFlag,
6966
+ directory,
6967
+ uid,
6968
+ gid
6969
+ } = entry;
6970
+ const entryOptions = {
6971
+ externalFileAttributes,
6972
+ versionMadeBy,
6973
+ comment,
6974
+ lastModDate,
6975
+ creationDate,
6976
+ lastAccessDate,
6977
+ internalFileAttributes,
6978
+ directory
6979
+ };
6980
+ if (bitFlag && bitFlag.languageEncodingFlag) {
6981
+ entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
6982
+ }
6983
+ const userExtraField = getUserExtraField(extraField);
6984
+ if (userExtraField) {
6985
+ entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
6986
+ }
6987
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
6988
+ Object.assign(entryOptions, {
6989
+ uid,
6990
+ gid,
6991
+ unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
6992
+ });
6993
+ }
6994
+ const passThroughOptions = {};
6995
+ if (passThrough && !directory) {
6996
+ Object.assign(passThroughOptions, {
6997
+ uncompressedSize,
6998
+ crc32,
6999
+ compressionMethod
7000
+ });
7001
+ if (passThrough !== PASS_THROUGH_COMPRESSED) {
7002
+ Object.assign(passThroughOptions, {
7003
+ encrypted,
7004
+ zipCrypto,
7005
+ encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
7006
+ });
7007
+ }
7008
+ if (bitFlag) {
7009
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
7010
+ passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
7011
+ }
7012
+ if (lastModDateOverride === UNDEFINED_VALUE) {
7013
+ passThroughOptions.rawLastModDate = rawLastModDate;
7014
+ } else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
7015
+ lastModDateOverride instanceof Date &&
7016
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
7017
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
7018
+ }
7019
+ }
7020
+ return { entryOptions, passThroughOptions };
7021
+ }
7022
+
7023
+ function getDosTimeHighByte(lastModDate) {
7024
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
7025
+ if (dosLastModDate < MIN_DATE) {
7026
+ dosLastModDate = MIN_DATE;
7027
+ } else if (dosLastModDate > MAX_DATE) {
7028
+ dosLastModDate = MAX_DATE;
7029
+ }
7030
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
7031
+ }
7032
+
6733
7033
  function resolveAttributes(zipWriter, name, options) {
6734
7034
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6735
7035
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6744,7 +7044,7 @@ function resolveAttributes(zipWriter, name, options) {
6744
7044
  checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6745
7045
  checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6746
7046
  checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6747
- if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
7047
+ if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6748
7048
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6749
7049
  }
6750
7050
  if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
@@ -6752,7 +7052,7 @@ function resolveAttributes(zipWriter, name, options) {
6752
7052
  throw new Error(ERR_INVALID_UNIX_ID_SIZE);
6753
7053
  }
6754
7054
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6755
- unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
7055
+ unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
6756
7056
  }
6757
7057
  let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6758
7058
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
@@ -6883,7 +7183,9 @@ function resolveMetadata(zipWriter, name, options) {
6883
7183
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6884
7184
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6885
7185
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6886
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
7186
+ const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7187
+ const passThroughCompression = Boolean(passThrough);
7188
+ const passThroughEncryption = passThrough === true;
6887
7189
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6888
7190
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6889
7191
  checkPasswordOption(password, rawPassword);
@@ -6899,10 +7201,11 @@ function resolveMetadata(zipWriter, name, options) {
6899
7201
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6900
7202
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6901
7203
  throwIfAborted(signal);
6902
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7204
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7205
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6903
7206
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6904
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6905
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7207
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7208
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6906
7209
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6907
7210
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6908
7211
  }
@@ -6916,15 +7219,15 @@ function resolveMetadata(zipWriter, name, options) {
6916
7219
  level = 0;
6917
7220
  }
6918
7221
  }
6919
- if (passThrough) {
6920
- level = UNDEFINED_VALUE;
7222
+ if (passThroughCompression) {
7223
+ level = toNumber(options[OPTION_LEVEL]);
6921
7224
  }
6922
7225
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6923
7226
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6924
7227
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6925
7228
  dataDescriptor = false;
6926
7229
  }
6927
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7230
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6928
7231
  dataDescriptor = true;
6929
7232
  }
6930
7233
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6948,7 +7251,8 @@ function resolveMetadata(zipWriter, name, options) {
6948
7251
  lastAccessDate,
6949
7252
  creationDate,
6950
7253
  internalFileAttributes,
6951
- passThrough,
7254
+ passThroughCompression,
7255
+ passThroughEncryption,
6952
7256
  password,
6953
7257
  rawPassword,
6954
7258
  encryptionStrength,
@@ -7009,7 +7313,7 @@ function serializeExtraField(extraField) {
7009
7313
  }
7010
7314
 
7011
7315
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
7012
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7316
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7013
7317
  throw new Error(ERR_UNDEFINED_READER);
7014
7318
  }
7015
7319
  let contentSize;
@@ -7025,12 +7329,12 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
7025
7329
  }
7026
7330
 
7027
7331
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7028
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7332
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7029
7333
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7030
7334
  let maximumCompressedSize = 0;
7031
7335
  let uncompressedSize = 0;
7032
7336
  let unknownSize = false;
7033
- if (passThrough && hasContent) {
7337
+ if (passThroughCompression && hasContent) {
7034
7338
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7035
7339
  if (uncompressedSize === UNDEFINED_VALUE) {
7036
7340
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7041,17 +7345,17 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7041
7345
  }
7042
7346
  const zip64Enabled = zip64 === true;
7043
7347
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7044
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7348
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7045
7349
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7046
7350
  }
7047
- const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
7351
+ const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
7048
7352
  if (!hasContent) {
7049
7353
  level = 0;
7050
7354
  compressionMethod = COMPRESSION_METHOD_STORE;
7051
7355
  }
7052
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7356
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7053
7357
  if (hasContent) {
7054
- if (!passThrough) {
7358
+ if (!passThroughCompression) {
7055
7359
  if (contentSize === UNDEFINED_VALUE) {
7056
7360
  dataDescriptor = true;
7057
7361
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7064,10 +7368,12 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7064
7368
  }
7065
7369
  } else {
7066
7370
  options.uncompressedSize = uncompressedSize;
7067
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7371
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7372
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7373
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7068
7374
  }
7069
7375
  }
7070
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7376
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7071
7377
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7072
7378
  dataDescriptor = false;
7073
7379
  }
@@ -7116,6 +7422,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7116
7422
  const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
7117
7423
  let offset = initialOffset;
7118
7424
  let minimumEntrySize = INFINITY_VALUE;
7425
+ const entrySizes = [];
7426
+ const entriesAlreadyZip64 = new Set();
7119
7427
  for (const entry of entries) {
7120
7428
  let { name } = entry;
7121
7429
  const { size } = entry;
@@ -7127,7 +7435,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7127
7435
  ({ name } = attributesInfo);
7128
7436
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
7129
7437
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
7130
- !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
7438
+ !metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
7131
7439
  metadata.level = 0;
7132
7440
  }
7133
7441
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -7135,7 +7443,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7135
7443
  throw new Error(ERR_UNDETERMINED_SIZE);
7136
7444
  }
7137
7445
  const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
7138
- if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
7446
+ if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
7139
7447
  throw new Error(ERR_UNDETERMINED_SIZE);
7140
7448
  }
7141
7449
  const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
@@ -7155,10 +7463,15 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7155
7463
  compressedSize
7156
7464
  }));
7157
7465
  const entrySize = entryInfo.metadataSize + compressedSize;
7466
+ entrySizes.push(entrySize);
7467
+ entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
7468
+ entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
7158
7469
  minimumEntrySize = Math.min(minimumEntrySize, entrySize);
7159
7470
  offset += entrySize;
7160
7471
  }
7161
- const layoutDependsOnWriteOrder = files.size > 1 && (usdz || offset - minimumEntrySize >= MAX_32_BITS);
7472
+ const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
7473
+ (offset - minimumEntrySize >= MAX_32_BITS &&
7474
+ (entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
7162
7475
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
7163
7476
  throw new Error(ERR_UNDETERMINED_SIZE);
7164
7477
  }
@@ -7176,6 +7489,20 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7176
7489
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7177
7490
  }
7178
7491
 
7492
+ function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
7493
+ const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
7494
+ let position = initialOffset;
7495
+ let count = 0;
7496
+ for (const entrySize of ordered) {
7497
+ if (position >= MAX_32_BITS) {
7498
+ break;
7499
+ }
7500
+ position += entrySize;
7501
+ count++;
7502
+ }
7503
+ return count;
7504
+ }
7505
+
7179
7506
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7180
7507
  const {
7181
7508
  fileEntries,
@@ -7351,6 +7678,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7351
7678
  localExtraFieldZip64Length,
7352
7679
  rawExtraFieldExtendedTimestamp,
7353
7680
  extraFieldExtendedTimestampFlag,
7681
+ extraFieldExtendedTimestampTime,
7354
7682
  rawExtraFieldNTFS,
7355
7683
  rawExtraFieldUnix,
7356
7684
  rawExtraFieldAES,
@@ -7363,6 +7691,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7363
7691
  password,
7364
7692
  rawPassword,
7365
7693
  level,
7694
+ useUnicodeFileNames,
7366
7695
  zip64,
7367
7696
  zip64Enabled,
7368
7697
  zip64UncompressedSize,
@@ -7397,7 +7726,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7397
7726
  msdosAttributesRaw,
7398
7727
  msdosAttributes,
7399
7728
  useCompressionStream,
7400
- passThrough,
7729
+ passThroughCompression,
7730
+ passThroughEncryption,
7401
7731
  format,
7402
7732
  codecURI
7403
7733
  } = options;
@@ -7408,9 +7738,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7408
7738
  zip64Enabled,
7409
7739
  directory: Boolean(directory),
7410
7740
  executable: Boolean(executable),
7411
- filenameUTF8: true,
7741
+ filenameUTF8: Boolean(useUnicodeFileNames),
7412
7742
  rawFilename,
7413
- commentUTF8: true,
7743
+ commentUTF8: Boolean(useUnicodeFileNames),
7414
7744
  rawComment,
7415
7745
  rawExtraFieldZip64,
7416
7746
  localExtraFieldZip64Length,
@@ -7441,7 +7771,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7441
7771
  uncompressedSize
7442
7772
  } = options;
7443
7773
  let compressedSize = 0;
7444
- if (!passThrough) {
7774
+ if (!passThroughCompression) {
7445
7775
  uncompressedSize = 0;
7446
7776
  }
7447
7777
  const { writable } = writer;
@@ -7458,9 +7788,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7458
7788
  encryptionStrength,
7459
7789
  zipCrypto: encrypted && zipCrypto,
7460
7790
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7461
- computeCrc32: !passThrough,
7462
- compressed: compressed && !passThrough,
7463
- encrypted: encrypted && !passThrough,
7791
+ computeCrc32: !passThroughCompression,
7792
+ compressed: compressed && !passThroughCompression,
7793
+ encrypted: encrypted && !passThroughEncryption,
7464
7794
  useWebWorkers,
7465
7795
  useCompressionStream,
7466
7796
  transferStreams,
@@ -7475,7 +7805,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7475
7805
  const result = await runWorker({ readable, writable }, workerOptions);
7476
7806
  compressedSize = result.outputSize;
7477
7807
  writer.size += compressedSize;
7478
- if (!passThrough) {
7808
+ if (!passThroughCompression) {
7479
7809
  uncompressedSize = result.inputSize;
7480
7810
  if (!encrypted || zipCrypto) {
7481
7811
  crc32 = result.crc32;
@@ -7518,8 +7848,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7518
7848
  headerArray,
7519
7849
  headerView,
7520
7850
  signature: crc32,
7521
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7851
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7522
7852
  extraFieldExtendedTimestampFlag,
7853
+ extraFieldExtendedTimestampTime,
7523
7854
  zip64UncompressedSize,
7524
7855
  zip64CompressedSize
7525
7856
  });
@@ -7544,7 +7875,7 @@ function getHeaderInfo(options) {
7544
7875
  encryptionStrength,
7545
7876
  extendedTimestamp,
7546
7877
  ntfsTimestamp,
7547
- passThrough,
7878
+ passThroughCompression,
7548
7879
  encrypted,
7549
7880
  zip64UncompressedSize,
7550
7881
  zip64CompressedSize,
@@ -7555,7 +7886,7 @@ function getHeaderInfo(options) {
7555
7886
  let { version, compressionMethod } = options;
7556
7887
  const compressed = !directory && isCompressed(compressionMethod, level);
7557
7888
  let rawLocalExtraFieldZip64;
7558
- const uncompressedFile = passThrough || !compressed;
7889
+ const uncompressedFile = passThroughCompression || !compressed;
7559
7890
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7560
7891
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7561
7892
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7567,8 +7898,8 @@ function getHeaderInfo(options) {
7567
7898
  if (zip64ExtraFieldComplete) {
7568
7899
  extraFieldZip64.writeUint64(uncompressedSize);
7569
7900
  if (uncompressedFile) {
7570
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7571
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7901
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
7902
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7572
7903
  }
7573
7904
  }
7574
7905
  } else {
@@ -7587,6 +7918,7 @@ function getHeaderInfo(options) {
7587
7918
  let rawExtraFieldNTFS;
7588
7919
  let rawExtraFieldExtendedTimestamp;
7589
7920
  let extraFieldExtendedTimestampFlag;
7921
+ let extraFieldExtendedTimestampTime;
7590
7922
  if (extendedTimestamp) {
7591
7923
  const lastModTimeUnix = getTimeUnix(lastModDate);
7592
7924
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7594,6 +7926,7 @@ function getHeaderInfo(options) {
7594
7926
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7595
7927
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7596
7928
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7929
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7597
7930
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7598
7931
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7599
7932
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7636,7 +7969,7 @@ function getHeaderInfo(options) {
7636
7969
  let rawExtraFieldUnix;
7637
7970
  try {
7638
7971
  const { uid, gid, unixExtraFieldType } = options;
7639
- if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7972
+ if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7640
7973
  const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7641
7974
  const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7642
7975
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
@@ -7677,7 +8010,7 @@ function getHeaderInfo(options) {
7677
8010
  }
7678
8011
  if (encrypted && !zipCrypto) {
7679
8012
  version = version > VERSION_AES ? version : VERSION_AES;
7680
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
8013
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7681
8014
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7682
8015
  }
7683
8016
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7739,12 +8072,14 @@ function getHeaderInfo(options) {
7739
8072
  headerArray,
7740
8073
  headerView,
7741
8074
  lastModDate: storedLastModDate,
8075
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7742
8076
  rawLastModDate,
7743
8077
  encrypted,
7744
8078
  compressed,
7745
8079
  version,
7746
8080
  compressionMethod,
7747
8081
  extraFieldExtendedTimestampFlag,
8082
+ extraFieldExtendedTimestampTime,
7748
8083
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7749
8084
  localExtraFieldZip64Length,
7750
8085
  rawExtraFieldExtendedTimestamp,
@@ -7847,7 +8182,7 @@ function setEntryInfo({
7847
8182
  }, {
7848
8183
  zip64,
7849
8184
  zipCrypto,
7850
- passThrough,
8185
+ passThroughCompression,
7851
8186
  dataDescriptor
7852
8187
  }) {
7853
8188
  const {
@@ -7858,7 +8193,7 @@ function setEntryInfo({
7858
8193
  dataDescriptorView,
7859
8194
  dataDescriptorOffset
7860
8195
  } = dataDescriptorInfo;
7861
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8196
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7862
8197
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7863
8198
  if (dataDescriptor) {
7864
8199
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7889,9 +8224,9 @@ function updateLocalHeader({
7889
8224
  uncompressedSize,
7890
8225
  zip64UncompressedSize,
7891
8226
  zip64CompressedSize
7892
- }, localHeaderView, { dataDescriptor, passThrough }) {
8227
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7893
8228
  if (!dataDescriptor) {
7894
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8229
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7895
8230
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7896
8231
  }
7897
8232
  if (!zip64CompressedSize) {
@@ -7928,9 +8263,8 @@ function createDirectoryRecords(files) {
7928
8263
  rawExtraFieldUnix,
7929
8264
  rawExtraField,
7930
8265
  rawCentralExtraField,
7931
- extendedTimestamp,
7932
8266
  extraFieldExtendedTimestampFlag,
7933
- lastModDate,
8267
+ extraFieldExtendedTimestampTime,
7934
8268
  zip64Enabled,
7935
8269
  uncompressedSize,
7936
8270
  compressedSize
@@ -7973,16 +8307,15 @@ function createDirectoryRecords(files) {
7973
8307
  fileEntry.zip64Offset = zip64Offset;
7974
8308
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
7975
8309
  let rawExtraFieldTimestamp;
7976
- const lastModTimeUnix = getTimeUnix(lastModDate);
7977
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8310
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8311
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8312
+ } else {
7978
8313
  const extraFieldTimestamp = createRecordWriter(9);
7979
8314
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7980
8315
  extraFieldTimestamp.writeUint16(5);
7981
8316
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7982
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8317
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
7983
8318
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7984
- } else {
7985
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
7986
8319
  }
7987
8320
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
7988
8321
  const extraFieldLength = getLength(
@@ -8482,6 +8815,11 @@ function getHeaderArrayData({
8482
8815
  };
8483
8816
  }
8484
8817
 
8818
+ function isPrintableASCIIText(rawText) {
8819
+ return rawText.every(characterCode =>
8820
+ characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
8821
+ }
8822
+
8485
8823
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8486
8824
  let bitFlag = 0;
8487
8825
  if (useUnicodeFileNames) {
@@ -8643,7 +8981,7 @@ function formatSupported(StreamClass, format) {
8643
8981
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8644
8982
  */
8645
8983
 
8646
- const VERSION = "2.11.4";
8984
+ const VERSION = "2.12.0";
8647
8985
 
8648
8986
  /*
8649
8987
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9162,7 +9500,10 @@ setDefaultConfiguration({
9162
9500
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
9163
9501
  const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
9164
9502
  const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
9165
- const ERR_ANCESTOR_ENTRY = "Entry is a ancestor of target entry";
9503
+ const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
9504
+ const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
9505
+ const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
9506
+ const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
9166
9507
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
9167
9508
  const DUPLICATES_THROW = "throw";
9168
9509
  const DUPLICATES_KEEP_FIRST = "keep-first";
@@ -9170,22 +9511,8 @@ const DUPLICATES_KEEP_LAST = "keep-last";
9170
9511
  const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
9171
9512
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9172
9513
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9173
- const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
9514
+ const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
9174
9515
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
9175
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
9176
- const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
9177
- EXTRAFIELD_TYPE_ZIP64,
9178
- EXTRAFIELD_TYPE_AES,
9179
- EXTRAFIELD_TYPE_NTFS,
9180
- EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
9181
- EXTRAFIELD_TYPE_UNICODE_PATH,
9182
- EXTRAFIELD_TYPE_UNICODE_COMMENT,
9183
- EXTRAFIELD_TYPE_USDZ,
9184
- EXTRAFIELD_TYPE_INFOZIP,
9185
- EXTRAFIELD_TYPE_UNIX,
9186
- EXTRAFIELD_TYPE_UNIX_TYPE1,
9187
- EXTRAFIELD_TYPE_PKWARE_UNIX
9188
- ]);
9189
9516
 
9190
9517
  class ZipEntry {
9191
9518
 
@@ -9557,6 +9884,7 @@ class ZipDirectoryEntry extends ZipEntry {
9557
9884
  await initStream(reader);
9558
9885
  zipReader = new ZipReader(reader, options);
9559
9886
  }
9887
+ checkPassThroughValue(options.passThrough);
9560
9888
  const duplicates = checkDuplicatesOption(options.duplicates);
9561
9889
  const importedEntries = [];
9562
9890
  const entries = await zipReader.getEntries(options);
@@ -9647,18 +9975,25 @@ class ZipDirectoryEntry extends ZipEntry {
9647
9975
 
9648
9976
  async exportZip(writer, options = {}) {
9649
9977
  const zipEntry = this;
9978
+ const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
9650
9979
  options = Object.assign({}, options);
9651
- if (options.bufferedWrite === UNDEFINED_VALUE) {
9980
+ if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
9652
9981
  options.bufferedWrite = true;
9653
9982
  }
9654
- const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
9655
- const zipWriter = new ZipWriter(writer, options);
9983
+ const [readers] = await Promise.all([
9984
+ initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
9985
+ zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
9986
+ ]);
9987
+ const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
9656
9988
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
9989
+ if (zipWriterProvided) {
9990
+ return zipWriter;
9991
+ }
9657
9992
  await zipWriter.close(options.globalComment);
9658
9993
  return writer.getData ? writer.getData() : writer.writable;
9659
9994
  }
9660
9995
 
9661
- getExportedSize(options = {}) {
9996
+ async getExportedSize(options = {}) {
9662
9997
  const zipEntry = this;
9663
9998
  options = Object.assign({}, options);
9664
9999
  checkReaderOptions(options.readerOptions);
@@ -9673,7 +10008,7 @@ class ZipDirectoryEntry extends ZipEntry {
9673
10008
  const writeOrderGuaranteed = !options.bufferedWrite ||
9674
10009
  (entries.every(entry => entry.options.keepOrder !== false) &&
9675
10010
  children.every(child => isImplicitDirectory(child) || !child.children.length));
9676
- return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10011
+ return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
9677
10012
  }
9678
10013
 
9679
10014
  getChildByName(name) {
@@ -9734,7 +10069,7 @@ class ZipFS {
9734
10069
 
9735
10070
  move(entry, destination) {
9736
10071
  if (entry == this.root) {
9737
- throw new Error("Root directory cannot be moved");
10072
+ throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
9738
10073
  } else {
9739
10074
  if (destination.directory) {
9740
10075
  if (!destination.isDescendantOf(entry)) {
@@ -9755,7 +10090,7 @@ class ZipFS {
9755
10090
  throw new Error(ERR_ANCESTOR_ENTRY);
9756
10091
  }
9757
10092
  } else {
9758
- throw new Error("Target entry is not a directory");
10093
+ throw new Error(ERR_TARGET_NOT_DIRECTORY);
9759
10094
  }
9760
10095
  }
9761
10096
  }
@@ -10068,70 +10403,11 @@ function getChildEntryOptions(child, selectedEntry, options) {
10068
10403
  let zipEntryMetadata = {};
10069
10404
  let passThroughOptions = {};
10070
10405
  if (child.data instanceof Entry) {
10071
- const {
10072
- externalFileAttributes,
10073
- versionMadeBy,
10074
- comment,
10075
- lastModDate,
10076
- rawLastModDate,
10077
- creationDate,
10078
- lastAccessDate,
10079
- uncompressedSize,
10080
- encrypted,
10081
- zipCrypto,
10082
- crc32,
10083
- compressionMethod,
10084
- extraFieldAES,
10085
- internalFileAttributes,
10086
- extraField,
10087
- bitFlag,
10088
- uid,
10089
- gid
10090
- } = child.data;
10091
- zipEntryMetadata = {
10092
- externalFileAttributes,
10093
- versionMadeBy,
10094
- comment,
10095
- lastModDate,
10096
- creationDate,
10097
- lastAccessDate,
10098
- internalFileAttributes
10099
- };
10100
- const userExtraField = getUserExtraField(extraField);
10101
- if (userExtraField) {
10102
- zipEntryMetadata.extraField = userExtraField;
10103
- }
10104
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
10105
- Object.assign(zipEntryMetadata, {
10106
- uid,
10107
- gid,
10108
- unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
10109
- });
10110
- }
10111
- if (isPassThrough(child, options)) {
10112
- let encryptionStrength;
10113
- if (extraFieldAES) {
10114
- encryptionStrength = extraFieldAES.strength;
10115
- }
10116
- passThroughOptions = {
10117
- passThrough: true,
10118
- encrypted,
10119
- zipCrypto,
10120
- crc32,
10121
- uncompressedSize,
10122
- encryptionStrength,
10123
- compressionMethod
10124
- };
10125
- if (bitFlag) {
10126
- passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
10127
- }
10128
- const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10129
- if (lastModDateOverride === UNDEFINED_VALUE) {
10130
- passThroughOptions.rawLastModDate = rawLastModDate;
10131
- } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
10132
- getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
10133
- throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
10134
- }
10406
+ const passThrough = isPassThrough(child, options);
10407
+ const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10408
+ ({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
10409
+ if (passThrough) {
10410
+ passThroughOptions.passThrough = true;
10135
10411
  }
10136
10412
  }
10137
10413
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -10141,16 +10417,6 @@ function getChildEntryOptions(child, selectedEntry, options) {
10141
10417
  return { name, entryOptions };
10142
10418
  }
10143
10419
 
10144
- function getDosTimeHighByte(lastModDate) {
10145
- let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
10146
- if (dosLastModDate < MIN_DATE) {
10147
- dosLastModDate = MIN_DATE;
10148
- } else if (dosLastModDate > MAX_DATE) {
10149
- dosLastModDate = MAX_DATE;
10150
- }
10151
- return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
10152
- }
10153
-
10154
10420
  function getDeterminedSize(child, passThrough) {
10155
10421
  const { reader } = child;
10156
10422
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10163,9 +10429,18 @@ function checkReaderOptions(readerOptions) {
10163
10429
  if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10164
10430
  throw new Error(ERR_INVALID_READER_OPTIONS);
10165
10431
  }
10432
+ if (readerOptions) {
10433
+ checkPassThroughValue(readerOptions.passThrough);
10434
+ }
10166
10435
  return readerOptions;
10167
10436
  }
10168
10437
 
10438
+ function checkPassThroughValue(passThrough) {
10439
+ if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
10440
+ throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
10441
+ }
10442
+ }
10443
+
10169
10444
  function replaceContent(zipEntry, params) {
10170
10445
  const { uncompressedSize } = params;
10171
10446
  Object.assign(zipEntry, params, {
@@ -10194,20 +10469,6 @@ function isImplicitDirectory(child) {
10194
10469
  return child.directory && child.data === null;
10195
10470
  }
10196
10471
 
10197
- function getUserExtraField(extraField) {
10198
- if (extraField) {
10199
- const userExtraField = new Map();
10200
- extraField.forEach((field, type) => {
10201
- if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
10202
- userExtraField.set(type, field.data);
10203
- }
10204
- });
10205
- if (userExtraField.size) {
10206
- return userExtraField;
10207
- }
10208
- }
10209
- }
10210
-
10211
10472
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
10212
10473
  const { onstart, onprogress, onend, onentryprogress } = options;
10213
10474
  const selectedEntry = entry;
@@ -10310,6 +10571,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
10310
10571
 
10311
10572
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10312
10573
  const { onstart, onprogress, onend } = options;
10574
+ checkPassThroughValue(options.passThrough);
10313
10575
  const readerOptions = checkReaderOptions(options.readerOptions);
10314
10576
  const abortController = new AbortController();
10315
10577
  const { signal } = abortController;
@@ -10385,7 +10647,7 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10385
10647
  if (exportAborted || isExportAborted(signal.reason)) {
10386
10648
  return;
10387
10649
  }
10388
- throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
10650
+ throwIfAborted(signal);
10389
10651
  }
10390
10652
  try {
10391
10653
  if (child.directory) {
@@ -10518,7 +10780,7 @@ function addChild(parent, name, params, directory) {
10518
10780
  }
10519
10781
  return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
10520
10782
  } else {
10521
- throw new Error("Parent entry is not a directory");
10783
+ throw new Error(ERR_PARENT_NOT_DIRECTORY);
10522
10784
  }
10523
10785
  }
10524
10786
 
@@ -10652,7 +10914,7 @@ function decodeMimeTypes(data) {
10652
10914
  */
10653
10915
 
10654
10916
 
10655
- c(setDefaultConfiguration);
10917
+ f(setDefaultConfiguration);
10656
10918
 
10657
10919
  exports.BlobReader = BlobReader;
10658
10920
  exports.BlobWriter = BlobWriter;
@@ -10660,6 +10922,7 @@ exports.Data64URIReader = Data64URIReader;
10660
10922
  exports.Data64URIWriter = Data64URIWriter;
10661
10923
  exports.ERR_ABORTED = ERR_ABORTED;
10662
10924
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
10925
+ exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
10663
10926
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
10664
10927
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
10665
10928
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
@@ -10673,7 +10936,9 @@ exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
10673
10936
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
10674
10937
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
10675
10938
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
10939
+ exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
10676
10940
  exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
10941
+ exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
10677
10942
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
10678
10943
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
10679
10944
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
@@ -10683,6 +10948,7 @@ exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
10683
10948
  exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
10684
10949
  exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
10685
10950
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
10951
+ exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
10686
10952
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
10687
10953
  exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
10688
10954
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
@@ -10701,6 +10967,7 @@ exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
10701
10967
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
10702
10968
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
10703
10969
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
10970
+ exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
10704
10971
  exports.ERR_INVALID_READER = ERR_INVALID_READER;
10705
10972
  exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
10706
10973
  exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
@@ -10711,14 +10978,19 @@ exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
10711
10978
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
10712
10979
  exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
10713
10980
  exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
10981
+ exports.ERR_INVALID_URI = ERR_INVALID_URI;
10714
10982
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
10715
10983
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
10716
10984
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
10717
10985
  exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
10986
+ exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
10718
10987
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
10719
10988
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
10989
+ exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
10720
10990
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
10991
+ exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
10721
10992
  exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
10993
+ exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
10722
10994
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
10723
10995
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
10724
10996
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -10730,10 +11002,12 @@ exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
10730
11002
  exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
10731
11003
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
10732
11004
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
11005
+ exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
10733
11006
  exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
10734
11007
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10735
11008
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10736
11009
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
11010
+ exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
10737
11011
  exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
10738
11012
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
10739
11013
  exports.HttpRangeReader = HttpRangeReader;
@@ -10747,13 +11021,17 @@ exports.Uint8ArrayReader = Uint8ArrayReader;
10747
11021
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
10748
11022
  exports.VERSION = VERSION;
10749
11023
  exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
11024
+ exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
10750
11025
  exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
11026
+ exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
10751
11027
  exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
10752
11028
  exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
10753
11029
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
10754
11030
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
10755
11031
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
11032
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
10756
11033
  exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
11034
+ exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
10757
11035
  exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
10758
11036
  exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
10759
11037
  exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;