@zip.js/zip.js 2.8.49 → 2.8.51

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.
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.zip = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, document, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker } = typeof globalThis !== 'undefined' ? globalThis : this || self;
7
+ const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, document, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker, Symbol, setTimeout, clearTimeout, structuredClone } = typeof globalThis !== 'undefined' ? globalThis : this || self;
8
8
 
9
9
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
10
  /*
@@ -117,6 +117,8 @@
117
117
  const UNDEFINED_TYPE = "undefined";
118
118
  const FUNCTION_TYPE = "function";
119
119
  const OBJECT_TYPE = "object";
120
+ const STRING_TYPE = "string";
121
+ const NUMBER_TYPE = "number";
120
122
 
121
123
  const EMPTY_UINT8_ARRAY = new Uint8Array();
122
124
 
@@ -248,7 +250,7 @@
248
250
  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],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],f=[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],n=[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],c=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e=new Uint8Array(288);e.fill(8,0,144),e.fill(9,144,256),e.fill(7,256,280),e.fill(8,280,288);const j$1=new Uint8Array(30).fill(5);function z$1(r){const t=new Uint16Array(16);for(const f of r)t[f]++;t[0]=0;const f=new Uint16Array(17);for(let r=1;15>=r;r++)f[r+1]=f[r]+t[r];const n=new Uint16Array(r.length);for(let t=0;t<r.length;t++)r[t]&&(n[f[r[t]]++]=t);return {j:t,symbols:n}}const W$1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p$1=(s=()=>(W=>{let p=0,s=0,o=0,Y=new Uint8Array(1024),l=0,B=0;for(;!B;){B=u(1);const r=u(2);if(0==r)T();else if(1==r)w(z$1(e),z$1(j$1));else {if(2!=r)throw Error("invalid deflate block type");w(...K());}}return Y.subarray(0,l);function S(){if(p>=W.length)throw Error("unexpected end of deflate data");return W[p++]}function u(r){for(;r>o;)s|=S()<<o,o+=8;const t=s&(1<<r)-1;return s>>>=r,o-=r,t}function T(){s=0,o=0;const r=S()|S()<<8;p+=2,D(l+r);for(let t=0;r>t;t++)Y[l++]=S();}function w(c,e){let j=q(c);for(;256!=j;){if(256>j)D(l+1),Y[l++]=j;else {const c=j-257,z=r[c]+u(t[c]),W=q(e),p=f[W]+u(n[W]);D(l+z);const s=l-p;for(let r=0;z>r;r++)Y[l++]=Y[s+r];}j=q(c);}}function K(){const r=u(5)+257,t=u(5)+1,f=u(4)+4,n=new Uint8Array(19);for(let r=0;f>r;r++)n[c[r]]=u(3);const e=z$1(n),j=new Uint8Array(r+t);let W=0;for(;W<j.length;){const r=q(e);if(16>r)j[W++]=r;else if(16==r){const r=j[W-1];let t=u(2)+3;for(;t--;)j[W++]=r;}else W+=17==r?u(3)+3:u(7)+11;}return [z$1(j.subarray(0,r)),z$1(j.subarray(r))]}function q(r){const{j:t,symbols:f}=r;let n=0,c=0,e=0;for(let r=1;15>=r;r++){n|=u(1);const j=t[r];if(j>n-c)return f[e+(n-c)];e+=j,c=c+j<<1,n<<=1;}throw Error("invalid huffman code")}function D(r){if(Y.length<r){let t=2*Y.length;for(;r>t;)t*=2;const f=new Uint8Array(t);f.set(Y.subarray(0,l)),Y=f;}}})((r=>{const t=(r=(r+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,f=[];for(let n=0;t>n;n+=4){const t=W$1.indexOf(r[n])<<18|W$1.indexOf(r[n+1])<<12|(63&W$1.indexOf(r[n+2]))<<6|63&W$1.indexOf(r[n+3]);f.push(t>>16&255),"="!==r[n+2]&&f.push(t>>8&255),"="!==r[n+3]&&f.push(255&t);}return new Uint8Array(f)})("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")),r=>r({workerURI:r=>{const t="text/javascript";let f=s();if("string"==typeof f&&(f=(new TextEncoder).encode(f)),r){const r=new Blob([f],{type:t});return URL.createObjectURL(r)}return "data:"+t+";base64,"+(r=>{let t="";const f=r.length;let n=0;for(;f>n+2;n+=3){const f=r[n]<<16|r[n+1]<<8|r[n+2];t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+W$1[63&f];}const c=f-n;if(1===c){const f=r[n]<<16;t+=W$1[f>>18&63]+W$1[f>>12&63]+"==";}else if(2===c){const f=r[n]<<16|r[n+1]<<8;t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+"=";}return t})(f)}}));var s;
249
251
 
250
252
  /*
251
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
253
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
252
254
 
253
255
  Redistribution and use in source and binary forms, with or without
254
256
  modification, are permitted provided that the following conditions are met:
@@ -276,72 +278,19 @@
276
278
  */
277
279
 
278
280
 
279
- const ERR_INVALID_CODEC_DEFINITION = "Invalid codec definition";
280
- const ERR_RESERVED_COMPRESSION_METHOD = "Reserved compression method";
281
- const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
282
-
283
- const STRING_TYPE = "string";
284
- const RESERVED_COMPRESSION_METHODS = [
285
- COMPRESSION_METHOD_STORE,
286
- COMPRESSION_METHOD_DEFLATE,
287
- COMPRESSION_METHOD_DEFLATE_64,
288
- COMPRESSION_METHOD_AES
289
- ];
290
-
291
- const registeredCodecs = new Map();
292
- const codecStreams = new Map();
293
-
294
- function registerCodec(codec = {}) {
295
- const { compressionMethod, format, codecURI, CompressionStream, DecompressionStream, versionNeeded } = codec;
296
- if (!Number.isInteger(compressionMethod) || compressionMethod < 0 || compressionMethod > MAX_16_BITS ||
297
- typeof format != STRING_TYPE || !format.length) {
298
- throw new Error(ERR_INVALID_CODEC_DEFINITION);
299
- }
300
- if (RESERVED_COMPRESSION_METHODS.includes(compressionMethod)) {
301
- throw new Error(ERR_RESERVED_COMPRESSION_METHOD);
302
- }
303
- const hasStreams = typeof CompressionStream == FUNCTION_TYPE || typeof DecompressionStream == FUNCTION_TYPE;
304
- if (!hasStreams && (typeof codecURI != STRING_TYPE || !codecURI.length)) {
305
- throw new Error(ERR_INVALID_CODEC_DEFINITION);
306
- }
307
- registeredCodecs.set(compressionMethod, { compressionMethod, format, codecURI, versionNeeded });
308
- if (hasStreams) {
309
- setCodecStreams(format, { CompressionStream, DecompressionStream });
310
- }
311
- }
312
-
313
- function unregisterCodec(compressionMethod) {
314
- const codec = registeredCodecs.get(compressionMethod);
315
- if (codec) {
316
- registeredCodecs.delete(compressionMethod);
317
- let formatUsed;
318
- registeredCodecs.forEach(otherCodec => formatUsed = formatUsed || otherCodec.format == codec.format);
319
- if (!formatUsed) {
320
- codecStreams.delete(codec.format);
321
- }
322
- }
323
- }
324
-
325
- function getRegisteredCodec(compressionMethod) {
326
- return registeredCodecs.get(compressionMethod);
327
- }
328
-
329
- function getCodecStreams(format) {
330
- return codecStreams.get(format);
281
+ function concat(first, second) {
282
+ const result = new Uint8Array(first.length + second.length);
283
+ result.set(first);
284
+ result.set(second, first.length);
285
+ return result;
331
286
  }
332
287
 
333
- function setCodecStreams(format, streams) {
334
- const { CompressionStream, DecompressionStream } = streams;
335
- if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
336
- throw new Error(ERR_INVALID_CODEC_MODULE);
337
- }
338
- codecStreams.set(format, { CompressionStream, DecompressionStream });
288
+ function toExactUint8Array(array) {
289
+ return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
339
290
  }
340
291
 
341
- async function ensureCodecStreams(format, codecURI) {
342
- if (!codecStreams.has(format) && codecURI) {
343
- setCodecStreams(format, await import(/* webpackIgnore: true */ /* @vite-ignore */ codecURI));
344
- }
292
+ function getDataView(array) {
293
+ return new DataView(array.buffer, array.byteOffset, array.byteLength);
345
294
  }
346
295
 
347
296
  /*
@@ -526,50 +475,6 @@
526
475
  }
527
476
  }
528
477
 
529
- /*
530
- Copyright (c) 2026 Gildas Lormeau. All rights reserved.
531
-
532
- Redistribution and use in source and binary forms, with or without
533
- modification, are permitted provided that the following conditions are met:
534
-
535
- 1. Redistributions of source code must retain the above copyright notice,
536
- this list of conditions and the following disclaimer.
537
-
538
- 2. Redistributions in binary form must reproduce the above copyright
539
- notice, this list of conditions and the following disclaimer in
540
- the documentation and/or other materials provided with the distribution.
541
-
542
- 3. The names of the authors may not be used to endorse or promote products
543
- derived from this software without specific prior written permission.
544
-
545
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
546
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
547
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
548
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
549
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
550
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
551
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
552
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
553
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
554
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
555
- */
556
-
557
-
558
- function concat(first, second) {
559
- const result = new Uint8Array(first.length + second.length);
560
- result.set(first);
561
- result.set(second, first.length);
562
- return result;
563
- }
564
-
565
- function toExactUint8Array(array) {
566
- return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
567
- }
568
-
569
- function getDataView(array) {
570
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
571
- }
572
-
573
478
  // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
574
479
 
575
480
  // deno-lint-ignore-file no-this-alias
@@ -1939,6 +1844,102 @@
1939
1844
  });
1940
1845
  }
1941
1846
 
1847
+ /*
1848
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
1849
+
1850
+ Redistribution and use in source and binary forms, with or without
1851
+ modification, are permitted provided that the following conditions are met:
1852
+
1853
+ 1. Redistributions of source code must retain the above copyright notice,
1854
+ this list of conditions and the following disclaimer.
1855
+
1856
+ 2. Redistributions in binary form must reproduce the above copyright
1857
+ notice, this list of conditions and the following disclaimer in
1858
+ the documentation and/or other materials provided with the distribution.
1859
+
1860
+ 3. The names of the authors may not be used to endorse or promote products
1861
+ derived from this software without specific prior written permission.
1862
+
1863
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
1864
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1865
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
1866
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
1867
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1868
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
1869
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1870
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1871
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
1872
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1873
+ */
1874
+
1875
+
1876
+ const ERR_INVALID_CODEC_DEFINITION = "Invalid codec definition";
1877
+ const ERR_RESERVED_COMPRESSION_METHOD = "Reserved compression method";
1878
+ const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
1879
+
1880
+ const RESERVED_COMPRESSION_METHODS = [
1881
+ COMPRESSION_METHOD_STORE,
1882
+ COMPRESSION_METHOD_DEFLATE,
1883
+ COMPRESSION_METHOD_DEFLATE_64,
1884
+ COMPRESSION_METHOD_AES
1885
+ ];
1886
+
1887
+ const registeredCodecs = new Map();
1888
+ const codecStreams = new Map();
1889
+
1890
+ function registerCodec(codec = {}) {
1891
+ const { compressionMethod, format, codecURI, CompressionStream, DecompressionStream, versionNeeded } = codec;
1892
+ if (!Number.isInteger(compressionMethod) || compressionMethod < 0 || compressionMethod > MAX_16_BITS ||
1893
+ typeof format != STRING_TYPE || !format.length) {
1894
+ throw new Error(ERR_INVALID_CODEC_DEFINITION);
1895
+ }
1896
+ if (RESERVED_COMPRESSION_METHODS.includes(compressionMethod)) {
1897
+ throw new Error(ERR_RESERVED_COMPRESSION_METHOD);
1898
+ }
1899
+ const hasStreams = typeof CompressionStream == FUNCTION_TYPE || typeof DecompressionStream == FUNCTION_TYPE;
1900
+ if (!hasStreams && (typeof codecURI != STRING_TYPE || !codecURI.length)) {
1901
+ throw new Error(ERR_INVALID_CODEC_DEFINITION);
1902
+ }
1903
+ registeredCodecs.set(compressionMethod, { compressionMethod, format, codecURI, versionNeeded });
1904
+ if (hasStreams) {
1905
+ setCodecStreams(format, { CompressionStream, DecompressionStream });
1906
+ }
1907
+ }
1908
+
1909
+ function unregisterCodec(compressionMethod) {
1910
+ const codec = registeredCodecs.get(compressionMethod);
1911
+ if (codec) {
1912
+ registeredCodecs.delete(compressionMethod);
1913
+ let formatUsed;
1914
+ registeredCodecs.forEach(otherCodec => formatUsed = formatUsed || otherCodec.format == codec.format);
1915
+ if (!formatUsed) {
1916
+ codecStreams.delete(codec.format);
1917
+ }
1918
+ }
1919
+ }
1920
+
1921
+ function getRegisteredCodec(compressionMethod) {
1922
+ return registeredCodecs.get(compressionMethod);
1923
+ }
1924
+
1925
+ function getCodecStreams(format) {
1926
+ return codecStreams.get(format);
1927
+ }
1928
+
1929
+ function setCodecStreams(format, streams) {
1930
+ const { CompressionStream, DecompressionStream } = streams;
1931
+ if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
1932
+ throw new Error(ERR_INVALID_CODEC_MODULE);
1933
+ }
1934
+ codecStreams.set(format, { CompressionStream, DecompressionStream });
1935
+ }
1936
+
1937
+ async function ensureCodecStreams(format, codecURI) {
1938
+ if (!codecStreams.has(format) && codecURI) {
1939
+ setCodecStreams(format, await import(/* webpackIgnore: true */ /* @vite-ignore */ codecURI));
1940
+ }
1941
+ }
1942
+
1942
1943
  /*
1943
1944
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
1944
1945
 
@@ -2492,8 +2493,8 @@
2492
2493
  1. Redistributions of source code must retain the above copyright notice,
2493
2494
  this list of conditions and the following disclaimer.
2494
2495
 
2495
- 2. Redistributions in binary form must reproduce the above copyright
2496
- notice, this list of conditions and the following disclaimer in
2496
+ 2. Redistributions in binary form must reproduce the above copyright
2497
+ notice, this list of conditions and the following disclaimer in
2497
2498
  the documentation and/or other materials provided with the distribution.
2498
2499
 
2499
2500
  3. The names of the authors may not be used to endorse or promote products
@@ -2512,20 +2513,15 @@
2512
2513
  */
2513
2514
 
2514
2515
 
2515
- const MODULE_WORKER_OPTIONS = { type: "module" };
2516
- const ERROR_EVENT_TYPE = "error";
2517
- const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2518
2516
  const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
2519
2517
 
2520
- let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions, createWorkerFailed;
2521
- let transferStreamsSupported = true;
2522
- try {
2523
- transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
2524
- } catch {
2525
- // ignored
2526
- }
2518
+ let webWorkerSupported, createWorkerFailed, webWorkerBackend;
2527
2519
  let initModule = () => { };
2528
2520
 
2521
+ function setWebWorkerBackend(backend) {
2522
+ webWorkerBackend = backend;
2523
+ }
2524
+
2529
2525
  async function supportsDeflate(config) {
2530
2526
  const { CompressionStream: NativeStream, CompressionStreamFallback: FallbackStream } = config;
2531
2527
  if (FallbackStream && !FallbackStream.requiresModule) {
@@ -2550,6 +2546,14 @@
2550
2546
  createWorkerFailed = false;
2551
2547
  }
2552
2548
 
2549
+ function disableWebWorker(workerData) {
2550
+ if (workerData.createWorker) {
2551
+ createWorkerFailed = true;
2552
+ } else {
2553
+ webWorkerSupported = false;
2554
+ }
2555
+ }
2556
+
2553
2557
  class CodecWorker {
2554
2558
 
2555
2559
  constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
@@ -2602,7 +2606,7 @@
2602
2606
  // deno-lint-ignore valid-typeof
2603
2607
  webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
2604
2608
  }
2605
- return (useWebWorkers && ((webWorkerSupported && workerURI) || createWorker) ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
2609
+ return (useWebWorkers && webWorkerBackend && ((webWorkerSupported && workerURI) || createWorker) ? webWorkerBackend : createWorkerInterface)(workerData, config);
2606
2610
  }
2607
2611
  }
2608
2612
 
@@ -2619,85 +2623,31 @@
2619
2623
  async transform(chunk, controller) {
2620
2624
  chunkOffset += chunk.length;
2621
2625
  if (onprogress) {
2622
- await callHandler(onprogress, chunkOffset, size);
2623
- }
2624
- controller.enqueue(chunk);
2625
- },
2626
- async flush() {
2627
- if (onend) {
2628
- await callHandler(onend, chunkOffset);
2629
- }
2630
- }
2631
- });
2632
- }
2633
- }
2634
-
2635
- async function callHandler(handler, ...parameters) {
2636
- try {
2637
- await handler(...parameters);
2638
- } catch {
2639
- // ignored
2640
- }
2641
- }
2642
-
2643
- function createWorkerInterface(workerData, config) {
2644
- return {
2645
- run: () => runWorker$1(workerData, config)
2646
- };
2647
- }
2648
-
2649
- function createWebWorkerInterface(workerData, config) {
2650
- const { baseURI, chunkSize, workerStartupTimeout } = config;
2651
- let { wasmURI } = config;
2652
-
2653
- if (!workerData.interface) {
2654
- // deno-lint-ignore valid-typeof
2655
- if (typeof wasmURI == FUNCTION_TYPE) {
2656
- wasmURI = wasmURI();
2657
- }
2658
- let worker;
2659
- try {
2660
- worker = getWebWorker(workerData.workerURI, baseURI, workerData);
2661
- } catch {
2662
- if (workerData.createWorker) {
2663
- createWorkerFailed = true;
2664
- } else {
2665
- webWorkerSupported = false;
2666
- }
2667
- return createWorkerInterface(workerData, config);
2668
- }
2669
- Object.assign(workerData, {
2670
- worker,
2671
- workerAlive: false,
2672
- terminated: false,
2673
- interface: {
2674
- run: async () => {
2675
- try {
2676
- return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
2677
- } catch (error) {
2678
- if (error && error.workerStartupFailed) {
2679
- if (workerData.createWorker) {
2680
- createWorkerFailed = true;
2681
- } else {
2682
- webWorkerSupported = false;
2683
- }
2684
- releaseWorkerStreams(workerData);
2685
- return runWorker$1(workerData, config);
2686
- }
2687
- if (error && error.codecImportFailed) {
2688
- if (workerData.reader) {
2689
- releaseWorkerStreams(workerData);
2690
- return runWorker$1(workerData, config);
2691
- }
2692
- workerData.onTaskFinished();
2693
- }
2694
- throw error;
2695
- }
2626
+ await callHandler(onprogress, chunkOffset, size);
2627
+ }
2628
+ controller.enqueue(chunk);
2629
+ },
2630
+ async flush() {
2631
+ if (onend) {
2632
+ await callHandler(onend, chunkOffset);
2696
2633
  }
2697
2634
  }
2698
2635
  });
2699
2636
  }
2700
- return workerData.interface;
2637
+ }
2638
+
2639
+ async function callHandler(handler, ...parameters) {
2640
+ try {
2641
+ await handler(...parameters);
2642
+ } catch {
2643
+ // ignored
2644
+ }
2645
+ }
2646
+
2647
+ function createWorkerInterface(workerData, config) {
2648
+ return {
2649
+ run: () => runWorker$1(workerData, config)
2650
+ };
2701
2651
  }
2702
2652
 
2703
2653
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
@@ -2748,6 +2698,95 @@
2748
2698
  }
2749
2699
  }
2750
2700
 
2701
+ /*
2702
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
2703
+
2704
+ Redistribution and use in source and binary forms, with or without
2705
+ modification, are permitted provided that the following conditions are met:
2706
+
2707
+ 1. Redistributions of source code must retain the above copyright notice,
2708
+ this list of conditions and the following disclaimer.
2709
+
2710
+ 2. Redistributions in binary form must reproduce the above copyright
2711
+ notice, this list of conditions and the following disclaimer in
2712
+ the documentation and/or other materials provided with the distribution.
2713
+
2714
+ 3. The names of the authors may not be used to endorse or promote products
2715
+ derived from this software without specific prior written permission.
2716
+
2717
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
2718
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2719
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
2720
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
2721
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2722
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
2723
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2724
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2725
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2726
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727
+ */
2728
+
2729
+
2730
+ const MODULE_WORKER_OPTIONS = { type: "module" };
2731
+ const ERROR_EVENT_TYPE = "error";
2732
+ const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2733
+
2734
+ let webWorkerSource, webWorkerURI, webWorkerOptions;
2735
+ let transferStreamsSupported = true;
2736
+ try {
2737
+ transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
2738
+ } catch {
2739
+ // ignored
2740
+ }
2741
+
2742
+ setWebWorkerBackend(createWebWorkerInterface);
2743
+
2744
+ function createWebWorkerInterface(workerData, config) {
2745
+ const { baseURI, chunkSize, workerStartupTimeout } = config;
2746
+ let { wasmURI } = config;
2747
+
2748
+ if (!workerData.interface) {
2749
+ // deno-lint-ignore valid-typeof
2750
+ if (typeof wasmURI == FUNCTION_TYPE) {
2751
+ wasmURI = wasmURI();
2752
+ }
2753
+ let worker;
2754
+ try {
2755
+ worker = getWebWorker(workerData.workerURI, baseURI, workerData);
2756
+ } catch {
2757
+ disableWebWorker(workerData);
2758
+ return createWorkerInterface(workerData, config);
2759
+ }
2760
+ Object.assign(workerData, {
2761
+ worker,
2762
+ workerAlive: false,
2763
+ terminated: false,
2764
+ interface: {
2765
+ run: async () => {
2766
+ try {
2767
+ return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
2768
+ } catch (error) {
2769
+ if (error && error.workerStartupFailed) {
2770
+ disableWebWorker(workerData);
2771
+ releaseWorkerStreams(workerData);
2772
+ return runWorker$1(workerData, config);
2773
+ }
2774
+ if (error && error.codecImportFailed) {
2775
+ if (workerData.reader) {
2776
+ releaseWorkerStreams(workerData);
2777
+ return runWorker$1(workerData, config);
2778
+ }
2779
+ workerData.onTaskFinished();
2780
+ }
2781
+ throw error;
2782
+ }
2783
+ }
2784
+ }
2785
+ });
2786
+ }
2787
+ return workerData.interface;
2788
+ }
2789
+
2751
2790
  async function runWebWorker(workerData, config) {
2752
2791
  let resolveResult, rejectResult;
2753
2792
  const result = new Promise((resolve, reject) => {
@@ -3624,7 +3663,7 @@
3624
3663
  forceRangeRequests,
3625
3664
  combineSizeEocd
3626
3665
  } = httpReader;
3627
- if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == "undefined" || preventHeadRequest)) {
3666
+ if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
3628
3667
  const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
3629
3668
  const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
3630
3669
  if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
@@ -4477,9 +4516,13 @@
4477
4516
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
4478
4517
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4479
4518
  const OPTION_STRICTNESS = "strictness";
4519
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
4520
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
4480
4521
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4481
4522
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4482
4523
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4524
+ const TEXT_TYPE_FILENAME = "filename";
4525
+ const TEXT_TYPE_COMMENT = "comment";
4483
4526
  const STRICTNESS_STRICT = "strict";
4484
4527
  const STRICTNESS_BALANCED = "balanced";
4485
4528
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4526,6 +4569,11 @@
4526
4569
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4527
4570
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4528
4571
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
4572
+ const ERR_UNSAFE_FILENAME = "Unsafe filename";
4573
+ const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
4574
+ const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4575
+ const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4576
+ const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4529
4577
  const CHARSET_UTF8 = "utf-8";
4530
4578
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4531
4579
  const CHARSET_CP437 = "cp437";
@@ -4547,6 +4595,10 @@
4547
4595
  bytes: 8
4548
4596
  }
4549
4597
  };
4598
+ const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4599
+ const CENTRAL_DIRECTORY_UNREACHABLE = 0;
4600
+ const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
4601
+ const CENTRAL_DIRECTORY_REACHABLE = 2;
4550
4602
 
4551
4603
  class ZipReader {
4552
4604
 
@@ -4575,6 +4627,8 @@
4575
4627
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4576
4628
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4577
4629
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
4630
+ const filenameValidation = getFilenameValidation(getOptionValue$1(zipReader, options, OPTION_FILENAME_VALIDATION), strictness);
4631
+ const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
4578
4632
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
4579
4633
  if (!endOfDirectoryInfo) {
4580
4634
  const signatureArray = await readUint8Array(reader, 0, 4);
@@ -4768,11 +4822,22 @@
4768
4822
  const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4769
4823
  const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
4770
4824
  const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
4771
- let filename = decode(rawFilename, rawFilenameEncoding);
4825
+ let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
4772
4826
  if (filename === UNDEFINED_VALUE) {
4773
4827
  filename = decodeText(rawFilename, rawFilenameEncoding);
4774
4828
  }
4775
- let comment = decode(rawComment, rawCommentEncoding);
4829
+ if (normalizeFilename) {
4830
+ const normalizedFilename = normalizeFilename(filename);
4831
+ if (normalizedFilename !== UNDEFINED_VALUE) {
4832
+ filename = normalizedFilename;
4833
+ }
4834
+ }
4835
+ if (isUnsafeFilename(filename, filenameValidation)) {
4836
+ const error = new Error(ERR_UNSAFE_FILENAME);
4837
+ error.filename = filename;
4838
+ throw error;
4839
+ }
4840
+ let comment = decode(rawComment, rawCommentEncoding, TEXT_TYPE_COMMENT);
4776
4841
  if (comment === UNDEFINED_VALUE) {
4777
4842
  comment = decodeText(rawComment, rawCommentEncoding);
4778
4843
  }
@@ -4833,10 +4898,10 @@
4833
4898
  entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader.readRanges, options);
4834
4899
  entry.arrayBuffer = async options => {
4835
4900
  const writer = new TransformStream();
4836
- const [arrayBuffer] = await Promise.all([
4837
- streamToBlob(writer.readable).then(blob => blob.arrayBuffer()),
4838
- fileEntry.getData(writer, entry, zipReader.readRanges, options)]);
4839
- return arrayBuffer;
4901
+ const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
4902
+ arrayBufferPromise.catch(() => { });
4903
+ await fileEntry.getData(writer, entry, zipReader.readRanges, options);
4904
+ return arrayBufferPromise;
4840
4905
  };
4841
4906
  offset = endOffset;
4842
4907
  const { onprogress } = options;
@@ -5087,7 +5152,7 @@
5087
5152
  readRanges
5088
5153
  });
5089
5154
  }
5090
- let writable;
5155
+ let writable, abortError;
5091
5156
  try {
5092
5157
  if (!checkOverlappingEntryOnly) {
5093
5158
  if (checkPasswordOnly) {
@@ -5107,12 +5172,22 @@
5107
5172
  writer.size += error.outputSize;
5108
5173
  }
5109
5174
  if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
5175
+ abortError = error;
5110
5176
  throw error;
5111
5177
  }
5112
5178
  } finally {
5113
5179
  const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
5114
5180
  if (!preventClose && writable && !writable.locked) {
5115
- await writable.getWriter().close();
5181
+ const writableWriter = writable.getWriter();
5182
+ if (abortError) {
5183
+ try {
5184
+ await writableWriter.abort(abortError);
5185
+ } catch {
5186
+ // the error being propagated is more relevant; ignored
5187
+ }
5188
+ } else {
5189
+ await writableWriter.close();
5190
+ }
5116
5191
  }
5117
5192
  }
5118
5193
  return checkPasswordOnly || checkOverlappingEntryOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable;
@@ -5492,16 +5567,51 @@
5492
5567
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5493
5568
  }
5494
5569
 
5570
+ function isStrictnessValue(value) {
5571
+ return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5572
+ }
5573
+
5495
5574
  function getStrictness(strictness, checkAmbiguity) {
5496
5575
  if (strictness === UNDEFINED_VALUE) {
5497
5576
  return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5498
5577
  }
5578
+ if (!isStrictnessValue(strictness)) {
5579
+ throw new Error(ERR_INVALID_STRICTNESS);
5580
+ }
5499
5581
  return strictness;
5500
5582
  }
5501
5583
 
5584
+ function getFilenameValidation(filenameValidation, strictness) {
5585
+ if (filenameValidation === UNDEFINED_VALUE) {
5586
+ return strictness;
5587
+ }
5588
+ if (!isStrictnessValue(filenameValidation)) {
5589
+ throw new Error(ERR_INVALID_FILENAME_VALIDATION);
5590
+ }
5591
+ return filenameValidation;
5592
+ }
5593
+
5594
+ function isUnsafeFilename(filename, filenameValidation) {
5595
+ if (filenameValidation == STRICTNESS_TOLERANT) {
5596
+ return false;
5597
+ }
5598
+ const pathParts = filename.split("/");
5599
+ if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
5600
+ pathParts.pop();
5601
+ }
5602
+ if (pathParts.includes("..") || filename.startsWith("/") || filename.startsWith("\\\\") || DRIVE_LETTER_REGEXP.test(filename)) {
5603
+ return true;
5604
+ }
5605
+ return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
5606
+ }
5607
+
5502
5608
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
5503
5609
  if (maxAppendedDataSize !== UNDEFINED_VALUE) {
5504
- return maxAppendedDataSize;
5610
+ const size = toNumber$1(maxAppendedDataSize);
5611
+ if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
5612
+ throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
5613
+ }
5614
+ return size;
5505
5615
  }
5506
5616
  if (strictness == STRICTNESS_STRICT) {
5507
5617
  return 0;
@@ -5512,12 +5622,6 @@
5512
5622
  return MAX_16_BITS;
5513
5623
  }
5514
5624
 
5515
- const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
5516
-
5517
- const CENTRAL_DIRECTORY_UNREACHABLE = 0;
5518
- const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
5519
- const CENTRAL_DIRECTORY_REACHABLE = 2;
5520
-
5521
5625
  async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDataSize) {
5522
5626
  const { size } = reader;
5523
5627
  const anchoredLength = Math.min(size, END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS);
@@ -5653,6 +5757,10 @@
5653
5757
  return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
5654
5758
  }
5655
5759
 
5760
+ function toNumber$1(value) {
5761
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
5762
+ }
5763
+
5656
5764
  function getDate(timeRaw) {
5657
5765
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5658
5766
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
@@ -5691,12 +5799,16 @@
5691
5799
  ERR_INVALID_AUTHENTICATION_CODE: ERR_INVALID_AUTHENTICATION_CODE,
5692
5800
  ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
5693
5801
  ERR_INVALID_CRC32: ERR_INVALID_CRC32,
5802
+ ERR_INVALID_FILENAME_VALIDATION: ERR_INVALID_FILENAME_VALIDATION,
5803
+ ERR_INVALID_MAX_APPENDED_DATA_SIZE: ERR_INVALID_MAX_APPENDED_DATA_SIZE,
5694
5804
  ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
5695
5805
  ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
5806
+ ERR_INVALID_STRICTNESS: ERR_INVALID_STRICTNESS,
5696
5807
  ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
5697
5808
  ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
5698
5809
  ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
5699
5810
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5811
+ ERR_UNSAFE_FILENAME: ERR_UNSAFE_FILENAME,
5700
5812
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5701
5813
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5702
5814
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
@@ -5758,6 +5870,8 @@
5758
5870
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5759
5871
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5760
5872
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5873
+ const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
5874
+ const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
5761
5875
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5762
5876
 
5763
5877
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
@@ -5765,6 +5879,7 @@
5765
5879
  const VENDOR_VERSION_AE_1 = 1;
5766
5880
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
5767
5881
  const UNIX_EXTRA_FIELD_TYPE = "unix";
5882
+ const MAX_LEVEL = 9;
5768
5883
 
5769
5884
  let workers = 0;
5770
5885
  const pendingEntries = [];
@@ -5927,7 +6042,8 @@
5927
6042
 
5928
6043
  remove(entry) {
5929
6044
  const { filenames, files } = this;
5930
- if (typeof entry == "string") {
6045
+ // deno-lint-ignore valid-typeof
6046
+ if (typeof entry == STRING_TYPE) {
5931
6047
  entry = files.get(entry);
5932
6048
  }
5933
6049
  if (entry && entry.filename !== UNDEFINED_VALUE) {
@@ -6065,20 +6181,20 @@
6065
6181
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6066
6182
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
6067
6183
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
6068
- const uid = getOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6069
- const gid = getOptionValue(zipWriter, options, PROPERTY_NAME_GID);
6070
- let unixMode = getOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
6184
+ const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6185
+ const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
6186
+ let unixMode = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
6071
6187
  let unixExtraFieldType = getOptionValue(zipWriter, options, OPTION_UNIX_EXTRA_FIELD_TYPE);
6072
6188
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6073
6189
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6074
6190
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6075
- if (uid !== UNDEFINED_VALUE && (uid < 0 || uid > MAX_32_BITS)) {
6191
+ if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6076
6192
  throw new Error(ERR_INVALID_UID);
6077
6193
  }
6078
- if (gid !== UNDEFINED_VALUE && (gid < 0 || gid > MAX_32_BITS)) {
6194
+ if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6079
6195
  throw new Error(ERR_INVALID_GID);
6080
6196
  }
6081
- if (unixMode !== UNDEFINED_VALUE && (unixMode < 0 || unixMode > MAX_16_BITS)) {
6197
+ if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6082
6198
  throw new Error(ERR_INVALID_UNIX_MODE);
6083
6199
  }
6084
6200
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
@@ -6190,7 +6306,7 @@
6190
6306
 
6191
6307
  function resolveMetadata(zipWriter, name, options) {
6192
6308
  const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
6193
- let rawFilename = encode(name);
6309
+ let rawFilename = encode(name, TEXT_TYPE_FILENAME);
6194
6310
  if (rawFilename === UNDEFINED_VALUE) {
6195
6311
  rawFilename = encodeText(name);
6196
6312
  }
@@ -6198,7 +6314,7 @@
6198
6314
  throw new Error(ERR_INVALID_ENTRY_NAME);
6199
6315
  }
6200
6316
  const comment = options[PROPERTY_NAME_COMMENT] || "";
6201
- let rawComment = encode(comment);
6317
+ let rawComment = encode(comment, TEXT_TYPE_COMMENT);
6202
6318
  if (rawComment === UNDEFINED_VALUE) {
6203
6319
  rawComment = encodeText(comment);
6204
6320
  }
@@ -6218,8 +6334,11 @@
6218
6334
  if (!passThrough) {
6219
6335
  password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6220
6336
  rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6337
+ if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
6338
+ throw new Error(ERR_INVALID_PASSWORD_TYPE);
6339
+ }
6221
6340
  }
6222
- const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6341
+ const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6223
6342
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
6224
6343
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
6225
6344
  const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
@@ -6237,7 +6356,10 @@
6237
6356
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6238
6357
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6239
6358
  }
6240
- let level = getOptionValue(zipWriter, options, OPTION_LEVEL);
6359
+ let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6360
+ if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6361
+ throw new Error(ERR_INVALID_LEVEL);
6362
+ }
6241
6363
  if (zipWriter.options[OPTION_USDZ]) {
6242
6364
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6243
6365
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6258,7 +6380,7 @@
6258
6380
  useCompressionStream = false;
6259
6381
  }
6260
6382
  const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
6261
- if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
6383
+ if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(Number.isInteger(encryptionStrength) && encryptionStrength >= 1 && encryptionStrength <= 3)) {
6262
6384
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
6263
6385
  }
6264
6386
  const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
@@ -7452,6 +7574,14 @@
7452
7574
  return result === UNDEFINED_VALUE ? defaultValue : result;
7453
7575
  }
7454
7576
 
7577
+ function getNumberOptionValue(zipWriter, options, name, defaultValue) {
7578
+ return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
7579
+ }
7580
+
7581
+ function toNumber(value) {
7582
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
7583
+ }
7584
+
7455
7585
  function getMaximumCompressedSize(uncompressedSize) {
7456
7586
  return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
7457
7587
  }
@@ -8104,6 +8234,9 @@
8104
8234
 
8105
8235
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
8106
8236
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
8237
+ const ERR_ABORT_EXPORT = "zipjs-abort-export";
8238
+ const ERR_ABORTED = "The operation was aborted";
8239
+ const ABORT_ERROR_NAME = "AbortError";
8107
8240
  const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
8108
8241
  const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
8109
8242
  EXTRAFIELD_TYPE_ZIP64,
@@ -8212,8 +8345,9 @@
8212
8345
  const uncompressedSize = zipEntry.data ? zipEntry.data.uncompressedSize : reader.size;
8213
8346
  await Promise.all([initStream(reader), initStream(writer, uncompressedSize)]);
8214
8347
  const { readable } = reader;
8348
+ const { signal } = options;
8215
8349
  zipEntry.uncompressedSize = reader.size;
8216
- await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable));
8350
+ await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal });
8217
8351
  return writer.getData ? writer.getData() : writer.writable;
8218
8352
  }
8219
8353
  }
@@ -8480,7 +8614,7 @@
8480
8614
  for (const entry of entries) {
8481
8615
  let parent = this;
8482
8616
  try {
8483
- const path = entry.filename.split("/");
8617
+ const path = entry.filename.split("/").filter(pathPart => pathPart != "" && pathPart != ".");
8484
8618
  const name = path.pop();
8485
8619
  path.forEach(pathPart => {
8486
8620
  const previousParent = parent;
@@ -8555,6 +8689,10 @@
8555
8689
  }
8556
8690
  }
8557
8691
 
8692
+ getChildren(options = {}) {
8693
+ return collectChildren(this, options.recursive);
8694
+ }
8695
+
8558
8696
  isPasswordProtected() {
8559
8697
  const children = this.children;
8560
8698
  for (let childIndex = 0; childIndex < children.length; childIndex++) {
@@ -8646,6 +8784,10 @@
8646
8784
  return this.root.getChildByName(name);
8647
8785
  }
8648
8786
 
8787
+ getChildren(options) {
8788
+ return this.root.getChildren(options);
8789
+ }
8790
+
8649
8791
  addDirectory(name, options) {
8650
8792
  return this.root.addDirectory(name, options);
8651
8793
  }
@@ -8855,6 +8997,39 @@
8855
8997
  }
8856
8998
  }
8857
8999
 
9000
+ function forwardAbort(signal, abortController) {
9001
+ if (!signal) {
9002
+ return () => { };
9003
+ }
9004
+ if (signal.aborted) {
9005
+ abortController.abort(signal.reason);
9006
+ return () => { };
9007
+ }
9008
+ const abort = () => abortController.abort(signal.reason);
9009
+ signal.addEventListener("abort", abort, { once: true });
9010
+ return () => signal.removeEventListener("abort", abort);
9011
+ }
9012
+
9013
+ function isExportAborted(error) {
9014
+ return Boolean(error) && error.message == ERR_ABORT_EXPORT;
9015
+ }
9016
+
9017
+ function aggregateEntryErrors(errors) {
9018
+ const [error] = errors;
9019
+ const otherErrors = errors
9020
+ .slice(1)
9021
+ .flatMap(otherError => [otherError, ...(otherError && otherError.entryErrors || [])])
9022
+ .filter(otherError => otherError !== error);
9023
+ if (otherErrors.length) {
9024
+ try {
9025
+ error.entryErrors = [...(error.entryErrors || []), ...otherErrors];
9026
+ } catch {
9027
+ // ignored
9028
+ }
9029
+ }
9030
+ return error;
9031
+ }
9032
+
8858
9033
  function getUserExtraField(extraField) {
8859
9034
  if (extraField) {
8860
9035
  const userExtraField = new Map();
@@ -8872,111 +9047,110 @@
8872
9047
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
8873
9048
  const selectedEntry = entry;
8874
9049
  const entryOffsets = new Map();
8875
- await process(zipWriter, entry);
9050
+ if (options.bufferedWrite) {
9051
+ await processChildren(entry);
9052
+ } else {
9053
+ for (const child of entry.getChildren({ recursive: true })) {
9054
+ await addChild(child);
9055
+ }
9056
+ }
8876
9057
 
8877
- async function process(zipWriter, entry) {
8878
- await exportChild();
9058
+ async function processChildren(entry) {
9059
+ const results = await Promise.allSettled(entry.children.map(async child => {
9060
+ await addChild(child);
9061
+ await processChildren(child);
9062
+ }));
9063
+ const errorResult = results.find(result => result.status == "rejected");
9064
+ if (errorResult) {
9065
+ throw errorResult.reason;
9066
+ }
9067
+ }
8879
9068
 
8880
- async function exportChild() {
8881
- if (options.bufferedWrite) {
8882
- const results = await Promise.allSettled(entry.children.map(processChild));
8883
- const errorResult = results.find(result => result.status == "rejected");
8884
- if (errorResult) {
8885
- throw errorResult.reason;
9069
+ async function addChild(child) {
9070
+ const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
9071
+ const childOptions = child.options || {};
9072
+ let zipEntryOptions = {};
9073
+ if (child.data instanceof Entry) {
9074
+ const {
9075
+ externalFileAttributes,
9076
+ versionMadeBy,
9077
+ comment,
9078
+ lastModDate,
9079
+ creationDate,
9080
+ lastAccessDate,
9081
+ uncompressedSize,
9082
+ encrypted,
9083
+ zipCrypto,
9084
+ crc32,
9085
+ compressionMethod,
9086
+ extraFieldAES,
9087
+ internalFileAttributes,
9088
+ extraField,
9089
+ uid,
9090
+ gid
9091
+ } = child.data;
9092
+ zipEntryOptions = {
9093
+ externalFileAttributes,
9094
+ versionMadeBy,
9095
+ comment,
9096
+ lastModDate,
9097
+ creationDate,
9098
+ lastAccessDate,
9099
+ internalFileAttributes
9100
+ };
9101
+ const userExtraField = getUserExtraField(extraField);
9102
+ if (userExtraField) {
9103
+ zipEntryOptions.extraField = userExtraField;
9104
+ }
9105
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
9106
+ Object.assign(zipEntryOptions, {
9107
+ uid,
9108
+ gid,
9109
+ unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
9110
+ });
9111
+ }
9112
+ if (child.passThrough) {
9113
+ let level, encryptionStrength;
9114
+ if (compressionMethod === 0) {
9115
+ level = 0;
8886
9116
  }
8887
- } else {
8888
- for (const child of entry.children) {
8889
- await processChild(child);
9117
+ if (extraFieldAES) {
9118
+ encryptionStrength = extraFieldAES.strength;
8890
9119
  }
8891
- }
8892
- }
8893
-
8894
- async function processChild(child) {
8895
- const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
8896
- const childOptions = child.options || {};
8897
- let zipEntryOptions = {};
8898
- if (child.data instanceof Entry) {
8899
- const {
8900
- externalFileAttributes,
8901
- versionMadeBy,
8902
- comment,
8903
- lastModDate,
8904
- creationDate,
8905
- lastAccessDate,
8906
- uncompressedSize,
9120
+ zipEntryOptions = Object.assign(zipEntryOptions, {
9121
+ passThrough: true,
8907
9122
  encrypted,
8908
9123
  zipCrypto,
8909
9124
  crc32,
8910
- compressionMethod,
8911
- extraFieldAES,
8912
- internalFileAttributes,
8913
- extraField,
8914
- uid,
8915
- gid
8916
- } = child.data;
8917
- zipEntryOptions = {
8918
- externalFileAttributes,
8919
- versionMadeBy,
8920
- comment,
8921
- lastModDate,
8922
- creationDate,
8923
- lastAccessDate,
8924
- internalFileAttributes
8925
- };
8926
- const userExtraField = getUserExtraField(extraField);
8927
- if (userExtraField) {
8928
- zipEntryOptions.extraField = userExtraField;
8929
- }
8930
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
8931
- Object.assign(zipEntryOptions, {
8932
- uid,
8933
- gid,
8934
- unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
8935
- });
8936
- }
8937
- if (child.passThrough) {
8938
- let level, encryptionStrength;
8939
- if (compressionMethod === 0) {
8940
- level = 0;
8941
- }
8942
- if (extraFieldAES) {
8943
- encryptionStrength = extraFieldAES.strength;
8944
- }
8945
- zipEntryOptions = Object.assign(zipEntryOptions, {
8946
- passThrough: true,
8947
- encrypted,
8948
- zipCrypto,
8949
- crc32,
8950
- uncompressedSize,
8951
- level,
8952
- encryptionStrength,
8953
- compressionMethod
8954
- });
8955
- }
9125
+ uncompressedSize,
9126
+ level,
9127
+ encryptionStrength,
9128
+ compressionMethod
9129
+ });
8956
9130
  }
8957
- await zipWriter.add(name, readers.get(child), Object.assign({}, options, zipEntryOptions, childOptions, {
8958
- directory: child.directory,
8959
- onprogress: async indexProgress => {
8960
- if (options.onprogress) {
8961
- entryOffsets.set(name, indexProgress);
8962
- try {
8963
- await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
8964
- } catch {
8965
- // ignored
8966
- }
9131
+ }
9132
+ await zipWriter.add(name, readers.get(child), Object.assign({}, options, zipEntryOptions, childOptions, {
9133
+ directory: child.directory,
9134
+ onprogress: async indexProgress => {
9135
+ if (options.onprogress) {
9136
+ entryOffsets.set(name, indexProgress);
9137
+ try {
9138
+ await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
9139
+ } catch {
9140
+ // ignored
8967
9141
  }
8968
9142
  }
8969
- }));
8970
- await process(zipWriter, child);
8971
- }
9143
+ }
9144
+ }));
8972
9145
  }
8973
9146
  }
8974
9147
 
8975
9148
  function addFileSystemHandle(zipEntry, handle, options) {
8976
9149
  return addFile(zipEntry, handle, []);
8977
9150
 
8978
- async function addFile(parentEntry, handle, addedEntries) {
9151
+ async function addFile(parentEntry, handle, addedEntries, parentName = "") {
8979
9152
  if (handle) {
9153
+ const entryName = parentName ? parentName + "/" + handle.name : handle.name;
8980
9154
  try {
8981
9155
  if (handle.isFile || handle.isDirectory) {
8982
9156
  handle = await transformToFileSystemhandle(handle);
@@ -8998,12 +9172,18 @@
8998
9172
  const directoryEntry = parentEntry.addDirectory(handle.name);
8999
9173
  addedEntries.push(directoryEntry);
9000
9174
  for await (const childHandle of handle.values()) {
9001
- await addFile(directoryEntry, childHandle, addedEntries);
9175
+ await addFile(directoryEntry, childHandle, addedEntries, entryName);
9002
9176
  }
9003
9177
  }
9004
9178
  } catch (error) {
9005
- const message = error.message + (handle ? " (" + handle.name + ")" : "");
9006
- throw new Error(message, { cause: error });
9179
+ try {
9180
+ if (error.entryName === UNDEFINED_VALUE) {
9181
+ error.entryName = entryName;
9182
+ }
9183
+ } catch {
9184
+ // ignored
9185
+ }
9186
+ throw error;
9007
9187
  }
9008
9188
  }
9009
9189
  return addedEntries;
@@ -9013,15 +9193,33 @@
9013
9193
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
9014
9194
  const totalSize = getTotalSize([zipEntry], "uncompressedSize");
9015
9195
  const writtenSizes = new Map();
9016
- await exportChildren(zipEntry, directoryHandle);
9196
+ const abortController = new AbortController();
9197
+ const { signal } = abortController;
9198
+ const releaseSignal = forwardAbort(options.signal, abortController);
9199
+ const exportedEntryNames = [];
9200
+ let exportAborted = false;
9201
+ try {
9202
+ await exportChildren(zipEntry, directoryHandle);
9203
+ } catch (error) {
9204
+ try {
9205
+ error.exportedEntryNames = exportedEntryNames;
9206
+ } catch {
9207
+ // ignored
9208
+ }
9209
+ throw error;
9210
+ } finally {
9211
+ releaseSignal();
9212
+ }
9017
9213
  return directoryHandle;
9018
9214
 
9019
9215
  async function exportChildren(entry, parentHandle) {
9020
9216
  if (options.concurrent) {
9021
9217
  const results = await Promise.allSettled(entry.children.map(child => exportChild(child, parentHandle)));
9022
- const failedResult = results.find(result => result.status == "rejected");
9023
- if (failedResult) {
9024
- throw failedResult.reason;
9218
+ const rejectedResults = results.filter(result => result.status == "rejected");
9219
+ if (rejectedResults.length) {
9220
+ const failedResults = rejectedResults.filter(result => !isExportAborted(result.reason));
9221
+ const reportedResults = failedResults.length ? failedResults : rejectedResults;
9222
+ throw aggregateEntryErrors(reportedResults.map(result => result.reason));
9025
9223
  }
9026
9224
  } else {
9027
9225
  for (const child of entry.children) {
@@ -9031,6 +9229,12 @@
9031
9229
  }
9032
9230
 
9033
9231
  async function exportChild(child, parentHandle) {
9232
+ if (signal.aborted) {
9233
+ if (exportAborted || isExportAborted(signal.reason)) {
9234
+ return;
9235
+ }
9236
+ throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
9237
+ }
9034
9238
  try {
9035
9239
  if (child.directory) {
9036
9240
  const childDirectoryHandle = await parentHandle.getDirectoryHandle(child.name, { create: true });
@@ -9038,21 +9242,37 @@
9038
9242
  } else {
9039
9243
  const fileHandle = await parentHandle.getFileHandle(child.name, { create: true });
9040
9244
  const writable = await fileHandle.createWritable();
9041
- await child.getData({ writable }, Object.assign({}, options, {
9042
- onprogress: async progress => {
9043
- if (options.onprogress) {
9044
- writtenSizes.set(child.id, progress);
9045
- try {
9046
- await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
9047
- } catch {
9048
- // ignored
9245
+ try {
9246
+ await child.getData({ writable }, Object.assign({}, options, {
9247
+ signal,
9248
+ onprogress: async progress => {
9249
+ if (options.onprogress) {
9250
+ writtenSizes.set(child.id, progress);
9251
+ try {
9252
+ await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
9253
+ } catch {
9254
+ // ignored
9255
+ }
9049
9256
  }
9050
9257
  }
9051
- }
9052
- }));
9258
+ }));
9259
+ } catch (error) {
9260
+ throw exportAborted ? new Error(ERR_ABORT_EXPORT) : error;
9261
+ }
9262
+ exportedEntryNames.push(child.getRelativeName(zipEntry));
9053
9263
  }
9054
9264
  } catch (error) {
9055
- throw new Error(error.message + (child ? " (" + child.name + ")" : ""), { cause: error });
9265
+ exportAborted = true;
9266
+ abortController.abort(new Error(ERR_ABORT_EXPORT));
9267
+ try {
9268
+ if (error.entryName === UNDEFINED_VALUE) {
9269
+ error.entryName = child.getRelativeName(zipEntry);
9270
+ error.entryId = child.id;
9271
+ }
9272
+ } catch {
9273
+ // ignored
9274
+ }
9275
+ throw error;
9056
9276
  }
9057
9277
  }
9058
9278
  }
@@ -9114,6 +9334,21 @@
9114
9334
  fs.root = new ZipDirectoryEntry(fs);
9115
9335
  }
9116
9336
 
9337
+ function collectChildren(directory, recursive) {
9338
+ const children = [];
9339
+ const pendingDirectories = [directory];
9340
+ let directoryIndex = 0;
9341
+ while (directoryIndex < pendingDirectories.length) {
9342
+ for (const child of pendingDirectories[directoryIndex++].children) {
9343
+ children.push(child);
9344
+ if (recursive) {
9345
+ pendingDirectories.push(child);
9346
+ }
9347
+ }
9348
+ }
9349
+ return children;
9350
+ }
9351
+
9117
9352
  function registerEntries(fs, entry) {
9118
9353
  const pendingEntries = [entry];
9119
9354
  while (pendingEntries.length) {
@@ -9232,6 +9467,7 @@
9232
9467
  exports.BlobWriter = BlobWriter;
9233
9468
  exports.Data64URIReader = Data64URIReader;
9234
9469
  exports.Data64URIWriter = Data64URIWriter;
9470
+ exports.ERR_ABORTED = ERR_ABORTED;
9235
9471
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
9236
9472
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
9237
9473
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
@@ -9255,12 +9491,17 @@
9255
9491
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
9256
9492
  exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
9257
9493
  exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
9494
+ exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
9258
9495
  exports.ERR_INVALID_GID = ERR_INVALID_GID;
9496
+ exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
9497
+ exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
9259
9498
  exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
9260
9499
  exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
9261
9500
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
9501
+ exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
9262
9502
  exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
9263
9503
  exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
9504
+ exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
9264
9505
  exports.ERR_INVALID_UID = ERR_INVALID_UID;
9265
9506
  exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
9266
9507
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
@@ -9275,6 +9516,7 @@
9275
9516
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
9276
9517
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
9277
9518
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
9519
+ exports.ERR_UNSAFE_FILENAME = ERR_UNSAFE_FILENAME;
9278
9520
  exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION$1;
9279
9521
  exports.ERR_UNSUPPORTED_CONTEXT = ERR_UNSUPPORTED_CONTEXT;
9280
9522
  exports.ERR_UNSUPPORTED_CRYPTO_API = ERR_UNSUPPORTED_CRYPTO_API;