@zip.js/zip.js 2.20.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.cts CHANGED
@@ -635,13 +635,6 @@ export interface WorkerConfiguration {
635
635
  * @defaultValue true
636
636
  */
637
637
  useCompressionStream?: boolean;
638
- /**
639
- * `true` to transfer stream ownership to web workers.
640
- *
641
- * @deprecated The option is ignored whatever its value: the data always crosses the worker boundary chunk by
642
- * chunk, transferring the streams instead was slower on every engine measured.
643
- */
644
- transferStreams?: boolean;
645
638
  }
646
639
 
647
640
  /**
@@ -1545,8 +1538,9 @@ export class ZipReader<Type> {
1545
1538
  * {@link WARNING_APPENDED_DATA}, {@link WARNING_PREPENDED_DATA}, {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA},
1546
1539
  * {@link WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET}, {@link WARNING_DUPLICATE_FILENAME} and
1547
1540
  * {@link WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY}.
1548
- * {@link WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY} is the one reason of that group which is never tolerated,
1549
- * so it is only ever the reason of an error. {@link WARNING_MISSING_ZIP64_EXTRA_FIELD} is deposited when an
1541
+ * {@link WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY} is never deposited as a warning: `"balanced"` rejects it
1542
+ * like `"strict"`, and `"tolerant"` reads the last record and reports the stale one as
1543
+ * {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA}. {@link WARNING_MISSING_ZIP64_EXTRA_FIELD} is deposited when an
1550
1544
  * entry cannot be read because its central directory record lacks a Zip64 extra field, and `"strict"` throws
1551
1545
  * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} for it.
1552
1546
  *
@@ -1889,7 +1883,10 @@ export interface ZipReaderOptions {
1889
1883
  * (e.g. streaming readers based on local file headers) interpret the entry differently. This detects mismatched
1890
1884
  * filenames, general purpose bit flags (encryption, data descriptor and language encoding flags), compression
1891
1885
  * methods, CRC-32 checksums and sizes. The extra fields are not compared because the zip specification allows
1892
- * them to differ.
1886
+ * them to differ. A local file header whose CRC-32 checksum and sizes are all zero without the data descriptor
1887
+ * flag is tolerated, because some streaming writers leave these fields blank. When the entry has a data
1888
+ * descriptor, its CRC-32 checksum and sizes are compared with the central directory record instead, provided
1889
+ * the descriptor is read, i.e. when {@link ZipReaderOptions#checkOverlappingEntry} is set.
1893
1890
  *
1894
1891
  * This is the boolean form of {@link ZipReaderOptions#strictness}: `true` means `"strict"` and `false` means
1895
1892
  * any value but `"strict"`. When both options are set, the value passed to {@link FileEntry#getData} takes
@@ -2566,11 +2563,13 @@ export interface EntryMetaData {
2566
2563
  */
2567
2564
  lastModDate: Date;
2568
2565
  /**
2569
- * The last access date.
2566
+ * The last access date, read from the extra fields of the central directory record or, when it holds none, from
2567
+ * the extra fields of the local file header once the data of the entry has been read.
2570
2568
  */
2571
2569
  lastAccessDate?: Date;
2572
2570
  /**
2573
- * The creation date.
2571
+ * The creation date, read from the extra fields of the central directory record or, when it holds none, from
2572
+ * the extra fields of the local file header once the data of the entry has been read.
2574
2573
  */
2575
2574
  creationDate?: Date;
2576
2575
  /**
@@ -3073,15 +3072,25 @@ export class ZipWriter<Type> {
3073
3072
  * @remarks
3074
3073
  * The data of the zip file is copied, its central directory is rebuilt and its entries are relocated to
3075
3074
  * the positions they get in the output. The disks of a split zip file passed as input are therefore unrelated to
3076
- * the disks of the output, which is a single zip file unless the writer is a split zip file writer. The data of
3075
+ * the disks of the output, which is a single zip file unless the writer is a split zip file writer. In that case,
3076
+ * the bytes before the first entry (e.g. a self-extracting stub) are copied after the split zip file signature of
3077
+ * the first disk, where no system runs them; use the {@link ZipWriterAppendZipOptions#filter} option to drop them. The data of
3077
3078
  * the entries is copied as-is; in particular, the constraints set by {@link ZipWriterConstructorOptions#usdz}
3078
- * are not applied to the copied entries.
3079
+ * are not applied to the copied entries. The comment and the digital signature of the zip file are not copied,
3080
+ * since its central directory is rebuilt: pass them to {@link ZipWriter#close}.
3079
3081
  *
3080
- * Pending {@link ZipWriter#add} calls are completed before the data is copied, and add() calls made
3081
- * while the copy is in progress are written after it. If an entry of the zip file has the same
3082
+ * Pending {@link ZipWriter#add} calls are completed before the data is copied. add() calls made while the
3083
+ * `filter` option runs are written before the copied entries, and add() calls made once the copy has started
3084
+ * are written after it. If an entry of the zip file has the same
3082
3085
  * filename as an entry of the current zip, the method throws with the `ERR_DUPLICATED_NAME` error
3083
3086
  * message and leaves the current zip unchanged; call {@link ZipWriter#remove} beforehand to resolve
3084
- * the conflicts.
3087
+ * the conflicts. The same error is thrown when two entries of the zip file share a filename, since a
3088
+ * `ZipWriter` holds one entry per filename: use the {@link ZipWriterAppendZipOptions#filter} option to
3089
+ * keep one of them. The entries passed to `filter` are not modified by the copy. An entry whose sizes or
3090
+ * offset are unusable because its Zip64 extra field is missing (see
3091
+ * {@link WARNING_MISSING_ZIP64_EXTRA_FIELD}) cannot be copied: the method throws
3092
+ * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} and leaves the current zip unchanged, unless the
3093
+ * {@link ZipWriterAppendZipOptions#filter} option leaves the entry out.
3085
3094
  *
3086
3095
  * The returned promise can safely be left un-awaited: {@link ZipWriter#close} waits for the copy
3087
3096
  * and throws its error if it was not caught.
@@ -3162,10 +3171,11 @@ export class ZipWriter<Type> {
3162
3171
  * Removes an entry from the central directory that will be written for the zip file. The entry
3163
3172
  * data itself cannot be removed because it has already been streamed to the output.
3164
3173
  *
3165
- * @param entry The entry to remove. This can be an {@link Entry} instance or the filename of the entry.
3174
+ * @param entry The entry to remove. This can be an {@link Entry} instance, the {@link EntryMetaData} returned by
3175
+ * {@link ZipWriter#add} or passed to the `filter` option of {@link ZipWriter#appendZip}, or the filename of the entry.
3166
3176
  * @returns `true` if the entry has been removed, `false` otherwise.
3167
3177
  */
3168
- remove(entry: Entry | string): boolean;
3178
+ remove(entry: EntryMetaData | string): boolean;
3169
3179
 
3170
3180
  /**
3171
3181
  * Writes the entries directory, writes the global comment, and returns the content of the zip file
@@ -3328,20 +3338,52 @@ export interface ZipWriterAppendZipOptions {
3328
3338
  /**
3329
3339
  * Selects the entries of the zip file to copy: the function is called once per entry, in the order of the
3330
3340
  * central directory, and the entry is copied when it returns (or resolves to) `true`. The function can read
3331
- * the data of the entry with {@link Entry#getData} to decide, the zip file is closed after the last call.
3341
+ * the data of the entry with {@link Entry#getData} to decide: every call completes before any data is copied.
3342
+ *
3343
+ * The second argument is the entry of the current zip which has the same filename, as {@link ZipWriter#add}
3344
+ * or a previous call to {@link ZipWriter#appendZip} left it, or `undefined` when there is none. It is the way to
3345
+ * apply a duplicate filename policy, since keeping both entries throws `ERR_DUPLICATED_NAME`: return
3346
+ * `!existingEntry` to keep the entry of the current zip, call {@link ZipWriter#remove} with `existingEntry` and
3347
+ * return `true` to replace it, or compare `crc32`, `uncompressedSize` or `lastModDate` to decide. An entry
3348
+ * being added concurrently by a pending {@link ZipWriter#add} call is not passed.
3332
3349
  *
3333
3350
  * @remarks
3334
3351
  * When the option is set, the data of the zip file is copied entry by entry and the entries left out leave no
3335
3352
  * bytes behind in the output, unlike {@link ZipWriter#remove}, which drops an entry from the central directory
3336
- * after its data has been written. The bytes of the zip file outside its entries, e.g. a self-extracting stub
3337
- * before the first entry, are not copied either. Without the option, the data of the zip file is copied as a
3338
- * whole. The duplicate filename check applies to the entries kept only, so an entry can be replaced by
3339
- * leaving it out and adding its replacement with {@link ZipWriter#add}.
3353
+ * after its data has been written. The bytes of the zip file outside the entries kept are not copied either:
3354
+ * a self-extracting stub, the data of entries removed earlier and the padding between entries, so a zip file
3355
+ * aligned with {@link ZipWriterConstructorOptions#usdz} is not aligned any more once filtered. Without the
3356
+ * option, the data of the zip file is copied as a whole. The duplicate filename check applies to the entries
3357
+ * kept only, so an entry can be replaced by leaving it out and adding its replacement with {@link ZipWriter#add}.
3358
+ *
3359
+ * An entry is copied from its local file header to the end of its data or, when it has one, of its data
3360
+ * descriptor, whose layout is read back from the zip file; when no layout matches, the entry is copied up to
3361
+ * the next entry or to the central directory. Before anything is written, each kept entry is checked to start
3362
+ * with a local file header and to end before the next entry or the central directory; otherwise the method
3363
+ * throws {@link ERR_LOCAL_FILE_HEADER_NOT_FOUND} or {@link ERR_OVERLAPPING_ENTRY} and leaves the current zip
3364
+ * unchanged. The same checks apply when the output is a split zip file, whose entries are copied one by one
3365
+ * as well.
3340
3366
  *
3341
3367
  * @param entry The entry read from the zip file.
3368
+ * @param existingEntry The entry of the current zip with the same filename, if any.
3342
3369
  * @returns `true` to copy the entry.
3343
3370
  */
3344
- filter?: (entry: Entry) => boolean | Promise<boolean>;
3371
+ filter?: (entry: Entry, existingEntry?: EntryMetaData) => boolean | Promise<boolean>;
3372
+ /**
3373
+ * The options of the {@link ZipReader} which reads the zip file.
3374
+ *
3375
+ * @remarks
3376
+ * The zip file is read with the default options otherwise, so a zip file which a `ZipReader` rejects by default
3377
+ * cannot be appended as-is: set {@link ZipReaderConstructorOptions#filenameValidation} or
3378
+ * {@link ZipReaderConstructorOptions#strictness} here to copy the entries of a zip file holding unsafe or
3379
+ * unusual filenames, {@link ZipReaderConstructorOptions#filenameEncoding} to decode the filenames the
3380
+ * duplicate check and the `filter` option see, and {@link ZipReaderConstructorOptions#password} to let
3381
+ * `filter` read the data of encrypted entries with {@link Entry#getData}. The bytes of the entries are copied
3382
+ * as-is whatever the options are.
3383
+ *
3384
+ * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
3385
+ */
3386
+ readerOptions?: ZipReaderConstructorOptions;
3345
3387
  }
3346
3388
 
3347
3389
  export interface ZipWriterCloseOptions extends EntryOnprogressOptions {
@@ -5046,6 +5088,9 @@ export const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: string;
5046
5088
  export const ERR_CENTRAL_DIRECTORY_NOT_FOUND: string;
5047
5089
  /**
5048
5090
  * Local file header not found error
5091
+ *
5092
+ * @remarks Also thrown by {@link ZipWriter#appendZip} when a copied entry does not point at a local file header
5093
+ * (see {@link ZipWriterAppendZipOptions#filter}).
5049
5094
  */
5050
5095
  export const ERR_LOCAL_FILE_HEADER_NOT_FOUND: string;
5051
5096
  /**
@@ -5059,7 +5104,8 @@ export const ERR_LOCAL_FILE_HEADER_NOT_FOUND: string;
5059
5104
  * {@link WARNING_MALFORMED_EXTRA_FIELD} on {@link EntryMetaData#warnings}, and an entry without a data descriptor
5060
5105
  * keeps the sentinels as its local sizes, which the local file header check reports as
5061
5106
  * {@link WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES}, an error or a warning depending on
5062
- * {@link ZipReaderOptions#strictness}.
5107
+ * {@link ZipReaderOptions#strictness}. Also thrown by {@link ZipWriter#appendZip}, before anything is written,
5108
+ * when an entry to copy lacks the field (see {@link WARNING_MISSING_ZIP64_EXTRA_FIELD}).
5063
5109
  */
5064
5110
  export const ERR_EXTRAFIELD_ZIP64_NOT_FOUND: string;
5065
5111
  /**
@@ -5281,13 +5327,16 @@ export const ERR_SPLIT_ZIP_FILE: string;
5281
5327
  *
5282
5328
  * @remarks Thrown by {@link FileEntry#getData} when {@link ZipReaderOptions#checkOverlappingEntry} is set and the
5283
5329
  * data of the entry overlaps the data of an entry already read. The thrown error carries the other entry in its
5284
- * `overlappingEntry` property.
5330
+ * `overlappingEntry` property. Also thrown by {@link ZipWriter#appendZip} when the data of a copied entry runs
5331
+ * into the next entry or into the central directory (see {@link ZipWriterAppendZipOptions#filter}).
5285
5332
  */
5286
5333
  export const ERR_OVERLAPPING_ENTRY: string;
5287
5334
  /**
5288
5335
  * Entry data out of bounds error
5289
5336
  *
5290
- * @remarks Thrown by {@link FileEntry#getData} when the declared extent of the entry data (i.e. its offset plus its compressed size) ends past the end of the zip file.
5337
+ * @remarks Thrown by {@link FileEntry#getData} when the declared extent of the entry data (i.e. its offset plus
5338
+ * its compressed size) ends past the central directory or past the end of the zip file, whatever
5339
+ * {@link ZipReaderOptions#strictness} and {@link ZipReaderOptions#checkOverlappingEntry} are set to.
5291
5340
  */
5292
5341
  export const ERR_ENTRY_DATA_OUT_OF_BOUNDS: string;
5293
5342
  /**
@@ -5295,7 +5344,8 @@ export const ERR_ENTRY_DATA_OUT_OF_BOUNDS: string;
5295
5344
  *
5296
5345
  * @remarks The thrown error carries a `reason` property describing the ambiguity: `"appended data"`,
5297
5346
  * `"prepended data"`, `"trailing central directory data"`, `"multiple end of central directory records"`,
5298
- * `"mismatched zip64 end of central directory record"`, `"duplicate filename"`, or, when
5347
+ * `"mismatched central directory offset"`, `"mismatched zip64 end of central directory record"`,
5348
+ * `"duplicate filename"`, or, when
5299
5349
  * {@link ZipReaderOptions#checkLocalDirectory} compares the local header of an entry with its central
5300
5350
  * directory record, `"mismatched local file header (filename)"`,
5301
5351
  * `"mismatched local file header (general purpose bit flag)"`,
@@ -5477,7 +5527,8 @@ export const ERR_UNSUPPORTED_PASS_THROUGH_VALUE: string;
5477
5527
  /**
5478
5528
  * Invalid readerOptions error (thrown by `{@link ZipDirectoryEntry}#export*()`,
5479
5529
  * {@link ZipDirectoryEntry#getExportedSize} and {@link ZipDirectoryEntry#exportFileSystemHandle} when the
5480
- * {@link ZipDirectoryEntryExportOptions#readerOptions} option is neither an object nor unset)
5530
+ * {@link ZipDirectoryEntryExportOptions#readerOptions} option is neither an object nor unset, and by
5531
+ * {@link ZipWriter#appendZip} for {@link ZipWriterAppendZipOptions#readerOptions})
5481
5532
  *
5482
5533
  * @remarks A value of another type was silently ignored: a password passed as a string instead of an object failed
5483
5534
  * with the unrelated {@link ERR_ENCRYPTED}, while the other options were dropped without any error. Note that an
@@ -5637,24 +5688,26 @@ export const WARNING_PREPENDED_CENTRAL_DIRECTORY: string;
5637
5688
  */
5638
5689
  export const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: string;
5639
5690
  /**
5640
- * Warning reason: the end of central directory record stores a central directory offset that points past the
5641
- * central directory actually found before it, so the archive was read from the directory found rather than from
5642
- * the stored offset (see {@link ZipReader#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5691
+ * Warning reason: the end of central directory record stores a central directory offset that does not point at
5692
+ * the central directory actually found before it, so the archive was read from the directory found rather than
5693
+ * from the stored offset (see {@link ZipReader#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5643
5694
  * `strictness: "strict"`
5644
5695
  *
5645
5696
  * @remarks
5646
5697
  * Such an archive is typically one written with absolute offsets for a prefix that is no longer there, e.g. a
5647
- * self-extracting archive whose stub was removed. When the local file header of the first entry is found at
5648
- * the same shifted position, the entries are read from the shifted positions; otherwise the offsets stored in
5649
- * the central directory are used as they are.
5698
+ * self-extracting archive whose stub was removed, or one whose end of central directory record was damaged.
5699
+ * When the local file header of the first entry is found at the same shifted position only, the entries are
5700
+ * read from the shifted positions; otherwise the offsets stored in the central directory are used as they are.
5701
+ * A stored offset short of the directory whose entries are found at the shifted positions is diagnosed as
5702
+ * {@link WARNING_PREPENDED_DATA} instead.
5650
5703
  */
5651
5704
  export const WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET: string;
5652
5705
  /**
5653
5706
  * Warning reason: a central directory record holds the Zip64 sentinel in a size, offset or disk number field
5654
5707
  * but carries no Zip64 extra field resolving it (see {@link ZipReader#warnings}). The entry is listed, its
5655
- * sizes and offset are unusable, and reading its data throws {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND}; the
5656
- * other entries are unaffected. Under `strictness: "strict"`, {@link ZipReader#getEntries} throws
5657
- * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} instead.
5708
+ * sizes and offset are unusable, and reading its data or copying it with {@link ZipWriter#appendZip} throws
5709
+ * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND}; the other entries are unaffected. Under `strictness: "strict"`,
5710
+ * {@link ZipReader#getEntries} throws {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} instead.
5658
5711
  */
5659
5712
  export const WARNING_MISSING_ZIP64_EXTRA_FIELD: string;
5660
5713
  /**
@@ -5669,8 +5722,9 @@ export const WARNING_DUPLICATE_FILENAME: string;
5669
5722
  export const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: string;
5670
5723
  /**
5671
5724
  * Warning reason: more than one end of central directory record reaches the end of the file, so another reader
5672
- * may select a different one and list different entries; the reason of {@link ERR_AMBIGUOUS_ARCHIVE} when
5673
- * {@link ZipReaderOptions#checkAmbiguity} is enabled
5725
+ * may select a different one and list different entries; the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5726
+ * `strictness: "strict"` and `"balanced"`. It is never deposited as a warning: `"tolerant"` reads the last
5727
+ * record and reports the stale one as {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA}.
5674
5728
  */
5675
5729
  export const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: string;
5676
5730
  /**
@@ -5694,7 +5748,8 @@ export const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: string;
5694
5748
  */
5695
5749
  export const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: string;
5696
5750
  /**
5697
- * Warning reason: the crc32 or the sizes of the local file header contradict the central directory
5751
+ * Warning reason: the crc32 or the sizes of the local file header, or of the data descriptor when it is read
5752
+ * (see {@link ZipReaderOptions#checkOverlappingEntry}), contradict the central directory
5698
5753
  * (see {@link EntryMetaData#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} when
5699
5754
  * {@link ZipReaderOptions#checkLocalDirectory} is enabled
5700
5755
  */
package/index.d.ts CHANGED
@@ -635,13 +635,6 @@ export interface WorkerConfiguration {
635
635
  * @defaultValue true
636
636
  */
637
637
  useCompressionStream?: boolean;
638
- /**
639
- * `true` to transfer stream ownership to web workers.
640
- *
641
- * @deprecated The option is ignored whatever its value: the data always crosses the worker boundary chunk by
642
- * chunk, transferring the streams instead was slower on every engine measured.
643
- */
644
- transferStreams?: boolean;
645
638
  }
646
639
 
647
640
  /**
@@ -1545,8 +1538,9 @@ export class ZipReader<Type> {
1545
1538
  * {@link WARNING_APPENDED_DATA}, {@link WARNING_PREPENDED_DATA}, {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA},
1546
1539
  * {@link WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET}, {@link WARNING_DUPLICATE_FILENAME} and
1547
1540
  * {@link WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY}.
1548
- * {@link WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY} is the one reason of that group which is never tolerated,
1549
- * so it is only ever the reason of an error. {@link WARNING_MISSING_ZIP64_EXTRA_FIELD} is deposited when an
1541
+ * {@link WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY} is never deposited as a warning: `"balanced"` rejects it
1542
+ * like `"strict"`, and `"tolerant"` reads the last record and reports the stale one as
1543
+ * {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA}. {@link WARNING_MISSING_ZIP64_EXTRA_FIELD} is deposited when an
1550
1544
  * entry cannot be read because its central directory record lacks a Zip64 extra field, and `"strict"` throws
1551
1545
  * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} for it.
1552
1546
  *
@@ -1889,7 +1883,10 @@ export interface ZipReaderOptions {
1889
1883
  * (e.g. streaming readers based on local file headers) interpret the entry differently. This detects mismatched
1890
1884
  * filenames, general purpose bit flags (encryption, data descriptor and language encoding flags), compression
1891
1885
  * methods, CRC-32 checksums and sizes. The extra fields are not compared because the zip specification allows
1892
- * them to differ.
1886
+ * them to differ. A local file header whose CRC-32 checksum and sizes are all zero without the data descriptor
1887
+ * flag is tolerated, because some streaming writers leave these fields blank. When the entry has a data
1888
+ * descriptor, its CRC-32 checksum and sizes are compared with the central directory record instead, provided
1889
+ * the descriptor is read, i.e. when {@link ZipReaderOptions#checkOverlappingEntry} is set.
1893
1890
  *
1894
1891
  * This is the boolean form of {@link ZipReaderOptions#strictness}: `true` means `"strict"` and `false` means
1895
1892
  * any value but `"strict"`. When both options are set, the value passed to {@link FileEntry#getData} takes
@@ -2566,11 +2563,13 @@ export interface EntryMetaData {
2566
2563
  */
2567
2564
  lastModDate: Date;
2568
2565
  /**
2569
- * The last access date.
2566
+ * The last access date, read from the extra fields of the central directory record or, when it holds none, from
2567
+ * the extra fields of the local file header once the data of the entry has been read.
2570
2568
  */
2571
2569
  lastAccessDate?: Date;
2572
2570
  /**
2573
- * The creation date.
2571
+ * The creation date, read from the extra fields of the central directory record or, when it holds none, from
2572
+ * the extra fields of the local file header once the data of the entry has been read.
2574
2573
  */
2575
2574
  creationDate?: Date;
2576
2575
  /**
@@ -3073,15 +3072,25 @@ export class ZipWriter<Type> {
3073
3072
  * @remarks
3074
3073
  * The data of the zip file is copied, its central directory is rebuilt and its entries are relocated to
3075
3074
  * the positions they get in the output. The disks of a split zip file passed as input are therefore unrelated to
3076
- * the disks of the output, which is a single zip file unless the writer is a split zip file writer. The data of
3075
+ * the disks of the output, which is a single zip file unless the writer is a split zip file writer. In that case,
3076
+ * the bytes before the first entry (e.g. a self-extracting stub) are copied after the split zip file signature of
3077
+ * the first disk, where no system runs them; use the {@link ZipWriterAppendZipOptions#filter} option to drop them. The data of
3077
3078
  * the entries is copied as-is; in particular, the constraints set by {@link ZipWriterConstructorOptions#usdz}
3078
- * are not applied to the copied entries.
3079
+ * are not applied to the copied entries. The comment and the digital signature of the zip file are not copied,
3080
+ * since its central directory is rebuilt: pass them to {@link ZipWriter#close}.
3079
3081
  *
3080
- * Pending {@link ZipWriter#add} calls are completed before the data is copied, and add() calls made
3081
- * while the copy is in progress are written after it. If an entry of the zip file has the same
3082
+ * Pending {@link ZipWriter#add} calls are completed before the data is copied. add() calls made while the
3083
+ * `filter` option runs are written before the copied entries, and add() calls made once the copy has started
3084
+ * are written after it. If an entry of the zip file has the same
3082
3085
  * filename as an entry of the current zip, the method throws with the `ERR_DUPLICATED_NAME` error
3083
3086
  * message and leaves the current zip unchanged; call {@link ZipWriter#remove} beforehand to resolve
3084
- * the conflicts.
3087
+ * the conflicts. The same error is thrown when two entries of the zip file share a filename, since a
3088
+ * `ZipWriter` holds one entry per filename: use the {@link ZipWriterAppendZipOptions#filter} option to
3089
+ * keep one of them. The entries passed to `filter` are not modified by the copy. An entry whose sizes or
3090
+ * offset are unusable because its Zip64 extra field is missing (see
3091
+ * {@link WARNING_MISSING_ZIP64_EXTRA_FIELD}) cannot be copied: the method throws
3092
+ * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} and leaves the current zip unchanged, unless the
3093
+ * {@link ZipWriterAppendZipOptions#filter} option leaves the entry out.
3085
3094
  *
3086
3095
  * The returned promise can safely be left un-awaited: {@link ZipWriter#close} waits for the copy
3087
3096
  * and throws its error if it was not caught.
@@ -3162,10 +3171,11 @@ export class ZipWriter<Type> {
3162
3171
  * Removes an entry from the central directory that will be written for the zip file. The entry
3163
3172
  * data itself cannot be removed because it has already been streamed to the output.
3164
3173
  *
3165
- * @param entry The entry to remove. This can be an {@link Entry} instance or the filename of the entry.
3174
+ * @param entry The entry to remove. This can be an {@link Entry} instance, the {@link EntryMetaData} returned by
3175
+ * {@link ZipWriter#add} or passed to the `filter` option of {@link ZipWriter#appendZip}, or the filename of the entry.
3166
3176
  * @returns `true` if the entry has been removed, `false` otherwise.
3167
3177
  */
3168
- remove(entry: Entry | string): boolean;
3178
+ remove(entry: EntryMetaData | string): boolean;
3169
3179
 
3170
3180
  /**
3171
3181
  * Writes the entries directory, writes the global comment, and returns the content of the zip file
@@ -3328,20 +3338,52 @@ export interface ZipWriterAppendZipOptions {
3328
3338
  /**
3329
3339
  * Selects the entries of the zip file to copy: the function is called once per entry, in the order of the
3330
3340
  * central directory, and the entry is copied when it returns (or resolves to) `true`. The function can read
3331
- * the data of the entry with {@link Entry#getData} to decide, the zip file is closed after the last call.
3341
+ * the data of the entry with {@link Entry#getData} to decide: every call completes before any data is copied.
3342
+ *
3343
+ * The second argument is the entry of the current zip which has the same filename, as {@link ZipWriter#add}
3344
+ * or a previous call to {@link ZipWriter#appendZip} left it, or `undefined` when there is none. It is the way to
3345
+ * apply a duplicate filename policy, since keeping both entries throws `ERR_DUPLICATED_NAME`: return
3346
+ * `!existingEntry` to keep the entry of the current zip, call {@link ZipWriter#remove} with `existingEntry` and
3347
+ * return `true` to replace it, or compare `crc32`, `uncompressedSize` or `lastModDate` to decide. An entry
3348
+ * being added concurrently by a pending {@link ZipWriter#add} call is not passed.
3332
3349
  *
3333
3350
  * @remarks
3334
3351
  * When the option is set, the data of the zip file is copied entry by entry and the entries left out leave no
3335
3352
  * bytes behind in the output, unlike {@link ZipWriter#remove}, which drops an entry from the central directory
3336
- * after its data has been written. The bytes of the zip file outside its entries, e.g. a self-extracting stub
3337
- * before the first entry, are not copied either. Without the option, the data of the zip file is copied as a
3338
- * whole. The duplicate filename check applies to the entries kept only, so an entry can be replaced by
3339
- * leaving it out and adding its replacement with {@link ZipWriter#add}.
3353
+ * after its data has been written. The bytes of the zip file outside the entries kept are not copied either:
3354
+ * a self-extracting stub, the data of entries removed earlier and the padding between entries, so a zip file
3355
+ * aligned with {@link ZipWriterConstructorOptions#usdz} is not aligned any more once filtered. Without the
3356
+ * option, the data of the zip file is copied as a whole. The duplicate filename check applies to the entries
3357
+ * kept only, so an entry can be replaced by leaving it out and adding its replacement with {@link ZipWriter#add}.
3358
+ *
3359
+ * An entry is copied from its local file header to the end of its data or, when it has one, of its data
3360
+ * descriptor, whose layout is read back from the zip file; when no layout matches, the entry is copied up to
3361
+ * the next entry or to the central directory. Before anything is written, each kept entry is checked to start
3362
+ * with a local file header and to end before the next entry or the central directory; otherwise the method
3363
+ * throws {@link ERR_LOCAL_FILE_HEADER_NOT_FOUND} or {@link ERR_OVERLAPPING_ENTRY} and leaves the current zip
3364
+ * unchanged. The same checks apply when the output is a split zip file, whose entries are copied one by one
3365
+ * as well.
3340
3366
  *
3341
3367
  * @param entry The entry read from the zip file.
3368
+ * @param existingEntry The entry of the current zip with the same filename, if any.
3342
3369
  * @returns `true` to copy the entry.
3343
3370
  */
3344
- filter?: (entry: Entry) => boolean | Promise<boolean>;
3371
+ filter?: (entry: Entry, existingEntry?: EntryMetaData) => boolean | Promise<boolean>;
3372
+ /**
3373
+ * The options of the {@link ZipReader} which reads the zip file.
3374
+ *
3375
+ * @remarks
3376
+ * The zip file is read with the default options otherwise, so a zip file which a `ZipReader` rejects by default
3377
+ * cannot be appended as-is: set {@link ZipReaderConstructorOptions#filenameValidation} or
3378
+ * {@link ZipReaderConstructorOptions#strictness} here to copy the entries of a zip file holding unsafe or
3379
+ * unusual filenames, {@link ZipReaderConstructorOptions#filenameEncoding} to decode the filenames the
3380
+ * duplicate check and the `filter` option see, and {@link ZipReaderConstructorOptions#password} to let
3381
+ * `filter` read the data of encrypted entries with {@link Entry#getData}. The bytes of the entries are copied
3382
+ * as-is whatever the options are.
3383
+ *
3384
+ * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
3385
+ */
3386
+ readerOptions?: ZipReaderConstructorOptions;
3345
3387
  }
3346
3388
 
3347
3389
  export interface ZipWriterCloseOptions extends EntryOnprogressOptions {
@@ -5046,6 +5088,9 @@ export const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: string;
5046
5088
  export const ERR_CENTRAL_DIRECTORY_NOT_FOUND: string;
5047
5089
  /**
5048
5090
  * Local file header not found error
5091
+ *
5092
+ * @remarks Also thrown by {@link ZipWriter#appendZip} when a copied entry does not point at a local file header
5093
+ * (see {@link ZipWriterAppendZipOptions#filter}).
5049
5094
  */
5050
5095
  export const ERR_LOCAL_FILE_HEADER_NOT_FOUND: string;
5051
5096
  /**
@@ -5059,7 +5104,8 @@ export const ERR_LOCAL_FILE_HEADER_NOT_FOUND: string;
5059
5104
  * {@link WARNING_MALFORMED_EXTRA_FIELD} on {@link EntryMetaData#warnings}, and an entry without a data descriptor
5060
5105
  * keeps the sentinels as its local sizes, which the local file header check reports as
5061
5106
  * {@link WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES}, an error or a warning depending on
5062
- * {@link ZipReaderOptions#strictness}.
5107
+ * {@link ZipReaderOptions#strictness}. Also thrown by {@link ZipWriter#appendZip}, before anything is written,
5108
+ * when an entry to copy lacks the field (see {@link WARNING_MISSING_ZIP64_EXTRA_FIELD}).
5063
5109
  */
5064
5110
  export const ERR_EXTRAFIELD_ZIP64_NOT_FOUND: string;
5065
5111
  /**
@@ -5281,13 +5327,16 @@ export const ERR_SPLIT_ZIP_FILE: string;
5281
5327
  *
5282
5328
  * @remarks Thrown by {@link FileEntry#getData} when {@link ZipReaderOptions#checkOverlappingEntry} is set and the
5283
5329
  * data of the entry overlaps the data of an entry already read. The thrown error carries the other entry in its
5284
- * `overlappingEntry` property.
5330
+ * `overlappingEntry` property. Also thrown by {@link ZipWriter#appendZip} when the data of a copied entry runs
5331
+ * into the next entry or into the central directory (see {@link ZipWriterAppendZipOptions#filter}).
5285
5332
  */
5286
5333
  export const ERR_OVERLAPPING_ENTRY: string;
5287
5334
  /**
5288
5335
  * Entry data out of bounds error
5289
5336
  *
5290
- * @remarks Thrown by {@link FileEntry#getData} when the declared extent of the entry data (i.e. its offset plus its compressed size) ends past the end of the zip file.
5337
+ * @remarks Thrown by {@link FileEntry#getData} when the declared extent of the entry data (i.e. its offset plus
5338
+ * its compressed size) ends past the central directory or past the end of the zip file, whatever
5339
+ * {@link ZipReaderOptions#strictness} and {@link ZipReaderOptions#checkOverlappingEntry} are set to.
5291
5340
  */
5292
5341
  export const ERR_ENTRY_DATA_OUT_OF_BOUNDS: string;
5293
5342
  /**
@@ -5295,7 +5344,8 @@ export const ERR_ENTRY_DATA_OUT_OF_BOUNDS: string;
5295
5344
  *
5296
5345
  * @remarks The thrown error carries a `reason` property describing the ambiguity: `"appended data"`,
5297
5346
  * `"prepended data"`, `"trailing central directory data"`, `"multiple end of central directory records"`,
5298
- * `"mismatched zip64 end of central directory record"`, `"duplicate filename"`, or, when
5347
+ * `"mismatched central directory offset"`, `"mismatched zip64 end of central directory record"`,
5348
+ * `"duplicate filename"`, or, when
5299
5349
  * {@link ZipReaderOptions#checkLocalDirectory} compares the local header of an entry with its central
5300
5350
  * directory record, `"mismatched local file header (filename)"`,
5301
5351
  * `"mismatched local file header (general purpose bit flag)"`,
@@ -5477,7 +5527,8 @@ export const ERR_UNSUPPORTED_PASS_THROUGH_VALUE: string;
5477
5527
  /**
5478
5528
  * Invalid readerOptions error (thrown by `{@link ZipDirectoryEntry}#export*()`,
5479
5529
  * {@link ZipDirectoryEntry#getExportedSize} and {@link ZipDirectoryEntry#exportFileSystemHandle} when the
5480
- * {@link ZipDirectoryEntryExportOptions#readerOptions} option is neither an object nor unset)
5530
+ * {@link ZipDirectoryEntryExportOptions#readerOptions} option is neither an object nor unset, and by
5531
+ * {@link ZipWriter#appendZip} for {@link ZipWriterAppendZipOptions#readerOptions})
5481
5532
  *
5482
5533
  * @remarks A value of another type was silently ignored: a password passed as a string instead of an object failed
5483
5534
  * with the unrelated {@link ERR_ENCRYPTED}, while the other options were dropped without any error. Note that an
@@ -5637,24 +5688,26 @@ export const WARNING_PREPENDED_CENTRAL_DIRECTORY: string;
5637
5688
  */
5638
5689
  export const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: string;
5639
5690
  /**
5640
- * Warning reason: the end of central directory record stores a central directory offset that points past the
5641
- * central directory actually found before it, so the archive was read from the directory found rather than from
5642
- * the stored offset (see {@link ZipReader#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5691
+ * Warning reason: the end of central directory record stores a central directory offset that does not point at
5692
+ * the central directory actually found before it, so the archive was read from the directory found rather than
5693
+ * from the stored offset (see {@link ZipReader#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5643
5694
  * `strictness: "strict"`
5644
5695
  *
5645
5696
  * @remarks
5646
5697
  * Such an archive is typically one written with absolute offsets for a prefix that is no longer there, e.g. a
5647
- * self-extracting archive whose stub was removed. When the local file header of the first entry is found at
5648
- * the same shifted position, the entries are read from the shifted positions; otherwise the offsets stored in
5649
- * the central directory are used as they are.
5698
+ * self-extracting archive whose stub was removed, or one whose end of central directory record was damaged.
5699
+ * When the local file header of the first entry is found at the same shifted position only, the entries are
5700
+ * read from the shifted positions; otherwise the offsets stored in the central directory are used as they are.
5701
+ * A stored offset short of the directory whose entries are found at the shifted positions is diagnosed as
5702
+ * {@link WARNING_PREPENDED_DATA} instead.
5650
5703
  */
5651
5704
  export const WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET: string;
5652
5705
  /**
5653
5706
  * Warning reason: a central directory record holds the Zip64 sentinel in a size, offset or disk number field
5654
5707
  * but carries no Zip64 extra field resolving it (see {@link ZipReader#warnings}). The entry is listed, its
5655
- * sizes and offset are unusable, and reading its data throws {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND}; the
5656
- * other entries are unaffected. Under `strictness: "strict"`, {@link ZipReader#getEntries} throws
5657
- * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} instead.
5708
+ * sizes and offset are unusable, and reading its data or copying it with {@link ZipWriter#appendZip} throws
5709
+ * {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND}; the other entries are unaffected. Under `strictness: "strict"`,
5710
+ * {@link ZipReader#getEntries} throws {@link ERR_EXTRAFIELD_ZIP64_NOT_FOUND} instead.
5658
5711
  */
5659
5712
  export const WARNING_MISSING_ZIP64_EXTRA_FIELD: string;
5660
5713
  /**
@@ -5669,8 +5722,9 @@ export const WARNING_DUPLICATE_FILENAME: string;
5669
5722
  export const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: string;
5670
5723
  /**
5671
5724
  * Warning reason: more than one end of central directory record reaches the end of the file, so another reader
5672
- * may select a different one and list different entries; the reason of {@link ERR_AMBIGUOUS_ARCHIVE} when
5673
- * {@link ZipReaderOptions#checkAmbiguity} is enabled
5725
+ * may select a different one and list different entries; the reason of {@link ERR_AMBIGUOUS_ARCHIVE} under
5726
+ * `strictness: "strict"` and `"balanced"`. It is never deposited as a warning: `"tolerant"` reads the last
5727
+ * record and reports the stale one as {@link WARNING_TRAILING_CENTRAL_DIRECTORY_DATA}.
5674
5728
  */
5675
5729
  export const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: string;
5676
5730
  /**
@@ -5694,7 +5748,8 @@ export const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: string;
5694
5748
  */
5695
5749
  export const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: string;
5696
5750
  /**
5697
- * Warning reason: the crc32 or the sizes of the local file header contradict the central directory
5751
+ * Warning reason: the crc32 or the sizes of the local file header, or of the data descriptor when it is read
5752
+ * (see {@link ZipReaderOptions#checkOverlappingEntry}), contradict the central directory
5698
5753
  * (see {@link EntryMetaData#warnings}); the reason of {@link ERR_AMBIGUOUS_ARCHIVE} when
5699
5754
  * {@link ZipReaderOptions#checkLocalDirectory} is enabled
5700
5755
  */