@zip.js/zip.js 2.11.4 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +427 -110
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +437 -107
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +492 -230
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +505 -227
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +492 -230
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +507 -229
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +508 -230
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +439 -109
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +439 -109
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +440 -110
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +507 -229
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +508 -230
  27. package/index.d.cts +468 -59
  28. package/index.d.ts +468 -59
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-worker-web.js +10 -2
  31. package/lib/core/codec-worker.js +4 -3
  32. package/lib/core/configuration.js +20 -5
  33. package/lib/core/constants.js +2 -0
  34. package/lib/core/io.js +13 -5
  35. package/lib/core/options.js +16 -0
  36. package/lib/core/streams/codec-stream.js +6 -0
  37. package/lib/core/util/warnings.js +42 -0
  38. package/lib/core/version.js +1 -1
  39. package/lib/core/web-worker-base.js +4 -3
  40. package/lib/core/web-worker-inline-native.js +1 -1
  41. package/lib/core/web-worker-inline-wasm.js +1 -1
  42. package/lib/core/zip-entry.js +49 -1
  43. package/lib/core/zip-fs.js +43 -132
  44. package/lib/core/zip-reader.js +106 -48
  45. package/lib/core/zip-writer.js +236 -54
  46. package/lib/zip-core-base.js +9 -3
  47. package/lib/zip-core-reader.js +2 -0
  48. package/lib/zip-core-writer.js +6 -1
  49. package/lib/zip-module-wasm-base.js +2 -2
  50. package/package.json +5 -3
@@ -134,6 +134,7 @@
134
134
  const BOOLEAN_TYPE = "boolean";
135
135
 
136
136
  const EMPTY_UINT8_ARRAY = new Uint8Array();
137
+ const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
137
138
 
138
139
  /*
139
140
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -178,6 +179,7 @@
178
179
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
179
180
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
180
181
  const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
182
+ const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
181
183
  const OPTION_CHECK_SIGNATURE = "checkSignature";
182
184
  const OPTION_CHECK_CRC32 = "checkCrc32";
183
185
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -208,15 +210,18 @@
208
210
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
209
211
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
210
212
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
213
+ const OPTION_ENTRY = "entry";
211
214
  const TEXT_TYPE_FILENAME = "filename";
212
215
  const TEXT_TYPE_COMMENT = "comment";
213
216
  const STRICTNESS_STRICT = "strict";
214
217
  const STRICTNESS_BALANCED = "balanced";
215
218
  const STRICTNESS_TOLERANT = "tolerant";
219
+ const PASS_THROUGH_COMPRESSED = "compressed";
216
220
 
217
221
  const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
218
222
  const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
219
223
  const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
224
+ const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
220
225
  const ERR_ABORTED = "The operation was aborted";
221
226
  const ABORT_ERROR_NAME = "AbortError";
222
227
 
@@ -246,6 +251,13 @@
246
251
  }
247
252
  }
248
253
 
254
+ function checkPassThroughOption(passThrough) {
255
+ if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
256
+ throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
257
+ }
258
+ return passThrough;
259
+ }
260
+
249
261
  function checkInteger(value, maxValue, errorMessage) {
250
262
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
251
263
  throw new Error(errorMessage);
@@ -295,6 +307,8 @@
295
307
  const MINIMUM_CHUNK_SIZE = 64;
296
308
  const MINIMUM_PROPERTY_VALUE = 1;
297
309
  const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
310
+ const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
311
+ const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
298
312
  let maxWorkers = 2;
299
313
  try {
300
314
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -319,9 +333,9 @@
319
333
  };
320
334
 
321
335
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
336
+ const PROPERTY_NAME_BASE_URI = "baseURI";
322
337
 
323
- const STRING_PROPERTY_NAMES = [
324
- "baseURI",
338
+ const URI_PROPERTY_NAMES = [
325
339
  "wasmURI",
326
340
  "workerURI"
327
341
  ];
@@ -345,7 +359,8 @@
345
359
  "DecompressionStreamFallback"
346
360
  ];
347
361
  const CONFIGURABLE_PROPERTY_NAMES = [
348
- ...STRING_PROPERTY_NAMES,
362
+ PROPERTY_NAME_BASE_URI,
363
+ ...URI_PROPERTY_NAMES,
349
364
  ...BOOLEAN_PROPERTY_NAMES,
350
365
  ...NUMBER_PROPERTY_NAMES,
351
366
  ...FUNCTION_PROPERTY_NAMES
@@ -389,6 +404,14 @@
389
404
  }
390
405
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
391
406
  checkFunctionOption(propertyValue);
407
+ } else if (propertyName == PROPERTY_NAME_BASE_URI) {
408
+ if (propertyValue && typeof propertyValue != STRING_TYPE) {
409
+ throw new Error(ERR_INVALID_BASE_URI);
410
+ }
411
+ } else if (URI_PROPERTY_NAMES.includes(propertyName)) {
412
+ if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
413
+ throw new Error(ERR_INVALID_URI);
414
+ }
392
415
  }
393
416
  return propertyValue;
394
417
  }
@@ -422,7 +445,7 @@
422
445
  Object.assign(config, DEFAULT_CONFIGURATION);
423
446
  }
424
447
 
425
- 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;
448
+ const r=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],e=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],c=new Uint8Array(288);c.fill(8,0,144),c.fill(9,144,256),c.fill(7,256,280),c.fill(8,280,288);const n=new Uint8Array(30).fill(5);function B(r){const o=new Uint16Array(16);for(const s of r)o[s]++;o[0]=0;const s=new Uint16Array(17);for(let r=1;r<=15;r++)s[r+1]=s[r]+o[r];const e=new Uint16Array(r.length);for(let o=0;o<r.length;o++)r[o]&&(e[s[r[o]]++]=o);return {o:o,symbols:e}}const A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",f=(w=()=>function(A){let f=0,w=0,K=0,g=new Uint8Array(1024),O=0,T=0;for(;!T;){T=W(1);const r=W(2);if(0==r)i();else if(1==r)z(B(c),B(n));else {if(2!=r)throw new Error("invalid deflate block type");z(...D());}}return g.subarray(0,O);function l(){if(f>=A.length)throw new Error("unexpected end of deflate data");return A[f++]}function W(r){for(;K<r;)w|=l()<<K,K+=8;const o=w&(1<<r)-1;return w>>>=r,K-=r,o}function i(){w=0,K=0;const r=l()|l()<<8;f+=2,u(O+r);for(let o=0;o<r;o++)g[O++]=l();}function z(t,c){let n=E(t);for(;256!=n;){if(n<256)u(O+1),g[O++]=n;else {const t=n-257,B=r[t]+W(o[t]),A=E(c),f=s[A]+W(e[A]);u(O+B);const w=O-f;for(let r=0;r<B;r++)g[O++]=g[w+r];}n=E(t);}}function D(){const r=W(5)+257,o=W(5)+1,s=W(4)+4,e=new Uint8Array(19);for(let r=0;r<s;r++)e[t[r]]=W(3);const c=B(e),n=new Uint8Array(r+o);let A=0;for(;A<n.length;){const r=E(c);if(r<16)n[A++]=r;else if(16==r){const r=n[A-1];let o=W(2)+3;for(;o--;)n[A++]=r;}else A+=17==r?W(3)+3:W(7)+11;}return [B(n.subarray(0,r)),B(n.subarray(r))]}function E(r){const{o:o,symbols:s}=r;let e=0,t=0,c=0;for(let r=1;r<=15;r++){e|=W(1);const n=o[r];if(e-t<n)return s[c+(e-t)];c+=n,t=t+n<<1,e<<=1;}throw new Error("invalid huffman code")}function u(r){if(g.length<r){let o=2*g.length;for(;o<r;)o*=2;const s=new Uint8Array(o);s.set(g.subarray(0,O)),g=s;}}}(function(r){const o=(r=String(r).replace(/[^A-Za-z0-9+/=]/g,"")).length,s=[];for(let e=0;e<o;e+=4){const o=A.indexOf(r[e])<<18|A.indexOf(r[e+1])<<12|(63&A.indexOf(r[e+2]))<<6|63&A.indexOf(r[e+3]);s.push(o>>16&255),"="!==r[e+2]&&s.push(o>>8&255),"="!==r[e+3]&&s.push(255&o);}return new Uint8Array(s)}("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")),r=>r({workerURI:r=>{const o="text/javascript";let s=w();if("string"==typeof s&&(s=(new TextEncoder).encode(s)),r){const r=new Blob([s],{type:o});return URL.createObjectURL(r)}return "data:"+o+";base64,"+function(r){let o="";const s=r.length;let e=0;for(;e+2<s;e+=3){const s=r[e]<<16|r[e+1]<<8|r[e+2];o+=A[s>>18&63]+A[s>>12&63]+A[s>>6&63]+A[63&s];}const t=s-e;if(1===t){const s=r[e]<<16;o+=A[s>>18&63]+A[s>>12&63]+"==";}else if(2===t){const s=r[e]<<16|r[e+1]<<8;o+=A[s>>18&63]+A[s>>12&63]+A[s>>6&63]+"=";}return o}(s)}}));var w;
426
449
 
427
450
  /*
428
451
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -2607,6 +2630,7 @@
2607
2630
  constructor(chunkSize) {
2608
2631
  const pendingChunks = [];
2609
2632
  let pendingLength = 0;
2633
+ let outputSize = 0;
2610
2634
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2611
2635
  chunkSize = DEFAULT_CHUNK_SIZE;
2612
2636
  }
@@ -2615,15 +2639,20 @@
2615
2639
  pendingChunks.push(chunk);
2616
2640
  pendingLength += chunk.length;
2617
2641
  while (pendingLength > chunkSize) {
2642
+ outputSize += chunkSize;
2618
2643
  controller.enqueue(shiftChunk());
2619
2644
  }
2620
2645
  },
2621
2646
  flush(controller) {
2622
2647
  if (pendingLength) {
2648
+ outputSize += pendingLength;
2623
2649
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2624
2650
  }
2625
2651
  }
2626
2652
  });
2653
+ Object.defineProperty(this, "outputSize", {
2654
+ get: () => outputSize
2655
+ });
2627
2656
 
2628
2657
  function shiftChunk() {
2629
2658
  const result = new Uint8Array(chunkSize);
@@ -2824,7 +2853,7 @@
2824
2853
  }
2825
2854
 
2826
2855
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2827
- let codecStream;
2856
+ let codecStream, chunkStream;
2828
2857
  try {
2829
2858
  if (options.compressed && !options.format) {
2830
2859
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2847,9 +2876,10 @@
2847
2876
  }
2848
2877
  }
2849
2878
  codecStream = new CodecStream(options, config);
2879
+ chunkStream = new ChunkStream(getChunkSize(config));
2850
2880
  await readable
2851
2881
  .pipeThrough(codecStream)
2852
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2882
+ .pipeThrough(chunkStream)
2853
2883
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2854
2884
  const {
2855
2885
  crc32,
@@ -2863,7 +2893,7 @@
2863
2893
  };
2864
2894
  } catch (error) {
2865
2895
  if (codecStream) {
2866
- error.outputSize = codecStream.outputSize;
2896
+ error.outputSize = chunkStream ? chunkStream.outputSize : 0;
2867
2897
  }
2868
2898
  throw error;
2869
2899
  } finally {
@@ -2972,11 +3002,17 @@
2972
3002
  let resolveResult, rejectResult;
2973
3003
  const result = new Promise((resolve, reject) => {
2974
3004
  resolveResult = resolve;
2975
- rejectResult = reject;
3005
+ rejectResult = error => {
3006
+ if (error && error.outputSize === UNDEFINED_VALUE) {
3007
+ error.outputSize = workerData.outputSize;
3008
+ }
3009
+ reject(error);
3010
+ };
2976
3011
  });
2977
3012
  Object.assign(workerData, {
2978
3013
  reader: null,
2979
3014
  writer: null,
3015
+ outputSize: 0,
2980
3016
  resolveResult,
2981
3017
  rejectResult,
2982
3018
  result
@@ -3260,8 +3296,10 @@
3260
3296
  }
3261
3297
  }
3262
3298
  if (type == MESSAGE_DATA) {
3299
+ const chunk = new Uint8Array(value);
3263
3300
  await writer.ready;
3264
- await writer.write(new Uint8Array(value));
3301
+ await writer.write(chunk);
3302
+ workerData.outputSize += chunk.length;
3265
3303
  if (!stale()) {
3266
3304
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3267
3305
  }
@@ -3569,10 +3607,13 @@
3569
3607
 
3570
3608
 
3571
3609
  const ERR_HTTP_STATUS = "HTTP error ";
3610
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3611
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3572
3612
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3573
3613
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3574
3614
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3575
3615
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3616
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3576
3617
 
3577
3618
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3578
3619
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3764,6 +3805,7 @@
3764
3805
  const reader = this;
3765
3806
  const { sourceBlob, size } = reader;
3766
3807
  const { offset = 0, size: readSize = size - offset } = options || {};
3808
+ // deno-lint-ignore valid-typeof
3767
3809
  if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3768
3810
  if (!offset && readSize >= size) {
3769
3811
  return toCompatibleReadable(sourceBlob.stream());
@@ -4170,7 +4212,7 @@
4170
4212
 
4171
4213
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4172
4214
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4173
- if (response.status < 400) {
4215
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4174
4216
  return response;
4175
4217
  } else {
4176
4218
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4181,7 +4223,7 @@
4181
4223
  return new Promise((resolve, reject) => {
4182
4224
  const request = new XMLHttpRequest();
4183
4225
  request.addEventListener("load", () => {
4184
- if (request.status < 400) {
4226
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4185
4227
  const headers = [];
4186
4228
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4187
4229
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4485,8 +4527,10 @@
4485
4527
  writable: toCompatibleWritable(writer)
4486
4528
  };
4487
4529
  }
4488
- if (writer.size === UNDEFINED_VALUE) {
4489
- writer.size = 0;
4530
+ try {
4531
+ writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
4532
+ } catch {
4533
+ throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
4490
4534
  }
4491
4535
  return writer;
4492
4536
  }
@@ -4534,6 +4578,45 @@
4534
4578
  }
4535
4579
  }
4536
4580
 
4581
+ /*
4582
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
4583
+
4584
+ Redistribution and use in source and binary forms, with or without
4585
+ modification, are permitted provided that the following conditions are met:
4586
+
4587
+ 1. Redistributions of source code must retain the above copyright notice,
4588
+ this list of conditions and the following disclaimer.
4589
+
4590
+ 2. Redistributions in binary form must reproduce the above copyright
4591
+ notice, this list of conditions and the following disclaimer in
4592
+ the documentation and/or other materials provided with the distribution.
4593
+
4594
+ 3. The names of the authors may not be used to endorse or promote products
4595
+ derived from this software without specific prior written permission.
4596
+
4597
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4598
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4599
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4600
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4601
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4602
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4603
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4604
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4605
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4606
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4607
+ */
4608
+
4609
+
4610
+ function addWarning(warnings, reason, filename) {
4611
+ if (!warnings.some(warning => warning.reason == reason)) {
4612
+ const warning = { reason };
4613
+ if (filename !== UNDEFINED_VALUE) {
4614
+ warning.filename = filename;
4615
+ }
4616
+ warnings.push(warning);
4617
+ }
4618
+ }
4619
+
4537
4620
  /*
4538
4621
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4539
4622
 
@@ -4562,6 +4645,7 @@
4562
4645
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4563
4646
  */
4564
4647
 
4648
+
4565
4649
  const PROPERTY_NAME_FILENAME = "filename";
4566
4650
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4567
4651
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4686,6 +4770,38 @@
4686
4770
 
4687
4771
  }
4688
4772
 
4773
+ const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
4774
+ EXTRAFIELD_TYPE_ZIP64,
4775
+ EXTRAFIELD_TYPE_AES,
4776
+ EXTRAFIELD_TYPE_NTFS,
4777
+ EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
4778
+ EXTRAFIELD_TYPE_UNICODE_PATH,
4779
+ EXTRAFIELD_TYPE_UNICODE_COMMENT,
4780
+ EXTRAFIELD_TYPE_USDZ,
4781
+ EXTRAFIELD_TYPE_INFOZIP,
4782
+ EXTRAFIELD_TYPE_UNIX,
4783
+ EXTRAFIELD_TYPE_UNIX_TYPE1,
4784
+ EXTRAFIELD_TYPE_PKWARE_UNIX
4785
+ ]);
4786
+
4787
+ function getUserExtraField(extraField) {
4788
+ if (extraField) {
4789
+ const userExtraField = new Map();
4790
+ extraField.forEach((field, type) => {
4791
+ if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
4792
+ userExtraField.set(type, field.data);
4793
+ }
4794
+ });
4795
+ if (userExtraField.size) {
4796
+ return userExtraField;
4797
+ }
4798
+ }
4799
+ }
4800
+
4801
+ function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
4802
+ return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
4803
+ }
4804
+
4689
4805
  /*
4690
4806
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4691
4807
 
@@ -4745,6 +4861,8 @@
4745
4861
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4746
4862
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4747
4863
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4864
+ const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
4865
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
4748
4866
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4749
4867
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4750
4868
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4815,7 +4933,7 @@
4815
4933
  }
4816
4934
  }
4817
4935
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4818
- throwAmbiguousArchive("multiple end of central directory records");
4936
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4819
4937
  }
4820
4938
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4821
4939
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5113,7 +5231,8 @@
5113
5231
  const writer = new TransformStream();
5114
5232
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5115
5233
  arrayBufferPromise.catch(() => { });
5116
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5234
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5235
+ Object.assign({}, options, { preventClose: false }));
5117
5236
  return arrayBufferPromise;
5118
5237
  };
5119
5238
  offset = endOffset;
@@ -5194,49 +5313,101 @@
5194
5313
  await reader.readable.cancel();
5195
5314
  }
5196
5315
  }
5316
+
5317
+ [SYMBOL_ASYNC_DISPOSE]() {
5318
+ return this.close();
5319
+ }
5197
5320
  }
5198
5321
 
5199
5322
  class ZipReaderStream {
5200
5323
 
5201
5324
  constructor(options = {}) {
5202
- const { readable, writable } = new TransformStream();
5203
- const gen = new ZipReader(readable, options).getEntriesGenerator();
5325
+ let sourceController;
5326
+ const { readable, writable } = new TransformStream({
5327
+ start(controller) {
5328
+ sourceController = controller;
5329
+ }
5330
+ });
5331
+ const zipReader = new ZipReader(readable, options);
5332
+ const gen = zipReader.getEntriesGenerator();
5333
+ const pendingEntries = new Set();
5204
5334
  this.readable = new ReadableStream({
5205
5335
  async pull(controller) {
5206
5336
  const { done, value } = await gen.next();
5207
5337
  if (done)
5208
5338
  return controller.close();
5209
- const entryReadable = (function () {
5210
- const { readable, writable } = new TransformStream();
5211
- if (value.getData) {
5212
- getData();
5213
- return readable;
5214
- }
5215
-
5216
- async function getData() {
5217
- try {
5218
- await value.getData(writable);
5219
- } catch (error) {
5220
- try {
5221
- await writable.abort(error);
5222
- } catch {
5223
- // ignored
5224
- }
5225
- }
5226
- }
5227
- })();
5339
+ const entryStream = createEntryStream(value, pendingEntries);
5228
5340
  const chunk = {
5229
5341
  ...value,
5230
- readable: entryReadable
5342
+ readable: entryStream.readable
5231
5343
  };
5232
5344
  delete chunk.getData;
5345
+ Object.defineProperties(chunk, {
5346
+ localDirectory: {
5347
+ get: () => value.localDirectory,
5348
+ enumerable: true
5349
+ },
5350
+ warnings: {
5351
+ get: () => value.warnings,
5352
+ enumerable: true
5353
+ }
5354
+ });
5233
5355
  controller.enqueue(chunk);
5356
+ },
5357
+ async cancel(reason) {
5358
+ const entryStreams = Array.from(pendingEntries);
5359
+ pendingEntries.clear();
5360
+ sourceController.error(reason);
5361
+ await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
5362
+ await Promise.allSettled([gen.return(), zipReader.close()]);
5234
5363
  }
5235
5364
  });
5236
5365
  this.writable = writable;
5237
5366
  }
5238
5367
  }
5239
5368
 
5369
+ function createEntryStream(entry, pendingEntries) {
5370
+ const { readable, writable } = new TransformStream();
5371
+ let dataReader;
5372
+ const entryStream = {
5373
+ cancel: async reason => {
5374
+ pendingEntries.delete(entryStream);
5375
+ await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
5376
+ }
5377
+ };
5378
+ entryStream.readable = new ReadableStream({
5379
+ async pull(controller) {
5380
+ if (!dataReader) {
5381
+ dataReader = readable.getReader();
5382
+ pendingEntries.add(entryStream);
5383
+ getData();
5384
+ }
5385
+ const { done, value } = await dataReader.read();
5386
+ if (done) {
5387
+ controller.close();
5388
+ } else {
5389
+ controller.enqueue(value);
5390
+ }
5391
+ },
5392
+ cancel: reason => entryStream.cancel(reason)
5393
+ }, { highWaterMark: 0 });
5394
+ return entryStream;
5395
+
5396
+ async function getData() {
5397
+ try {
5398
+ await entry.getData(writable, { preventClose: false });
5399
+ } catch (error) {
5400
+ try {
5401
+ await writable.abort(error);
5402
+ } catch {
5403
+ // ignored
5404
+ }
5405
+ } finally {
5406
+ pendingEntries.delete(entryStream);
5407
+ }
5408
+ }
5409
+ }
5410
+
5240
5411
  async function isZipFile(reader, options = {}) {
5241
5412
  reader = new GenericReader(reader);
5242
5413
  await initStream(reader);
@@ -5296,7 +5467,9 @@
5296
5467
  const dataView = getDataView(dataArray);
5297
5468
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5298
5469
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5299
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5470
+ const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
5471
+ const passThroughCompression = Boolean(passThrough);
5472
+ const passThroughEncryption = passThrough === true;
5300
5473
  checkPasswordOption(password, rawPassword);
5301
5474
  password = password && password.length && password;
5302
5475
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5317,7 +5490,9 @@
5317
5490
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5318
5491
  const entryStrictness = getStrictness(options, zipEntry.options);
5319
5492
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5320
- const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5493
+ const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
5494
+ const checkLocalFilename = getCheckLocalFilename(
5495
+ checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
5321
5496
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5322
5497
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5323
5498
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5348,16 +5523,17 @@
5348
5523
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5349
5524
  fileEntry.gid = gid;
5350
5525
  }
5351
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5526
+ const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5527
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5352
5528
  const zipCrypto = encrypted && !extraFieldAES;
5353
- if (!passThrough) {
5529
+ if (!passThroughEncryption) {
5354
5530
  fileEntry.zipCrypto = zipCrypto;
5355
5531
  }
5356
5532
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5357
5533
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5358
5534
  }
5359
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5360
- if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThrough) {
5535
+ const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5536
+ if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
5361
5537
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5362
5538
  }
5363
5539
  if (encrypted) {
@@ -5374,15 +5550,16 @@
5374
5550
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5375
5551
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5376
5552
  throwIfAborted(signal);
5377
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5378
5553
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5379
5554
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5380
5555
  if (checkOverlappingEntryOnly) {
5381
5556
  checkOverlappingEntry = true;
5382
5557
  }
5383
5558
  const { onstart, onprogress, onend } = options;
5384
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5385
- const outputSize = passThrough ? compressedSize : uncompressedSize;
5559
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
5560
+ const outputSize = passThroughCompression ?
5561
+ compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
5562
+ uncompressedSize;
5386
5563
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5387
5564
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5388
5565
  if (deflate64) {
@@ -5391,7 +5568,7 @@
5391
5568
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5392
5569
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5393
5570
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5394
- checkCrc32Option) && !passThrough &&
5571
+ checkCrc32Option) && !passThroughCompression &&
5395
5572
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5396
5573
  const workerOptions = {
5397
5574
  options: {
@@ -5445,10 +5622,10 @@
5445
5622
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5446
5623
  ({ writable } = writer);
5447
5624
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5448
- writer.size += writtenSize;
5449
5625
  if (writtenSize != outputSize) {
5450
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5626
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5451
5627
  }
5628
+ writer.size += writtenSize;
5452
5629
  }
5453
5630
  } catch (error) {
5454
5631
  if (error.outputSize !== UNDEFINED_VALUE) {
@@ -6114,7 +6291,7 @@
6114
6291
  if (checkLocalFilename && !maskedLocalDirectory &&
6115
6292
  (rawLocalFilename.length != rawFilename.length ||
6116
6293
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6117
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6294
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6118
6295
  }
6119
6296
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6120
6297
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6139,16 +6316,6 @@
6139
6316
  }
6140
6317
  }
6141
6318
 
6142
- function addWarning(warnings, reason, filename) {
6143
- if (!warnings.some(warning => warning.reason == reason)) {
6144
- const warning = { reason };
6145
- if (filename !== UNDEFINED_VALUE) {
6146
- warning.filename = filename;
6147
- }
6148
- warnings.push(warning);
6149
- }
6150
- }
6151
-
6152
6319
  function throwAmbiguousArchive(reason) {
6153
6320
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6154
6321
  error.reason = reason;
@@ -6228,7 +6395,9 @@
6228
6395
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6229
6396
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6230
6397
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6398
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6231
6399
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6400
+ WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6232
6401
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6233
6402
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6234
6403
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6281,7 +6450,7 @@
6281
6450
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6282
6451
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6283
6452
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6284
- const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6453
+ const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
6285
6454
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6286
6455
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6287
6456
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6293,6 +6462,7 @@
6293
6462
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6294
6463
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6295
6464
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6465
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6296
6466
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6297
6467
  const ERR_UNDEFINED_READER = "Undefined reader";
6298
6468
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6306,14 +6476,21 @@
6306
6476
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6307
6477
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6308
6478
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6479
+ const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
6480
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
6481
+ const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
6482
+ const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
6309
6483
 
6310
6484
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6311
6485
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6312
6486
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6313
6487
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6488
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6489
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6314
6490
  const VENDOR_VERSION_AE_1 = 1;
6315
- const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6491
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6316
6492
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6493
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6317
6494
  const MAX_LEVEL = 9;
6318
6495
 
6319
6496
  let workers = 0;
@@ -6340,9 +6517,11 @@
6340
6517
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6341
6518
  pendingAddFileCalls: new Set(),
6342
6519
  pendingErrors: [],
6520
+ warnings: [],
6343
6521
  bufferedWrites: 0,
6344
6522
  directWrites: 0,
6345
- lastFileEntry: UNDEFINED_VALUE
6523
+ lastFileEntry: UNDEFINED_VALUE,
6524
+ archiveClosed: false
6346
6525
  });
6347
6526
  }
6348
6527
 
@@ -6507,6 +6686,9 @@
6507
6686
  const zipWriter = this;
6508
6687
  const { pendingAddFileCalls, writer } = this;
6509
6688
  const { writable } = writer;
6689
+ if (zipWriter.archiveClosed) {
6690
+ return getWriterData(writer);
6691
+ }
6510
6692
  if (!(comment instanceof Uint8Array)) {
6511
6693
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6512
6694
  }
@@ -6530,11 +6712,16 @@
6530
6712
  throw error;
6531
6713
  }
6532
6714
  await closeFile(zipWriter, comment, options);
6715
+ zipWriter.archiveClosed = true;
6533
6716
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6534
6717
  if (!preventClose) {
6535
6718
  await writable.getWriter().close();
6536
6719
  }
6537
- return writer.getData ? writer.getData() : writable;
6720
+ return getWriterData(writer);
6721
+ }
6722
+
6723
+ [SYMBOL_ASYNC_DISPOSE]() {
6724
+ return this.close();
6538
6725
  }
6539
6726
  }
6540
6727
 
@@ -6613,6 +6800,10 @@
6613
6800
  }
6614
6801
  }
6615
6802
 
6803
+ function getWriterData(writer) {
6804
+ return writer.getData ? writer.getData() : writer.writable;
6805
+ }
6806
+
6616
6807
  function watchPromiseError(zipWriter, promise) {
6617
6808
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6618
6809
  const watcher = {};
@@ -6631,6 +6822,14 @@
6631
6822
 
6632
6823
  async function addFileEntry(zipWriter, name, reader, options) {
6633
6824
  options = Object.assign({}, options);
6825
+ const entry = options[OPTION_ENTRY];
6826
+ if (entry !== UNDEFINED_VALUE) {
6827
+ const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
6828
+ checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
6829
+ getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
6830
+ delete options[OPTION_ENTRY];
6831
+ options = Object.assign(entryOptions, passThroughOptions, options);
6832
+ }
6634
6833
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6635
6834
  name += DIRECTORY_SIGNATURE;
6636
6835
  }
@@ -6695,21 +6894,33 @@
6695
6894
  try {
6696
6895
  const { resolvedOptions } = metadataInfo;
6697
6896
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6698
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6897
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6699
6898
  resolvedOptions.level = 0;
6899
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6700
6900
  }
6701
6901
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6702
6902
  ({ reader } = sizesInfo);
6703
6903
  const diskOffset = getDiskOffset(zipWriter.writer);
6704
6904
  const diskNumber = getDiskNumber(zipWriter.writer);
6905
+ let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
6906
+ const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
6907
+ if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
6908
+ crc32 = UNDEFINED_VALUE;
6909
+ }
6910
+ if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
6911
+ throw new Error(ERR_UNDEFINED_CRC32);
6912
+ }
6705
6913
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6706
6914
  signature: options[PROPERTY_NAME_SIGNATURE],
6707
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6915
+ crc32,
6708
6916
  offset: zipWriter.offset - diskOffset,
6709
6917
  diskNumberStart: diskNumber,
6710
6918
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6711
6919
  });
6712
6920
  const headerInfo = getHeaderInfo(options);
6921
+ if (headerInfo.lastModDateClamped) {
6922
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
6923
+ }
6713
6924
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6714
6925
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6715
6926
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6736,6 +6947,95 @@
6736
6947
  return new Entry(fileEntry);
6737
6948
  }
6738
6949
 
6950
+ function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
6951
+ if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
6952
+ throw new Error(ERR_INVALID_ENTRY);
6953
+ }
6954
+ const {
6955
+ externalFileAttributes,
6956
+ versionMadeBy,
6957
+ comment,
6958
+ lastModDate,
6959
+ rawLastModDate,
6960
+ creationDate,
6961
+ lastAccessDate,
6962
+ uncompressedSize,
6963
+ encrypted,
6964
+ zipCrypto,
6965
+ crc32,
6966
+ compressionMethod,
6967
+ extraFieldAES,
6968
+ extraFieldUnix,
6969
+ internalFileAttributes,
6970
+ extraField,
6971
+ bitFlag,
6972
+ directory,
6973
+ uid,
6974
+ gid
6975
+ } = entry;
6976
+ const entryOptions = {
6977
+ externalFileAttributes,
6978
+ versionMadeBy,
6979
+ comment,
6980
+ lastModDate,
6981
+ creationDate,
6982
+ lastAccessDate,
6983
+ internalFileAttributes,
6984
+ directory
6985
+ };
6986
+ if (bitFlag && bitFlag.languageEncodingFlag) {
6987
+ entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
6988
+ }
6989
+ const userExtraField = getUserExtraField(extraField);
6990
+ if (userExtraField) {
6991
+ entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
6992
+ }
6993
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
6994
+ Object.assign(entryOptions, {
6995
+ uid,
6996
+ gid,
6997
+ unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
6998
+ });
6999
+ }
7000
+ const passThroughOptions = {};
7001
+ if (passThrough && !directory) {
7002
+ Object.assign(passThroughOptions, {
7003
+ uncompressedSize,
7004
+ crc32,
7005
+ compressionMethod
7006
+ });
7007
+ if (passThrough !== PASS_THROUGH_COMPRESSED) {
7008
+ Object.assign(passThroughOptions, {
7009
+ encrypted,
7010
+ zipCrypto,
7011
+ encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
7012
+ });
7013
+ }
7014
+ if (bitFlag) {
7015
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
7016
+ passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
7017
+ }
7018
+ if (lastModDateOverride === UNDEFINED_VALUE) {
7019
+ passThroughOptions.rawLastModDate = rawLastModDate;
7020
+ } else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
7021
+ lastModDateOverride instanceof Date &&
7022
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
7023
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
7024
+ }
7025
+ }
7026
+ return { entryOptions, passThroughOptions };
7027
+ }
7028
+
7029
+ function getDosTimeHighByte(lastModDate) {
7030
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
7031
+ if (dosLastModDate < MIN_DATE) {
7032
+ dosLastModDate = MIN_DATE;
7033
+ } else if (dosLastModDate > MAX_DATE) {
7034
+ dosLastModDate = MAX_DATE;
7035
+ }
7036
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
7037
+ }
7038
+
6739
7039
  function resolveAttributes(zipWriter, name, options) {
6740
7040
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6741
7041
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6750,7 +7050,7 @@
6750
7050
  checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6751
7051
  checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6752
7052
  checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6753
- if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
7053
+ if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6754
7054
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6755
7055
  }
6756
7056
  if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
@@ -6758,7 +7058,7 @@
6758
7058
  throw new Error(ERR_INVALID_UNIX_ID_SIZE);
6759
7059
  }
6760
7060
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6761
- unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
7061
+ unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
6762
7062
  }
6763
7063
  let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6764
7064
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
@@ -6889,7 +7189,9 @@
6889
7189
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6890
7190
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6891
7191
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6892
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
7192
+ const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7193
+ const passThroughCompression = Boolean(passThrough);
7194
+ const passThroughEncryption = passThrough === true;
6893
7195
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6894
7196
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6895
7197
  checkPasswordOption(password, rawPassword);
@@ -6905,10 +7207,11 @@
6905
7207
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6906
7208
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6907
7209
  throwIfAborted(signal);
6908
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7210
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7211
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6909
7212
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6910
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6911
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7213
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7214
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6912
7215
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6913
7216
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6914
7217
  }
@@ -6922,15 +7225,15 @@
6922
7225
  level = 0;
6923
7226
  }
6924
7227
  }
6925
- if (passThrough) {
6926
- level = UNDEFINED_VALUE;
7228
+ if (passThroughCompression) {
7229
+ level = toNumber(options[OPTION_LEVEL]);
6927
7230
  }
6928
7231
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6929
7232
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6930
7233
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6931
7234
  dataDescriptor = false;
6932
7235
  }
6933
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7236
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6934
7237
  dataDescriptor = true;
6935
7238
  }
6936
7239
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6954,7 +7257,8 @@
6954
7257
  lastAccessDate,
6955
7258
  creationDate,
6956
7259
  internalFileAttributes,
6957
- passThrough,
7260
+ passThroughCompression,
7261
+ passThroughEncryption,
6958
7262
  password,
6959
7263
  rawPassword,
6960
7264
  encryptionStrength,
@@ -7015,7 +7319,7 @@
7015
7319
  }
7016
7320
 
7017
7321
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
7018
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7322
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7019
7323
  throw new Error(ERR_UNDEFINED_READER);
7020
7324
  }
7021
7325
  let contentSize;
@@ -7031,12 +7335,12 @@
7031
7335
  }
7032
7336
 
7033
7337
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7034
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7338
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7035
7339
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7036
7340
  let maximumCompressedSize = 0;
7037
7341
  let uncompressedSize = 0;
7038
7342
  let unknownSize = false;
7039
- if (passThrough && hasContent) {
7343
+ if (passThroughCompression && hasContent) {
7040
7344
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7041
7345
  if (uncompressedSize === UNDEFINED_VALUE) {
7042
7346
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7047,17 +7351,17 @@
7047
7351
  }
7048
7352
  const zip64Enabled = zip64 === true;
7049
7353
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7050
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7354
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7051
7355
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7052
7356
  }
7053
- const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
7357
+ const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
7054
7358
  if (!hasContent) {
7055
7359
  level = 0;
7056
7360
  compressionMethod = COMPRESSION_METHOD_STORE;
7057
7361
  }
7058
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7362
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7059
7363
  if (hasContent) {
7060
- if (!passThrough) {
7364
+ if (!passThroughCompression) {
7061
7365
  if (contentSize === UNDEFINED_VALUE) {
7062
7366
  dataDescriptor = true;
7063
7367
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7070,10 +7374,12 @@
7070
7374
  }
7071
7375
  } else {
7072
7376
  options.uncompressedSize = uncompressedSize;
7073
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7377
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7378
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7379
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7074
7380
  }
7075
7381
  }
7076
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7382
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7077
7383
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7078
7384
  dataDescriptor = false;
7079
7385
  }
@@ -7122,6 +7428,8 @@
7122
7428
  const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
7123
7429
  let offset = initialOffset;
7124
7430
  let minimumEntrySize = INFINITY_VALUE;
7431
+ const entrySizes = [];
7432
+ const entriesAlreadyZip64 = new Set();
7125
7433
  for (const entry of entries) {
7126
7434
  let { name } = entry;
7127
7435
  const { size } = entry;
@@ -7133,7 +7441,7 @@
7133
7441
  ({ name } = attributesInfo);
7134
7442
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
7135
7443
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
7136
- !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
7444
+ !metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
7137
7445
  metadata.level = 0;
7138
7446
  }
7139
7447
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -7141,7 +7449,7 @@
7141
7449
  throw new Error(ERR_UNDETERMINED_SIZE);
7142
7450
  }
7143
7451
  const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
7144
- if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
7452
+ if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
7145
7453
  throw new Error(ERR_UNDETERMINED_SIZE);
7146
7454
  }
7147
7455
  const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
@@ -7161,10 +7469,15 @@
7161
7469
  compressedSize
7162
7470
  }));
7163
7471
  const entrySize = entryInfo.metadataSize + compressedSize;
7472
+ entrySizes.push(entrySize);
7473
+ entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
7474
+ entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
7164
7475
  minimumEntrySize = Math.min(minimumEntrySize, entrySize);
7165
7476
  offset += entrySize;
7166
7477
  }
7167
- const layoutDependsOnWriteOrder = files.size > 1 && (usdz || offset - minimumEntrySize >= MAX_32_BITS);
7478
+ const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
7479
+ (offset - minimumEntrySize >= MAX_32_BITS &&
7480
+ (entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
7168
7481
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
7169
7482
  throw new Error(ERR_UNDETERMINED_SIZE);
7170
7483
  }
@@ -7182,6 +7495,20 @@
7182
7495
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7183
7496
  }
7184
7497
 
7498
+ function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
7499
+ const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
7500
+ let position = initialOffset;
7501
+ let count = 0;
7502
+ for (const entrySize of ordered) {
7503
+ if (position >= MAX_32_BITS) {
7504
+ break;
7505
+ }
7506
+ position += entrySize;
7507
+ count++;
7508
+ }
7509
+ return count;
7510
+ }
7511
+
7185
7512
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7186
7513
  const {
7187
7514
  fileEntries,
@@ -7357,6 +7684,7 @@
7357
7684
  localExtraFieldZip64Length,
7358
7685
  rawExtraFieldExtendedTimestamp,
7359
7686
  extraFieldExtendedTimestampFlag,
7687
+ extraFieldExtendedTimestampTime,
7360
7688
  rawExtraFieldNTFS,
7361
7689
  rawExtraFieldUnix,
7362
7690
  rawExtraFieldAES,
@@ -7369,6 +7697,7 @@
7369
7697
  password,
7370
7698
  rawPassword,
7371
7699
  level,
7700
+ useUnicodeFileNames,
7372
7701
  zip64,
7373
7702
  zip64Enabled,
7374
7703
  zip64UncompressedSize,
@@ -7403,7 +7732,8 @@
7403
7732
  msdosAttributesRaw,
7404
7733
  msdosAttributes,
7405
7734
  useCompressionStream,
7406
- passThrough,
7735
+ passThroughCompression,
7736
+ passThroughEncryption,
7407
7737
  format,
7408
7738
  codecURI
7409
7739
  } = options;
@@ -7414,9 +7744,9 @@
7414
7744
  zip64Enabled,
7415
7745
  directory: Boolean(directory),
7416
7746
  executable: Boolean(executable),
7417
- filenameUTF8: true,
7747
+ filenameUTF8: Boolean(useUnicodeFileNames),
7418
7748
  rawFilename,
7419
- commentUTF8: true,
7749
+ commentUTF8: Boolean(useUnicodeFileNames),
7420
7750
  rawComment,
7421
7751
  rawExtraFieldZip64,
7422
7752
  localExtraFieldZip64Length,
@@ -7447,7 +7777,7 @@
7447
7777
  uncompressedSize
7448
7778
  } = options;
7449
7779
  let compressedSize = 0;
7450
- if (!passThrough) {
7780
+ if (!passThroughCompression) {
7451
7781
  uncompressedSize = 0;
7452
7782
  }
7453
7783
  const { writable } = writer;
@@ -7464,9 +7794,9 @@
7464
7794
  encryptionStrength,
7465
7795
  zipCrypto: encrypted && zipCrypto,
7466
7796
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7467
- computeCrc32: !passThrough,
7468
- compressed: compressed && !passThrough,
7469
- encrypted: encrypted && !passThrough,
7797
+ computeCrc32: !passThroughCompression,
7798
+ compressed: compressed && !passThroughCompression,
7799
+ encrypted: encrypted && !passThroughEncryption,
7470
7800
  useWebWorkers,
7471
7801
  useCompressionStream,
7472
7802
  transferStreams,
@@ -7481,7 +7811,7 @@
7481
7811
  const result = await runWorker({ readable, writable }, workerOptions);
7482
7812
  compressedSize = result.outputSize;
7483
7813
  writer.size += compressedSize;
7484
- if (!passThrough) {
7814
+ if (!passThroughCompression) {
7485
7815
  uncompressedSize = result.inputSize;
7486
7816
  if (!encrypted || zipCrypto) {
7487
7817
  crc32 = result.crc32;
@@ -7524,8 +7854,9 @@
7524
7854
  headerArray,
7525
7855
  headerView,
7526
7856
  signature: crc32,
7527
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7857
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7528
7858
  extraFieldExtendedTimestampFlag,
7859
+ extraFieldExtendedTimestampTime,
7529
7860
  zip64UncompressedSize,
7530
7861
  zip64CompressedSize
7531
7862
  });
@@ -7550,7 +7881,7 @@
7550
7881
  encryptionStrength,
7551
7882
  extendedTimestamp,
7552
7883
  ntfsTimestamp,
7553
- passThrough,
7884
+ passThroughCompression,
7554
7885
  encrypted,
7555
7886
  zip64UncompressedSize,
7556
7887
  zip64CompressedSize,
@@ -7561,7 +7892,7 @@
7561
7892
  let { version, compressionMethod } = options;
7562
7893
  const compressed = !directory && isCompressed(compressionMethod, level);
7563
7894
  let rawLocalExtraFieldZip64;
7564
- const uncompressedFile = passThrough || !compressed;
7895
+ const uncompressedFile = passThroughCompression || !compressed;
7565
7896
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7566
7897
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7567
7898
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7573,8 +7904,8 @@
7573
7904
  if (zip64ExtraFieldComplete) {
7574
7905
  extraFieldZip64.writeUint64(uncompressedSize);
7575
7906
  if (uncompressedFile) {
7576
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7577
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7907
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
7908
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7578
7909
  }
7579
7910
  }
7580
7911
  } else {
@@ -7593,6 +7924,7 @@
7593
7924
  let rawExtraFieldNTFS;
7594
7925
  let rawExtraFieldExtendedTimestamp;
7595
7926
  let extraFieldExtendedTimestampFlag;
7927
+ let extraFieldExtendedTimestampTime;
7596
7928
  if (extendedTimestamp) {
7597
7929
  const lastModTimeUnix = getTimeUnix(lastModDate);
7598
7930
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7600,6 +7932,7 @@
7600
7932
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7601
7933
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7602
7934
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7935
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7603
7936
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7604
7937
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7605
7938
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7642,7 +7975,7 @@
7642
7975
  let rawExtraFieldUnix;
7643
7976
  try {
7644
7977
  const { uid, gid, unixExtraFieldType } = options;
7645
- if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7978
+ if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7646
7979
  const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7647
7980
  const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7648
7981
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
@@ -7683,7 +8016,7 @@
7683
8016
  }
7684
8017
  if (encrypted && !zipCrypto) {
7685
8018
  version = version > VERSION_AES ? version : VERSION_AES;
7686
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
8019
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7687
8020
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7688
8021
  }
7689
8022
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7745,12 +8078,14 @@
7745
8078
  headerArray,
7746
8079
  headerView,
7747
8080
  lastModDate: storedLastModDate,
8081
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7748
8082
  rawLastModDate,
7749
8083
  encrypted,
7750
8084
  compressed,
7751
8085
  version,
7752
8086
  compressionMethod,
7753
8087
  extraFieldExtendedTimestampFlag,
8088
+ extraFieldExtendedTimestampTime,
7754
8089
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7755
8090
  localExtraFieldZip64Length,
7756
8091
  rawExtraFieldExtendedTimestamp,
@@ -7853,7 +8188,7 @@
7853
8188
  }, {
7854
8189
  zip64,
7855
8190
  zipCrypto,
7856
- passThrough,
8191
+ passThroughCompression,
7857
8192
  dataDescriptor
7858
8193
  }) {
7859
8194
  const {
@@ -7864,7 +8199,7 @@
7864
8199
  dataDescriptorView,
7865
8200
  dataDescriptorOffset
7866
8201
  } = dataDescriptorInfo;
7867
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8202
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7868
8203
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7869
8204
  if (dataDescriptor) {
7870
8205
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7895,9 +8230,9 @@
7895
8230
  uncompressedSize,
7896
8231
  zip64UncompressedSize,
7897
8232
  zip64CompressedSize
7898
- }, localHeaderView, { dataDescriptor, passThrough }) {
8233
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7899
8234
  if (!dataDescriptor) {
7900
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8235
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7901
8236
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7902
8237
  }
7903
8238
  if (!zip64CompressedSize) {
@@ -7934,9 +8269,8 @@
7934
8269
  rawExtraFieldUnix,
7935
8270
  rawExtraField,
7936
8271
  rawCentralExtraField,
7937
- extendedTimestamp,
7938
8272
  extraFieldExtendedTimestampFlag,
7939
- lastModDate,
8273
+ extraFieldExtendedTimestampTime,
7940
8274
  zip64Enabled,
7941
8275
  uncompressedSize,
7942
8276
  compressedSize
@@ -7979,16 +8313,15 @@
7979
8313
  fileEntry.zip64Offset = zip64Offset;
7980
8314
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
7981
8315
  let rawExtraFieldTimestamp;
7982
- const lastModTimeUnix = getTimeUnix(lastModDate);
7983
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8316
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8317
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8318
+ } else {
7984
8319
  const extraFieldTimestamp = createRecordWriter(9);
7985
8320
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7986
8321
  extraFieldTimestamp.writeUint16(5);
7987
8322
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7988
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8323
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
7989
8324
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7990
- } else {
7991
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
7992
8325
  }
7993
8326
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
7994
8327
  const extraFieldLength = getLength(
@@ -8488,6 +8821,11 @@
8488
8821
  };
8489
8822
  }
8490
8823
 
8824
+ function isPrintableASCIIText(rawText) {
8825
+ return rawText.every(characterCode =>
8826
+ characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
8827
+ }
8828
+
8491
8829
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8492
8830
  let bitFlag = 0;
8493
8831
  if (useUnicodeFileNames) {
@@ -8649,7 +8987,7 @@
8649
8987
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8650
8988
  */
8651
8989
 
8652
- const VERSION = "2.11.4";
8990
+ const VERSION = "2.12.0";
8653
8991
 
8654
8992
  /*
8655
8993
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9168,7 +9506,10 @@
9168
9506
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
9169
9507
  const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
9170
9508
  const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
9171
- const ERR_ANCESTOR_ENTRY = "Entry is a ancestor of target entry";
9509
+ const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
9510
+ const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
9511
+ const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
9512
+ const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
9172
9513
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
9173
9514
  const DUPLICATES_THROW = "throw";
9174
9515
  const DUPLICATES_KEEP_FIRST = "keep-first";
@@ -9176,22 +9517,8 @@
9176
9517
  const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
9177
9518
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9178
9519
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9179
- const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
9520
+ const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
9180
9521
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
9181
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
9182
- const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
9183
- EXTRAFIELD_TYPE_ZIP64,
9184
- EXTRAFIELD_TYPE_AES,
9185
- EXTRAFIELD_TYPE_NTFS,
9186
- EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
9187
- EXTRAFIELD_TYPE_UNICODE_PATH,
9188
- EXTRAFIELD_TYPE_UNICODE_COMMENT,
9189
- EXTRAFIELD_TYPE_USDZ,
9190
- EXTRAFIELD_TYPE_INFOZIP,
9191
- EXTRAFIELD_TYPE_UNIX,
9192
- EXTRAFIELD_TYPE_UNIX_TYPE1,
9193
- EXTRAFIELD_TYPE_PKWARE_UNIX
9194
- ]);
9195
9522
 
9196
9523
  class ZipEntry {
9197
9524
 
@@ -9563,6 +9890,7 @@
9563
9890
  await initStream(reader);
9564
9891
  zipReader = new ZipReader(reader, options);
9565
9892
  }
9893
+ checkPassThroughValue(options.passThrough);
9566
9894
  const duplicates = checkDuplicatesOption(options.duplicates);
9567
9895
  const importedEntries = [];
9568
9896
  const entries = await zipReader.getEntries(options);
@@ -9653,18 +9981,25 @@
9653
9981
 
9654
9982
  async exportZip(writer, options = {}) {
9655
9983
  const zipEntry = this;
9984
+ const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
9656
9985
  options = Object.assign({}, options);
9657
- if (options.bufferedWrite === UNDEFINED_VALUE) {
9986
+ if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
9658
9987
  options.bufferedWrite = true;
9659
9988
  }
9660
- const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
9661
- const zipWriter = new ZipWriter(writer, options);
9989
+ const [readers] = await Promise.all([
9990
+ initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
9991
+ zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
9992
+ ]);
9993
+ const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
9662
9994
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
9995
+ if (zipWriterProvided) {
9996
+ return zipWriter;
9997
+ }
9663
9998
  await zipWriter.close(options.globalComment);
9664
9999
  return writer.getData ? writer.getData() : writer.writable;
9665
10000
  }
9666
10001
 
9667
- getExportedSize(options = {}) {
10002
+ async getExportedSize(options = {}) {
9668
10003
  const zipEntry = this;
9669
10004
  options = Object.assign({}, options);
9670
10005
  checkReaderOptions(options.readerOptions);
@@ -9679,7 +10014,7 @@
9679
10014
  const writeOrderGuaranteed = !options.bufferedWrite ||
9680
10015
  (entries.every(entry => entry.options.keepOrder !== false) &&
9681
10016
  children.every(child => isImplicitDirectory(child) || !child.children.length));
9682
- return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10017
+ return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
9683
10018
  }
9684
10019
 
9685
10020
  getChildByName(name) {
@@ -9740,7 +10075,7 @@
9740
10075
 
9741
10076
  move(entry, destination) {
9742
10077
  if (entry == this.root) {
9743
- throw new Error("Root directory cannot be moved");
10078
+ throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
9744
10079
  } else {
9745
10080
  if (destination.directory) {
9746
10081
  if (!destination.isDescendantOf(entry)) {
@@ -9761,7 +10096,7 @@
9761
10096
  throw new Error(ERR_ANCESTOR_ENTRY);
9762
10097
  }
9763
10098
  } else {
9764
- throw new Error("Target entry is not a directory");
10099
+ throw new Error(ERR_TARGET_NOT_DIRECTORY);
9765
10100
  }
9766
10101
  }
9767
10102
  }
@@ -10074,70 +10409,11 @@
10074
10409
  let zipEntryMetadata = {};
10075
10410
  let passThroughOptions = {};
10076
10411
  if (child.data instanceof Entry) {
10077
- const {
10078
- externalFileAttributes,
10079
- versionMadeBy,
10080
- comment,
10081
- lastModDate,
10082
- rawLastModDate,
10083
- creationDate,
10084
- lastAccessDate,
10085
- uncompressedSize,
10086
- encrypted,
10087
- zipCrypto,
10088
- crc32,
10089
- compressionMethod,
10090
- extraFieldAES,
10091
- internalFileAttributes,
10092
- extraField,
10093
- bitFlag,
10094
- uid,
10095
- gid
10096
- } = child.data;
10097
- zipEntryMetadata = {
10098
- externalFileAttributes,
10099
- versionMadeBy,
10100
- comment,
10101
- lastModDate,
10102
- creationDate,
10103
- lastAccessDate,
10104
- internalFileAttributes
10105
- };
10106
- const userExtraField = getUserExtraField(extraField);
10107
- if (userExtraField) {
10108
- zipEntryMetadata.extraField = userExtraField;
10109
- }
10110
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
10111
- Object.assign(zipEntryMetadata, {
10112
- uid,
10113
- gid,
10114
- unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
10115
- });
10116
- }
10117
- if (isPassThrough(child, options)) {
10118
- let encryptionStrength;
10119
- if (extraFieldAES) {
10120
- encryptionStrength = extraFieldAES.strength;
10121
- }
10122
- passThroughOptions = {
10123
- passThrough: true,
10124
- encrypted,
10125
- zipCrypto,
10126
- crc32,
10127
- uncompressedSize,
10128
- encryptionStrength,
10129
- compressionMethod
10130
- };
10131
- if (bitFlag) {
10132
- passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
10133
- }
10134
- const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10135
- if (lastModDateOverride === UNDEFINED_VALUE) {
10136
- passThroughOptions.rawLastModDate = rawLastModDate;
10137
- } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
10138
- getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
10139
- throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
10140
- }
10412
+ const passThrough = isPassThrough(child, options);
10413
+ const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10414
+ ({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
10415
+ if (passThrough) {
10416
+ passThroughOptions.passThrough = true;
10141
10417
  }
10142
10418
  }
10143
10419
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -10147,16 +10423,6 @@
10147
10423
  return { name, entryOptions };
10148
10424
  }
10149
10425
 
10150
- function getDosTimeHighByte(lastModDate) {
10151
- let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
10152
- if (dosLastModDate < MIN_DATE) {
10153
- dosLastModDate = MIN_DATE;
10154
- } else if (dosLastModDate > MAX_DATE) {
10155
- dosLastModDate = MAX_DATE;
10156
- }
10157
- return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
10158
- }
10159
-
10160
10426
  function getDeterminedSize(child, passThrough) {
10161
10427
  const { reader } = child;
10162
10428
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10169,9 +10435,18 @@
10169
10435
  if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10170
10436
  throw new Error(ERR_INVALID_READER_OPTIONS);
10171
10437
  }
10438
+ if (readerOptions) {
10439
+ checkPassThroughValue(readerOptions.passThrough);
10440
+ }
10172
10441
  return readerOptions;
10173
10442
  }
10174
10443
 
10444
+ function checkPassThroughValue(passThrough) {
10445
+ if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
10446
+ throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
10447
+ }
10448
+ }
10449
+
10175
10450
  function replaceContent(zipEntry, params) {
10176
10451
  const { uncompressedSize } = params;
10177
10452
  Object.assign(zipEntry, params, {
@@ -10200,20 +10475,6 @@
10200
10475
  return child.directory && child.data === null;
10201
10476
  }
10202
10477
 
10203
- function getUserExtraField(extraField) {
10204
- if (extraField) {
10205
- const userExtraField = new Map();
10206
- extraField.forEach((field, type) => {
10207
- if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
10208
- userExtraField.set(type, field.data);
10209
- }
10210
- });
10211
- if (userExtraField.size) {
10212
- return userExtraField;
10213
- }
10214
- }
10215
- }
10216
-
10217
10478
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
10218
10479
  const { onstart, onprogress, onend, onentryprogress } = options;
10219
10480
  const selectedEntry = entry;
@@ -10316,6 +10577,7 @@
10316
10577
 
10317
10578
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10318
10579
  const { onstart, onprogress, onend } = options;
10580
+ checkPassThroughValue(options.passThrough);
10319
10581
  const readerOptions = checkReaderOptions(options.readerOptions);
10320
10582
  const abortController = new AbortController();
10321
10583
  const { signal } = abortController;
@@ -10391,7 +10653,7 @@
10391
10653
  if (exportAborted || isExportAborted(signal.reason)) {
10392
10654
  return;
10393
10655
  }
10394
- throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
10656
+ throwIfAborted(signal);
10395
10657
  }
10396
10658
  try {
10397
10659
  if (child.directory) {
@@ -10524,7 +10786,7 @@
10524
10786
  }
10525
10787
  return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
10526
10788
  } else {
10527
- throw new Error("Parent entry is not a directory");
10789
+ throw new Error(ERR_PARENT_NOT_DIRECTORY);
10528
10790
  }
10529
10791
  }
10530
10792
 
@@ -10658,7 +10920,7 @@
10658
10920
  */
10659
10921
 
10660
10922
 
10661
- c(setDefaultConfiguration);
10923
+ f(setDefaultConfiguration);
10662
10924
 
10663
10925
  exports.BlobReader = BlobReader;
10664
10926
  exports.BlobWriter = BlobWriter;
@@ -10666,6 +10928,7 @@
10666
10928
  exports.Data64URIWriter = Data64URIWriter;
10667
10929
  exports.ERR_ABORTED = ERR_ABORTED;
10668
10930
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
10931
+ exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
10669
10932
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
10670
10933
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
10671
10934
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
@@ -10679,7 +10942,9 @@
10679
10942
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
10680
10943
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
10681
10944
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
10945
+ exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
10682
10946
  exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
10947
+ exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
10683
10948
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
10684
10949
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
10685
10950
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
@@ -10689,6 +10954,7 @@
10689
10954
  exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
10690
10955
  exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
10691
10956
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
10957
+ exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
10692
10958
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
10693
10959
  exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
10694
10960
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
@@ -10707,6 +10973,7 @@
10707
10973
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
10708
10974
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
10709
10975
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
10976
+ exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
10710
10977
  exports.ERR_INVALID_READER = ERR_INVALID_READER;
10711
10978
  exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
10712
10979
  exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
@@ -10717,14 +10984,19 @@
10717
10984
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
10718
10985
  exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
10719
10986
  exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
10987
+ exports.ERR_INVALID_URI = ERR_INVALID_URI;
10720
10988
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
10721
10989
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
10722
10990
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
10723
10991
  exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
10992
+ exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
10724
10993
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
10725
10994
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
10995
+ exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
10726
10996
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
10997
+ exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
10727
10998
  exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
10999
+ exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
10728
11000
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
10729
11001
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
10730
11002
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -10736,10 +11008,12 @@
10736
11008
  exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
10737
11009
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
10738
11010
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
11011
+ exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
10739
11012
  exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
10740
11013
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10741
11014
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10742
11015
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
11016
+ exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
10743
11017
  exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
10744
11018
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
10745
11019
  exports.HttpRangeReader = HttpRangeReader;
@@ -10753,13 +11027,17 @@
10753
11027
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
10754
11028
  exports.VERSION = VERSION;
10755
11029
  exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
11030
+ exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
10756
11031
  exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
11032
+ exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
10757
11033
  exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
10758
11034
  exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
10759
11035
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
10760
11036
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
10761
11037
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
11038
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
10762
11039
  exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
11040
+ exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
10763
11041
  exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
10764
11042
  exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
10765
11043
  exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;