@zip.js/zip.js 2.11.3 → 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 +444 -114
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +454 -111
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +509 -236
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +522 -233
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +509 -236
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +524 -235
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +525 -236
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +456 -113
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +456 -113
  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 +457 -114
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +524 -235
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +525 -236
  27. package/index.d.cts +480 -59
  28. package/index.d.ts +480 -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 +20 -10
  35. package/lib/core/options.js +29 -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 -134
  44. package/lib/core/zip-reader.js +108 -47
  45. package/lib/core/zip-writer.js +238 -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
@@ -134,6 +134,7 @@
134
134
  const BOOLEAN_TYPE = "boolean";
135
135
 
136
136
  const EMPTY_UINT8_ARRAY = new Uint8Array();
137
+ const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
137
138
 
138
139
  /*
139
140
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -178,6 +179,7 @@
178
179
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
179
180
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
180
181
  const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
182
+ const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
181
183
  const OPTION_CHECK_SIGNATURE = "checkSignature";
182
184
  const OPTION_CHECK_CRC32 = "checkCrc32";
183
185
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -208,15 +210,20 @@
208
210
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
209
211
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
210
212
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
213
+ const OPTION_ENTRY = "entry";
211
214
  const TEXT_TYPE_FILENAME = "filename";
212
215
  const TEXT_TYPE_COMMENT = "comment";
213
216
  const STRICTNESS_STRICT = "strict";
214
217
  const STRICTNESS_BALANCED = "balanced";
215
218
  const STRICTNESS_TOLERANT = "tolerant";
219
+ const PASS_THROUGH_COMPRESSED = "compressed";
216
220
 
217
221
  const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
218
222
  const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
219
223
  const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
224
+ const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
225
+ const ERR_ABORTED = "The operation was aborted";
226
+ const ABORT_ERROR_NAME = "AbortError";
220
227
 
221
228
  function checkFunctionOption(value) {
222
229
  if (value && typeof value != FUNCTION_TYPE) {
@@ -232,12 +239,25 @@
232
239
  return signal || UNDEFINED_VALUE;
233
240
  }
234
241
 
242
+ function throwIfAborted(signal) {
243
+ if (signal && signal.aborted) {
244
+ throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
245
+ }
246
+ }
247
+
235
248
  function checkPasswordOption(password, rawPassword) {
236
249
  if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
237
250
  throw new Error(ERR_INVALID_PASSWORD_TYPE);
238
251
  }
239
252
  }
240
253
 
254
+ function checkPassThroughOption(passThrough) {
255
+ if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
256
+ throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
257
+ }
258
+ return passThrough;
259
+ }
260
+
241
261
  function checkInteger(value, maxValue, errorMessage) {
242
262
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
243
263
  throw new Error(errorMessage);
@@ -287,6 +307,8 @@
287
307
  const MINIMUM_CHUNK_SIZE = 64;
288
308
  const MINIMUM_PROPERTY_VALUE = 1;
289
309
  const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
310
+ const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
311
+ const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
290
312
  let maxWorkers = 2;
291
313
  try {
292
314
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -311,9 +333,9 @@
311
333
  };
312
334
 
313
335
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
336
+ const PROPERTY_NAME_BASE_URI = "baseURI";
314
337
 
315
- const STRING_PROPERTY_NAMES = [
316
- "baseURI",
338
+ const URI_PROPERTY_NAMES = [
317
339
  "wasmURI",
318
340
  "workerURI"
319
341
  ];
@@ -337,7 +359,8 @@
337
359
  "DecompressionStreamFallback"
338
360
  ];
339
361
  const CONFIGURABLE_PROPERTY_NAMES = [
340
- ...STRING_PROPERTY_NAMES,
362
+ PROPERTY_NAME_BASE_URI,
363
+ ...URI_PROPERTY_NAMES,
341
364
  ...BOOLEAN_PROPERTY_NAMES,
342
365
  ...NUMBER_PROPERTY_NAMES,
343
366
  ...FUNCTION_PROPERTY_NAMES
@@ -381,6 +404,14 @@
381
404
  }
382
405
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
383
406
  checkFunctionOption(propertyValue);
407
+ } else if (propertyName == PROPERTY_NAME_BASE_URI) {
408
+ if (propertyValue && typeof propertyValue != STRING_TYPE) {
409
+ throw new Error(ERR_INVALID_BASE_URI);
410
+ }
411
+ } else if (URI_PROPERTY_NAMES.includes(propertyName)) {
412
+ if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
413
+ throw new Error(ERR_INVALID_URI);
414
+ }
384
415
  }
385
416
  return propertyValue;
386
417
  }
@@ -414,7 +445,7 @@
414
445
  Object.assign(config, DEFAULT_CONFIGURATION);
415
446
  }
416
447
 
417
- 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="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.indexOf(o[s])<<18|g.indexOf(o[s+1])<<12|(63&g.indexOf(o[s+2]))<<6|63&g.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[e>>18&63]+g[e>>12&63]+g[e>>6&63]+g[63&e];}const r=e-s;if(1===r){const e=o[s]<<16;t+=g[e>>18&63]+g[e>>12&63]+"==";}else if(2===r){const e=o[s]<<16|o[s+1]<<8;t+=g[e>>18&63]+g[e>>12&63]+g[e>>6&63]+"=";}return t}(e)}}));var O;
448
+ 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;
418
449
 
419
450
  /*
420
451
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -2599,6 +2630,7 @@
2599
2630
  constructor(chunkSize) {
2600
2631
  const pendingChunks = [];
2601
2632
  let pendingLength = 0;
2633
+ let outputSize = 0;
2602
2634
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2603
2635
  chunkSize = DEFAULT_CHUNK_SIZE;
2604
2636
  }
@@ -2607,15 +2639,20 @@
2607
2639
  pendingChunks.push(chunk);
2608
2640
  pendingLength += chunk.length;
2609
2641
  while (pendingLength > chunkSize) {
2642
+ outputSize += chunkSize;
2610
2643
  controller.enqueue(shiftChunk());
2611
2644
  }
2612
2645
  },
2613
2646
  flush(controller) {
2614
2647
  if (pendingLength) {
2648
+ outputSize += pendingLength;
2615
2649
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2616
2650
  }
2617
2651
  }
2618
2652
  });
2653
+ Object.defineProperty(this, "outputSize", {
2654
+ get: () => outputSize
2655
+ });
2619
2656
 
2620
2657
  function shiftChunk() {
2621
2658
  const result = new Uint8Array(chunkSize);
@@ -2816,7 +2853,7 @@
2816
2853
  }
2817
2854
 
2818
2855
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2819
- let codecStream;
2856
+ let codecStream, chunkStream;
2820
2857
  try {
2821
2858
  if (options.compressed && !options.format) {
2822
2859
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2839,9 +2876,10 @@
2839
2876
  }
2840
2877
  }
2841
2878
  codecStream = new CodecStream(options, config);
2879
+ chunkStream = new ChunkStream(getChunkSize(config));
2842
2880
  await readable
2843
2881
  .pipeThrough(codecStream)
2844
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2882
+ .pipeThrough(chunkStream)
2845
2883
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2846
2884
  const {
2847
2885
  crc32,
@@ -2855,7 +2893,7 @@
2855
2893
  };
2856
2894
  } catch (error) {
2857
2895
  if (codecStream) {
2858
- error.outputSize = codecStream.outputSize;
2896
+ error.outputSize = chunkStream ? chunkStream.outputSize : 0;
2859
2897
  }
2860
2898
  throw error;
2861
2899
  } finally {
@@ -2964,11 +3002,17 @@
2964
3002
  let resolveResult, rejectResult;
2965
3003
  const result = new Promise((resolve, reject) => {
2966
3004
  resolveResult = resolve;
2967
- rejectResult = reject;
3005
+ rejectResult = error => {
3006
+ if (error && error.outputSize === UNDEFINED_VALUE) {
3007
+ error.outputSize = workerData.outputSize;
3008
+ }
3009
+ reject(error);
3010
+ };
2968
3011
  });
2969
3012
  Object.assign(workerData, {
2970
3013
  reader: null,
2971
3014
  writer: null,
3015
+ outputSize: 0,
2972
3016
  resolveResult,
2973
3017
  rejectResult,
2974
3018
  result
@@ -3252,8 +3296,10 @@
3252
3296
  }
3253
3297
  }
3254
3298
  if (type == MESSAGE_DATA) {
3299
+ const chunk = new Uint8Array(value);
3255
3300
  await writer.ready;
3256
- await writer.write(new Uint8Array(value));
3301
+ await writer.write(chunk);
3302
+ workerData.outputSize += chunk.length;
3257
3303
  if (!stale()) {
3258
3304
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3259
3305
  }
@@ -3561,10 +3607,13 @@
3561
3607
 
3562
3608
 
3563
3609
  const ERR_HTTP_STATUS = "HTTP error ";
3610
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3611
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3564
3612
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3565
3613
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3566
3614
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3567
3615
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3616
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3568
3617
 
3569
3618
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3570
3619
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3756,11 +3805,14 @@
3756
3805
  const reader = this;
3757
3806
  const { sourceBlob, size } = reader;
3758
3807
  const { offset = 0, size: readSize = size - offset } = options || {};
3759
- if (!offset && readSize >= size) {
3760
- return toCompatibleReadable(sourceBlob.stream());
3761
- }
3762
- if (blobSliceReliable) {
3763
- return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3808
+ // deno-lint-ignore valid-typeof
3809
+ if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3810
+ if (!offset && readSize >= size) {
3811
+ return toCompatibleReadable(sourceBlob.stream());
3812
+ }
3813
+ if (blobSliceReliable) {
3814
+ return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3815
+ }
3764
3816
  }
3765
3817
  return super.createReadable(options);
3766
3818
  }
@@ -4140,7 +4192,7 @@
4140
4192
 
4141
4193
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4142
4194
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4143
- if (response.status < 400) {
4195
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4144
4196
  return response;
4145
4197
  } else {
4146
4198
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4151,7 +4203,7 @@
4151
4203
  return new Promise((resolve, reject) => {
4152
4204
  const request = new XMLHttpRequest();
4153
4205
  request.addEventListener("load", () => {
4154
- if (request.status < 400) {
4206
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4155
4207
  const headers = [];
4156
4208
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4157
4209
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4455,8 +4507,10 @@
4455
4507
  writable: toCompatibleWritable(writer)
4456
4508
  };
4457
4509
  }
4458
- if (writer.size === UNDEFINED_VALUE) {
4459
- writer.size = 0;
4510
+ try {
4511
+ writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
4512
+ } catch {
4513
+ throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
4460
4514
  }
4461
4515
  return writer;
4462
4516
  }
@@ -4504,6 +4558,45 @@
4504
4558
  }
4505
4559
  }
4506
4560
 
4561
+ /*
4562
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
4563
+
4564
+ Redistribution and use in source and binary forms, with or without
4565
+ modification, are permitted provided that the following conditions are met:
4566
+
4567
+ 1. Redistributions of source code must retain the above copyright notice,
4568
+ this list of conditions and the following disclaimer.
4569
+
4570
+ 2. Redistributions in binary form must reproduce the above copyright
4571
+ notice, this list of conditions and the following disclaimer in
4572
+ the documentation and/or other materials provided with the distribution.
4573
+
4574
+ 3. The names of the authors may not be used to endorse or promote products
4575
+ derived from this software without specific prior written permission.
4576
+
4577
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4578
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4579
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4580
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4581
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4582
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4583
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4584
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4585
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4586
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4587
+ */
4588
+
4589
+
4590
+ function addWarning(warnings, reason, filename) {
4591
+ if (!warnings.some(warning => warning.reason == reason)) {
4592
+ const warning = { reason };
4593
+ if (filename !== UNDEFINED_VALUE) {
4594
+ warning.filename = filename;
4595
+ }
4596
+ warnings.push(warning);
4597
+ }
4598
+ }
4599
+
4507
4600
  /*
4508
4601
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4509
4602
 
@@ -4532,6 +4625,7 @@
4532
4625
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4533
4626
  */
4534
4627
 
4628
+
4535
4629
  const PROPERTY_NAME_FILENAME = "filename";
4536
4630
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4537
4631
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4656,6 +4750,38 @@
4656
4750
 
4657
4751
  }
4658
4752
 
4753
+ const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
4754
+ EXTRAFIELD_TYPE_ZIP64,
4755
+ EXTRAFIELD_TYPE_AES,
4756
+ EXTRAFIELD_TYPE_NTFS,
4757
+ EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
4758
+ EXTRAFIELD_TYPE_UNICODE_PATH,
4759
+ EXTRAFIELD_TYPE_UNICODE_COMMENT,
4760
+ EXTRAFIELD_TYPE_USDZ,
4761
+ EXTRAFIELD_TYPE_INFOZIP,
4762
+ EXTRAFIELD_TYPE_UNIX,
4763
+ EXTRAFIELD_TYPE_UNIX_TYPE1,
4764
+ EXTRAFIELD_TYPE_PKWARE_UNIX
4765
+ ]);
4766
+
4767
+ function getUserExtraField(extraField) {
4768
+ if (extraField) {
4769
+ const userExtraField = new Map();
4770
+ extraField.forEach((field, type) => {
4771
+ if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
4772
+ userExtraField.set(type, field.data);
4773
+ }
4774
+ });
4775
+ if (userExtraField.size) {
4776
+ return userExtraField;
4777
+ }
4778
+ }
4779
+ }
4780
+
4781
+ function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
4782
+ return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
4783
+ }
4784
+
4659
4785
  /*
4660
4786
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4661
4787
 
@@ -4715,6 +4841,8 @@
4715
4841
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4716
4842
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4717
4843
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4844
+ const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
4845
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
4718
4846
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4719
4847
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4720
4848
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4785,7 +4913,7 @@
4785
4913
  }
4786
4914
  }
4787
4915
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4788
- throwAmbiguousArchive("multiple end of central directory records");
4916
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4789
4917
  }
4790
4918
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4791
4919
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5083,7 +5211,8 @@
5083
5211
  const writer = new TransformStream();
5084
5212
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5085
5213
  arrayBufferPromise.catch(() => { });
5086
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5214
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5215
+ Object.assign({}, options, { preventClose: false }));
5087
5216
  return arrayBufferPromise;
5088
5217
  };
5089
5218
  offset = endOffset;
@@ -5164,48 +5293,101 @@
5164
5293
  await reader.readable.cancel();
5165
5294
  }
5166
5295
  }
5296
+
5297
+ [SYMBOL_ASYNC_DISPOSE]() {
5298
+ return this.close();
5299
+ }
5167
5300
  }
5168
5301
 
5169
5302
  class ZipReaderStream {
5170
5303
 
5171
5304
  constructor(options = {}) {
5172
- const { readable, writable } = new TransformStream();
5173
- const gen = new ZipReader(readable, options).getEntriesGenerator();
5305
+ let sourceController;
5306
+ const { readable, writable } = new TransformStream({
5307
+ start(controller) {
5308
+ sourceController = controller;
5309
+ }
5310
+ });
5311
+ const zipReader = new ZipReader(readable, options);
5312
+ const gen = zipReader.getEntriesGenerator();
5313
+ const pendingEntries = new Set();
5174
5314
  this.readable = new ReadableStream({
5175
5315
  async pull(controller) {
5176
5316
  const { done, value } = await gen.next();
5177
5317
  if (done)
5178
5318
  return controller.close();
5319
+ const entryStream = createEntryStream(value, pendingEntries);
5179
5320
  const chunk = {
5180
5321
  ...value,
5181
- readable: (function () {
5182
- const { readable, writable } = new TransformStream();
5183
- if (value.getData) {
5184
- getData();
5185
- return readable;
5186
- }
5187
-
5188
- async function getData() {
5189
- try {
5190
- await value.getData(writable);
5191
- } catch (error) {
5192
- try {
5193
- await writable.abort(error);
5194
- } catch {
5195
- // ignored
5196
- }
5197
- }
5198
- }
5199
- })()
5322
+ readable: entryStream.readable
5200
5323
  };
5201
5324
  delete chunk.getData;
5325
+ Object.defineProperties(chunk, {
5326
+ localDirectory: {
5327
+ get: () => value.localDirectory,
5328
+ enumerable: true
5329
+ },
5330
+ warnings: {
5331
+ get: () => value.warnings,
5332
+ enumerable: true
5333
+ }
5334
+ });
5202
5335
  controller.enqueue(chunk);
5336
+ },
5337
+ async cancel(reason) {
5338
+ const entryStreams = Array.from(pendingEntries);
5339
+ pendingEntries.clear();
5340
+ sourceController.error(reason);
5341
+ await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
5342
+ await Promise.allSettled([gen.return(), zipReader.close()]);
5203
5343
  }
5204
5344
  });
5205
5345
  this.writable = writable;
5206
5346
  }
5207
5347
  }
5208
5348
 
5349
+ function createEntryStream(entry, pendingEntries) {
5350
+ const { readable, writable } = new TransformStream();
5351
+ let dataReader;
5352
+ const entryStream = {
5353
+ cancel: async reason => {
5354
+ pendingEntries.delete(entryStream);
5355
+ await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
5356
+ }
5357
+ };
5358
+ entryStream.readable = new ReadableStream({
5359
+ async pull(controller) {
5360
+ if (!dataReader) {
5361
+ dataReader = readable.getReader();
5362
+ pendingEntries.add(entryStream);
5363
+ getData();
5364
+ }
5365
+ const { done, value } = await dataReader.read();
5366
+ if (done) {
5367
+ controller.close();
5368
+ } else {
5369
+ controller.enqueue(value);
5370
+ }
5371
+ },
5372
+ cancel: reason => entryStream.cancel(reason)
5373
+ }, { highWaterMark: 0 });
5374
+ return entryStream;
5375
+
5376
+ async function getData() {
5377
+ try {
5378
+ await entry.getData(writable, { preventClose: false });
5379
+ } catch (error) {
5380
+ try {
5381
+ await writable.abort(error);
5382
+ } catch {
5383
+ // ignored
5384
+ }
5385
+ } finally {
5386
+ pendingEntries.delete(entryStream);
5387
+ }
5388
+ }
5389
+ }
5390
+
5209
5391
  async function isZipFile(reader, options = {}) {
5210
5392
  reader = new GenericReader(reader);
5211
5393
  await initStream(reader);
@@ -5265,7 +5447,9 @@
5265
5447
  const dataView = getDataView(dataArray);
5266
5448
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5267
5449
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5268
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5450
+ const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
5451
+ const passThroughCompression = Boolean(passThrough);
5452
+ const passThroughEncryption = passThrough === true;
5269
5453
  checkPasswordOption(password, rawPassword);
5270
5454
  password = password && password.length && password;
5271
5455
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5286,7 +5470,9 @@
5286
5470
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5287
5471
  const entryStrictness = getStrictness(options, zipEntry.options);
5288
5472
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5289
- const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5473
+ const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
5474
+ const checkLocalFilename = getCheckLocalFilename(
5475
+ checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
5290
5476
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5291
5477
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5292
5478
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5317,16 +5503,17 @@
5317
5503
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5318
5504
  fileEntry.gid = gid;
5319
5505
  }
5320
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5506
+ const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5507
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5321
5508
  const zipCrypto = encrypted && !extraFieldAES;
5322
- if (!passThrough) {
5509
+ if (!passThroughEncryption) {
5323
5510
  fileEntry.zipCrypto = zipCrypto;
5324
5511
  }
5325
5512
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5326
5513
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5327
5514
  }
5328
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5329
- if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThrough) {
5515
+ const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5516
+ if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
5330
5517
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5331
5518
  }
5332
5519
  if (encrypted) {
@@ -5342,15 +5529,17 @@
5342
5529
  const size = compressedSize;
5343
5530
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5344
5531
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5345
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5532
+ throwIfAborted(signal);
5346
5533
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5347
5534
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5348
5535
  if (checkOverlappingEntryOnly) {
5349
5536
  checkOverlappingEntry = true;
5350
5537
  }
5351
5538
  const { onstart, onprogress, onend } = options;
5352
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5353
- const outputSize = passThrough ? compressedSize : uncompressedSize;
5539
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
5540
+ const outputSize = passThroughCompression ?
5541
+ compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
5542
+ uncompressedSize;
5354
5543
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5355
5544
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5356
5545
  if (deflate64) {
@@ -5359,7 +5548,7 @@
5359
5548
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5360
5549
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5361
5550
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5362
- checkCrc32Option) && !passThrough &&
5551
+ checkCrc32Option) && !passThroughCompression &&
5363
5552
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5364
5553
  const workerOptions = {
5365
5554
  options: {
@@ -5413,10 +5602,10 @@
5413
5602
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5414
5603
  ({ writable } = writer);
5415
5604
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5416
- writer.size += writtenSize;
5417
5605
  if (writtenSize != outputSize) {
5418
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5606
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5419
5607
  }
5608
+ writer.size += writtenSize;
5420
5609
  }
5421
5610
  } catch (error) {
5422
5611
  if (error.outputSize !== UNDEFINED_VALUE) {
@@ -6082,7 +6271,7 @@
6082
6271
  if (checkLocalFilename && !maskedLocalDirectory &&
6083
6272
  (rawLocalFilename.length != rawFilename.length ||
6084
6273
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6085
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6274
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6086
6275
  }
6087
6276
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6088
6277
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6107,16 +6296,6 @@
6107
6296
  }
6108
6297
  }
6109
6298
 
6110
- function addWarning(warnings, reason, filename) {
6111
- if (!warnings.some(warning => warning.reason == reason)) {
6112
- const warning = { reason };
6113
- if (filename !== UNDEFINED_VALUE) {
6114
- warning.filename = filename;
6115
- }
6116
- warnings.push(warning);
6117
- }
6118
- }
6119
-
6120
6299
  function throwAmbiguousArchive(reason) {
6121
6300
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6122
6301
  error.reason = reason;
@@ -6196,7 +6375,9 @@
6196
6375
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6197
6376
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6198
6377
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6378
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6199
6379
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6380
+ WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6200
6381
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6201
6382
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6202
6383
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6249,7 +6430,7 @@
6249
6430
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6250
6431
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6251
6432
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6252
- const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6433
+ const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
6253
6434
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6254
6435
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6255
6436
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6261,6 +6442,7 @@
6261
6442
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6262
6443
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6263
6444
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6445
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6264
6446
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6265
6447
  const ERR_UNDEFINED_READER = "Undefined reader";
6266
6448
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6274,14 +6456,21 @@
6274
6456
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6275
6457
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6276
6458
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6459
+ const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
6460
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
6461
+ const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
6462
+ const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
6277
6463
 
6278
6464
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6279
6465
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6280
6466
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6281
6467
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6468
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6469
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6282
6470
  const VENDOR_VERSION_AE_1 = 1;
6283
6471
  const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6284
6472
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6473
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6285
6474
  const MAX_LEVEL = 9;
6286
6475
 
6287
6476
  let workers = 0;
@@ -6308,9 +6497,11 @@
6308
6497
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6309
6498
  pendingAddFileCalls: new Set(),
6310
6499
  pendingErrors: [],
6500
+ warnings: [],
6311
6501
  bufferedWrites: 0,
6312
6502
  directWrites: 0,
6313
- lastFileEntry: UNDEFINED_VALUE
6503
+ lastFileEntry: UNDEFINED_VALUE,
6504
+ archiveClosed: false
6314
6505
  });
6315
6506
  }
6316
6507
 
@@ -6475,6 +6666,9 @@
6475
6666
  const zipWriter = this;
6476
6667
  const { pendingAddFileCalls, writer } = this;
6477
6668
  const { writable } = writer;
6669
+ if (zipWriter.archiveClosed) {
6670
+ return getWriterData(writer);
6671
+ }
6478
6672
  if (!(comment instanceof Uint8Array)) {
6479
6673
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6480
6674
  }
@@ -6498,11 +6692,16 @@
6498
6692
  throw error;
6499
6693
  }
6500
6694
  await closeFile(zipWriter, comment, options);
6695
+ zipWriter.archiveClosed = true;
6501
6696
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6502
6697
  if (!preventClose) {
6503
6698
  await writable.getWriter().close();
6504
6699
  }
6505
- return writer.getData ? writer.getData() : writable;
6700
+ return getWriterData(writer);
6701
+ }
6702
+
6703
+ [SYMBOL_ASYNC_DISPOSE]() {
6704
+ return this.close();
6506
6705
  }
6507
6706
  }
6508
6707
 
@@ -6581,6 +6780,10 @@
6581
6780
  }
6582
6781
  }
6583
6782
 
6783
+ function getWriterData(writer) {
6784
+ return writer.getData ? writer.getData() : writer.writable;
6785
+ }
6786
+
6584
6787
  function watchPromiseError(zipWriter, promise) {
6585
6788
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6586
6789
  const watcher = {};
@@ -6599,6 +6802,14 @@
6599
6802
 
6600
6803
  async function addFileEntry(zipWriter, name, reader, options) {
6601
6804
  options = Object.assign({}, options);
6805
+ const entry = options[OPTION_ENTRY];
6806
+ if (entry !== UNDEFINED_VALUE) {
6807
+ const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
6808
+ checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
6809
+ getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
6810
+ delete options[OPTION_ENTRY];
6811
+ options = Object.assign(entryOptions, passThroughOptions, options);
6812
+ }
6602
6813
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6603
6814
  name += DIRECTORY_SIGNATURE;
6604
6815
  }
@@ -6663,21 +6874,33 @@
6663
6874
  try {
6664
6875
  const { resolvedOptions } = metadataInfo;
6665
6876
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6666
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6877
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6667
6878
  resolvedOptions.level = 0;
6879
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6668
6880
  }
6669
6881
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6670
6882
  ({ reader } = sizesInfo);
6671
6883
  const diskOffset = getDiskOffset(zipWriter.writer);
6672
6884
  const diskNumber = getDiskNumber(zipWriter.writer);
6885
+ let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
6886
+ const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
6887
+ if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
6888
+ crc32 = UNDEFINED_VALUE;
6889
+ }
6890
+ if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
6891
+ throw new Error(ERR_UNDEFINED_CRC32);
6892
+ }
6673
6893
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6674
6894
  signature: options[PROPERTY_NAME_SIGNATURE],
6675
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6895
+ crc32,
6676
6896
  offset: zipWriter.offset - diskOffset,
6677
6897
  diskNumberStart: diskNumber,
6678
6898
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6679
6899
  });
6680
6900
  const headerInfo = getHeaderInfo(options);
6901
+ if (headerInfo.lastModDateClamped) {
6902
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
6903
+ }
6681
6904
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6682
6905
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6683
6906
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6704,6 +6927,95 @@
6704
6927
  return new Entry(fileEntry);
6705
6928
  }
6706
6929
 
6930
+ function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
6931
+ if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
6932
+ throw new Error(ERR_INVALID_ENTRY);
6933
+ }
6934
+ const {
6935
+ externalFileAttributes,
6936
+ versionMadeBy,
6937
+ comment,
6938
+ lastModDate,
6939
+ rawLastModDate,
6940
+ creationDate,
6941
+ lastAccessDate,
6942
+ uncompressedSize,
6943
+ encrypted,
6944
+ zipCrypto,
6945
+ crc32,
6946
+ compressionMethod,
6947
+ extraFieldAES,
6948
+ extraFieldUnix,
6949
+ internalFileAttributes,
6950
+ extraField,
6951
+ bitFlag,
6952
+ directory,
6953
+ uid,
6954
+ gid
6955
+ } = entry;
6956
+ const entryOptions = {
6957
+ externalFileAttributes,
6958
+ versionMadeBy,
6959
+ comment,
6960
+ lastModDate,
6961
+ creationDate,
6962
+ lastAccessDate,
6963
+ internalFileAttributes,
6964
+ directory
6965
+ };
6966
+ if (bitFlag && bitFlag.languageEncodingFlag) {
6967
+ entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
6968
+ }
6969
+ const userExtraField = getUserExtraField(extraField);
6970
+ if (userExtraField) {
6971
+ entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
6972
+ }
6973
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
6974
+ Object.assign(entryOptions, {
6975
+ uid,
6976
+ gid,
6977
+ unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
6978
+ });
6979
+ }
6980
+ const passThroughOptions = {};
6981
+ if (passThrough && !directory) {
6982
+ Object.assign(passThroughOptions, {
6983
+ uncompressedSize,
6984
+ crc32,
6985
+ compressionMethod
6986
+ });
6987
+ if (passThrough !== PASS_THROUGH_COMPRESSED) {
6988
+ Object.assign(passThroughOptions, {
6989
+ encrypted,
6990
+ zipCrypto,
6991
+ encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
6992
+ });
6993
+ }
6994
+ if (bitFlag) {
6995
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
6996
+ passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
6997
+ }
6998
+ if (lastModDateOverride === UNDEFINED_VALUE) {
6999
+ passThroughOptions.rawLastModDate = rawLastModDate;
7000
+ } else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
7001
+ lastModDateOverride instanceof Date &&
7002
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
7003
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
7004
+ }
7005
+ }
7006
+ return { entryOptions, passThroughOptions };
7007
+ }
7008
+
7009
+ function getDosTimeHighByte(lastModDate) {
7010
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
7011
+ if (dosLastModDate < MIN_DATE) {
7012
+ dosLastModDate = MIN_DATE;
7013
+ } else if (dosLastModDate > MAX_DATE) {
7014
+ dosLastModDate = MAX_DATE;
7015
+ }
7016
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
7017
+ }
7018
+
6707
7019
  function resolveAttributes(zipWriter, name, options) {
6708
7020
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6709
7021
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6857,7 +7169,9 @@
6857
7169
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6858
7170
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6859
7171
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6860
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
7172
+ const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7173
+ const passThroughCompression = Boolean(passThrough);
7174
+ const passThroughEncryption = passThrough === true;
6861
7175
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6862
7176
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6863
7177
  checkPasswordOption(password, rawPassword);
@@ -6872,10 +7186,12 @@
6872
7186
  const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6873
7187
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6874
7188
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6875
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7189
+ throwIfAborted(signal);
7190
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7191
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6876
7192
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6877
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6878
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7193
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7194
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6879
7195
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6880
7196
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6881
7197
  }
@@ -6889,15 +7205,15 @@
6889
7205
  level = 0;
6890
7206
  }
6891
7207
  }
6892
- if (passThrough) {
6893
- level = UNDEFINED_VALUE;
7208
+ if (passThroughCompression) {
7209
+ level = toNumber(options[OPTION_LEVEL]);
6894
7210
  }
6895
7211
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6896
7212
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6897
7213
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6898
7214
  dataDescriptor = false;
6899
7215
  }
6900
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7216
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6901
7217
  dataDescriptor = true;
6902
7218
  }
6903
7219
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6921,7 +7237,8 @@
6921
7237
  lastAccessDate,
6922
7238
  creationDate,
6923
7239
  internalFileAttributes,
6924
- passThrough,
7240
+ passThroughCompression,
7241
+ passThroughEncryption,
6925
7242
  password,
6926
7243
  rawPassword,
6927
7244
  encryptionStrength,
@@ -6982,7 +7299,7 @@
6982
7299
  }
6983
7300
 
6984
7301
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
6985
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7302
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
6986
7303
  throw new Error(ERR_UNDEFINED_READER);
6987
7304
  }
6988
7305
  let contentSize;
@@ -6998,12 +7315,12 @@
6998
7315
  }
6999
7316
 
7000
7317
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7001
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7318
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7002
7319
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7003
7320
  let maximumCompressedSize = 0;
7004
7321
  let uncompressedSize = 0;
7005
7322
  let unknownSize = false;
7006
- if (passThrough && hasContent) {
7323
+ if (passThroughCompression && hasContent) {
7007
7324
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7008
7325
  if (uncompressedSize === UNDEFINED_VALUE) {
7009
7326
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7014,17 +7331,17 @@
7014
7331
  }
7015
7332
  const zip64Enabled = zip64 === true;
7016
7333
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7017
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7334
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7018
7335
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7019
7336
  }
7020
- const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
7337
+ const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
7021
7338
  if (!hasContent) {
7022
7339
  level = 0;
7023
7340
  compressionMethod = COMPRESSION_METHOD_STORE;
7024
7341
  }
7025
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7342
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7026
7343
  if (hasContent) {
7027
- if (!passThrough) {
7344
+ if (!passThroughCompression) {
7028
7345
  if (contentSize === UNDEFINED_VALUE) {
7029
7346
  dataDescriptor = true;
7030
7347
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7037,10 +7354,12 @@
7037
7354
  }
7038
7355
  } else {
7039
7356
  options.uncompressedSize = uncompressedSize;
7040
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7357
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7358
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7359
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7041
7360
  }
7042
7361
  }
7043
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7362
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7044
7363
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7045
7364
  dataDescriptor = false;
7046
7365
  }
@@ -7247,6 +7566,7 @@
7247
7566
  localExtraFieldZip64Length,
7248
7567
  rawExtraFieldExtendedTimestamp,
7249
7568
  extraFieldExtendedTimestampFlag,
7569
+ extraFieldExtendedTimestampTime,
7250
7570
  rawExtraFieldNTFS,
7251
7571
  rawExtraFieldUnix,
7252
7572
  rawExtraFieldAES,
@@ -7259,6 +7579,7 @@
7259
7579
  password,
7260
7580
  rawPassword,
7261
7581
  level,
7582
+ useUnicodeFileNames,
7262
7583
  zip64,
7263
7584
  zip64Enabled,
7264
7585
  zip64UncompressedSize,
@@ -7293,7 +7614,8 @@
7293
7614
  msdosAttributesRaw,
7294
7615
  msdosAttributes,
7295
7616
  useCompressionStream,
7296
- passThrough,
7617
+ passThroughCompression,
7618
+ passThroughEncryption,
7297
7619
  format,
7298
7620
  codecURI
7299
7621
  } = options;
@@ -7304,9 +7626,9 @@
7304
7626
  zip64Enabled,
7305
7627
  directory: Boolean(directory),
7306
7628
  executable: Boolean(executable),
7307
- filenameUTF8: true,
7629
+ filenameUTF8: Boolean(useUnicodeFileNames),
7308
7630
  rawFilename,
7309
- commentUTF8: true,
7631
+ commentUTF8: Boolean(useUnicodeFileNames),
7310
7632
  rawComment,
7311
7633
  rawExtraFieldZip64,
7312
7634
  localExtraFieldZip64Length,
@@ -7337,7 +7659,7 @@
7337
7659
  uncompressedSize
7338
7660
  } = options;
7339
7661
  let compressedSize = 0;
7340
- if (!passThrough) {
7662
+ if (!passThroughCompression) {
7341
7663
  uncompressedSize = 0;
7342
7664
  }
7343
7665
  const { writable } = writer;
@@ -7354,9 +7676,9 @@
7354
7676
  encryptionStrength,
7355
7677
  zipCrypto: encrypted && zipCrypto,
7356
7678
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7357
- computeCrc32: !passThrough,
7358
- compressed: compressed && !passThrough,
7359
- encrypted: encrypted && !passThrough,
7679
+ computeCrc32: !passThroughCompression,
7680
+ compressed: compressed && !passThroughCompression,
7681
+ encrypted: encrypted && !passThroughEncryption,
7360
7682
  useWebWorkers,
7361
7683
  useCompressionStream,
7362
7684
  transferStreams,
@@ -7371,7 +7693,7 @@
7371
7693
  const result = await runWorker({ readable, writable }, workerOptions);
7372
7694
  compressedSize = result.outputSize;
7373
7695
  writer.size += compressedSize;
7374
- if (!passThrough) {
7696
+ if (!passThroughCompression) {
7375
7697
  uncompressedSize = result.inputSize;
7376
7698
  if (!encrypted || zipCrypto) {
7377
7699
  crc32 = result.crc32;
@@ -7414,8 +7736,9 @@
7414
7736
  headerArray,
7415
7737
  headerView,
7416
7738
  signature: crc32,
7417
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7739
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7418
7740
  extraFieldExtendedTimestampFlag,
7741
+ extraFieldExtendedTimestampTime,
7419
7742
  zip64UncompressedSize,
7420
7743
  zip64CompressedSize
7421
7744
  });
@@ -7440,7 +7763,7 @@
7440
7763
  encryptionStrength,
7441
7764
  extendedTimestamp,
7442
7765
  ntfsTimestamp,
7443
- passThrough,
7766
+ passThroughCompression,
7444
7767
  encrypted,
7445
7768
  zip64UncompressedSize,
7446
7769
  zip64CompressedSize,
@@ -7451,7 +7774,7 @@
7451
7774
  let { version, compressionMethod } = options;
7452
7775
  const compressed = !directory && isCompressed(compressionMethod, level);
7453
7776
  let rawLocalExtraFieldZip64;
7454
- const uncompressedFile = passThrough || !compressed;
7777
+ const uncompressedFile = passThroughCompression || !compressed;
7455
7778
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7456
7779
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7457
7780
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7463,8 +7786,8 @@
7463
7786
  if (zip64ExtraFieldComplete) {
7464
7787
  extraFieldZip64.writeUint64(uncompressedSize);
7465
7788
  if (uncompressedFile) {
7466
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7467
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7789
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
7790
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7468
7791
  }
7469
7792
  }
7470
7793
  } else {
@@ -7483,6 +7806,7 @@
7483
7806
  let rawExtraFieldNTFS;
7484
7807
  let rawExtraFieldExtendedTimestamp;
7485
7808
  let extraFieldExtendedTimestampFlag;
7809
+ let extraFieldExtendedTimestampTime;
7486
7810
  if (extendedTimestamp) {
7487
7811
  const lastModTimeUnix = getTimeUnix(lastModDate);
7488
7812
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7490,6 +7814,7 @@
7490
7814
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7491
7815
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7492
7816
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7817
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7493
7818
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7494
7819
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7495
7820
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7573,7 +7898,7 @@
7573
7898
  }
7574
7899
  if (encrypted && !zipCrypto) {
7575
7900
  version = version > VERSION_AES ? version : VERSION_AES;
7576
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
7901
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7577
7902
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7578
7903
  }
7579
7904
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7635,12 +7960,14 @@
7635
7960
  headerArray,
7636
7961
  headerView,
7637
7962
  lastModDate: storedLastModDate,
7963
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7638
7964
  rawLastModDate,
7639
7965
  encrypted,
7640
7966
  compressed,
7641
7967
  version,
7642
7968
  compressionMethod,
7643
7969
  extraFieldExtendedTimestampFlag,
7970
+ extraFieldExtendedTimestampTime,
7644
7971
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7645
7972
  localExtraFieldZip64Length,
7646
7973
  rawExtraFieldExtendedTimestamp,
@@ -7743,7 +8070,7 @@
7743
8070
  }, {
7744
8071
  zip64,
7745
8072
  zipCrypto,
7746
- passThrough,
8073
+ passThroughCompression,
7747
8074
  dataDescriptor
7748
8075
  }) {
7749
8076
  const {
@@ -7754,7 +8081,7 @@
7754
8081
  dataDescriptorView,
7755
8082
  dataDescriptorOffset
7756
8083
  } = dataDescriptorInfo;
7757
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8084
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7758
8085
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7759
8086
  if (dataDescriptor) {
7760
8087
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7785,9 +8112,9 @@
7785
8112
  uncompressedSize,
7786
8113
  zip64UncompressedSize,
7787
8114
  zip64CompressedSize
7788
- }, localHeaderView, { dataDescriptor, passThrough }) {
8115
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7789
8116
  if (!dataDescriptor) {
7790
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8117
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7791
8118
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7792
8119
  }
7793
8120
  if (!zip64CompressedSize) {
@@ -7824,9 +8151,8 @@
7824
8151
  rawExtraFieldUnix,
7825
8152
  rawExtraField,
7826
8153
  rawCentralExtraField,
7827
- extendedTimestamp,
7828
8154
  extraFieldExtendedTimestampFlag,
7829
- lastModDate,
8155
+ extraFieldExtendedTimestampTime,
7830
8156
  zip64Enabled,
7831
8157
  uncompressedSize,
7832
8158
  compressedSize
@@ -7869,16 +8195,15 @@
7869
8195
  fileEntry.zip64Offset = zip64Offset;
7870
8196
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
7871
8197
  let rawExtraFieldTimestamp;
7872
- const lastModTimeUnix = getTimeUnix(lastModDate);
7873
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8198
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8199
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8200
+ } else {
7874
8201
  const extraFieldTimestamp = createRecordWriter(9);
7875
8202
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7876
8203
  extraFieldTimestamp.writeUint16(5);
7877
8204
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7878
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8205
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
7879
8206
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7880
- } else {
7881
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
7882
8207
  }
7883
8208
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
7884
8209
  const extraFieldLength = getLength(
@@ -8378,6 +8703,11 @@
8378
8703
  };
8379
8704
  }
8380
8705
 
8706
+ function isPrintableASCIIText(rawText) {
8707
+ return rawText.every(characterCode =>
8708
+ characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
8709
+ }
8710
+
8381
8711
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8382
8712
  let bitFlag = 0;
8383
8713
  if (useUnicodeFileNames) {
@@ -8539,7 +8869,7 @@
8539
8869
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8540
8870
  */
8541
8871
 
8542
- const VERSION = "2.11.3";
8872
+ const VERSION = "2.12.0";
8543
8873
 
8544
8874
  /*
8545
8875
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9017,12 +9347,13 @@
9017
9347
  */
9018
9348
 
9019
9349
 
9020
- c(setDefaultConfiguration);
9350
+ f(setDefaultConfiguration);
9021
9351
 
9022
9352
  exports.BlobReader = BlobReader;
9023
9353
  exports.BlobWriter = BlobWriter;
9024
9354
  exports.Data64URIReader = Data64URIReader;
9025
9355
  exports.Data64URIWriter = Data64URIWriter;
9356
+ exports.ERR_ABORTED = ERR_ABORTED;
9026
9357
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
9027
9358
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
9028
9359
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
@@ -9035,7 +9366,9 @@
9035
9366
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
9036
9367
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
9037
9368
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
9369
+ exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
9038
9370
  exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
9371
+ exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
9039
9372
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
9040
9373
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
9041
9374
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
@@ -9044,6 +9377,7 @@
9044
9377
  exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
9045
9378
  exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
9046
9379
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
9380
+ exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
9047
9381
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
9048
9382
  exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
9049
9383
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
@@ -9061,6 +9395,7 @@
9061
9395
  exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
9062
9396
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
9063
9397
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
9398
+ exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
9064
9399
  exports.ERR_INVALID_READER = ERR_INVALID_READER;
9065
9400
  exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
9066
9401
  exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
@@ -9070,6 +9405,7 @@
9070
9405
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
9071
9406
  exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
9072
9407
  exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
9408
+ exports.ERR_INVALID_URI = ERR_INVALID_URI;
9073
9409
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
9074
9410
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
9075
9411
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
@@ -9077,6 +9413,7 @@
9077
9413
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
9078
9414
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
9079
9415
  exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
9416
+ exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
9080
9417
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
9081
9418
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
9082
9419
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -9092,6 +9429,8 @@
9092
9429
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
9093
9430
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
9094
9431
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
9432
+ exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
9433
+ exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
9095
9434
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
9096
9435
  exports.HttpRangeReader = HttpRangeReader;
9097
9436
  exports.HttpReader = HttpReader;
@@ -9104,13 +9443,17 @@
9104
9443
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
9105
9444
  exports.VERSION = VERSION;
9106
9445
  exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
9446
+ exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
9107
9447
  exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
9448
+ exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
9108
9449
  exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
9109
9450
  exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
9110
9451
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
9111
9452
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
9112
9453
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
9454
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
9113
9455
  exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
9456
+ exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
9114
9457
  exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
9115
9458
  exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
9116
9459
  exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;