@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
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,20 @@ 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')";
219
+ const ERR_ABORTED = "The operation was aborted";
220
+ const ABORT_ERROR_NAME = "AbortError";
214
221
 
215
222
  function checkFunctionOption(value) {
216
223
  if (value && typeof value != FUNCTION_TYPE) {
@@ -226,12 +233,25 @@ function checkSignalOption(signal) {
226
233
  return signal || UNDEFINED_VALUE;
227
234
  }
228
235
 
236
+ function throwIfAborted(signal) {
237
+ if (signal && signal.aborted) {
238
+ throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
239
+ }
240
+ }
241
+
229
242
  function checkPasswordOption(password, rawPassword) {
230
243
  if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
231
244
  throw new Error(ERR_INVALID_PASSWORD_TYPE);
232
245
  }
233
246
  }
234
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
+
235
255
  function checkInteger(value, maxValue, errorMessage) {
236
256
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
237
257
  throw new Error(errorMessage);
@@ -281,6 +301,8 @@ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
281
301
  const MINIMUM_CHUNK_SIZE = 64;
282
302
  const MINIMUM_PROPERTY_VALUE = 1;
283
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)";
284
306
  let maxWorkers = 2;
285
307
  try {
286
308
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -305,9 +327,9 @@ const DEFAULT_CONFIGURATION = {
305
327
  };
306
328
 
307
329
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
330
+ const PROPERTY_NAME_BASE_URI = "baseURI";
308
331
 
309
- const STRING_PROPERTY_NAMES = [
310
- "baseURI",
332
+ const URI_PROPERTY_NAMES = [
311
333
  "wasmURI",
312
334
  "workerURI"
313
335
  ];
@@ -331,7 +353,8 @@ const FUNCTION_PROPERTY_NAMES = [
331
353
  "DecompressionStreamFallback"
332
354
  ];
333
355
  const CONFIGURABLE_PROPERTY_NAMES = [
334
- ...STRING_PROPERTY_NAMES,
356
+ PROPERTY_NAME_BASE_URI,
357
+ ...URI_PROPERTY_NAMES,
335
358
  ...BOOLEAN_PROPERTY_NAMES,
336
359
  ...NUMBER_PROPERTY_NAMES,
337
360
  ...FUNCTION_PROPERTY_NAMES
@@ -375,6 +398,14 @@ function checkPropertyValue(propertyName, propertyValue) {
375
398
  }
376
399
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
377
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
+ }
378
409
  }
379
410
  return propertyValue;
380
411
  }
@@ -408,7 +439,7 @@ function resetConfiguration() {
408
439
  Object.assign(config, DEFAULT_CONFIGURATION);
409
440
  }
410
441
 
411
- 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;
412
443
 
413
444
  /*
414
445
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -2593,6 +2624,7 @@ class ChunkStream extends TransformStream {
2593
2624
  constructor(chunkSize) {
2594
2625
  const pendingChunks = [];
2595
2626
  let pendingLength = 0;
2627
+ let outputSize = 0;
2596
2628
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2597
2629
  chunkSize = DEFAULT_CHUNK_SIZE;
2598
2630
  }
@@ -2601,15 +2633,20 @@ class ChunkStream extends TransformStream {
2601
2633
  pendingChunks.push(chunk);
2602
2634
  pendingLength += chunk.length;
2603
2635
  while (pendingLength > chunkSize) {
2636
+ outputSize += chunkSize;
2604
2637
  controller.enqueue(shiftChunk());
2605
2638
  }
2606
2639
  },
2607
2640
  flush(controller) {
2608
2641
  if (pendingLength) {
2642
+ outputSize += pendingLength;
2609
2643
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2610
2644
  }
2611
2645
  }
2612
2646
  });
2647
+ Object.defineProperty(this, "outputSize", {
2648
+ get: () => outputSize
2649
+ });
2613
2650
 
2614
2651
  function shiftChunk() {
2615
2652
  const result = new Uint8Array(chunkSize);
@@ -2810,7 +2847,7 @@ function createWorkerInterface(workerData, config) {
2810
2847
  }
2811
2848
 
2812
2849
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2813
- let codecStream;
2850
+ let codecStream, chunkStream;
2814
2851
  try {
2815
2852
  if (options.compressed && !options.format) {
2816
2853
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2833,9 +2870,10 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2833
2870
  }
2834
2871
  }
2835
2872
  codecStream = new CodecStream(options, config);
2873
+ chunkStream = new ChunkStream(getChunkSize(config));
2836
2874
  await readable
2837
2875
  .pipeThrough(codecStream)
2838
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2876
+ .pipeThrough(chunkStream)
2839
2877
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2840
2878
  const {
2841
2879
  crc32,
@@ -2849,7 +2887,7 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2849
2887
  };
2850
2888
  } catch (error) {
2851
2889
  if (codecStream) {
2852
- error.outputSize = codecStream.outputSize;
2890
+ error.outputSize = chunkStream ? chunkStream.outputSize : 0;
2853
2891
  }
2854
2892
  throw error;
2855
2893
  } finally {
@@ -2958,11 +2996,17 @@ async function runWebWorker(workerData, config) {
2958
2996
  let resolveResult, rejectResult;
2959
2997
  const result = new Promise((resolve, reject) => {
2960
2998
  resolveResult = resolve;
2961
- rejectResult = reject;
2999
+ rejectResult = error => {
3000
+ if (error && error.outputSize === UNDEFINED_VALUE) {
3001
+ error.outputSize = workerData.outputSize;
3002
+ }
3003
+ reject(error);
3004
+ };
2962
3005
  });
2963
3006
  Object.assign(workerData, {
2964
3007
  reader: null,
2965
3008
  writer: null,
3009
+ outputSize: 0,
2966
3010
  resolveResult,
2967
3011
  rejectResult,
2968
3012
  result
@@ -3246,8 +3290,10 @@ async function onMessage({ data }, workerData) {
3246
3290
  }
3247
3291
  }
3248
3292
  if (type == MESSAGE_DATA) {
3293
+ const chunk = new Uint8Array(value);
3249
3294
  await writer.ready;
3250
- await writer.write(new Uint8Array(value));
3295
+ await writer.write(chunk);
3296
+ workerData.outputSize += chunk.length;
3251
3297
  if (!stale()) {
3252
3298
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3253
3299
  }
@@ -3555,10 +3601,13 @@ function decode(value, encoding, ignoreBOM) {
3555
3601
 
3556
3602
 
3557
3603
  const ERR_HTTP_STATUS = "HTTP error ";
3604
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3605
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3558
3606
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3559
3607
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3560
3608
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3561
3609
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3610
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3562
3611
 
3563
3612
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3564
3613
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3750,11 +3799,14 @@ class BlobReader extends Reader {
3750
3799
  const reader = this;
3751
3800
  const { sourceBlob, size } = reader;
3752
3801
  const { offset = 0, size: readSize = size - offset } = options || {};
3753
- if (!offset && readSize >= size) {
3754
- return toCompatibleReadable(sourceBlob.stream());
3755
- }
3756
- if (blobSliceReliable) {
3757
- return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3802
+ // deno-lint-ignore valid-typeof
3803
+ if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3804
+ if (!offset && readSize >= size) {
3805
+ return toCompatibleReadable(sourceBlob.stream());
3806
+ }
3807
+ if (blobSliceReliable) {
3808
+ return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3809
+ }
3758
3810
  }
3759
3811
  return super.createReadable(options);
3760
3812
  }
@@ -4154,7 +4206,7 @@ async function getContentLength(httpReader, sendRequest, getRequestData) {
4154
4206
 
4155
4207
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4156
4208
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4157
- if (response.status < 400) {
4209
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4158
4210
  return response;
4159
4211
  } else {
4160
4212
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4165,7 +4217,7 @@ function sendXMLHttpRequest(method, { url }, headers) {
4165
4217
  return new Promise((resolve, reject) => {
4166
4218
  const request = new XMLHttpRequest();
4167
4219
  request.addEventListener("load", () => {
4168
- if (request.status < 400) {
4220
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4169
4221
  const headers = [];
4170
4222
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4171
4223
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4469,8 +4521,10 @@ class GenericWriter {
4469
4521
  writable: toCompatibleWritable(writer)
4470
4522
  };
4471
4523
  }
4472
- if (writer.size === UNDEFINED_VALUE) {
4473
- 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);
4474
4528
  }
4475
4529
  return writer;
4476
4530
  }
@@ -4518,6 +4572,45 @@ function createReadable(reader, options) {
4518
4572
  }
4519
4573
  }
4520
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
+
4521
4614
  /*
4522
4615
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4523
4616
 
@@ -4546,6 +4639,7 @@ function createReadable(reader, options) {
4546
4639
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4547
4640
  */
4548
4641
 
4642
+
4549
4643
  const PROPERTY_NAME_FILENAME = "filename";
4550
4644
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4551
4645
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4670,6 +4764,38 @@ class Entry {
4670
4764
 
4671
4765
  }
4672
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
+
4673
4799
  /*
4674
4800
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4675
4801
 
@@ -4729,6 +4855,8 @@ const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
4729
4855
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4730
4856
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4731
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)";
4732
4860
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4733
4861
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4734
4862
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4799,7 +4927,7 @@ class ZipReader {
4799
4927
  }
4800
4928
  }
4801
4929
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4802
- throwAmbiguousArchive("multiple end of central directory records");
4930
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4803
4931
  }
4804
4932
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4805
4933
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5097,7 +5225,8 @@ class ZipReader {
5097
5225
  const writer = new TransformStream();
5098
5226
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5099
5227
  arrayBufferPromise.catch(() => { });
5100
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5228
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5229
+ Object.assign({}, options, { preventClose: false }));
5101
5230
  return arrayBufferPromise;
5102
5231
  };
5103
5232
  offset = endOffset;
@@ -5178,48 +5307,101 @@ class ZipReader {
5178
5307
  await reader.readable.cancel();
5179
5308
  }
5180
5309
  }
5310
+
5311
+ [SYMBOL_ASYNC_DISPOSE]() {
5312
+ return this.close();
5313
+ }
5181
5314
  }
5182
5315
 
5183
5316
  class ZipReaderStream {
5184
5317
 
5185
5318
  constructor(options = {}) {
5186
- const { readable, writable } = new TransformStream();
5187
- 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();
5188
5328
  this.readable = new ReadableStream({
5189
5329
  async pull(controller) {
5190
5330
  const { done, value } = await gen.next();
5191
5331
  if (done)
5192
5332
  return controller.close();
5333
+ const entryStream = createEntryStream(value, pendingEntries);
5193
5334
  const chunk = {
5194
5335
  ...value,
5195
- readable: (function () {
5196
- const { readable, writable } = new TransformStream();
5197
- if (value.getData) {
5198
- getData();
5199
- return readable;
5200
- }
5201
-
5202
- async function getData() {
5203
- try {
5204
- await value.getData(writable);
5205
- } catch (error) {
5206
- try {
5207
- await writable.abort(error);
5208
- } catch {
5209
- // ignored
5210
- }
5211
- }
5212
- }
5213
- })()
5336
+ readable: entryStream.readable
5214
5337
  };
5215
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
+ });
5216
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()]);
5217
5357
  }
5218
5358
  });
5219
5359
  this.writable = writable;
5220
5360
  }
5221
5361
  }
5222
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
+
5223
5405
  async function isZipFile(reader, options = {}) {
5224
5406
  reader = new GenericReader(reader);
5225
5407
  await initStream(reader);
@@ -5279,7 +5461,9 @@ let ZipEntry$1 = class ZipEntry {
5279
5461
  const dataView = getDataView(dataArray);
5280
5462
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5281
5463
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5282
- 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;
5283
5467
  checkPasswordOption(password, rawPassword);
5284
5468
  password = password && password.length && password;
5285
5469
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5300,7 +5484,9 @@ let ZipEntry$1 = class ZipEntry {
5300
5484
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5301
5485
  const entryStrictness = getStrictness(options, zipEntry.options);
5302
5486
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5303
- 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);
5304
5490
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5305
5491
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5306
5492
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5331,16 +5517,17 @@ let ZipEntry$1 = class ZipEntry {
5331
5517
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5332
5518
  fileEntry.gid = gid;
5333
5519
  }
5334
- 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);
5335
5522
  const zipCrypto = encrypted && !extraFieldAES;
5336
- if (!passThrough) {
5523
+ if (!passThroughEncryption) {
5337
5524
  fileEntry.zipCrypto = zipCrypto;
5338
5525
  }
5339
5526
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5340
5527
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5341
5528
  }
5342
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5343
- 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) {
5344
5531
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5345
5532
  }
5346
5533
  if (encrypted) {
@@ -5356,15 +5543,17 @@ let ZipEntry$1 = class ZipEntry {
5356
5543
  const size = compressedSize;
5357
5544
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5358
5545
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5359
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5546
+ throwIfAborted(signal);
5360
5547
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5361
5548
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5362
5549
  if (checkOverlappingEntryOnly) {
5363
5550
  checkOverlappingEntry = true;
5364
5551
  }
5365
5552
  const { onstart, onprogress, onend } = options;
5366
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5367
- 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;
5368
5557
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5369
5558
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5370
5559
  if (deflate64) {
@@ -5373,7 +5562,7 @@ let ZipEntry$1 = class ZipEntry {
5373
5562
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5374
5563
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5375
5564
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5376
- checkCrc32Option) && !passThrough &&
5565
+ checkCrc32Option) && !passThroughCompression &&
5377
5566
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5378
5567
  const workerOptions = {
5379
5568
  options: {
@@ -5427,10 +5616,10 @@ let ZipEntry$1 = class ZipEntry {
5427
5616
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5428
5617
  ({ writable } = writer);
5429
5618
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5430
- writer.size += writtenSize;
5431
5619
  if (writtenSize != outputSize) {
5432
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5620
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5433
5621
  }
5622
+ writer.size += writtenSize;
5434
5623
  }
5435
5624
  } catch (error) {
5436
5625
  if (error.outputSize !== UNDEFINED_VALUE) {
@@ -6096,7 +6285,7 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
6096
6285
  if (checkLocalFilename && !maskedLocalDirectory &&
6097
6286
  (rawLocalFilename.length != rawFilename.length ||
6098
6287
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6099
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6288
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6100
6289
  }
6101
6290
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6102
6291
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6121,16 +6310,6 @@ function reportAmbiguity(reject, warnings, reason) {
6121
6310
  }
6122
6311
  }
6123
6312
 
6124
- function addWarning(warnings, reason, filename) {
6125
- if (!warnings.some(warning => warning.reason == reason)) {
6126
- const warning = { reason };
6127
- if (filename !== UNDEFINED_VALUE) {
6128
- warning.filename = filename;
6129
- }
6130
- warnings.push(warning);
6131
- }
6132
- }
6133
-
6134
6313
  function throwAmbiguousArchive(reason) {
6135
6314
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6136
6315
  error.reason = reason;
@@ -6210,7 +6389,9 @@ var zipReader = /*#__PURE__*/Object.freeze({
6210
6389
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6211
6390
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6212
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,
6213
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,
6214
6395
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6215
6396
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6216
6397
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6263,7 +6444,7 @@ const ERR_INVALID_VERSION = "Version exceeds 65535";
6263
6444
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6264
6445
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6265
6446
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6266
- 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)";
6267
6448
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6268
6449
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6269
6450
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6275,6 +6456,7 @@ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
6275
6456
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6276
6457
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6277
6458
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6459
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6278
6460
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6279
6461
  const ERR_UNDEFINED_READER = "Undefined reader";
6280
6462
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6288,14 +6470,21 @@ const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be intege
6288
6470
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6289
6471
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6290
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";
6291
6477
 
6292
6478
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6293
6479
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6294
6480
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6295
6481
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6482
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6483
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6296
6484
  const VENDOR_VERSION_AE_1 = 1;
6297
- const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6485
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6298
6486
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6487
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6299
6488
  const MAX_LEVEL = 9;
6300
6489
 
6301
6490
  let workers = 0;
@@ -6322,9 +6511,11 @@ class ZipWriter {
6322
6511
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6323
6512
  pendingAddFileCalls: new Set(),
6324
6513
  pendingErrors: [],
6514
+ warnings: [],
6325
6515
  bufferedWrites: 0,
6326
6516
  directWrites: 0,
6327
- lastFileEntry: UNDEFINED_VALUE
6517
+ lastFileEntry: UNDEFINED_VALUE,
6518
+ archiveClosed: false
6328
6519
  });
6329
6520
  }
6330
6521
 
@@ -6489,6 +6680,9 @@ class ZipWriter {
6489
6680
  const zipWriter = this;
6490
6681
  const { pendingAddFileCalls, writer } = this;
6491
6682
  const { writable } = writer;
6683
+ if (zipWriter.archiveClosed) {
6684
+ return getWriterData(writer);
6685
+ }
6492
6686
  if (!(comment instanceof Uint8Array)) {
6493
6687
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6494
6688
  }
@@ -6512,11 +6706,16 @@ class ZipWriter {
6512
6706
  throw error;
6513
6707
  }
6514
6708
  await closeFile(zipWriter, comment, options);
6709
+ zipWriter.archiveClosed = true;
6515
6710
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6516
6711
  if (!preventClose) {
6517
6712
  await writable.getWriter().close();
6518
6713
  }
6519
- return writer.getData ? writer.getData() : writable;
6714
+ return getWriterData(writer);
6715
+ }
6716
+
6717
+ [SYMBOL_ASYNC_DISPOSE]() {
6718
+ return this.close();
6520
6719
  }
6521
6720
  }
6522
6721
 
@@ -6595,6 +6794,10 @@ class WatchedPromise extends Promise {
6595
6794
  }
6596
6795
  }
6597
6796
 
6797
+ function getWriterData(writer) {
6798
+ return writer.getData ? writer.getData() : writer.writable;
6799
+ }
6800
+
6598
6801
  function watchPromiseError(zipWriter, promise) {
6599
6802
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6600
6803
  const watcher = {};
@@ -6613,6 +6816,14 @@ async function prependZipEntries(zipWriter, reader) {
6613
6816
 
6614
6817
  async function addFileEntry(zipWriter, name, reader, options) {
6615
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
+ }
6616
6827
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6617
6828
  name += DIRECTORY_SIGNATURE;
6618
6829
  }
@@ -6677,21 +6888,33 @@ async function addFile(zipWriter, name, reader, options) {
6677
6888
  try {
6678
6889
  const { resolvedOptions } = metadataInfo;
6679
6890
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6680
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6891
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6681
6892
  resolvedOptions.level = 0;
6893
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6682
6894
  }
6683
6895
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6684
6896
  ({ reader } = sizesInfo);
6685
6897
  const diskOffset = getDiskOffset(zipWriter.writer);
6686
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
+ }
6687
6907
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6688
6908
  signature: options[PROPERTY_NAME_SIGNATURE],
6689
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6909
+ crc32,
6690
6910
  offset: zipWriter.offset - diskOffset,
6691
6911
  diskNumberStart: diskNumber,
6692
6912
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6693
6913
  });
6694
6914
  const headerInfo = getHeaderInfo(options);
6915
+ if (headerInfo.lastModDateClamped) {
6916
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
6917
+ }
6695
6918
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6696
6919
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6697
6920
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6718,6 +6941,95 @@ async function addFile(zipWriter, name, reader, options) {
6718
6941
  return new Entry(fileEntry);
6719
6942
  }
6720
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
+
6721
7033
  function resolveAttributes(zipWriter, name, options) {
6722
7034
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6723
7035
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6732,7 +7044,7 @@ function resolveAttributes(zipWriter, name, options) {
6732
7044
  checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6733
7045
  checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6734
7046
  checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6735
- 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) {
6736
7048
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6737
7049
  }
6738
7050
  if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
@@ -6740,7 +7052,7 @@ function resolveAttributes(zipWriter, name, options) {
6740
7052
  throw new Error(ERR_INVALID_UNIX_ID_SIZE);
6741
7053
  }
6742
7054
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6743
- unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
7055
+ unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
6744
7056
  }
6745
7057
  let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6746
7058
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
@@ -6871,7 +7183,9 @@ function resolveMetadata(zipWriter, name, options) {
6871
7183
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6872
7184
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6873
7185
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6874
- 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;
6875
7189
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6876
7190
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6877
7191
  checkPasswordOption(password, rawPassword);
@@ -6886,10 +7200,12 @@ function resolveMetadata(zipWriter, name, options) {
6886
7200
  const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6887
7201
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6888
7202
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6889
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7203
+ throwIfAborted(signal);
7204
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7205
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6890
7206
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6891
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6892
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7207
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7208
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6893
7209
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6894
7210
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6895
7211
  }
@@ -6903,15 +7219,15 @@ function resolveMetadata(zipWriter, name, options) {
6903
7219
  level = 0;
6904
7220
  }
6905
7221
  }
6906
- if (passThrough) {
6907
- level = UNDEFINED_VALUE;
7222
+ if (passThroughCompression) {
7223
+ level = toNumber(options[OPTION_LEVEL]);
6908
7224
  }
6909
7225
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6910
7226
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6911
7227
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6912
7228
  dataDescriptor = false;
6913
7229
  }
6914
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7230
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6915
7231
  dataDescriptor = true;
6916
7232
  }
6917
7233
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6935,7 +7251,8 @@ function resolveMetadata(zipWriter, name, options) {
6935
7251
  lastAccessDate,
6936
7252
  creationDate,
6937
7253
  internalFileAttributes,
6938
- passThrough,
7254
+ passThroughCompression,
7255
+ passThroughEncryption,
6939
7256
  password,
6940
7257
  rawPassword,
6941
7258
  encryptionStrength,
@@ -6996,7 +7313,7 @@ function serializeExtraField(extraField) {
6996
7313
  }
6997
7314
 
6998
7315
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
6999
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7316
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7000
7317
  throw new Error(ERR_UNDEFINED_READER);
7001
7318
  }
7002
7319
  let contentSize;
@@ -7012,12 +7329,12 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
7012
7329
  }
7013
7330
 
7014
7331
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7015
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7332
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7016
7333
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7017
7334
  let maximumCompressedSize = 0;
7018
7335
  let uncompressedSize = 0;
7019
7336
  let unknownSize = false;
7020
- if (passThrough && hasContent) {
7337
+ if (passThroughCompression && hasContent) {
7021
7338
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7022
7339
  if (uncompressedSize === UNDEFINED_VALUE) {
7023
7340
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7028,17 +7345,17 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7028
7345
  }
7029
7346
  const zip64Enabled = zip64 === true;
7030
7347
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7031
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7348
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7032
7349
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7033
7350
  }
7034
- 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));
7035
7352
  if (!hasContent) {
7036
7353
  level = 0;
7037
7354
  compressionMethod = COMPRESSION_METHOD_STORE;
7038
7355
  }
7039
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7356
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7040
7357
  if (hasContent) {
7041
- if (!passThrough) {
7358
+ if (!passThroughCompression) {
7042
7359
  if (contentSize === UNDEFINED_VALUE) {
7043
7360
  dataDescriptor = true;
7044
7361
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7051,10 +7368,12 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7051
7368
  }
7052
7369
  } else {
7053
7370
  options.uncompressedSize = uncompressedSize;
7054
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7371
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7372
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7373
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7055
7374
  }
7056
7375
  }
7057
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7376
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7058
7377
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7059
7378
  dataDescriptor = false;
7060
7379
  }
@@ -7103,6 +7422,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7103
7422
  const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
7104
7423
  let offset = initialOffset;
7105
7424
  let minimumEntrySize = INFINITY_VALUE;
7425
+ const entrySizes = [];
7426
+ const entriesAlreadyZip64 = new Set();
7106
7427
  for (const entry of entries) {
7107
7428
  let { name } = entry;
7108
7429
  const { size } = entry;
@@ -7114,7 +7435,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7114
7435
  ({ name } = attributesInfo);
7115
7436
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
7116
7437
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
7117
- !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
7438
+ !metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
7118
7439
  metadata.level = 0;
7119
7440
  }
7120
7441
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -7122,7 +7443,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7122
7443
  throw new Error(ERR_UNDETERMINED_SIZE);
7123
7444
  }
7124
7445
  const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
7125
- if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
7446
+ if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
7126
7447
  throw new Error(ERR_UNDETERMINED_SIZE);
7127
7448
  }
7128
7449
  const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
@@ -7142,10 +7463,15 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7142
7463
  compressedSize
7143
7464
  }));
7144
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));
7145
7469
  minimumEntrySize = Math.min(minimumEntrySize, entrySize);
7146
7470
  offset += entrySize;
7147
7471
  }
7148
- 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))));
7149
7475
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
7150
7476
  throw new Error(ERR_UNDETERMINED_SIZE);
7151
7477
  }
@@ -7163,6 +7489,20 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7163
7489
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7164
7490
  }
7165
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
+
7166
7506
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7167
7507
  const {
7168
7508
  fileEntries,
@@ -7338,6 +7678,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7338
7678
  localExtraFieldZip64Length,
7339
7679
  rawExtraFieldExtendedTimestamp,
7340
7680
  extraFieldExtendedTimestampFlag,
7681
+ extraFieldExtendedTimestampTime,
7341
7682
  rawExtraFieldNTFS,
7342
7683
  rawExtraFieldUnix,
7343
7684
  rawExtraFieldAES,
@@ -7350,6 +7691,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7350
7691
  password,
7351
7692
  rawPassword,
7352
7693
  level,
7694
+ useUnicodeFileNames,
7353
7695
  zip64,
7354
7696
  zip64Enabled,
7355
7697
  zip64UncompressedSize,
@@ -7384,7 +7726,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7384
7726
  msdosAttributesRaw,
7385
7727
  msdosAttributes,
7386
7728
  useCompressionStream,
7387
- passThrough,
7729
+ passThroughCompression,
7730
+ passThroughEncryption,
7388
7731
  format,
7389
7732
  codecURI
7390
7733
  } = options;
@@ -7395,9 +7738,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7395
7738
  zip64Enabled,
7396
7739
  directory: Boolean(directory),
7397
7740
  executable: Boolean(executable),
7398
- filenameUTF8: true,
7741
+ filenameUTF8: Boolean(useUnicodeFileNames),
7399
7742
  rawFilename,
7400
- commentUTF8: true,
7743
+ commentUTF8: Boolean(useUnicodeFileNames),
7401
7744
  rawComment,
7402
7745
  rawExtraFieldZip64,
7403
7746
  localExtraFieldZip64Length,
@@ -7428,7 +7771,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7428
7771
  uncompressedSize
7429
7772
  } = options;
7430
7773
  let compressedSize = 0;
7431
- if (!passThrough) {
7774
+ if (!passThroughCompression) {
7432
7775
  uncompressedSize = 0;
7433
7776
  }
7434
7777
  const { writable } = writer;
@@ -7445,9 +7788,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7445
7788
  encryptionStrength,
7446
7789
  zipCrypto: encrypted && zipCrypto,
7447
7790
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7448
- computeCrc32: !passThrough,
7449
- compressed: compressed && !passThrough,
7450
- encrypted: encrypted && !passThrough,
7791
+ computeCrc32: !passThroughCompression,
7792
+ compressed: compressed && !passThroughCompression,
7793
+ encrypted: encrypted && !passThroughEncryption,
7451
7794
  useWebWorkers,
7452
7795
  useCompressionStream,
7453
7796
  transferStreams,
@@ -7462,7 +7805,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7462
7805
  const result = await runWorker({ readable, writable }, workerOptions);
7463
7806
  compressedSize = result.outputSize;
7464
7807
  writer.size += compressedSize;
7465
- if (!passThrough) {
7808
+ if (!passThroughCompression) {
7466
7809
  uncompressedSize = result.inputSize;
7467
7810
  if (!encrypted || zipCrypto) {
7468
7811
  crc32 = result.crc32;
@@ -7505,8 +7848,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7505
7848
  headerArray,
7506
7849
  headerView,
7507
7850
  signature: crc32,
7508
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7851
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7509
7852
  extraFieldExtendedTimestampFlag,
7853
+ extraFieldExtendedTimestampTime,
7510
7854
  zip64UncompressedSize,
7511
7855
  zip64CompressedSize
7512
7856
  });
@@ -7531,7 +7875,7 @@ function getHeaderInfo(options) {
7531
7875
  encryptionStrength,
7532
7876
  extendedTimestamp,
7533
7877
  ntfsTimestamp,
7534
- passThrough,
7878
+ passThroughCompression,
7535
7879
  encrypted,
7536
7880
  zip64UncompressedSize,
7537
7881
  zip64CompressedSize,
@@ -7542,7 +7886,7 @@ function getHeaderInfo(options) {
7542
7886
  let { version, compressionMethod } = options;
7543
7887
  const compressed = !directory && isCompressed(compressionMethod, level);
7544
7888
  let rawLocalExtraFieldZip64;
7545
- const uncompressedFile = passThrough || !compressed;
7889
+ const uncompressedFile = passThroughCompression || !compressed;
7546
7890
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7547
7891
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7548
7892
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7554,8 +7898,8 @@ function getHeaderInfo(options) {
7554
7898
  if (zip64ExtraFieldComplete) {
7555
7899
  extraFieldZip64.writeUint64(uncompressedSize);
7556
7900
  if (uncompressedFile) {
7557
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7558
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7901
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
7902
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7559
7903
  }
7560
7904
  }
7561
7905
  } else {
@@ -7574,6 +7918,7 @@ function getHeaderInfo(options) {
7574
7918
  let rawExtraFieldNTFS;
7575
7919
  let rawExtraFieldExtendedTimestamp;
7576
7920
  let extraFieldExtendedTimestampFlag;
7921
+ let extraFieldExtendedTimestampTime;
7577
7922
  if (extendedTimestamp) {
7578
7923
  const lastModTimeUnix = getTimeUnix(lastModDate);
7579
7924
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7581,6 +7926,7 @@ function getHeaderInfo(options) {
7581
7926
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7582
7927
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7583
7928
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7929
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7584
7930
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7585
7931
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7586
7932
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7623,7 +7969,7 @@ function getHeaderInfo(options) {
7623
7969
  let rawExtraFieldUnix;
7624
7970
  try {
7625
7971
  const { uid, gid, unixExtraFieldType } = options;
7626
- 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)) {
7627
7973
  const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7628
7974
  const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7629
7975
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
@@ -7664,7 +8010,7 @@ function getHeaderInfo(options) {
7664
8010
  }
7665
8011
  if (encrypted && !zipCrypto) {
7666
8012
  version = version > VERSION_AES ? version : VERSION_AES;
7667
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
8013
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7668
8014
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7669
8015
  }
7670
8016
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7726,12 +8072,14 @@ function getHeaderInfo(options) {
7726
8072
  headerArray,
7727
8073
  headerView,
7728
8074
  lastModDate: storedLastModDate,
8075
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7729
8076
  rawLastModDate,
7730
8077
  encrypted,
7731
8078
  compressed,
7732
8079
  version,
7733
8080
  compressionMethod,
7734
8081
  extraFieldExtendedTimestampFlag,
8082
+ extraFieldExtendedTimestampTime,
7735
8083
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7736
8084
  localExtraFieldZip64Length,
7737
8085
  rawExtraFieldExtendedTimestamp,
@@ -7834,7 +8182,7 @@ function setEntryInfo({
7834
8182
  }, {
7835
8183
  zip64,
7836
8184
  zipCrypto,
7837
- passThrough,
8185
+ passThroughCompression,
7838
8186
  dataDescriptor
7839
8187
  }) {
7840
8188
  const {
@@ -7845,7 +8193,7 @@ function setEntryInfo({
7845
8193
  dataDescriptorView,
7846
8194
  dataDescriptorOffset
7847
8195
  } = dataDescriptorInfo;
7848
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8196
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7849
8197
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7850
8198
  if (dataDescriptor) {
7851
8199
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7876,9 +8224,9 @@ function updateLocalHeader({
7876
8224
  uncompressedSize,
7877
8225
  zip64UncompressedSize,
7878
8226
  zip64CompressedSize
7879
- }, localHeaderView, { dataDescriptor, passThrough }) {
8227
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7880
8228
  if (!dataDescriptor) {
7881
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8229
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7882
8230
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7883
8231
  }
7884
8232
  if (!zip64CompressedSize) {
@@ -7915,9 +8263,8 @@ function createDirectoryRecords(files) {
7915
8263
  rawExtraFieldUnix,
7916
8264
  rawExtraField,
7917
8265
  rawCentralExtraField,
7918
- extendedTimestamp,
7919
8266
  extraFieldExtendedTimestampFlag,
7920
- lastModDate,
8267
+ extraFieldExtendedTimestampTime,
7921
8268
  zip64Enabled,
7922
8269
  uncompressedSize,
7923
8270
  compressedSize
@@ -7960,16 +8307,15 @@ function createDirectoryRecords(files) {
7960
8307
  fileEntry.zip64Offset = zip64Offset;
7961
8308
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
7962
8309
  let rawExtraFieldTimestamp;
7963
- const lastModTimeUnix = getTimeUnix(lastModDate);
7964
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8310
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8311
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8312
+ } else {
7965
8313
  const extraFieldTimestamp = createRecordWriter(9);
7966
8314
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7967
8315
  extraFieldTimestamp.writeUint16(5);
7968
8316
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7969
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8317
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
7970
8318
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7971
- } else {
7972
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
7973
8319
  }
7974
8320
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
7975
8321
  const extraFieldLength = getLength(
@@ -8469,6 +8815,11 @@ function getHeaderArrayData({
8469
8815
  };
8470
8816
  }
8471
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
+
8472
8823
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8473
8824
  let bitFlag = 0;
8474
8825
  if (useUnicodeFileNames) {
@@ -8630,7 +8981,7 @@ function formatSupported(StreamClass, format) {
8630
8981
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8631
8982
  */
8632
8983
 
8633
- const VERSION = "2.11.3";
8984
+ const VERSION = "2.12.0";
8634
8985
 
8635
8986
  /*
8636
8987
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9149,7 +9500,10 @@ setDefaultConfiguration({
9149
9500
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
9150
9501
  const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
9151
9502
  const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
9152
- 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";
9153
9507
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
9154
9508
  const DUPLICATES_THROW = "throw";
9155
9509
  const DUPLICATES_KEEP_FIRST = "keep-first";
@@ -9157,24 +9511,8 @@ const DUPLICATES_KEEP_LAST = "keep-last";
9157
9511
  const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
9158
9512
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9159
9513
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9160
- 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()";
9161
9515
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
9162
- const ERR_ABORTED = "The operation was aborted";
9163
- const ABORT_ERROR_NAME = "AbortError";
9164
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
9165
- const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
9166
- EXTRAFIELD_TYPE_ZIP64,
9167
- EXTRAFIELD_TYPE_AES,
9168
- EXTRAFIELD_TYPE_NTFS,
9169
- EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
9170
- EXTRAFIELD_TYPE_UNICODE_PATH,
9171
- EXTRAFIELD_TYPE_UNICODE_COMMENT,
9172
- EXTRAFIELD_TYPE_USDZ,
9173
- EXTRAFIELD_TYPE_INFOZIP,
9174
- EXTRAFIELD_TYPE_UNIX,
9175
- EXTRAFIELD_TYPE_UNIX_TYPE1,
9176
- EXTRAFIELD_TYPE_PKWARE_UNIX
9177
- ]);
9178
9516
 
9179
9517
  class ZipEntry {
9180
9518
 
@@ -9546,6 +9884,7 @@ class ZipDirectoryEntry extends ZipEntry {
9546
9884
  await initStream(reader);
9547
9885
  zipReader = new ZipReader(reader, options);
9548
9886
  }
9887
+ checkPassThroughValue(options.passThrough);
9549
9888
  const duplicates = checkDuplicatesOption(options.duplicates);
9550
9889
  const importedEntries = [];
9551
9890
  const entries = await zipReader.getEntries(options);
@@ -9636,18 +9975,25 @@ class ZipDirectoryEntry extends ZipEntry {
9636
9975
 
9637
9976
  async exportZip(writer, options = {}) {
9638
9977
  const zipEntry = this;
9978
+ const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
9639
9979
  options = Object.assign({}, options);
9640
- if (options.bufferedWrite === UNDEFINED_VALUE) {
9980
+ if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
9641
9981
  options.bufferedWrite = true;
9642
9982
  }
9643
- const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
9644
- 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);
9645
9988
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
9989
+ if (zipWriterProvided) {
9990
+ return zipWriter;
9991
+ }
9646
9992
  await zipWriter.close(options.globalComment);
9647
9993
  return writer.getData ? writer.getData() : writer.writable;
9648
9994
  }
9649
9995
 
9650
- getExportedSize(options = {}) {
9996
+ async getExportedSize(options = {}) {
9651
9997
  const zipEntry = this;
9652
9998
  options = Object.assign({}, options);
9653
9999
  checkReaderOptions(options.readerOptions);
@@ -9662,7 +10008,7 @@ class ZipDirectoryEntry extends ZipEntry {
9662
10008
  const writeOrderGuaranteed = !options.bufferedWrite ||
9663
10009
  (entries.every(entry => entry.options.keepOrder !== false) &&
9664
10010
  children.every(child => isImplicitDirectory(child) || !child.children.length));
9665
- return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10011
+ return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
9666
10012
  }
9667
10013
 
9668
10014
  getChildByName(name) {
@@ -9723,7 +10069,7 @@ class ZipFS {
9723
10069
 
9724
10070
  move(entry, destination) {
9725
10071
  if (entry == this.root) {
9726
- throw new Error("Root directory cannot be moved");
10072
+ throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
9727
10073
  } else {
9728
10074
  if (destination.directory) {
9729
10075
  if (!destination.isDescendantOf(entry)) {
@@ -9744,7 +10090,7 @@ class ZipFS {
9744
10090
  throw new Error(ERR_ANCESTOR_ENTRY);
9745
10091
  }
9746
10092
  } else {
9747
- throw new Error("Target entry is not a directory");
10093
+ throw new Error(ERR_TARGET_NOT_DIRECTORY);
9748
10094
  }
9749
10095
  }
9750
10096
  }
@@ -10057,70 +10403,11 @@ function getChildEntryOptions(child, selectedEntry, options) {
10057
10403
  let zipEntryMetadata = {};
10058
10404
  let passThroughOptions = {};
10059
10405
  if (child.data instanceof Entry) {
10060
- const {
10061
- externalFileAttributes,
10062
- versionMadeBy,
10063
- comment,
10064
- lastModDate,
10065
- rawLastModDate,
10066
- creationDate,
10067
- lastAccessDate,
10068
- uncompressedSize,
10069
- encrypted,
10070
- zipCrypto,
10071
- crc32,
10072
- compressionMethod,
10073
- extraFieldAES,
10074
- internalFileAttributes,
10075
- extraField,
10076
- bitFlag,
10077
- uid,
10078
- gid
10079
- } = child.data;
10080
- zipEntryMetadata = {
10081
- externalFileAttributes,
10082
- versionMadeBy,
10083
- comment,
10084
- lastModDate,
10085
- creationDate,
10086
- lastAccessDate,
10087
- internalFileAttributes
10088
- };
10089
- const userExtraField = getUserExtraField(extraField);
10090
- if (userExtraField) {
10091
- zipEntryMetadata.extraField = userExtraField;
10092
- }
10093
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
10094
- Object.assign(zipEntryMetadata, {
10095
- uid,
10096
- gid,
10097
- unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
10098
- });
10099
- }
10100
- if (isPassThrough(child, options)) {
10101
- let encryptionStrength;
10102
- if (extraFieldAES) {
10103
- encryptionStrength = extraFieldAES.strength;
10104
- }
10105
- passThroughOptions = {
10106
- passThrough: true,
10107
- encrypted,
10108
- zipCrypto,
10109
- crc32,
10110
- uncompressedSize,
10111
- encryptionStrength,
10112
- compressionMethod
10113
- };
10114
- if (bitFlag) {
10115
- passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
10116
- }
10117
- const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10118
- if (lastModDateOverride === UNDEFINED_VALUE) {
10119
- passThroughOptions.rawLastModDate = rawLastModDate;
10120
- } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
10121
- getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
10122
- throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
10123
- }
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;
10124
10411
  }
10125
10412
  }
10126
10413
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -10130,16 +10417,6 @@ function getChildEntryOptions(child, selectedEntry, options) {
10130
10417
  return { name, entryOptions };
10131
10418
  }
10132
10419
 
10133
- function getDosTimeHighByte(lastModDate) {
10134
- let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
10135
- if (dosLastModDate < MIN_DATE) {
10136
- dosLastModDate = MIN_DATE;
10137
- } else if (dosLastModDate > MAX_DATE) {
10138
- dosLastModDate = MAX_DATE;
10139
- }
10140
- return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
10141
- }
10142
-
10143
10420
  function getDeterminedSize(child, passThrough) {
10144
10421
  const { reader } = child;
10145
10422
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10152,9 +10429,18 @@ function checkReaderOptions(readerOptions) {
10152
10429
  if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10153
10430
  throw new Error(ERR_INVALID_READER_OPTIONS);
10154
10431
  }
10432
+ if (readerOptions) {
10433
+ checkPassThroughValue(readerOptions.passThrough);
10434
+ }
10155
10435
  return readerOptions;
10156
10436
  }
10157
10437
 
10438
+ function checkPassThroughValue(passThrough) {
10439
+ if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
10440
+ throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
10441
+ }
10442
+ }
10443
+
10158
10444
  function replaceContent(zipEntry, params) {
10159
10445
  const { uncompressedSize } = params;
10160
10446
  Object.assign(zipEntry, params, {
@@ -10183,20 +10469,6 @@ function isImplicitDirectory(child) {
10183
10469
  return child.directory && child.data === null;
10184
10470
  }
10185
10471
 
10186
- function getUserExtraField(extraField) {
10187
- if (extraField) {
10188
- const userExtraField = new Map();
10189
- extraField.forEach((field, type) => {
10190
- if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
10191
- userExtraField.set(type, field.data);
10192
- }
10193
- });
10194
- if (userExtraField.size) {
10195
- return userExtraField;
10196
- }
10197
- }
10198
- }
10199
-
10200
10472
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
10201
10473
  const { onstart, onprogress, onend, onentryprogress } = options;
10202
10474
  const selectedEntry = entry;
@@ -10299,6 +10571,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
10299
10571
 
10300
10572
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10301
10573
  const { onstart, onprogress, onend } = options;
10574
+ checkPassThroughValue(options.passThrough);
10302
10575
  const readerOptions = checkReaderOptions(options.readerOptions);
10303
10576
  const abortController = new AbortController();
10304
10577
  const { signal } = abortController;
@@ -10374,7 +10647,7 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10374
10647
  if (exportAborted || isExportAborted(signal.reason)) {
10375
10648
  return;
10376
10649
  }
10377
- throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
10650
+ throwIfAborted(signal);
10378
10651
  }
10379
10652
  try {
10380
10653
  if (child.directory) {
@@ -10507,7 +10780,7 @@ function addChild(parent, name, params, directory) {
10507
10780
  }
10508
10781
  return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
10509
10782
  } else {
10510
- throw new Error("Parent entry is not a directory");
10783
+ throw new Error(ERR_PARENT_NOT_DIRECTORY);
10511
10784
  }
10512
10785
  }
10513
10786
 
@@ -10641,7 +10914,7 @@ function decodeMimeTypes(data) {
10641
10914
  */
10642
10915
 
10643
10916
 
10644
- c(setDefaultConfiguration);
10917
+ f(setDefaultConfiguration);
10645
10918
 
10646
10919
  exports.BlobReader = BlobReader;
10647
10920
  exports.BlobWriter = BlobWriter;
@@ -10649,6 +10922,7 @@ exports.Data64URIReader = Data64URIReader;
10649
10922
  exports.Data64URIWriter = Data64URIWriter;
10650
10923
  exports.ERR_ABORTED = ERR_ABORTED;
10651
10924
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
10925
+ exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
10652
10926
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
10653
10927
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
10654
10928
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
@@ -10662,7 +10936,9 @@ exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
10662
10936
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
10663
10937
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
10664
10938
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
10939
+ exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
10665
10940
  exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
10941
+ exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
10666
10942
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
10667
10943
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
10668
10944
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
@@ -10672,6 +10948,7 @@ exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
10672
10948
  exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
10673
10949
  exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
10674
10950
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
10951
+ exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
10675
10952
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
10676
10953
  exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
10677
10954
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
@@ -10690,6 +10967,7 @@ exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
10690
10967
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
10691
10968
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
10692
10969
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
10970
+ exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
10693
10971
  exports.ERR_INVALID_READER = ERR_INVALID_READER;
10694
10972
  exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
10695
10973
  exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
@@ -10700,14 +10978,19 @@ exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
10700
10978
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
10701
10979
  exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
10702
10980
  exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
10981
+ exports.ERR_INVALID_URI = ERR_INVALID_URI;
10703
10982
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
10704
10983
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
10705
10984
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
10706
10985
  exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
10986
+ exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
10707
10987
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
10708
10988
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
10989
+ exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
10709
10990
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
10991
+ exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
10710
10992
  exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
10993
+ exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
10711
10994
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
10712
10995
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
10713
10996
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -10719,10 +11002,12 @@ exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
10719
11002
  exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
10720
11003
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
10721
11004
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
11005
+ exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
10722
11006
  exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
10723
11007
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10724
11008
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10725
11009
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
11010
+ exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
10726
11011
  exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
10727
11012
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
10728
11013
  exports.HttpRangeReader = HttpRangeReader;
@@ -10736,13 +11021,17 @@ exports.Uint8ArrayReader = Uint8ArrayReader;
10736
11021
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
10737
11022
  exports.VERSION = VERSION;
10738
11023
  exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
11024
+ exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
10739
11025
  exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
11026
+ exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
10740
11027
  exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
10741
11028
  exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
10742
11029
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
10743
11030
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
10744
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;
10745
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;
10746
11035
  exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
10747
11036
  exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
10748
11037
  exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;