@zip.js/zip.js 2.8.45 → 2.8.47

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 (56) hide show
  1. package/README.md +28 -2
  2. package/deno.json +13 -3
  3. package/dist/zip-core-external.js +146 -35
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +154 -32
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +146 -35
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +124 -30
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +146 -35
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +160 -36
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +160 -36
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +156 -34
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +158 -36
  20. package/dist/zip-native.min.js +1 -1
  21. package/dist/zip-web-worker-native.js +1 -1
  22. package/dist/zip-web-worker.js +1 -1
  23. package/dist/zip.js +158 -36
  24. package/dist/zip.min.js +1 -1
  25. package/index-native.cjs +160 -36
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +160 -36
  28. package/index.d.cts +232 -1
  29. package/index.d.ts +232 -1
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +9 -5
  32. package/lib/core/codec-worker.js +30 -13
  33. package/lib/core/configuration.js +20 -2
  34. package/lib/core/constants.js +2 -0
  35. package/lib/core/options.js +4 -0
  36. package/lib/core/streams/codec-stream.js +2 -0
  37. package/lib/core/streams/common-crypto.js +2 -1
  38. package/lib/core/streams/zip-entry-stream.js +12 -10
  39. package/lib/core/util/sync-access-handle-temp-stream.js +2 -1
  40. package/lib/core/web-worker-base.js +27 -0
  41. package/lib/core/web-worker-inline-native.js +1 -1
  42. package/lib/core/web-worker-inline-wasm.js +1 -1
  43. package/lib/core/web-worker-native.js +7 -9
  44. package/lib/core/web-worker-wasm.js +9 -12
  45. package/lib/core/zip-fs.js +1 -1
  46. package/lib/core/zip-reader.js +58 -5
  47. package/lib/core/zip-writer.js +43 -8
  48. package/lib/zip-core-base.js +2 -1
  49. package/lib/{core/web-worker-inline-template.js → zip-core-custom.js} +13 -20
  50. package/lib/zip-core-reader.js +2 -1
  51. package/lib/zip-core-writer.js +10 -1
  52. package/lib/zip-module-native.js +3 -3
  53. package/lib/zip-module-wasm-base.js +3 -3
  54. package/package.json +20 -2
  55. package/lib/core/web-worker-inline-template-native.js +0 -48
  56. package/lib/core/zlib-streams-inline-template.js +0 -45
@@ -46,6 +46,7 @@
46
46
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
47
47
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
48
48
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
49
+ const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
49
50
  const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
50
51
  const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
51
52
  const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
@@ -2815,7 +2816,7 @@
2815
2816
 
2816
2817
  class DeflateStream extends TransformStream {
2817
2818
 
2818
- constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
2819
+ constructor(options, { chunkSize, CompressionStreamFallback, CompressionStream }) {
2819
2820
  super({});
2820
2821
  const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod } = options;
2821
2822
  const stream = this;
@@ -2837,7 +2838,7 @@
2837
2838
  readable = pipeThrough(readable, gzipCrc32Stream);
2838
2839
  } else {
2839
2840
  try {
2840
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamZlib);
2841
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
2841
2842
  } catch (error) {
2842
2843
  let gzipStream;
2843
2844
  try {
@@ -2979,7 +2980,7 @@
2979
2980
 
2980
2981
  class InflateStream extends TransformStream {
2981
2982
 
2982
- constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
2983
+ constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
2983
2984
  super({});
2984
2985
  const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
2985
2986
  let crc32Stream, decryptionStream;
@@ -2998,7 +2999,7 @@
2998
2999
  readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
2999
3000
  } else {
3000
3001
  try {
3001
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib);
3002
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
3002
3003
  } catch (error) {
3003
3004
  if (deflate64 || outputSize === UNDEFINED_VALUE) {
3004
3005
  throw error;
@@ -3077,17 +3078,17 @@
3077
3078
  return new CodecStreamClass(format, options);
3078
3079
  }
3079
3080
 
3080
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib) {
3081
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
3081
3082
  const Stream = useCompressionStream && CompressionStreamNative ?
3082
3083
  CompressionStreamNative :
3083
- CompressionStreamZlib || CompressionStreamNative;
3084
+ CompressionStreamFallback || CompressionStreamNative;
3084
3085
  const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
3085
3086
  let codecStream;
3086
3087
  try {
3087
3088
  codecStream = new Stream(format, options);
3088
3089
  } catch (error) {
3089
- if (useCompressionStream && CompressionStreamZlib && Stream != CompressionStreamZlib) {
3090
- codecStream = new CompressionStreamZlib(format, options);
3090
+ if (useCompressionStream && CompressionStreamFallback && Stream != CompressionStreamFallback) {
3091
+ codecStream = new CompressionStreamFallback(format, options);
3091
3092
  } else {
3092
3093
  throw error;
3093
3094
  }
@@ -3350,7 +3351,7 @@
3350
3351
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
3351
3352
  const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
3352
3353
 
3353
- let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions;
3354
+ let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions, createWorkerFailed;
3354
3355
  let transferStreamsSupported = true;
3355
3356
  try {
3356
3357
  transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
@@ -3360,14 +3361,14 @@
3360
3361
  let initModule = () => { };
3361
3362
 
3362
3363
  async function supportsDeflate(config) {
3363
- const { CompressionStream: NativeStream, CompressionStreamZlib: ZlibStream } = config;
3364
- if (ZlibStream && !ZlibStream.requiresModule) {
3364
+ const { CompressionStream: NativeStream, CompressionStreamFallback: FallbackStream } = config;
3365
+ if (FallbackStream && !FallbackStream.requiresModule) {
3365
3366
  return true;
3366
3367
  }
3367
3368
  if (supportsDeflateRaw(NativeStream) || supportsGzip(NativeStream)) {
3368
3369
  return true;
3369
3370
  }
3370
- if (ZlibStream) {
3371
+ if (FallbackStream) {
3371
3372
  try {
3372
3373
  await initModule(config);
3373
3374
  return true;
@@ -3380,8 +3381,11 @@
3380
3381
 
3381
3382
  class CodecWorker {
3382
3383
 
3383
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI }, onTaskFinished) {
3384
+ constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
3384
3385
  const { signal } = streamOptions;
3386
+ if (createWorkerFailed) {
3387
+ createWorker = UNDEFINED_VALUE;
3388
+ }
3385
3389
  Object.assign(workerData, {
3386
3390
  busy: true,
3387
3391
  generation: (workerData.generation || 0) + 1,
@@ -3391,6 +3395,7 @@
3391
3395
  writable,
3392
3396
  options: Object.assign({}, options),
3393
3397
  workerURI,
3398
+ createWorker,
3394
3399
  transferStreams,
3395
3400
  terminate() {
3396
3401
  return new Promise(resolve => {
@@ -3426,7 +3431,7 @@
3426
3431
  // deno-lint-ignore valid-typeof
3427
3432
  webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
3428
3433
  }
3429
- return (useWebWorkers && webWorkerSupported ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
3434
+ return (useWebWorkers && ((webWorkerSupported && workerURI) || createWorker) ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
3430
3435
  }
3431
3436
  }
3432
3437
 
@@ -3483,7 +3488,11 @@
3483
3488
  try {
3484
3489
  worker = getWebWorker(workerData.workerURI, baseURI, workerData);
3485
3490
  } catch {
3486
- webWorkerSupported = false;
3491
+ if (workerData.createWorker) {
3492
+ createWorkerFailed = true;
3493
+ } else {
3494
+ webWorkerSupported = false;
3495
+ }
3487
3496
  return createWorkerInterface(workerData, config);
3488
3497
  }
3489
3498
  Object.assign(workerData, {
@@ -3496,7 +3505,11 @@
3496
3505
  return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
3497
3506
  } catch (error) {
3498
3507
  if (error && error.workerStartupFailed) {
3499
- webWorkerSupported = false;
3508
+ if (workerData.createWorker) {
3509
+ createWorkerFailed = true;
3510
+ } else {
3511
+ webWorkerSupported = false;
3512
+ }
3500
3513
  const { reader } = workerData;
3501
3514
  if (reader) {
3502
3515
  reader.releaseLock();
@@ -3519,17 +3532,17 @@
3519
3532
  try {
3520
3533
  if (options.compressed && !options.format) {
3521
3534
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
3522
- const ZlibStream = deflate ? config.CompressionStreamZlib : config.DecompressionStreamZlib;
3535
+ const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
3523
3536
  const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
3524
3537
  if (!options.useCompressionStream) {
3525
3538
  try {
3526
3539
  await initModule(config);
3527
3540
  } catch {
3528
- if (!ZlibStream || ZlibStream.requiresModule) {
3541
+ if (!FallbackStream || FallbackStream.requiresModule) {
3529
3542
  options.useCompressionStream = true;
3530
3543
  }
3531
3544
  }
3532
- } else if (ZlibStream && ZlibStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
3545
+ } else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
3533
3546
  try {
3534
3547
  await initModule(config);
3535
3548
  } catch {
@@ -3654,8 +3667,11 @@
3654
3667
  }
3655
3668
 
3656
3669
  function getWebWorker(url, baseURI, workerData, isModuleType, useBlobURI = true) {
3670
+ const { createWorker } = workerData;
3657
3671
  let worker, resolvedURI, resolvedOptions;
3658
- if (webWorkerURI === UNDEFINED_VALUE || webWorkerSource !== url) {
3672
+ if (createWorker) {
3673
+ worker = createWorker();
3674
+ } else if (webWorkerURI === UNDEFINED_VALUE || webWorkerSource !== url) {
3659
3675
  // deno-lint-ignore valid-typeof
3660
3676
  const isFunctionURI = typeof url == FUNCTION_TYPE;
3661
3677
  if (isFunctionURI) {
@@ -3910,7 +3926,7 @@
3910
3926
  async function runWorker(stream, workerOptions) {
3911
3927
  const { options, config } = workerOptions;
3912
3928
  const { transferStreams, useWebWorkers, useCompressionStream, compressed, checkCrc32, computeCrc32, encrypted, format, codecURI } = options;
3913
- const { workerURI, maxWorkers } = config;
3929
+ const { workerURI, createWorker, maxWorkers } = config;
3914
3930
  if (format) {
3915
3931
  if (codecURI) {
3916
3932
  options.codecURI = resolveCodecURI(codecURI, config.baseURI);
@@ -3922,6 +3938,7 @@
3922
3938
  const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
3923
3939
  workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
3924
3940
  workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
3941
+ workerOptions.createWorker = workerOptions.useWebWorkers && createWorker ? createWorker : UNDEFINED_VALUE;
3925
3942
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
3926
3943
  return (await getWorker()).run();
3927
3944
 
@@ -3985,7 +4002,7 @@
3985
4002
  starvationTimeout = null;
3986
4003
  if (pendingRequests.length) {
3987
4004
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
3988
- const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE });
4005
+ const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
3989
4006
  resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
3990
4007
  armStarvationTimeout();
3991
4008
  }
@@ -4313,6 +4330,8 @@
4313
4330
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4314
4331
  const OPTION_STRICTNESS = "strictness";
4315
4332
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4333
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4334
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4316
4335
  const STRICTNESS_STRICT = "strict";
4317
4336
  const STRICTNESS_BALANCED = "balanced";
4318
4337
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4438,6 +4457,7 @@
4438
4457
  let startOffset;
4439
4458
  let zip64EndOfDirectory;
4440
4459
  let zip64EndOfDirectoryVersion2;
4460
+ let directoryEncryptionInfo;
4441
4461
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4442
4462
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4443
4463
  directoryDataOffset += getDiskOffset$1(reader, diskNumber);
@@ -4468,6 +4488,15 @@
4468
4488
  }
4469
4489
  zip64EndOfDirectory = true;
4470
4490
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
4491
+ if (zip64EndOfDirectoryVersion2) {
4492
+ const extensibleDataLength = Math.min(
4493
+ Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4494
+ reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4495
+ if (extensibleDataLength > 0) {
4496
+ const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4497
+ directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4498
+ }
4499
+ }
4471
4500
  if (lastDiskNumber == MAX_16_BITS) {
4472
4501
  lastDiskNumber = getUint32(endOfDirectoryView, 16);
4473
4502
  } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
@@ -4491,7 +4520,7 @@
4491
4520
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4492
4521
  }
4493
4522
  }
4494
- const declaredDirectoryDataLength = directoryDataLength;
4523
+ let declaredDirectoryDataLength = directoryDataLength;
4495
4524
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4496
4525
  (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4497
4526
  if (directoryDataOffset >= reader.size) {
@@ -4539,6 +4568,18 @@
4539
4568
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
4540
4569
  throw new Error(ERR_BAD_FORMAT);
4541
4570
  }
4571
+ zipReader.directoryOffset = directoryDataOffset;
4572
+ zipReader.directoryLength = declaredDirectoryDataLength;
4573
+ const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4574
+ let decryptedDirectory;
4575
+ if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4576
+ getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4577
+ (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4578
+ directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4579
+ directoryView = getDataView(directoryArray);
4580
+ declaredDirectoryDataLength = directoryArray.length;
4581
+ decryptedDirectory = true;
4582
+ }
4542
4583
  startOffset = directoryDataOffset;
4543
4584
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4544
4585
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
@@ -4547,7 +4588,7 @@
4547
4588
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4548
4589
  const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
4549
4590
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4550
- if (indexFile == 0 && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4591
+ if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4551
4592
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4552
4593
  }
4553
4594
  throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
@@ -4660,7 +4701,15 @@
4660
4701
  }
4661
4702
  yield entry;
4662
4703
  }
4663
- if (checkAmbiguity && offset != declaredDirectoryDataLength) {
4704
+ let offsetAfterSignature = offset;
4705
+ if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4706
+ const signatureDataLength = getUint16(directoryView, offset + 4);
4707
+ if (offset + 6 + signatureDataLength <= directoryArray.length) {
4708
+ zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4709
+ offsetAfterSignature = offset + 6 + signatureDataLength;
4710
+ }
4711
+ }
4712
+ if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
4664
4713
  throwAmbiguousArchive("trailing central directory data");
4665
4714
  }
4666
4715
  if (duplicateFilename) {
@@ -4892,6 +4941,25 @@
4892
4941
  return false;
4893
4942
  }
4894
4943
 
4944
+ function getDirectoryEncryptionInfo(rawExtensibleData) {
4945
+ const directoryEncryptionInfo = { rawExtensibleData };
4946
+ if (rawExtensibleData.length >= 28) {
4947
+ const extensibleDataView = getDataView(rawExtensibleData);
4948
+ const hashDataLength = getUint16(extensibleDataView, 26);
4949
+ Object.assign(directoryEncryptionInfo, {
4950
+ compressionMethod: getUint16(extensibleDataView, 0),
4951
+ compressedSize: Number(getBigUint64(extensibleDataView, 2)),
4952
+ uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
4953
+ encryptionAlgorithm: getUint16(extensibleDataView, 18),
4954
+ bitLength: getUint16(extensibleDataView, 20),
4955
+ flags: getUint16(extensibleDataView, 22),
4956
+ hashAlgorithm: getUint16(extensibleDataView, 24),
4957
+ hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
4958
+ });
4959
+ }
4960
+ return directoryEncryptionInfo;
4961
+ }
4962
+
4895
4963
  function readCommonHeader(directory, dataView, offset) {
4896
4964
  const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
4897
4965
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
@@ -5443,6 +5511,7 @@
5443
5511
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5444
5512
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5445
5513
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5514
+ ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
5446
5515
  ZipReader: ZipReader
5447
5516
  });
5448
5517
 
@@ -5500,6 +5569,7 @@
5500
5569
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5501
5570
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5502
5571
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5572
+ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5503
5573
 
5504
5574
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
5505
5575
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
@@ -6797,8 +6867,9 @@
6797
6867
 
6798
6868
  async function closeFile(zipWriter, comment, options) {
6799
6869
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
6800
- const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6801
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
6870
+ const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6871
+ const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
6872
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
6802
6873
  }
6803
6874
 
6804
6875
  function createDirectoryRecords(files) {
@@ -6955,12 +7026,33 @@
6955
7026
  }
6956
7027
  }
6957
7028
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
6958
- return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
7029
+ return {
7030
+ directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
7031
+ directoryArray
7032
+ };
7033
+ }
7034
+
7035
+ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7036
+ const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7037
+ if (signCentralDirectory) {
7038
+ const signatureData = await signCentralDirectory(directoryArray);
7039
+ const signatureDataLength = getLength(signatureData);
7040
+ if (signatureDataLength > MAX_16_BITS) {
7041
+ throw new Error(ERR_INVALID_SIGNATURE_DATA);
7042
+ }
7043
+ const signatureRecord = createRecordWriter(6 + signatureDataLength);
7044
+ signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7045
+ signatureRecord.uint16(signatureDataLength);
7046
+ signatureRecord.bytes(signatureData);
7047
+ await writeData(zipWriter.writer, signatureRecord.array);
7048
+ return 6 + signatureDataLength;
7049
+ }
7050
+ return 0;
6959
7051
  }
6960
7052
 
6961
7053
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
6962
7054
  const { writer } = zipWriter;
6963
- const { directoryStart } = cdInfo;
7055
+ const { directoryStart, signatureLength } = cdInfo;
6964
7056
  let { directoryDataLength } = cdInfo;
6965
7057
  let filesLength = zipWriter.files.size;
6966
7058
  let diskNumber = directoryStart.diskNumber;
@@ -6999,7 +7091,7 @@
6999
7091
  endOfdirectoryRecord.uint64(directoryOffset);
7000
7092
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7001
7093
  endOfdirectoryRecord.uint32(lastDiskNumber);
7002
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
7094
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7003
7095
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7004
7096
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7005
7097
  if (supportZip64SplitFile) {
@@ -8272,6 +8364,8 @@
8272
8364
  }
8273
8365
  }
8274
8366
 
8367
+ exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
8368
+ exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
8275
8369
  exports.fs = fs;
8276
8370
 
8277
8371
  }));