@zip.js/zip.js 2.13.0 → 2.14.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.
Files changed (50) hide show
  1. package/BENCHMARKS.md +46 -1
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +594 -935
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +461 -908
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +601 -938
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +468 -911
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +601 -938
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +470 -913
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +604 -941
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +463 -910
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-module.wasm +0 -0
  20. package/dist/zip-native.js +463 -910
  21. package/dist/zip-native.min.js +1 -1
  22. package/dist/zip-web-worker-native.js +1 -1
  23. package/dist/zip-web-worker.js +1 -1
  24. package/dist/zip.js +597 -938
  25. package/dist/zip.min.js +1 -1
  26. package/index-native.cjs +470 -913
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +604 -941
  29. package/index.d.cts +58 -12
  30. package/index.d.ts +58 -12
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-worker-web.js +35 -11
  33. package/lib/core/codec-worker.js +33 -23
  34. package/lib/core/io.js +29 -21
  35. package/lib/core/streams/aes-crypto-stream.js +58 -99
  36. package/lib/core/streams/codecs/aes-hmac-sha1.js +348 -0
  37. package/lib/core/streams/zlib-wasm/aes-hmac-sha1-wasm.js +106 -0
  38. package/lib/core/streams/zlib-wasm/zlib-streams-loader.js +4 -0
  39. package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
  40. package/lib/core/version.js +1 -1
  41. package/lib/core/web-worker-base.js +15 -9
  42. package/lib/core/web-worker-inline-native.js +1 -1
  43. package/lib/core/web-worker-inline-wasm.js +1 -1
  44. package/lib/core/web-worker-wasm.js +2 -0
  45. package/lib/core/zip-fs.js +7 -3
  46. package/lib/core/zip-writer.js +1 -2
  47. package/lib/core/zlib-streams-inline.js +1 -1
  48. package/lib/zip-module-wasm-base.js +3 -1
  49. package/package.json +1 -1
  50. package/lib/core/streams/codecs/sjcl.js +0 -795
package/index.d.cts CHANGED
@@ -1043,7 +1043,13 @@ export interface HttpOptions extends HttpRangeOptions {
1043
1043
  */
1044
1044
  preventHeadRequest?: boolean;
1045
1045
  /**
1046
- * `true` to use `Range: bytes=-22` on the first request and cache the EOCD, make sure beforehand that the server supports a suffix range request.
1046
+ * `true` to read the end of the archive with the same request that gives its size, and to serve the later reads
1047
+ * landing in that range from the response instead of requesting them again, make sure beforehand that the server
1048
+ * supports a suffix range request.
1049
+ *
1050
+ * The request asks for the last 65,557 bytes, which is how far back the reader scans for the end of central directory
1051
+ * record, so it fetches nothing the reader was not going to read anyway. An archive shorter than that is fetched
1052
+ * whole, and reading it then costs a single request.
1047
1053
  *
1048
1054
  * @defaultValue false
1049
1055
  */
@@ -1108,10 +1114,14 @@ export interface WritableWriter {
1108
1114
  */
1109
1115
  writable: WritableStream;
1110
1116
  /**
1111
- * The number of bytes written into the instance. It is set to 0 before the first write and
1112
- * updated as the data is written, so a writer needing the value (e.g. to compute the offset of a
1113
- * disk) can read it. A value set before the first write is kept and used as the starting offset
1114
- * instead of being reset to 0.
1117
+ * The number of bytes written into the instance. It is set to 0 before the first write, and a value
1118
+ * set beforehand is kept and used as the starting offset instead of being reset to 0.
1119
+ *
1120
+ * The bytes of a section are added once that section is written, so the value is settled between
1121
+ * entries rather than after every chunk: an instance reading it from its own `write()` method sees
1122
+ * the total of the sections already finished. The exception is an instance yielded by a generator of
1123
+ * split disks, which is updated on each chunk written to it, so it can compute the offset of the disk
1124
+ * it is filling.
1115
1125
  *
1116
1126
  * It must therefore be assignable, see {@link ERR_WRITER_SIZE_NOT_WRITABLE}: a getter with no setter
1117
1127
  * is rejected when the writer is passed, not once the first entry has been written.
@@ -2378,6 +2388,12 @@ export interface EntryError extends Error {
2378
2388
  * failure reason cannot carry it, which does not affect the salvage described in
2379
2389
  * {@link ZipWriter#close}: zip.js tracks the size of a failed entry on its own, so the offsets of
2380
2390
  * the entries written afterwards stay correct whatever the reason a stream was aborted with.
2391
+ *
2392
+ * When a stream is aborted or cancelled, the reason the caller passed is what reaches the caller
2393
+ * back, unchanged and with its class and its own properties intact whether or not the codec ran in
2394
+ * a worker, and this property is set on that object. So aborting with an error of your own leaves
2395
+ * that error carrying an `outputSize` afterwards, and aborting with a value that cannot take a new
2396
+ * property, e.g. a frozen error or a value that is not an object, simply leaves it unannotated.
2381
2397
  */
2382
2398
  outputSize?: number;
2383
2399
  /**
@@ -3492,7 +3508,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
3492
3508
  * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the entry is a folder
3493
3509
  * or an empty entry stored without compression or encryption, since the header can then carry the sizes and
3494
3510
  * the CRC-32 directly. It will be automatically set to `true` when the
3495
- * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`. Otherwise, the default value is `true`.
3511
+ * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`, except for such a folder or empty
3512
+ * entry, which holds no encrypted data and therefore needs no descriptor either. Otherwise, the default
3513
+ * value is `true`.
3496
3514
  */
3497
3515
  dataDescriptor?: boolean;
3498
3516
  /**
@@ -4197,6 +4215,9 @@ export class ZipDirectoryEntry extends ZipEntry {
4197
4215
  *
4198
4216
  * @param blob The `Blob` instance.
4199
4217
  * @param options The options.
4218
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4219
+ * instances created by the import, which includes the directories created for the path components of
4220
+ * the filenames.
4200
4221
  *
4201
4222
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4202
4223
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4204,12 +4225,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4204
4225
  importBlob(
4205
4226
  blob: Blob,
4206
4227
  options?: ZipDirectoryEntryImportOptions
4207
- ): Promise<[ZipEntry]>;
4228
+ ): Promise<ZipEntry[]>;
4208
4229
  /**
4209
4230
  * Extracts a zip file provided as a Data URI `string` encoded in Base64 into the entry
4210
4231
  *
4211
4232
  * @param dataURI The Data URI `string` encoded in Base64.
4212
4233
  * @param options The options.
4234
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4235
+ * instances created by the import, which includes the directories created for the path components of
4236
+ * the filenames.
4213
4237
  *
4214
4238
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4215
4239
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4217,12 +4241,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4217
4241
  importData64URI(
4218
4242
  dataURI: string,
4219
4243
  options?: ZipDirectoryEntryImportOptions
4220
- ): Promise<[ZipEntry]>;
4244
+ ): Promise<ZipEntry[]>;
4221
4245
  /**
4222
4246
  * Extracts a zip file provided as a `Uint8Array` instance into the entry
4223
4247
  *
4224
4248
  * @param array The `Uint8Array` instance.
4225
4249
  * @param options The options.
4250
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4251
+ * instances created by the import, which includes the directories created for the path components of
4252
+ * the filenames.
4226
4253
  *
4227
4254
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4228
4255
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4230,12 +4257,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4230
4257
  importUint8Array(
4231
4258
  array: Uint8Array,
4232
4259
  options?: ZipDirectoryEntryImportOptions
4233
- ): Promise<[ZipEntry]>;
4260
+ ): Promise<ZipEntry[]>;
4234
4261
  /**
4235
4262
  * Extracts a zip file fetched from a URL into the entry
4236
4263
  *
4237
4264
  * @param url The URL.
4238
4265
  * @param options The options.
4266
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4267
+ * instances created by the import, which includes the directories created for the path components of
4268
+ * the filenames.
4239
4269
  *
4240
4270
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4241
4271
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4243,12 +4273,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4243
4273
  importHttpContent(
4244
4274
  url: string,
4245
4275
  options?: ZipDirectoryEntryImportHttpOptions
4246
- ): Promise<[ZipEntry]>;
4276
+ ): Promise<ZipEntry[]>;
4247
4277
  /**
4248
4278
  * Extracts a zip file provided via a `ReadableStream` instance into the entry
4249
4279
  *
4250
4280
  * @param readable The `ReadableStream` instance.
4251
4281
  * @param options The options.
4282
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4283
+ * instances created by the import, which includes the directories created for the path components of
4284
+ * the filenames.
4252
4285
  *
4253
4286
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4254
4287
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4260,13 +4293,16 @@ export class ZipDirectoryEntry extends ZipEntry {
4260
4293
  importReadable(
4261
4294
  readable: ReadableStream,
4262
4295
  options?: ZipDirectoryEntryImportOptions
4263
- ): Promise<[ZipEntry]>;
4296
+ ): Promise<ZipEntry[]>;
4264
4297
  /**
4265
4298
  * Extracts a zip file provided via a custom {@link Reader} instance or a {@link ZipReader} instance into
4266
4299
  * the entry
4267
4300
  *
4268
4301
  * @param reader The {@link Reader} instance or the {@link ZipReader} instance.
4269
4302
  * @param options The options.
4303
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4304
+ * instances created by the import, which includes the directories created for the path components of
4305
+ * the filenames.
4270
4306
  *
4271
4307
  * @remarks The filename of each entry is split into path components to build the tree of entries. Empty
4272
4308
  * components and `"."` components are ignored, so `"a//b.txt"`, `"./a/b.txt"` and `"a/./b.txt"` all produce
@@ -4296,7 +4332,7 @@ export class ZipDirectoryEntry extends ZipEntry {
4296
4332
  | ReadableStream[]
4297
4333
  | ZipReader<unknown>,
4298
4334
  options?: ZipDirectoryEntryImportOptions
4299
- ): Promise<[ZipEntry]>;
4335
+ ): Promise<ZipEntry[]>;
4300
4336
  /**
4301
4337
  * Returns a `Blob` instance containing a zip file of the entry and its descendants
4302
4338
  *
@@ -4472,6 +4508,16 @@ export interface ZipDirectoryEntryImportOptions
4472
4508
  * entry holding the node, which is the behavior of most zip tools. The entries that do not collide
4473
4509
  * are imported in both cases.
4474
4510
  *
4511
+ * When both entries are directory records, `"keep-last"` replaces the record held by the node and keeps
4512
+ * the entries already imported below it, which belong to the node rather than to either record. A
4513
+ * directory record claiming a node created implicitly by the entries below it is not a collision, it is
4514
+ * the record that node was missing.
4515
+ *
4516
+ * A file claiming a node already holding a directory is the one collision that also drops entries that
4517
+ * did not collide: `"keep-last"` replaces the directory with the file, and the entries below it go with
4518
+ * it, since a file node cannot hold them. `"keep-first"` keeps the directory and its entries and ignores
4519
+ * the file instead, so the two policies are mirrors of each other for that shape.
4520
+ *
4475
4521
  * @defaultValue "throw"
4476
4522
  */
4477
4523
  duplicates?: "throw" | "keep-first" | "keep-last";
package/index.d.ts CHANGED
@@ -1043,7 +1043,13 @@ export interface HttpOptions extends HttpRangeOptions {
1043
1043
  */
1044
1044
  preventHeadRequest?: boolean;
1045
1045
  /**
1046
- * `true` to use `Range: bytes=-22` on the first request and cache the EOCD, make sure beforehand that the server supports a suffix range request.
1046
+ * `true` to read the end of the archive with the same request that gives its size, and to serve the later reads
1047
+ * landing in that range from the response instead of requesting them again, make sure beforehand that the server
1048
+ * supports a suffix range request.
1049
+ *
1050
+ * The request asks for the last 65,557 bytes, which is how far back the reader scans for the end of central directory
1051
+ * record, so it fetches nothing the reader was not going to read anyway. An archive shorter than that is fetched
1052
+ * whole, and reading it then costs a single request.
1047
1053
  *
1048
1054
  * @defaultValue false
1049
1055
  */
@@ -1108,10 +1114,14 @@ export interface WritableWriter {
1108
1114
  */
1109
1115
  writable: WritableStream;
1110
1116
  /**
1111
- * The number of bytes written into the instance. It is set to 0 before the first write and
1112
- * updated as the data is written, so a writer needing the value (e.g. to compute the offset of a
1113
- * disk) can read it. A value set before the first write is kept and used as the starting offset
1114
- * instead of being reset to 0.
1117
+ * The number of bytes written into the instance. It is set to 0 before the first write, and a value
1118
+ * set beforehand is kept and used as the starting offset instead of being reset to 0.
1119
+ *
1120
+ * The bytes of a section are added once that section is written, so the value is settled between
1121
+ * entries rather than after every chunk: an instance reading it from its own `write()` method sees
1122
+ * the total of the sections already finished. The exception is an instance yielded by a generator of
1123
+ * split disks, which is updated on each chunk written to it, so it can compute the offset of the disk
1124
+ * it is filling.
1115
1125
  *
1116
1126
  * It must therefore be assignable, see {@link ERR_WRITER_SIZE_NOT_WRITABLE}: a getter with no setter
1117
1127
  * is rejected when the writer is passed, not once the first entry has been written.
@@ -2378,6 +2388,12 @@ export interface EntryError extends Error {
2378
2388
  * failure reason cannot carry it, which does not affect the salvage described in
2379
2389
  * {@link ZipWriter#close}: zip.js tracks the size of a failed entry on its own, so the offsets of
2380
2390
  * the entries written afterwards stay correct whatever the reason a stream was aborted with.
2391
+ *
2392
+ * When a stream is aborted or cancelled, the reason the caller passed is what reaches the caller
2393
+ * back, unchanged and with its class and its own properties intact whether or not the codec ran in
2394
+ * a worker, and this property is set on that object. So aborting with an error of your own leaves
2395
+ * that error carrying an `outputSize` afterwards, and aborting with a value that cannot take a new
2396
+ * property, e.g. a frozen error or a value that is not an object, simply leaves it unannotated.
2381
2397
  */
2382
2398
  outputSize?: number;
2383
2399
  /**
@@ -3492,7 +3508,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
3492
3508
  * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the entry is a folder
3493
3509
  * or an empty entry stored without compression or encryption, since the header can then carry the sizes and
3494
3510
  * the CRC-32 directly. It will be automatically set to `true` when the
3495
- * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`. Otherwise, the default value is `true`.
3511
+ * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`, except for such a folder or empty
3512
+ * entry, which holds no encrypted data and therefore needs no descriptor either. Otherwise, the default
3513
+ * value is `true`.
3496
3514
  */
3497
3515
  dataDescriptor?: boolean;
3498
3516
  /**
@@ -4197,6 +4215,9 @@ export class ZipDirectoryEntry extends ZipEntry {
4197
4215
  *
4198
4216
  * @param blob The `Blob` instance.
4199
4217
  * @param options The options.
4218
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4219
+ * instances created by the import, which includes the directories created for the path components of
4220
+ * the filenames.
4200
4221
  *
4201
4222
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4202
4223
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4204,12 +4225,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4204
4225
  importBlob(
4205
4226
  blob: Blob,
4206
4227
  options?: ZipDirectoryEntryImportOptions
4207
- ): Promise<[ZipEntry]>;
4228
+ ): Promise<ZipEntry[]>;
4208
4229
  /**
4209
4230
  * Extracts a zip file provided as a Data URI `string` encoded in Base64 into the entry
4210
4231
  *
4211
4232
  * @param dataURI The Data URI `string` encoded in Base64.
4212
4233
  * @param options The options.
4234
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4235
+ * instances created by the import, which includes the directories created for the path components of
4236
+ * the filenames.
4213
4237
  *
4214
4238
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4215
4239
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4217,12 +4241,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4217
4241
  importData64URI(
4218
4242
  dataURI: string,
4219
4243
  options?: ZipDirectoryEntryImportOptions
4220
- ): Promise<[ZipEntry]>;
4244
+ ): Promise<ZipEntry[]>;
4221
4245
  /**
4222
4246
  * Extracts a zip file provided as a `Uint8Array` instance into the entry
4223
4247
  *
4224
4248
  * @param array The `Uint8Array` instance.
4225
4249
  * @param options The options.
4250
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4251
+ * instances created by the import, which includes the directories created for the path components of
4252
+ * the filenames.
4226
4253
  *
4227
4254
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4228
4255
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4230,12 +4257,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4230
4257
  importUint8Array(
4231
4258
  array: Uint8Array,
4232
4259
  options?: ZipDirectoryEntryImportOptions
4233
- ): Promise<[ZipEntry]>;
4260
+ ): Promise<ZipEntry[]>;
4234
4261
  /**
4235
4262
  * Extracts a zip file fetched from a URL into the entry
4236
4263
  *
4237
4264
  * @param url The URL.
4238
4265
  * @param options The options.
4266
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4267
+ * instances created by the import, which includes the directories created for the path components of
4268
+ * the filenames.
4239
4269
  *
4240
4270
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4241
4271
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4243,12 +4273,15 @@ export class ZipDirectoryEntry extends ZipEntry {
4243
4273
  importHttpContent(
4244
4274
  url: string,
4245
4275
  options?: ZipDirectoryEntryImportHttpOptions
4246
- ): Promise<[ZipEntry]>;
4276
+ ): Promise<ZipEntry[]>;
4247
4277
  /**
4248
4278
  * Extracts a zip file provided via a `ReadableStream` instance into the entry
4249
4279
  *
4250
4280
  * @param readable The `ReadableStream` instance.
4251
4281
  * @param options The options.
4282
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4283
+ * instances created by the import, which includes the directories created for the path components of
4284
+ * the filenames.
4252
4285
  *
4253
4286
  * @remarks Use {@link ZipDirectoryEntry#importZip} with a {@link ZipReader} instance to read the data of the
4254
4287
  * zip file itself, e.g. its {@link ZipReader#prependedData} or its {@link ZipReader#comment} property.
@@ -4260,13 +4293,16 @@ export class ZipDirectoryEntry extends ZipEntry {
4260
4293
  importReadable(
4261
4294
  readable: ReadableStream,
4262
4295
  options?: ZipDirectoryEntryImportOptions
4263
- ): Promise<[ZipEntry]>;
4296
+ ): Promise<ZipEntry[]>;
4264
4297
  /**
4265
4298
  * Extracts a zip file provided via a custom {@link Reader} instance or a {@link ZipReader} instance into
4266
4299
  * the entry
4267
4300
  *
4268
4301
  * @param reader The {@link Reader} instance or the {@link ZipReader} instance.
4269
4302
  * @param options The options.
4303
+ * @returns A promise resolving to an array of the {@link ZipFileEntry} and {@link ZipDirectoryEntry}
4304
+ * instances created by the import, which includes the directories created for the path components of
4305
+ * the filenames.
4270
4306
  *
4271
4307
  * @remarks The filename of each entry is split into path components to build the tree of entries. Empty
4272
4308
  * components and `"."` components are ignored, so `"a//b.txt"`, `"./a/b.txt"` and `"a/./b.txt"` all produce
@@ -4296,7 +4332,7 @@ export class ZipDirectoryEntry extends ZipEntry {
4296
4332
  | ReadableStream[]
4297
4333
  | ZipReader<unknown>,
4298
4334
  options?: ZipDirectoryEntryImportOptions
4299
- ): Promise<[ZipEntry]>;
4335
+ ): Promise<ZipEntry[]>;
4300
4336
  /**
4301
4337
  * Returns a `Blob` instance containing a zip file of the entry and its descendants
4302
4338
  *
@@ -4472,6 +4508,16 @@ export interface ZipDirectoryEntryImportOptions
4472
4508
  * entry holding the node, which is the behavior of most zip tools. The entries that do not collide
4473
4509
  * are imported in both cases.
4474
4510
  *
4511
+ * When both entries are directory records, `"keep-last"` replaces the record held by the node and keeps
4512
+ * the entries already imported below it, which belong to the node rather than to either record. A
4513
+ * directory record claiming a node created implicitly by the entries below it is not a collision, it is
4514
+ * the record that node was missing.
4515
+ *
4516
+ * A file claiming a node already holding a directory is the one collision that also drops entries that
4517
+ * did not collide: `"keep-last"` replaces the directory with the file, and the entries below it go with
4518
+ * it, since a file node cannot hold them. `"keep-first"` keeps the directory and its entries and ignores
4519
+ * the file instead, so the two policies are mirrors of each other for that shape.
4520
+ *
4475
4521
  * @defaultValue "throw"
4476
4522
  */
4477
4523
  duplicates?: "throw" | "keep-first" | "keep-last";