@zip.js/zip.js 2.7.63 → 2.7.64

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.
package/dist/zip-fs.js CHANGED
@@ -78,6 +78,8 @@
78
78
 
79
79
  const DIRECTORY_SIGNATURE = "/";
80
80
 
81
+ const HEADER_SIZE = 26;
82
+
81
83
  const MAX_DATE = new Date(2107, 11, 31);
82
84
  const MIN_DATE = new Date(1980, 0, 1);
83
85
 
@@ -3027,6 +3029,7 @@
3027
3029
 
3028
3030
  constructor(array) {
3029
3031
  super();
3032
+ array = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
3030
3033
  Object.assign(this, {
3031
3034
  array,
3032
3035
  size: array.length
@@ -3721,7 +3724,8 @@
3721
3724
  compressedSize
3722
3725
  } = zipEntry;
3723
3726
  const localDirectory = fileEntry.localDirectory = {};
3724
- const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
3727
+ const dataArraySize = HEADER_SIZE + 4;
3728
+ const dataArray = await readUint8Array(reader, offset, dataArraySize + 4, diskNumberStart);
3725
3729
  const dataView = getDataView$1(dataArray);
3726
3730
  let password = getOptionValue$1(zipEntry, options, "password");
3727
3731
  let rawPassword = getOptionValue$1(zipEntry, options, "rawPassword");
@@ -3741,7 +3745,7 @@
3741
3745
  }
3742
3746
  readCommonHeader(localDirectory, dataView, 4);
3743
3747
  localDirectory.rawExtraField = localDirectory.extraFieldLength ?
3744
- await readUint8Array(reader, offset + 30 + localDirectory.filenameLength, localDirectory.extraFieldLength, diskNumberStart) :
3748
+ await readUint8Array(reader, offset + dataArraySize + localDirectory.filenameLength, localDirectory.extraFieldLength, diskNumberStart) :
3745
3749
  new Uint8Array();
3746
3750
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
3747
3751
  Object.assign(fileEntry, {
@@ -3760,7 +3764,7 @@
3760
3764
  throw new Error(ERR_ENCRYPTED);
3761
3765
  }
3762
3766
  }
3763
- const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
3767
+ const dataOffset = offset + dataArraySize + localDirectory.filenameLength + localDirectory.extraFieldLength;
3764
3768
  const size = compressedSize;
3765
3769
  const readable = reader.readable;
3766
3770
  Object.assign(readable, {
@@ -4122,6 +4126,7 @@
4122
4126
  const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
4123
4127
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
4124
4128
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
4129
+ const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
4125
4130
 
4126
4131
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
4127
4132
 
@@ -4149,6 +4154,99 @@
4149
4154
  });
4150
4155
  }
4151
4156
 
4157
+ async prependZip(reader) {
4158
+ if (this.filenames.size) {
4159
+ throw new Error(ERR_ZIP_NOT_EMPTY);
4160
+ }
4161
+ ({ reader } = initReader(reader));
4162
+ const [zipEntriesReader, zipDataReader] = reader.readable.tee();
4163
+ const zipReader = new ZipReader(new ReadableStream({
4164
+ async start(controller) {
4165
+ const reader = zipEntriesReader.getReader();
4166
+ await readChunk();
4167
+
4168
+ async function readChunk() {
4169
+ const { done, value } = await reader.read();
4170
+ if (done) {
4171
+ controller.close();
4172
+ } else {
4173
+ controller.enqueue(value);
4174
+ await readChunk();
4175
+ }
4176
+ }
4177
+ }
4178
+ }));
4179
+ const entries = await zipReader.getEntries();
4180
+ await zipReader.close();
4181
+ await zipDataReader.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
4182
+ this.writer.writable.size = this.offset = reader.size;
4183
+ this.filenames = new Set(entries.map(entry => entry.filename));
4184
+ this.files = new Map(entries.map(entry => {
4185
+ const {
4186
+ version,
4187
+ compressionMethod,
4188
+ lastModDate,
4189
+ lastAccessDate,
4190
+ creationDate,
4191
+ rawFilename,
4192
+ bitFlag,
4193
+ encrypted,
4194
+ uncompressedSize,
4195
+ compressedSize,
4196
+ diskOffset,
4197
+ diskNumber,
4198
+ zip64
4199
+ } = entry;
4200
+ let {
4201
+ rawExtraFieldZip64,
4202
+ rawExtraFieldAES,
4203
+ rawExtraFieldExtendedTimestamp,
4204
+ rawExtraFieldNTFS,
4205
+ rawExtraField,
4206
+ } = entry;
4207
+ const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
4208
+ rawExtraFieldZip64 = rawExtraFieldZip64 || new Uint8Array();
4209
+ rawExtraFieldAES = rawExtraFieldAES || new Uint8Array();
4210
+ rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || new Uint8Array();
4211
+ rawExtraFieldNTFS = rawExtraFieldNTFS || new Uint8Array();
4212
+ rawExtraField = rawExtraField || new Uint8Array();
4213
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
4214
+ const zip64UncompressedSize = zip64 && uncompressedSize > MAX_32_BITS;
4215
+ const zip64CompressedSize = zip64 && compressedSize > MAX_32_BITS;
4216
+ const {
4217
+ headerArray,
4218
+ headerView
4219
+ } = getHeaderArrayData({
4220
+ version,
4221
+ bitflag: getBitflag(level, languageEncodingFlag, dataDescriptor, encrypted),
4222
+ compressionMethod,
4223
+ uncompressedSize,
4224
+ compressedSize,
4225
+ lastModDate,
4226
+ rawFilename,
4227
+ zip64CompressedSize,
4228
+ zip64UncompressedSize,
4229
+ extraFieldLength
4230
+ });
4231
+ Object.assign(entry, {
4232
+ zip64UncompressedSize,
4233
+ zip64CompressedSize,
4234
+ zip64Offset: zip64 && this.offset - diskOffset > MAX_32_BITS,
4235
+ zip64DiskNumberStart: zip64 && diskNumber > MAX_16_BITS,
4236
+ rawExtraFieldZip64,
4237
+ rawExtraFieldAES,
4238
+ rawExtraFieldExtendedTimestamp,
4239
+ rawExtraFieldNTFS,
4240
+ rawExtraField,
4241
+ extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
4242
+ extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
4243
+ headerArray,
4244
+ headerView
4245
+ });
4246
+ return [entry.filename, entry];
4247
+ }));
4248
+ }
4249
+
4152
4250
  async add(name = "", reader, options = {}) {
4153
4251
  const zipWriter = this;
4154
4252
  const {
@@ -4184,6 +4282,22 @@
4184
4282
  }
4185
4283
  }
4186
4284
 
4285
+ remove(entry) {
4286
+ const { filenames, files } = this;
4287
+ if (typeof entry == "string") {
4288
+ entry = files.get(entry);
4289
+ }
4290
+ if (entry && entry.filename !== UNDEFINED_VALUE) {
4291
+ const { filename } = entry;
4292
+ if (filenames.has(filename) && files.has(filename)) {
4293
+ filenames.delete(filename);
4294
+ files.delete(filename);
4295
+ return true;
4296
+ }
4297
+ }
4298
+ return false;
4299
+ }
4300
+
4187
4301
  async close(comment = new Uint8Array(), options = {}) {
4188
4302
  const zipWriter = this;
4189
4303
  const { pendingAddFileCalls, writer } = this;
@@ -4305,7 +4419,13 @@
4305
4419
  const useUnicodeFileNames = getOptionValue(zipWriter, options, "useUnicodeFileNames", true);
4306
4420
  const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
4307
4421
  const compressionMethod = getOptionValue(zipWriter, options, "compressionMethod");
4308
- let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor", true);
4422
+ let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor");
4423
+ if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
4424
+ dataDescriptor = false;
4425
+ }
4426
+ if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
4427
+ dataDescriptor = true;
4428
+ }
4309
4429
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
4310
4430
  if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
4311
4431
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
@@ -4351,10 +4471,11 @@
4351
4471
  uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
4352
4472
  }
4353
4473
  } else {
4354
- uncompressedSize = reader.size;
4474
+ options.uncompressedSize = uncompressedSize = reader.size;
4355
4475
  maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
4356
4476
  }
4357
4477
  } else {
4478
+ options.uncompressedSize = uncompressedSize;
4358
4479
  maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
4359
4480
  }
4360
4481
  }
@@ -4410,7 +4531,10 @@
4410
4531
  passThrough,
4411
4532
  encrypted: Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted),
4412
4533
  signature,
4413
- compressionMethod
4534
+ compressionMethod,
4535
+ uncompressedSize,
4536
+ offset: zipWriter.offset - diskOffset,
4537
+ diskNumberStart: diskNumber,
4414
4538
  });
4415
4539
  const headerInfo = getHeaderInfo(options);
4416
4540
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -4502,20 +4626,26 @@
4502
4626
  await lockPreviousFileEntry;
4503
4627
  await requestLockWriter();
4504
4628
  writingBufferedEntryData = true;
4505
- if (!dataDescriptor) {
4506
- blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
4507
- }
4508
- await skipDiskIfNeeded(writable);
4509
4629
  fileEntry.diskNumberStart = writer.diskNumber;
4510
4630
  diskOffset = writer.diskOffset;
4631
+ fileEntry.offset = zipWriter.offset - diskOffset;
4632
+ if (fileEntry.zip64) {
4633
+ setExtraFieldZip64Data(fileEntry);
4634
+ }
4635
+ if (fileEntry.zip64 || !dataDescriptor) {
4636
+ blob = await patchLocalHeader(fileEntry, blob, writable, options);
4637
+ }
4638
+ await skipDiskIfNeeded(writable);
4511
4639
  await blob.stream().pipeTo(writable, { preventClose: true, preventAbort: true, signal });
4512
4640
  writable.size += blob.size;
4513
4641
  writingBufferedEntryData = false;
4642
+ } else {
4643
+ fileEntry.offset = zipWriter.offset - diskOffset;
4644
+ if (fileEntry.zip64) {
4645
+ setExtraFieldZip64Data(fileEntry);
4646
+ }
4514
4647
  }
4515
- fileEntry.offset = zipWriter.offset - diskOffset;
4516
- if (fileEntry.zip64) {
4517
- setZip64ExtraInfo(fileEntry, options);
4518
- } else if (fileEntry.offset > MAX_32_BITS) {
4648
+ if (fileEntry.offset > MAX_32_BITS && !fileEntry.zip64) {
4519
4649
  throw new Error(ERR_UNSUPPORTED_FORMAT);
4520
4650
  }
4521
4651
  zipWriter.offset += fileEntry.size;
@@ -4582,12 +4712,15 @@
4582
4712
  const {
4583
4713
  localHeaderArray,
4584
4714
  headerArray,
4715
+ headerView,
4585
4716
  lastModDate,
4586
4717
  rawLastModDate,
4587
4718
  encrypted,
4588
4719
  compressed,
4589
4720
  version,
4590
4721
  compressionMethod,
4722
+ rawExtraFieldZip64,
4723
+ localExtraFieldZip64Length,
4591
4724
  rawExtraFieldExtendedTimestamp,
4592
4725
  extraFieldExtendedTimestampFlag,
4593
4726
  rawExtraFieldNTFS,
@@ -4636,6 +4769,8 @@
4636
4769
  rawFilename,
4637
4770
  commentUTF8: true,
4638
4771
  rawComment,
4772
+ rawExtraFieldZip64,
4773
+ localExtraFieldZip64Length,
4639
4774
  rawExtraFieldExtendedTimestamp,
4640
4775
  rawExtraFieldNTFS,
4641
4776
  rawExtraFieldAES,
@@ -4689,28 +4824,8 @@
4689
4824
  } else {
4690
4825
  await writeData(writable, localHeaderArray);
4691
4826
  }
4692
- let rawExtraFieldZip64;
4693
- if (zip64) {
4694
- let rawExtraFieldZip64Length = 4;
4695
- if (zip64UncompressedSize) {
4696
- rawExtraFieldZip64Length += 8;
4697
- }
4698
- if (zip64CompressedSize) {
4699
- rawExtraFieldZip64Length += 8;
4700
- }
4701
- if (zip64Offset) {
4702
- rawExtraFieldZip64Length += 8;
4703
- }
4704
- if (zip64DiskNumberStart) {
4705
- rawExtraFieldZip64Length += 4;
4706
- }
4707
- rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
4708
- } else {
4709
- rawExtraFieldZip64 = new Uint8Array();
4710
- }
4711
4827
  setEntryInfo({
4712
4828
  signature,
4713
- rawExtraFieldZip64,
4714
4829
  compressedSize,
4715
4830
  uncompressedSize,
4716
4831
  headerInfo,
@@ -4732,8 +4847,8 @@
4732
4847
  compressionMethod,
4733
4848
  version,
4734
4849
  headerArray,
4850
+ headerView,
4735
4851
  signature,
4736
- rawExtraFieldZip64,
4737
4852
  extraFieldExtendedTimestampFlag,
4738
4853
  zip64UncompressedSize,
4739
4854
  zip64CompressedSize,
@@ -4758,10 +4873,62 @@
4758
4873
  rawExtraField,
4759
4874
  encryptionStrength,
4760
4875
  extendedTimestamp,
4761
- encrypted
4876
+ passThrough,
4877
+ encrypted,
4878
+ zip64UncompressedSize,
4879
+ zip64CompressedSize,
4880
+ zip64Offset,
4881
+ zip64DiskNumberStart,
4882
+ uncompressedSize,
4883
+ offset,
4884
+ diskNumberStart
4762
4885
  } = options;
4763
4886
  let { version, compressionMethod } = options;
4764
4887
  const compressed = !directory && (level > 0 || (level === UNDEFINED_VALUE && compressionMethod !== 0));
4888
+ let rawExtraFieldZip64;
4889
+ const uncompressedFile = passThrough || !compressed;
4890
+ const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
4891
+ if (zip64) {
4892
+ let rawExtraFieldZip64Length = 4;
4893
+ if (zip64UncompressedSize) {
4894
+ rawExtraFieldZip64Length += 8;
4895
+ }
4896
+ if (zip64CompressedSize) {
4897
+ rawExtraFieldZip64Length += 8;
4898
+ }
4899
+ if (zip64Offset) {
4900
+ rawExtraFieldZip64Length += 8;
4901
+ }
4902
+ if (zip64DiskNumberStart) {
4903
+ rawExtraFieldZip64Length += 4;
4904
+ }
4905
+ rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
4906
+ const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
4907
+ setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
4908
+ setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
4909
+ if (zip64ExtraFieldComplete) {
4910
+ const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
4911
+ let rawExtraFieldZip64Offset = 4;
4912
+ if (zip64UncompressedSize) {
4913
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
4914
+ rawExtraFieldZip64Offset += 8;
4915
+ }
4916
+ if (zip64CompressedSize && uncompressedFile) {
4917
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
4918
+ rawExtraFieldZip64Offset += 8;
4919
+ }
4920
+ if (zip64Offset) {
4921
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
4922
+ rawExtraFieldZip64Offset += 8;
4923
+ }
4924
+ if (zip64DiskNumberStart) {
4925
+ setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
4926
+ rawExtraFieldZip64Offset += 4;
4927
+ }
4928
+ }
4929
+ } else {
4930
+ rawExtraFieldZip64 = new Uint8Array();
4931
+ }
4765
4932
  let rawExtraFieldAES;
4766
4933
  if (encrypted && !zipCrypto) {
4767
4934
  rawExtraFieldAES = new Uint8Array(getLength(EXTRAFIELD_DATA_AES) + 2);
@@ -4810,69 +4977,52 @@
4810
4977
  } else {
4811
4978
  rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
4812
4979
  }
4813
- let bitFlag = 0;
4814
- if (useUnicodeFileNames) {
4815
- bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
4816
- }
4817
- if (dataDescriptor) {
4818
- bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
4819
- }
4820
4980
  if (compressionMethod === UNDEFINED_VALUE) {
4821
4981
  compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
4822
4982
  }
4823
- if (compressionMethod == COMPRESSION_METHOD_DEFLATE) {
4824
- if (level >= 1 && level < 3) {
4825
- bitFlag = bitFlag | 0b110;
4826
- }
4827
- if (level >= 3 && level < 5) {
4828
- bitFlag = bitFlag | 0b01;
4829
- }
4830
- if (level === 9) {
4831
- bitFlag = bitFlag | 0b10;
4832
- }
4833
- }
4834
4983
  if (zip64) {
4835
4984
  version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
4836
4985
  }
4837
- if (encrypted) {
4838
- bitFlag = bitFlag | BITFLAG_ENCRYPTED;
4839
- if (!zipCrypto) {
4840
- version = version > VERSION_AES ? version : VERSION_AES;
4841
- rawExtraFieldAES[9] = compressionMethod;
4842
- compressionMethod = COMPRESSION_METHOD_AES;
4843
- }
4844
- }
4845
- const headerArray = new Uint8Array(26);
4846
- const headerView = getDataView(headerArray);
4847
- setUint16(headerView, 0, version);
4848
- setUint16(headerView, 2, bitFlag);
4849
- setUint16(headerView, 4, compressionMethod);
4850
- const dateArray = new Uint32Array(1);
4851
- const dateView = getDataView(dateArray);
4852
- let lastModDateMsDos;
4853
- if (lastModDate < MIN_DATE) {
4854
- lastModDateMsDos = MIN_DATE;
4855
- } else if (lastModDate > MAX_DATE) {
4856
- lastModDateMsDos = MAX_DATE;
4857
- } else {
4858
- lastModDateMsDos = lastModDate;
4986
+ if (encrypted && !zipCrypto) {
4987
+ version = version > VERSION_AES ? version : VERSION_AES;
4988
+ rawExtraFieldAES[9] = compressionMethod;
4989
+ compressionMethod = COMPRESSION_METHOD_AES;
4859
4990
  }
4860
- setUint16(dateView, 0, (((lastModDateMsDos.getHours() << 6) | lastModDateMsDos.getMinutes()) << 5) | lastModDateMsDos.getSeconds() / 2);
4861
- setUint16(dateView, 2, ((((lastModDateMsDos.getFullYear() - 1980) << 4) | (lastModDateMsDos.getMonth() + 1)) << 5) | lastModDateMsDos.getDate());
4862
- const rawLastModDate = dateArray[0];
4863
- setUint32(headerView, 6, rawLastModDate);
4864
- setUint16(headerView, 22, getLength(rawFilename));
4865
- const extraFieldLength = getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
4866
- setUint16(headerView, 24, extraFieldLength);
4867
- const localHeaderArray = new Uint8Array(30 + getLength(rawFilename) + extraFieldLength);
4991
+ const localExtraFieldZip64Length = zip64ExtraFieldComplete ? getLength(rawExtraFieldZip64) : 0;
4992
+ const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
4993
+ const {
4994
+ headerArray,
4995
+ headerView,
4996
+ rawLastModDate
4997
+ } = getHeaderArrayData({
4998
+ version,
4999
+ bitflag: getBitflag(level, useUnicodeFileNames, dataDescriptor, encrypted),
5000
+ compressionMethod,
5001
+ uncompressedSize,
5002
+ lastModDate: lastModDate < MIN_DATE ? MIN_DATE : lastModDate > MAX_DATE ? MAX_DATE : lastModDate,
5003
+ rawFilename,
5004
+ zip64CompressedSize,
5005
+ zip64UncompressedSize,
5006
+ extraFieldLength
5007
+ });
5008
+ let localHeaderOffset = HEADER_SIZE + 4;
5009
+ const localHeaderArray = new Uint8Array(localHeaderOffset + getLength(rawFilename) + extraFieldLength);
4868
5010
  const localHeaderView = getDataView(localHeaderArray);
4869
5011
  setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE);
4870
5012
  arraySet(localHeaderArray, headerArray, 4);
4871
- arraySet(localHeaderArray, rawFilename, 30);
4872
- arraySet(localHeaderArray, rawExtraFieldAES, 30 + getLength(rawFilename));
4873
- arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, 30 + getLength(rawFilename, rawExtraFieldAES));
4874
- arraySet(localHeaderArray, rawExtraFieldNTFS, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp));
4875
- arraySet(localHeaderArray, rawExtraField, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS));
5013
+ arraySet(localHeaderArray, rawFilename, localHeaderOffset);
5014
+ localHeaderOffset += getLength(rawFilename);
5015
+ if (zip64ExtraFieldComplete) {
5016
+ arraySet(localHeaderArray, rawExtraFieldZip64, localHeaderOffset);
5017
+ }
5018
+ localHeaderOffset += localExtraFieldZip64Length;
5019
+ arraySet(localHeaderArray, rawExtraFieldAES, localHeaderOffset);
5020
+ localHeaderOffset += getLength(rawExtraFieldAES);
5021
+ arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, localHeaderOffset);
5022
+ localHeaderOffset += getLength(rawExtraFieldExtendedTimestamp);
5023
+ arraySet(localHeaderArray, rawExtraFieldNTFS, localHeaderOffset);
5024
+ localHeaderOffset += getLength(rawExtraFieldNTFS);
5025
+ arraySet(localHeaderArray, rawExtraField, localHeaderOffset);
4876
5026
  return {
4877
5027
  localHeaderArray,
4878
5028
  headerArray,
@@ -4884,6 +5034,8 @@
4884
5034
  version,
4885
5035
  compressionMethod,
4886
5036
  extraFieldExtendedTimestampFlag,
5037
+ rawExtraFieldZip64,
5038
+ localExtraFieldZip64Length,
4887
5039
  rawExtraFieldExtendedTimestamp,
4888
5040
  rawExtraFieldNTFS,
4889
5041
  rawExtraFieldAES,
@@ -4938,7 +5090,6 @@
4938
5090
  function setEntryInfo(entryInfo, options) {
4939
5091
  const {
4940
5092
  signature,
4941
- rawExtraFieldZip64,
4942
5093
  compressedSize,
4943
5094
  uncompressedSize,
4944
5095
  headerInfo,
@@ -4954,8 +5105,6 @@
4954
5105
  } = dataDescriptorInfo;
4955
5106
  const {
4956
5107
  zip64,
4957
- zip64UncompressedSize,
4958
- zip64CompressedSize,
4959
5108
  zipCrypto,
4960
5109
  dataDescriptor
4961
5110
  } = options;
@@ -4966,19 +5115,6 @@
4966
5115
  }
4967
5116
  }
4968
5117
  if (zip64) {
4969
- const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
4970
- setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
4971
- setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
4972
- let rawExtraFieldZip64Offset = 4;
4973
- if (zip64UncompressedSize) {
4974
- setUint32(headerView, 18, MAX_32_BITS);
4975
- setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
4976
- rawExtraFieldZip64Offset += 8;
4977
- }
4978
- if (zip64CompressedSize) {
4979
- setUint32(headerView, 14, MAX_32_BITS);
4980
- setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
4981
- }
4982
5118
  if (dataDescriptor) {
4983
5119
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
4984
5120
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
@@ -4993,44 +5129,82 @@
4993
5129
  }
4994
5130
  }
4995
5131
 
4996
- async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
5132
+ async function patchLocalHeader(fileEntry, entryData, writable, { zipCrypto, dataDescriptor }) {
5133
+ const {
5134
+ zip64,
5135
+ rawFilename,
5136
+ localExtraFieldZip64Length,
5137
+ signature,
5138
+ encrypted,
5139
+ zip64UncompressedSize,
5140
+ zip64CompressedSize,
5141
+ zip64Offset,
5142
+ zip64DiskNumberStart,
5143
+ uncompressedSize,
5144
+ compressedSize,
5145
+ offset,
5146
+ diskNumberStart
5147
+ } = fileEntry;
4997
5148
  let arrayBuffer;
4998
- arrayBuffer = await entryData.slice(0, 26).arrayBuffer();
4999
- if (arrayBuffer.byteLength != 26) {
5000
- arrayBuffer = arrayBuffer.slice(0, 26);
5149
+ let rawExtraFieldZip64Offset = HEADER_SIZE + 4 + getLength(rawFilename);
5150
+ const arrayBufferSize = zip64 && localExtraFieldZip64Length ? rawExtraFieldZip64Offset + localExtraFieldZip64Length : HEADER_SIZE;
5151
+ arrayBuffer = await entryData.slice(0, arrayBufferSize).arrayBuffer();
5152
+ if (arrayBuffer.byteLength != arrayBufferSize) {
5153
+ arrayBuffer = arrayBuffer.slice(0, arrayBufferSize);
5001
5154
  }
5002
5155
  const arrayBufferView = new DataView(arrayBuffer);
5003
- if (!fileEntry.encrypted || zipCrypto) {
5004
- setUint32(arrayBufferView, 14, fileEntry.signature);
5156
+ if (!dataDescriptor) {
5157
+ if (!encrypted || zipCrypto) {
5158
+ setUint32(arrayBufferView, 14, signature);
5159
+ }
5160
+ if (!zip64) {
5161
+ setUint32(arrayBufferView, 18, compressedSize);
5162
+ setUint32(arrayBufferView, 22, uncompressedSize);
5163
+ }
5005
5164
  }
5006
- if (fileEntry.zip64) {
5165
+ if (zip64) {
5007
5166
  setUint32(arrayBufferView, 18, MAX_32_BITS);
5008
5167
  setUint32(arrayBufferView, 22, MAX_32_BITS);
5009
- } else {
5010
- setUint32(arrayBufferView, 18, fileEntry.compressedSize);
5011
- setUint32(arrayBufferView, 22, fileEntry.uncompressedSize);
5168
+ if (localExtraFieldZip64Length) {
5169
+ rawExtraFieldZip64Offset += 4;
5170
+ if (zip64UncompressedSize) {
5171
+ setBigUint64(arrayBufferView, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
5172
+ rawExtraFieldZip64Offset += 8;
5173
+ }
5174
+ if (zip64CompressedSize) {
5175
+ setBigUint64(arrayBufferView, rawExtraFieldZip64Offset, BigInt(compressedSize));
5176
+ rawExtraFieldZip64Offset += 8;
5177
+ }
5178
+ if (zip64Offset) {
5179
+ setBigUint64(arrayBufferView, rawExtraFieldZip64Offset, BigInt(offset));
5180
+ rawExtraFieldZip64Offset += 8;
5181
+ }
5182
+ if (zip64DiskNumberStart) {
5183
+ setUint32(arrayBufferView, rawExtraFieldZip64Offset, diskNumberStart);
5184
+ }
5185
+ }
5012
5186
  }
5013
5187
  await writeData(writable, new Uint8Array(arrayBuffer));
5014
5188
  return entryData.slice(arrayBuffer.byteLength);
5015
5189
  }
5016
5190
 
5017
- function setZip64ExtraInfo(fileEntry, options) {
5018
- const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
5019
- const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
5020
- const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
5191
+ function setExtraFieldZip64Data(fileEntry) {
5192
+ const rawExtraFieldZip64View = getDataView(fileEntry.rawExtraFieldZip64);
5021
5193
  let rawExtraFieldZip64Offset = 4;
5022
- if (zip64UncompressedSize) {
5194
+ if (fileEntry.zip64UncompressedSize) {
5195
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(fileEntry.uncompressedSize));
5023
5196
  rawExtraFieldZip64Offset += 8;
5024
5197
  }
5025
- if (zip64CompressedSize) {
5198
+ if (fileEntry.zip64CompressedSize) {
5199
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(fileEntry.compressedSize));
5026
5200
  rawExtraFieldZip64Offset += 8;
5027
5201
  }
5028
- if (zip64Offset) {
5029
- setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
5202
+ if (fileEntry.zip64Offset) {
5203
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(fileEntry.offset));
5030
5204
  rawExtraFieldZip64Offset += 8;
5031
5205
  }
5032
- if (zip64DiskNumberStart) {
5033
- setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
5206
+ if (fileEntry.zip64DiskNumberStart) {
5207
+ setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, fileEntry.diskNumberStart);
5034
5208
  }
5035
5209
  }
5036
5210
 
@@ -5065,7 +5239,7 @@
5065
5239
  } else {
5066
5240
  rawExtraFieldTimestamp = new Uint8Array();
5067
5241
  }
5068
- fileEntry.rawExtraFieldCDExtendedTimestamp = rawExtraFieldTimestamp;
5242
+ fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
5069
5243
  directoryDataLength += 46 +
5070
5244
  getLength(
5071
5245
  rawFilename,
@@ -5086,12 +5260,13 @@
5086
5260
  rawFilename,
5087
5261
  rawExtraFieldZip64,
5088
5262
  rawExtraFieldAES,
5089
- rawExtraFieldCDExtendedTimestamp,
5263
+ rawExtraFieldExtendedTimestamp,
5090
5264
  rawExtraFieldNTFS,
5091
5265
  rawExtraField,
5092
5266
  rawComment,
5093
5267
  versionMadeBy,
5094
5268
  headerArray,
5269
+ headerView,
5095
5270
  zip64,
5096
5271
  zip64UncompressedSize,
5097
5272
  zip64CompressedSize,
@@ -5103,10 +5278,9 @@
5103
5278
  uncompressedSize,
5104
5279
  compressedSize
5105
5280
  } = fileEntry;
5106
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
5281
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
5107
5282
  setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
5108
5283
  setUint16(directoryView, offset + 4, versionMadeBy);
5109
- const headerView = getDataView(headerArray);
5110
5284
  if (!zip64UncompressedSize) {
5111
5285
  setUint32(headerView, 18, uncompressedSize);
5112
5286
  }
@@ -5114,28 +5288,40 @@
5114
5288
  setUint32(headerView, 14, compressedSize);
5115
5289
  }
5116
5290
  arraySet(directoryArray, headerArray, offset + 6);
5117
- setUint16(directoryView, offset + 30, extraFieldLength);
5118
- setUint16(directoryView, offset + 32, getLength(rawComment));
5119
- setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
5120
- setUint16(directoryView, offset + 36, internalFileAttributes);
5291
+ let directoryOffset = offset + HEADER_SIZE + 4;
5292
+ setUint16(directoryView, directoryOffset, extraFieldLength);
5293
+ directoryOffset += 2;
5294
+ setUint16(directoryView, directoryOffset, getLength(rawComment));
5295
+ directoryOffset += 2;
5296
+ setUint16(directoryView, directoryOffset, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
5297
+ directoryOffset += 2;
5298
+ setUint16(directoryView, directoryOffset, internalFileAttributes);
5299
+ directoryOffset += 2;
5121
5300
  if (externalFileAttributes) {
5122
- setUint32(directoryView, offset + 38, externalFileAttributes);
5123
- }
5124
- setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
5125
- arraySet(directoryArray, rawFilename, offset + 46);
5126
- arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
5127
- arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
5128
- arraySet(directoryArray, rawExtraFieldCDExtendedTimestamp, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES));
5129
- arraySet(directoryArray, rawExtraFieldNTFS, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp));
5130
- arraySet(directoryArray, rawExtraField, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS));
5131
- arraySet(directoryArray, rawComment, offset + 46 + getLength(rawFilename) + extraFieldLength);
5132
- const directoryEntryLength = 46 + getLength(rawFilename, rawComment) + extraFieldLength;
5301
+ setUint32(directoryView, directoryOffset, externalFileAttributes);
5302
+ }
5303
+ directoryOffset += 4;
5304
+ setUint32(directoryView, directoryOffset, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
5305
+ directoryOffset += 4;
5306
+ arraySet(directoryArray, rawFilename, directoryOffset);
5307
+ directoryOffset += getLength(rawFilename);
5308
+ arraySet(directoryArray, rawExtraFieldZip64, directoryOffset);
5309
+ directoryOffset += getLength(rawExtraFieldZip64);
5310
+ arraySet(directoryArray, rawExtraFieldAES, directoryOffset);
5311
+ directoryOffset += getLength(rawExtraFieldAES);
5312
+ arraySet(directoryArray, rawExtraFieldExtendedTimestamp, directoryOffset);
5313
+ directoryOffset += getLength(rawExtraFieldExtendedTimestamp);
5314
+ arraySet(directoryArray, rawExtraFieldNTFS, directoryOffset);
5315
+ directoryOffset += getLength(rawExtraFieldNTFS);
5316
+ arraySet(directoryArray, rawExtraField, directoryOffset);
5317
+ directoryOffset += getLength(rawExtraField);
5318
+ arraySet(directoryArray, rawComment, directoryOffset);
5133
5319
  if (offset - directoryDiskOffset > writer.availableSize) {
5134
5320
  writer.availableSize = 0;
5135
5321
  await writeData(writable, directoryArray.slice(directoryDiskOffset, offset));
5136
5322
  directoryDiskOffset = offset;
5137
5323
  }
5138
- offset += directoryEntryLength;
5324
+ offset = directoryOffset;
5139
5325
  if (options.onprogress) {
5140
5326
  try {
5141
5327
  await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
@@ -5263,6 +5449,67 @@
5263
5449
  return result;
5264
5450
  }
5265
5451
 
5452
+ function getHeaderArrayData({
5453
+ version,
5454
+ bitflag,
5455
+ compressionMethod,
5456
+ uncompressedSize,
5457
+ compressedSize,
5458
+ lastModDate,
5459
+ rawFilename,
5460
+ zip64CompressedSize,
5461
+ zip64UncompressedSize,
5462
+ extraFieldLength
5463
+ }) {
5464
+ const headerArray = new Uint8Array(HEADER_SIZE);
5465
+ const headerView = getDataView(headerArray);
5466
+ setUint16(headerView, 0, version);
5467
+ setUint16(headerView, 2, bitflag);
5468
+ setUint16(headerView, 4, compressionMethod);
5469
+ const dateArray = new Uint32Array(1);
5470
+ const dateView = getDataView(dateArray);
5471
+ setUint16(dateView, 0, (((lastModDate.getHours() << 6) | lastModDate.getMinutes()) << 5) | lastModDate.getSeconds() / 2);
5472
+ setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
5473
+ const rawLastModDate = dateArray[0];
5474
+ setUint32(headerView, 6, rawLastModDate);
5475
+ if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
5476
+ setUint32(headerView, 14, zip64CompressedSize ? MAX_32_BITS : compressedSize);
5477
+ }
5478
+ if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
5479
+ setUint32(headerView, 18, zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
5480
+ }
5481
+ setUint16(headerView, 22, getLength(rawFilename));
5482
+ setUint16(headerView, 24, extraFieldLength);
5483
+ return {
5484
+ headerArray,
5485
+ headerView,
5486
+ rawLastModDate
5487
+ };
5488
+ }
5489
+
5490
+ function getBitflag(level, useUnicodeFileNames, dataDescriptor, encrypted) {
5491
+ let bitFlag = 0;
5492
+ if (useUnicodeFileNames) {
5493
+ bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
5494
+ }
5495
+ if (dataDescriptor) {
5496
+ bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
5497
+ }
5498
+ if (level >= 1 && level < 3) {
5499
+ bitFlag = bitFlag | 0b110;
5500
+ }
5501
+ if (level >= 3 && level < 5) {
5502
+ bitFlag = bitFlag | 0b01;
5503
+ }
5504
+ if (level === 9) {
5505
+ bitFlag = bitFlag | 0b10;
5506
+ }
5507
+ if (encrypted) {
5508
+ bitFlag = bitFlag | BITFLAG_ENCRYPTED;
5509
+ }
5510
+ return bitFlag;
5511
+ }
5512
+
5266
5513
  /*
5267
5514
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
5268
5515
 
@@ -6009,9 +6256,8 @@
6009
6256
  });
6010
6257
  }
6011
6258
  }
6012
- await zipWriter.add(name, child.reader, Object.assign({
6013
- directory: child.directory
6014
- }, Object.assign({}, options, zipEntryOptions, childOptions, {
6259
+ await zipWriter.add(name, child.reader, Object.assign({}, options, zipEntryOptions, childOptions, {
6260
+ directory: child.directory,
6015
6261
  onprogress: async indexProgress => {
6016
6262
  if (options.onprogress) {
6017
6263
  entryOffsets.set(name, indexProgress);
@@ -6023,7 +6269,7 @@
6023
6269
  }
6024
6270
  }
6025
6271
  }
6026
- })));
6272
+ }));
6027
6273
  await process(zipWriter, child);
6028
6274
  }
6029
6275
  }
@@ -6199,6 +6445,7 @@
6199
6445
  exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
6200
6446
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
6201
6447
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
6448
+ exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
6202
6449
  exports.HttpRangeReader = HttpRangeReader;
6203
6450
  exports.HttpReader = HttpReader;
6204
6451
  exports.Reader = Reader;