@zip.js/zip.js 2.8.49 → 2.8.50

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.
@@ -7,8 +7,8 @@
7
7
  1. Redistributions of source code must retain the above copyright notice,
8
8
  this list of conditions and the following disclaimer.
9
9
 
10
- 2. Redistributions in binary form must reproduce the above copyright
11
- notice, this list of conditions and the following disclaimer in
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in
12
12
  the documentation and/or other materials provided with the distribution.
13
13
 
14
14
  3. The names of the authors may not be used to endorse or promote products
@@ -26,41 +26,24 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- /* global Worker, URL, TransformStream, AbortController, structuredClone, DOMException, setTimeout, clearTimeout */
29
+ /* global Worker, TransformStream */
30
30
 
31
31
  import {
32
32
  UNDEFINED_VALUE,
33
- UNDEFINED_TYPE,
34
- FUNCTION_TYPE
33
+ UNDEFINED_TYPE
35
34
  } from "./constants.js";
36
35
  import { getChunkSize } from "./configuration.js";
37
- import { toExactUint8Array } from "./util/array.js";
38
36
  import {
39
37
  CODEC_DEFLATE,
40
38
  CodecStream,
41
39
  ChunkStream,
42
40
  supportsDeflateRaw,
43
- supportsGzip,
44
- MESSAGE_EVENT_TYPE,
45
- MESSAGE_START,
46
- MESSAGE_PULL,
47
- MESSAGE_DATA,
48
- MESSAGE_ACK_DATA,
49
- MESSAGE_CLOSE
41
+ supportsGzip
50
42
  } from "./streams/codec-stream.js";
51
43
 
52
- const MODULE_WORKER_OPTIONS = { type: "module" };
53
- const ERROR_EVENT_TYPE = "error";
54
- const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
55
44
  const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
56
45
 
57
- let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions, createWorkerFailed;
58
- let transferStreamsSupported = true;
59
- try {
60
- transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
61
- } catch {
62
- // ignored
63
- }
46
+ let webWorkerSupported, createWorkerFailed, webWorkerBackend;
64
47
  let initModule = () => { };
65
48
 
66
49
  export {
@@ -68,6 +51,10 @@ export {
68
51
  configureWorker,
69
52
  resetWebWorkerSupport,
70
53
  supportsDeflate,
54
+ setWebWorkerBackend,
55
+ disableWebWorker,
56
+ createWorkerInterface,
57
+ runWorker,
71
58
  ERR_WORKER_STARTUP_TIMEOUT
72
59
  };
73
60
 
@@ -75,6 +62,10 @@ function configureWorker({ initModule: initModuleFunction }) {
75
62
  initModule = initModuleFunction;
76
63
  }
77
64
 
65
+ function setWebWorkerBackend(backend) {
66
+ webWorkerBackend = backend;
67
+ }
68
+
78
69
  async function supportsDeflate(config) {
79
70
  const { CompressionStream: NativeStream, CompressionStreamFallback: FallbackStream } = config;
80
71
  if (FallbackStream && !FallbackStream.requiresModule) {
@@ -99,6 +90,14 @@ function resetWebWorkerSupport() {
99
90
  createWorkerFailed = false;
100
91
  }
101
92
 
93
+ function disableWebWorker(workerData) {
94
+ if (workerData.createWorker) {
95
+ createWorkerFailed = true;
96
+ } else {
97
+ webWorkerSupported = false;
98
+ }
99
+ }
100
+
102
101
  class CodecWorker {
103
102
 
104
103
  constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
@@ -151,7 +150,7 @@ class CodecWorker {
151
150
  // deno-lint-ignore valid-typeof
152
151
  webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
153
152
  }
154
- return (useWebWorkers && ((webWorkerSupported && workerURI) || createWorker) ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
153
+ return (useWebWorkers && webWorkerBackend && ((webWorkerSupported && workerURI) || createWorker) ? webWorkerBackend : createWorkerInterface)(workerData, config);
155
154
  }
156
155
  }
157
156
 
@@ -195,60 +194,6 @@ function createWorkerInterface(workerData, config) {
195
194
  };
196
195
  }
197
196
 
198
- function createWebWorkerInterface(workerData, config) {
199
- const { baseURI, chunkSize, workerStartupTimeout } = config;
200
- let { wasmURI } = config;
201
-
202
- if (!workerData.interface) {
203
- // deno-lint-ignore valid-typeof
204
- if (typeof wasmURI == FUNCTION_TYPE) {
205
- wasmURI = wasmURI();
206
- }
207
- let worker;
208
- try {
209
- worker = getWebWorker(workerData.workerURI, baseURI, workerData);
210
- } catch {
211
- if (workerData.createWorker) {
212
- createWorkerFailed = true;
213
- } else {
214
- webWorkerSupported = false;
215
- }
216
- return createWorkerInterface(workerData, config);
217
- }
218
- Object.assign(workerData, {
219
- worker,
220
- workerAlive: false,
221
- terminated: false,
222
- interface: {
223
- run: async () => {
224
- try {
225
- return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
226
- } catch (error) {
227
- if (error && error.workerStartupFailed) {
228
- if (workerData.createWorker) {
229
- createWorkerFailed = true;
230
- } else {
231
- webWorkerSupported = false;
232
- }
233
- releaseWorkerStreams(workerData);
234
- return runWorker(workerData, config);
235
- }
236
- if (error && error.codecImportFailed) {
237
- if (workerData.reader) {
238
- releaseWorkerStreams(workerData);
239
- return runWorker(workerData, config);
240
- }
241
- workerData.onTaskFinished();
242
- }
243
- throw error;
244
- }
245
- }
246
- }
247
- });
248
- }
249
- return workerData.interface;
250
- }
251
-
252
197
  async function runWorker({ options, readable, writable, onTaskFinished }, config) {
253
198
  let codecStream;
254
199
  try {
@@ -296,329 +241,3 @@ async function runWorker({ options, readable, writable, onTaskFinished }, config
296
241
  onTaskFinished();
297
242
  }
298
243
  }
299
-
300
- async function runWebWorker(workerData, config) {
301
- let resolveResult, rejectResult;
302
- const result = new Promise((resolve, reject) => {
303
- resolveResult = resolve;
304
- rejectResult = reject;
305
- });
306
- Object.assign(workerData, {
307
- reader: null,
308
- writer: null,
309
- resolveResult,
310
- rejectResult,
311
- result
312
- });
313
- const { readable, options } = workerData;
314
- const { writable, closed, abortPipe } = watchClosedStream(workerData.writable);
315
- let streamsTransferred;
316
- try {
317
- streamsTransferred = sendMessage({
318
- type: MESSAGE_START,
319
- options,
320
- config,
321
- readable,
322
- writable
323
- }, workerData);
324
- } catch (error) {
325
- abortPipe();
326
- try {
327
- await closed;
328
- } catch {
329
- // ignored
330
- }
331
- workerData.onTaskFinished();
332
- throw error;
333
- }
334
- if (!streamsTransferred) {
335
- Object.assign(workerData, {
336
- reader: readable.getReader(),
337
- writer: writable.getWriter()
338
- });
339
- }
340
- const { workerStartupTimeout } = config;
341
- if (!workerData.workerAlive && Number.isFinite(workerStartupTimeout) && workerStartupTimeout >= 0) {
342
- workerData.startupTimeout = setTimeout(() => onStartupTimeout(workerData), workerStartupTimeout);
343
- }
344
- try {
345
- const resultValue = await result;
346
- await closeWritable();
347
- await closed;
348
- return resultValue;
349
- } catch (error) {
350
- await closeWritable();
351
- abortPipe();
352
- try {
353
- await closed;
354
- } catch {
355
- // ignored
356
- }
357
- throw error;
358
- }
359
-
360
- async function closeWritable() {
361
- if (!streamsTransferred && !writable.locked) {
362
- try {
363
- await writable.getWriter().close();
364
- } catch {
365
- // ignored
366
- }
367
- }
368
- }
369
- }
370
-
371
- function watchClosedStream(writableSource) {
372
- const abortController = new AbortController();
373
- const { writable, readable } = new TransformStream();
374
- const closed = readable.pipeTo(writableSource, { preventClose: true, preventAbort: true, signal: abortController.signal });
375
- closed.catch(() => { });
376
- return { writable, closed, abortPipe: () => abortController.abort() };
377
- }
378
-
379
- function releaseWorkerStreams(workerData) {
380
- const { reader } = workerData;
381
- if (reader) {
382
- reader.releaseLock();
383
- }
384
- workerData.reader = null;
385
- workerData.writer = null;
386
- }
387
-
388
- function terminateWorker(workerData) {
389
- const { worker } = workerData;
390
- if (worker) {
391
- try {
392
- worker.terminate();
393
- } catch {
394
- // ignored
395
- }
396
- }
397
- workerData.interface = null;
398
- }
399
-
400
- function getWebWorker(url, baseURI, workerData, isModuleType, useBlobURI = true) {
401
- const { createWorker } = workerData;
402
- let worker, resolvedURI, resolvedOptions;
403
- if (createWorker) {
404
- worker = createWorker();
405
- } else if (webWorkerURI === UNDEFINED_VALUE || webWorkerSource !== url) {
406
- // deno-lint-ignore valid-typeof
407
- const isFunctionURI = typeof url == FUNCTION_TYPE;
408
- if (isFunctionURI) {
409
- resolvedURI = url(useBlobURI);
410
- } else {
411
- resolvedURI = url;
412
- }
413
- const isDataURI = resolvedURI.startsWith("data:");
414
- const isBlobURI = resolvedURI.startsWith("blob:");
415
- if (isDataURI || isBlobURI) {
416
- if (isModuleType === UNDEFINED_VALUE) {
417
- isModuleType = false;
418
- }
419
- if (isModuleType) {
420
- resolvedOptions = MODULE_WORKER_OPTIONS;
421
- }
422
- try {
423
- worker = new Worker(resolvedURI, resolvedOptions);
424
- } catch (error) {
425
- if (isBlobURI) {
426
- try {
427
- URL.revokeObjectURL(resolvedURI);
428
- } catch {
429
- // ignored
430
- }
431
- }
432
- if (isFunctionURI && isBlobURI) {
433
- return getWebWorker(url, baseURI, workerData, isModuleType, false);
434
- } else if (!isModuleType) {
435
- return getWebWorker(url, baseURI, workerData, true, false);
436
- } else {
437
- throw error;
438
- }
439
- }
440
- } else {
441
- if (isModuleType === UNDEFINED_VALUE) {
442
- isModuleType = true;
443
- }
444
- if (isModuleType) {
445
- resolvedOptions = MODULE_WORKER_OPTIONS;
446
- }
447
- try {
448
- resolvedURI = new URL(resolvedURI, baseURI);
449
- } catch {
450
- // ignored
451
- }
452
- try {
453
- worker = new Worker(resolvedURI, resolvedOptions);
454
- } catch (error) {
455
- if (isModuleType) {
456
- return getWebWorker(url, baseURI, workerData, false, useBlobURI);
457
- } else {
458
- throw error;
459
- }
460
- }
461
- }
462
- webWorkerSource = url;
463
- webWorkerURI = resolvedURI;
464
- webWorkerOptions = resolvedOptions;
465
- } else {
466
- worker = new Worker(webWorkerURI, webWorkerOptions);
467
- }
468
- worker.addEventListener(MESSAGE_EVENT_TYPE, event => {
469
- workerData.workerAlive = true;
470
- clearStartupTimeout(workerData);
471
- onMessage(event, workerData);
472
- });
473
- worker.addEventListener(ERROR_EVENT_TYPE, event => onWorkerError(event, workerData));
474
- worker.addEventListener(MESSAGE_ERROR_EVENT_TYPE, event => onWorkerError(event, workerData));
475
- return worker;
476
- }
477
-
478
- function onStartupTimeout(workerData) {
479
- workerData.startupTimeout = null;
480
- if (workerData.workerAlive) {
481
- return;
482
- }
483
- const { rejectResult, writer } = workerData;
484
- terminateWorker(workerData);
485
- workerData.worker = null;
486
- if (rejectResult) {
487
- const error = new Error(ERR_WORKER_STARTUP_TIMEOUT);
488
- error.workerStartupFailed = true;
489
- rejectResult(error);
490
- if (writer) {
491
- writer.releaseLock();
492
- }
493
- }
494
- }
495
-
496
- function clearStartupTimeout(workerData) {
497
- const { startupTimeout } = workerData;
498
- if (startupTimeout) {
499
- clearTimeout(startupTimeout);
500
- workerData.startupTimeout = null;
501
- }
502
- }
503
-
504
- function onWorkerError(event, workerData) {
505
- if (event.preventDefault) {
506
- event.preventDefault();
507
- }
508
- clearStartupTimeout(workerData);
509
- const { workerAlive, rejectResult, writer, onTaskFinished } = workerData;
510
- terminateWorker(workerData);
511
- if (!workerAlive) {
512
- workerData.worker = null;
513
- }
514
- if (rejectResult) {
515
- let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
516
- if (!workerAlive) {
517
- error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
518
- }
519
- rejectResult(error);
520
- if (writer) {
521
- writer.releaseLock();
522
- }
523
- if (workerAlive) {
524
- onTaskFinished();
525
- }
526
- }
527
- }
528
-
529
- function sendMessage(message, { worker, writer, transferStreams, workerAlive }) {
530
- try {
531
- const { value, readable, writable } = message;
532
- const transferables = [];
533
- if (value) {
534
- message.value = toExactUint8Array(value);
535
- transferables.push(message.value.buffer);
536
- }
537
- if (transferStreams && transferStreamsSupported && workerAlive) {
538
- if (readable) {
539
- transferables.push(readable);
540
- }
541
- if (writable) {
542
- transferables.push(writable);
543
- }
544
- } else {
545
- message.readable = message.writable = null;
546
- }
547
- if (transferables.length) {
548
- try {
549
- worker.postMessage(message, transferables);
550
- return true;
551
- } catch {
552
- transferStreamsSupported = false;
553
- message.readable = message.writable = null;
554
- worker.postMessage(message);
555
- }
556
- } else {
557
- worker.postMessage(message);
558
- }
559
- } catch (error) {
560
- if (writer) {
561
- writer.releaseLock();
562
- }
563
- throw error;
564
- }
565
- }
566
-
567
- async function onMessage({ data }, workerData) {
568
- const { type, value, messageId, result, error } = data;
569
- const { reader, writer, resolveResult, rejectResult, onTaskFinished, generation } = workerData;
570
- const stale = () => workerData.generation != generation;
571
- try {
572
- if (error) {
573
- const { message, stack, code, name, outputSize, cause, codecImportFailed } = error;
574
- const responseError = new Error(message);
575
- Object.assign(responseError, { stack, code, name, outputSize });
576
- if (cause) {
577
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
578
- }
579
- if (codecImportFailed) {
580
- responseError.codecImportFailed = true;
581
- }
582
- close(responseError);
583
- } else {
584
- if (type == MESSAGE_PULL) {
585
- const { value, done } = await reader.read();
586
- if (!stale()) {
587
- sendMessage({ type: MESSAGE_DATA, value, done, messageId }, workerData);
588
- }
589
- }
590
- if (type == MESSAGE_DATA) {
591
- await writer.ready;
592
- await writer.write(new Uint8Array(value));
593
- if (!stale()) {
594
- sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
595
- }
596
- }
597
- if (type == MESSAGE_CLOSE) {
598
- close(null, result);
599
- }
600
- }
601
- } catch (error) {
602
- if (!stale()) {
603
- terminateWorker(workerData);
604
- close(error);
605
- }
606
- }
607
-
608
- function close(error, result) {
609
- if (stale()) {
610
- return;
611
- }
612
- if (error) {
613
- rejectResult(error);
614
- } else {
615
- resolveResult(result);
616
- }
617
- if (writer) {
618
- writer.releaseLock();
619
- }
620
- if (!(error && error.codecImportFailed)) {
621
- onTaskFinished();
622
- }
623
- }
624
- }
@@ -108,6 +108,8 @@ const INFINITY_VALUE = Infinity;
108
108
  const UNDEFINED_TYPE = "undefined";
109
109
  const FUNCTION_TYPE = "function";
110
110
  const OBJECT_TYPE = "object";
111
+ const STRING_TYPE = "string";
112
+ const NUMBER_TYPE = "number";
111
113
 
112
114
  const EMPTY_UINT8_ARRAY = new Uint8Array();
113
115
 
@@ -185,5 +187,7 @@ export {
185
187
  INFINITY_VALUE,
186
188
  UNDEFINED_TYPE,
187
189
  FUNCTION_TYPE,
188
- OBJECT_TYPE
190
+ OBJECT_TYPE,
191
+ STRING_TYPE,
192
+ NUMBER_TYPE
189
193
  };
package/lib/core/io.js CHANGED
@@ -32,6 +32,7 @@
32
32
  import {
33
33
  UNDEFINED_VALUE,
34
34
  FUNCTION_TYPE,
35
+ UNDEFINED_TYPE,
35
36
  END_OF_CENTRAL_DIR_LENGTH,
36
37
  EMPTY_UINT8_ARRAY
37
38
  } from "./constants.js";
@@ -399,7 +400,7 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
399
400
  forceRangeRequests,
400
401
  combineSizeEocd
401
402
  } = httpReader;
402
- if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == "undefined" || preventHeadRequest)) {
403
+ if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
403
404
  const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
404
405
  const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
405
406
  if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
@@ -63,9 +63,13 @@ const OPTION_USDZ = "usdz";
63
63
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
64
64
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
65
65
  const OPTION_STRICTNESS = "strictness";
66
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
67
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
66
68
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
67
69
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
68
70
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
71
+ const TEXT_TYPE_FILENAME = "filename";
72
+ const TEXT_TYPE_COMMENT = "comment";
69
73
  const STRICTNESS_STRICT = "strict";
70
74
  const STRICTNESS_BALANCED = "balanced";
71
75
  const STRICTNESS_TOLERANT = "tolerant";
@@ -108,9 +112,13 @@ export {
108
112
  OPTION_UNIX_EXTRA_FIELD_TYPE,
109
113
  OPTION_LOCAL_EXTRA_FIELD,
110
114
  OPTION_STRICTNESS,
115
+ OPTION_FILENAME_VALIDATION,
116
+ OPTION_NORMALIZE_FILENAME,
111
117
  OPTION_MAX_APPENDED_DATA_SIZE,
112
118
  OPTION_DECRYPT_CENTRAL_DIRECTORY,
113
119
  OPTION_SIGN_CENTRAL_DIRECTORY,
120
+ TEXT_TYPE_FILENAME,
121
+ TEXT_TYPE_COMMENT,
114
122
  STRICTNESS_STRICT,
115
123
  STRICTNESS_BALANCED,
116
124
  STRICTNESS_TOLERANT