@zip.js/zip.js 2.16.0 → 2.16.1

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 (42) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +284 -179
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +108 -61
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +426 -189
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +251 -70
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +426 -189
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +253 -72
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +428 -189
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +110 -63
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +110 -63
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +285 -180
  23. package/dist/zip.min.js +1 -1
  24. package/eslint.config.mjs +1 -1
  25. package/index-native.cjs +253 -72
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +428 -189
  28. package/index.d.cts +117 -16
  29. package/index.d.ts +117 -16
  30. package/index.min.js +1 -1
  31. package/lib/core/streams/aes-crypto-stream.js +60 -17
  32. package/lib/core/streams/zip-crypto-stream.js +7 -7
  33. package/lib/core/streams/zip-entry-stream.js +22 -26
  34. package/lib/core/streams/zlib-wasm/zlib-streams.js +176 -118
  35. package/lib/core/util/compatible-streams.js +10 -5
  36. package/lib/core/version.js +1 -1
  37. package/lib/core/web-worker-inline-native.js +1 -1
  38. package/lib/core/web-worker-inline-wasm.js +1 -1
  39. package/lib/core/zip-fs.js +144 -10
  40. package/lib/core/zip-reader.js +5 -5
  41. package/lib/core/zip-writer.js +4 -2
  42. package/package.json +3 -2
package/index.d.cts CHANGED
@@ -2440,13 +2440,21 @@ export interface EntryError extends Error {
2440
2440
  * {@link GetEntriesOptions#strictness}. See {@link ERR_AMBIGUOUS_ARCHIVE} for the values it takes.
2441
2441
  */
2442
2442
  reason?: string;
2443
+ /**
2444
+ * The related {@link ZipEntry} (filesystem API), set with {@link EntryError#entryId} and
2445
+ * {@link EntryError#entryName} when the data of an entry cannot be read while exporting. The error
2446
+ * is the one the reader of the entry raised, rethrown with its `cause` intact, e.g. the codec error
2447
+ * behind {@link ERR_INVALID_COMPRESSED_DATA} for an entry imported from a corrupted zip file.
2448
+ */
2449
+ entry?: ZipEntry;
2443
2450
  /**
2444
2451
  * The id of the related {@link ZipEntry} (filesystem API).
2445
2452
  */
2446
2453
  entryId?: number;
2447
2454
  /**
2448
2455
  * The name of the related {@link ZipEntry}, or of the related `FileSystemHandle` when importing
2449
- * one (filesystem API). Set by {@link ZipDirectoryEntry#addFileSystemHandle} and
2456
+ * one (filesystem API), relative to the exported entry or to the parent of the handle. Set by the
2457
+ * export methods, {@link ZipDirectoryEntry#addFileSystemHandle} and
2450
2458
  * {@link ZipDirectoryEntry#exportFileSystemHandle}, which rethrow the original error rather than
2451
2459
  * wrapping it, so its `message` stays comparable to the exported `ERR_*` constants.
2452
2460
  */
@@ -2871,6 +2879,13 @@ export interface EntryGetDataOptions
2871
2879
  */
2872
2880
  export interface EntryGetDataCheckPasswordOptions extends EntryGetDataOptions {}
2873
2881
 
2882
+ /**
2883
+ * Represents the options passed to `{@link ZipFileEntry}#get*()`.
2884
+ */
2885
+ export interface ZipFileEntryGetDataOptions
2886
+ extends EntryGetDataOptions,
2887
+ PasswordCandidatesOptions {}
2888
+
2874
2889
  /**
2875
2890
  * Represents an instance used to create a zipped stream.
2876
2891
  *
@@ -3977,7 +3992,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3977
3992
  * @param options The options.
3978
3993
  * @returns A promise resolving to a `string`.
3979
3994
  */
3980
- getText(encoding?: string, options?: EntryGetDataOptions): Promise<string>;
3995
+ getText(encoding?: string, options?: ZipFileEntryGetDataOptions): Promise<string>;
3981
3996
  /**
3982
3997
  * Retrieves the content of the entry as a `Blob` instance
3983
3998
  *
@@ -3985,7 +4000,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3985
4000
  * @param options The options.
3986
4001
  * @returns A promise resolving to a `Blob` instance.
3987
4002
  */
3988
- getBlob(mimeType?: string, options?: EntryGetDataOptions): Promise<Blob>;
4003
+ getBlob(mimeType?: string, options?: ZipFileEntryGetDataOptions): Promise<Blob>;
3989
4004
  /**
3990
4005
  * Retrieves the content of the entry as as a Data URI `string` encoded in Base64
3991
4006
  *
@@ -3995,7 +4010,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3995
4010
  */
3996
4011
  getData64URI(
3997
4012
  mimeType?: string,
3998
- options?: EntryGetDataOptions
4013
+ options?: ZipFileEntryGetDataOptions
3999
4014
  ): Promise<string>;
4000
4015
  /**
4001
4016
  * Retrieves the content of the entry as a `Uint8Array` instance
@@ -4003,7 +4018,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4003
4018
  * @param options The options.
4004
4019
  * @returns A promise resolving to a `Uint8Array` instance.
4005
4020
  */
4006
- getUint8Array(options?: EntryGetDataOptions): Promise<Uint8Array>;
4021
+ getUint8Array(options?: ZipFileEntryGetDataOptions): Promise<Uint8Array>;
4007
4022
  /**
4008
4023
  * Retrieves the content of the entry via a `WritableStream` instance
4009
4024
  *
@@ -4013,7 +4028,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4013
4028
  */
4014
4029
  getWritable(
4015
4030
  writable?: WritableStream,
4016
- options?: EntryGetDataOptions
4031
+ options?: ZipFileEntryGetDataOptions
4017
4032
  ): Promise<WritableStream>;
4018
4033
  /**
4019
4034
  * Retrieves the content of the entry via a {@link Writer} instance
@@ -4028,7 +4043,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4028
4043
  | WritableWriter
4029
4044
  | WritableStream
4030
4045
  | AsyncGenerator<Writer<unknown> | WritableWriter | WritableStream>,
4031
- options?: EntryGetDataOptions
4046
+ options?: ZipFileEntryGetDataOptions
4032
4047
  ): Promise<Type>;
4033
4048
  /**
4034
4049
  * Retrieves the content of the entry as an `ArrayBuffer` instance
@@ -4036,7 +4051,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4036
4051
  * @param options The options.
4037
4052
  * @returns A promise resolving to an `ArrayBuffer` instance.
4038
4053
  */
4039
- getArrayBuffer(options?: EntryGetDataOptions): Promise<ArrayBuffer>;
4054
+ getArrayBuffer(options?: ZipFileEntryGetDataOptions): Promise<ArrayBuffer>;
4040
4055
  /**
4041
4056
  * Replaces the content of the entry with a `Blob` instance
4042
4057
  *
@@ -4510,11 +4525,83 @@ export class ZipDirectoryEntry extends ZipEntry {
4510
4525
  getExportedSize(options?: ZipDirectoryEntryExportOptions): Promise<number>;
4511
4526
  }
4512
4527
 
4528
+ /**
4529
+ * Represents the options supplying several passwords to the entries imported from a zip file, tried in
4530
+ * order when an entry is read.
4531
+ *
4532
+ * @remarks
4533
+ * The core API takes one password per reader or per call. The filesystem API adds a list of
4534
+ * candidates and a function asked for a password when the candidates fail, because it reads each
4535
+ * entry into memory before using it and can therefore try again. The candidates are tried in this
4536
+ * order: the {@link ZipReaderOptions#password} or {@link ZipReaderOptions#rawPassword} option,
4537
+ * then the passwords that already decrypted an entry of the same imported zip file, most recent first,
4538
+ * then the {@link PasswordCandidatesOptions#passwords} option. Each candidate is tried once per entry,
4539
+ * and the entries of a zip file overwhelmingly share one password, so an archive costs one extra
4540
+ * attempt per wrong candidate ahead of the right one, and not one per entry.
4541
+ *
4542
+ * A candidate is rejected when the entry raises an {@link ERR_INVALID_PASSWORD} error, which both
4543
+ * encryption methods do on the first bytes of the entry, before any content is produced. An entry
4544
+ * encrypted with ZipCrypto verifies the password on a single byte, so one wrong password in 256 passes
4545
+ * that check and fails while reading the content instead: for such entries the password is first
4546
+ * verified alone, the CRC32 of the content is then checked whatever the {@link ZipReaderOptions#checkCrc32}
4547
+ * option says, and any failure of the read is treated as a wrong password and the next candidate is
4548
+ * tried. An entry encrypted with AES verifies it on two bytes, so a failure of the read that follows is
4549
+ * reported as-is, e.g. as an {@link ERR_INVALID_AUTHENTICATION_CODE} error.
4550
+ *
4551
+ * The options are set when importing the zip file, in the {@link ZipDirectoryEntryExportOptions#readerOptions}
4552
+ * option of an export, and when reading one entry with `{@link ZipFileEntry}#get*()`. They apply to the
4553
+ * entries imported from a zip file only, and never to the entries read as-is with the
4554
+ * {@link ZipReaderOptions#passThrough} option, which are not decrypted.
4555
+ */
4556
+ export interface PasswordCandidatesOptions {
4557
+ /**
4558
+ * The passwords tried in order, after the {@link ZipReaderOptions#password} option and the
4559
+ * passwords already accepted by another entry of the same imported zip file. An empty string is
4560
+ * ignored.
4561
+ *
4562
+ * When every candidate fails, the entry raises an {@link ERR_INVALID_PASSWORD} error, unless the
4563
+ * {@link PasswordCandidatesOptions#requestPassword} option is set.
4564
+ *
4565
+ * A value which is neither an array of strings nor unset throws an {@link ERR_INVALID_PASSWORDS}
4566
+ * error.
4567
+ */
4568
+ passwords?: string[];
4569
+ /**
4570
+ * The function asked for a password when every candidate has failed, or when there is none. It is
4571
+ * called with the entry being read and with the error raised by the last candidate, which is
4572
+ * `undefined` when no candidate was tried, and it can return a promise, e.g. when it prompts the user.
4573
+ *
4574
+ * A string is tried on the entry, and the function is called again when it fails, with the
4575
+ * {@link ERR_INVALID_PASSWORD} error. `undefined` or `null` gives up: the entry raises an
4576
+ * {@link ERR_INVALID_PASSWORD} error, or an {@link ERR_ENCRYPTED} error when no candidate was
4577
+ * tried. A value of another type throws an {@link ERR_INVALID_REQUEST_PASSWORD} error. The
4578
+ * function is not called for the entries whose password is already known.
4579
+ *
4580
+ * When several entries are read concurrently, e.g. by `{@link ZipDirectoryEntry}#export*()` with the
4581
+ * {@link ZipWriterConstructorOptions#bufferedWrite} option, only one call is pending at a time: the
4582
+ * other entries wait for its answer and try it before asking themselves. Cancelling the whole
4583
+ * operation from the function is done with the {@link ZipReaderOptions#signal} option, since giving
4584
+ * up fails the entry being read only.
4585
+ *
4586
+ * A value which is neither a function nor unset throws an {@link ERR_INVALID_REQUEST_PASSWORD}
4587
+ * error.
4588
+ *
4589
+ * @param entry The entry being read.
4590
+ * @param error The error raised by the last candidate, `undefined` when no candidate was tried.
4591
+ * @returns The password to try, or `undefined` to give up.
4592
+ */
4593
+ requestPassword?(
4594
+ entry: FileEntry,
4595
+ error?: Error
4596
+ ): Promise<string | undefined | null> | string | undefined | null;
4597
+ }
4598
+
4513
4599
  /**
4514
4600
  * Represents the options passed to `{@link ZipDirectoryEntry}#import*()`.
4515
4601
  */
4516
4602
  export interface ZipDirectoryEntryImportOptions
4517
- extends Omit<ZipReaderConstructorOptions, "passThrough"> {
4603
+ extends Omit<ZipReaderConstructorOptions, "passThrough">,
4604
+ PasswordCandidatesOptions {
4518
4605
  /**
4519
4606
  * `true` to import the entries of the zip file as-is, without decompressing and decrypting them
4520
4607
  *
@@ -4532,10 +4619,10 @@ export interface ZipDirectoryEntryImportOptions
4532
4619
  * path components ignored when building the tree (e.g. `"a/b.txt"` and `"./a/b.txt"`), or one can be
4533
4620
  * a file and the other a directory holding it (e.g. `"a"` and `"a/b.txt"`).
4534
4621
  *
4535
- * `"throw"` refuses the zip file with an {@link ERR_DUPLICATE_IMPORTED_ENTRY} error, whose `cause`
4536
- * property holds the {@link EntryMetaData} instance of the entry that could not be imported. The
4537
- * filesystem is left unchanged, i.e. the entries imported before the error are removed and the
4538
- * content held before the import is restored.
4622
+ * `"throw"` refuses the zip file with an {@link ERR_DUPLICATE_IMPORTED_ENTRY} error, whose
4623
+ * `cause.entry` property holds the {@link EntryMetaData} instance of the entry that could not be
4624
+ * imported. The filesystem is left unchanged, i.e. the entries imported before the error are
4625
+ * removed and the content held before the import is restored.
4539
4626
  *
4540
4627
  * `"keep-first"` ignores the entry claiming a node already taken, and `"keep-last"` replaces the
4541
4628
  * entry holding the node, which is the behavior of most zip tools. The entries that do not collide
@@ -4689,7 +4776,7 @@ export interface ZipDirectoryEntryExportOptions
4689
4776
  *
4690
4777
  * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
4691
4778
  */
4692
- readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean };
4779
+ readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean } & PasswordCandidatesOptions;
4693
4780
  }
4694
4781
 
4695
4782
  /**
@@ -4700,7 +4787,8 @@ export interface ZipDirectoryEntryExportOptions
4700
4787
  * file it creates and must close it for the data to be written.
4701
4788
  */
4702
4789
  export interface ZipDirectoryEntryExportFileSystemHandleOptions
4703
- extends EntryGetDataOptions {
4790
+ extends EntryGetDataOptions,
4791
+ PasswordCandidatesOptions {
4704
4792
  /**
4705
4793
  * `true` to write independent files concurrently instead of one after another.
4706
4794
  *
@@ -4722,7 +4810,7 @@ export interface ZipDirectoryEntryExportFileSystemHandleOptions
4722
4810
  *
4723
4811
  * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
4724
4812
  */
4725
- readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean };
4813
+ readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean } & PasswordCandidatesOptions;
4726
4814
  }
4727
4815
 
4728
4816
  /**
@@ -5276,6 +5364,19 @@ export const ERR_UNSUPPORTED_PASS_THROUGH_VALUE: string;
5276
5364
  * unknown property of a `readerOptions` object is still ignored, as everywhere else in the API.
5277
5365
  */
5278
5366
  export const ERR_INVALID_READER_OPTIONS: string;
5367
+ /**
5368
+ * Invalid passwords error (thrown by `{@link ZipDirectoryEntry}#import*()`, `{@link ZipDirectoryEntry}#export*()`,
5369
+ * {@link ZipDirectoryEntry#exportFileSystemHandle} and `{@link ZipFileEntry}#get*()` when the
5370
+ * {@link PasswordCandidatesOptions#passwords} option is neither an array of strings nor unset)
5371
+ */
5372
+ export const ERR_INVALID_PASSWORDS: string;
5373
+ /**
5374
+ * Invalid requestPassword error (thrown by `{@link ZipDirectoryEntry}#import*()`, `{@link ZipDirectoryEntry}#export*()`,
5375
+ * {@link ZipDirectoryEntry#exportFileSystemHandle} and `{@link ZipFileEntry}#get*()` when the
5376
+ * {@link PasswordCandidatesOptions#requestPassword} option is neither a function nor unset, and when it returns a
5377
+ * value which is neither a string, `undefined` nor `null`)
5378
+ */
5379
+ export const ERR_INVALID_REQUEST_PASSWORD: string;
5279
5380
  /**
5280
5381
  * Invalid entry error (thrown by {@link ZipWriter#add} when the {@link ZipWriterAddDataOptions#entry} option is
5281
5382
  * neither an entry nor unset)
package/index.d.ts CHANGED
@@ -2440,13 +2440,21 @@ export interface EntryError extends Error {
2440
2440
  * {@link GetEntriesOptions#strictness}. See {@link ERR_AMBIGUOUS_ARCHIVE} for the values it takes.
2441
2441
  */
2442
2442
  reason?: string;
2443
+ /**
2444
+ * The related {@link ZipEntry} (filesystem API), set with {@link EntryError#entryId} and
2445
+ * {@link EntryError#entryName} when the data of an entry cannot be read while exporting. The error
2446
+ * is the one the reader of the entry raised, rethrown with its `cause` intact, e.g. the codec error
2447
+ * behind {@link ERR_INVALID_COMPRESSED_DATA} for an entry imported from a corrupted zip file.
2448
+ */
2449
+ entry?: ZipEntry;
2443
2450
  /**
2444
2451
  * The id of the related {@link ZipEntry} (filesystem API).
2445
2452
  */
2446
2453
  entryId?: number;
2447
2454
  /**
2448
2455
  * The name of the related {@link ZipEntry}, or of the related `FileSystemHandle` when importing
2449
- * one (filesystem API). Set by {@link ZipDirectoryEntry#addFileSystemHandle} and
2456
+ * one (filesystem API), relative to the exported entry or to the parent of the handle. Set by the
2457
+ * export methods, {@link ZipDirectoryEntry#addFileSystemHandle} and
2450
2458
  * {@link ZipDirectoryEntry#exportFileSystemHandle}, which rethrow the original error rather than
2451
2459
  * wrapping it, so its `message` stays comparable to the exported `ERR_*` constants.
2452
2460
  */
@@ -2871,6 +2879,13 @@ export interface EntryGetDataOptions
2871
2879
  */
2872
2880
  export interface EntryGetDataCheckPasswordOptions extends EntryGetDataOptions {}
2873
2881
 
2882
+ /**
2883
+ * Represents the options passed to `{@link ZipFileEntry}#get*()`.
2884
+ */
2885
+ export interface ZipFileEntryGetDataOptions
2886
+ extends EntryGetDataOptions,
2887
+ PasswordCandidatesOptions {}
2888
+
2874
2889
  /**
2875
2890
  * Represents an instance used to create a zipped stream.
2876
2891
  *
@@ -3977,7 +3992,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3977
3992
  * @param options The options.
3978
3993
  * @returns A promise resolving to a `string`.
3979
3994
  */
3980
- getText(encoding?: string, options?: EntryGetDataOptions): Promise<string>;
3995
+ getText(encoding?: string, options?: ZipFileEntryGetDataOptions): Promise<string>;
3981
3996
  /**
3982
3997
  * Retrieves the content of the entry as a `Blob` instance
3983
3998
  *
@@ -3985,7 +4000,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3985
4000
  * @param options The options.
3986
4001
  * @returns A promise resolving to a `Blob` instance.
3987
4002
  */
3988
- getBlob(mimeType?: string, options?: EntryGetDataOptions): Promise<Blob>;
4003
+ getBlob(mimeType?: string, options?: ZipFileEntryGetDataOptions): Promise<Blob>;
3989
4004
  /**
3990
4005
  * Retrieves the content of the entry as as a Data URI `string` encoded in Base64
3991
4006
  *
@@ -3995,7 +4010,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
3995
4010
  */
3996
4011
  getData64URI(
3997
4012
  mimeType?: string,
3998
- options?: EntryGetDataOptions
4013
+ options?: ZipFileEntryGetDataOptions
3999
4014
  ): Promise<string>;
4000
4015
  /**
4001
4016
  * Retrieves the content of the entry as a `Uint8Array` instance
@@ -4003,7 +4018,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4003
4018
  * @param options The options.
4004
4019
  * @returns A promise resolving to a `Uint8Array` instance.
4005
4020
  */
4006
- getUint8Array(options?: EntryGetDataOptions): Promise<Uint8Array>;
4021
+ getUint8Array(options?: ZipFileEntryGetDataOptions): Promise<Uint8Array>;
4007
4022
  /**
4008
4023
  * Retrieves the content of the entry via a `WritableStream` instance
4009
4024
  *
@@ -4013,7 +4028,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4013
4028
  */
4014
4029
  getWritable(
4015
4030
  writable?: WritableStream,
4016
- options?: EntryGetDataOptions
4031
+ options?: ZipFileEntryGetDataOptions
4017
4032
  ): Promise<WritableStream>;
4018
4033
  /**
4019
4034
  * Retrieves the content of the entry via a {@link Writer} instance
@@ -4028,7 +4043,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4028
4043
  | WritableWriter
4029
4044
  | WritableStream
4030
4045
  | AsyncGenerator<Writer<unknown> | WritableWriter | WritableStream>,
4031
- options?: EntryGetDataOptions
4046
+ options?: ZipFileEntryGetDataOptions
4032
4047
  ): Promise<Type>;
4033
4048
  /**
4034
4049
  * Retrieves the content of the entry as an `ArrayBuffer` instance
@@ -4036,7 +4051,7 @@ export class ZipFileEntry<ReaderType, WriterType> extends ZipEntry {
4036
4051
  * @param options The options.
4037
4052
  * @returns A promise resolving to an `ArrayBuffer` instance.
4038
4053
  */
4039
- getArrayBuffer(options?: EntryGetDataOptions): Promise<ArrayBuffer>;
4054
+ getArrayBuffer(options?: ZipFileEntryGetDataOptions): Promise<ArrayBuffer>;
4040
4055
  /**
4041
4056
  * Replaces the content of the entry with a `Blob` instance
4042
4057
  *
@@ -4510,11 +4525,83 @@ export class ZipDirectoryEntry extends ZipEntry {
4510
4525
  getExportedSize(options?: ZipDirectoryEntryExportOptions): Promise<number>;
4511
4526
  }
4512
4527
 
4528
+ /**
4529
+ * Represents the options supplying several passwords to the entries imported from a zip file, tried in
4530
+ * order when an entry is read.
4531
+ *
4532
+ * @remarks
4533
+ * The core API takes one password per reader or per call. The filesystem API adds a list of
4534
+ * candidates and a function asked for a password when the candidates fail, because it reads each
4535
+ * entry into memory before using it and can therefore try again. The candidates are tried in this
4536
+ * order: the {@link ZipReaderOptions#password} or {@link ZipReaderOptions#rawPassword} option,
4537
+ * then the passwords that already decrypted an entry of the same imported zip file, most recent first,
4538
+ * then the {@link PasswordCandidatesOptions#passwords} option. Each candidate is tried once per entry,
4539
+ * and the entries of a zip file overwhelmingly share one password, so an archive costs one extra
4540
+ * attempt per wrong candidate ahead of the right one, and not one per entry.
4541
+ *
4542
+ * A candidate is rejected when the entry raises an {@link ERR_INVALID_PASSWORD} error, which both
4543
+ * encryption methods do on the first bytes of the entry, before any content is produced. An entry
4544
+ * encrypted with ZipCrypto verifies the password on a single byte, so one wrong password in 256 passes
4545
+ * that check and fails while reading the content instead: for such entries the password is first
4546
+ * verified alone, the CRC32 of the content is then checked whatever the {@link ZipReaderOptions#checkCrc32}
4547
+ * option says, and any failure of the read is treated as a wrong password and the next candidate is
4548
+ * tried. An entry encrypted with AES verifies it on two bytes, so a failure of the read that follows is
4549
+ * reported as-is, e.g. as an {@link ERR_INVALID_AUTHENTICATION_CODE} error.
4550
+ *
4551
+ * The options are set when importing the zip file, in the {@link ZipDirectoryEntryExportOptions#readerOptions}
4552
+ * option of an export, and when reading one entry with `{@link ZipFileEntry}#get*()`. They apply to the
4553
+ * entries imported from a zip file only, and never to the entries read as-is with the
4554
+ * {@link ZipReaderOptions#passThrough} option, which are not decrypted.
4555
+ */
4556
+ export interface PasswordCandidatesOptions {
4557
+ /**
4558
+ * The passwords tried in order, after the {@link ZipReaderOptions#password} option and the
4559
+ * passwords already accepted by another entry of the same imported zip file. An empty string is
4560
+ * ignored.
4561
+ *
4562
+ * When every candidate fails, the entry raises an {@link ERR_INVALID_PASSWORD} error, unless the
4563
+ * {@link PasswordCandidatesOptions#requestPassword} option is set.
4564
+ *
4565
+ * A value which is neither an array of strings nor unset throws an {@link ERR_INVALID_PASSWORDS}
4566
+ * error.
4567
+ */
4568
+ passwords?: string[];
4569
+ /**
4570
+ * The function asked for a password when every candidate has failed, or when there is none. It is
4571
+ * called with the entry being read and with the error raised by the last candidate, which is
4572
+ * `undefined` when no candidate was tried, and it can return a promise, e.g. when it prompts the user.
4573
+ *
4574
+ * A string is tried on the entry, and the function is called again when it fails, with the
4575
+ * {@link ERR_INVALID_PASSWORD} error. `undefined` or `null` gives up: the entry raises an
4576
+ * {@link ERR_INVALID_PASSWORD} error, or an {@link ERR_ENCRYPTED} error when no candidate was
4577
+ * tried. A value of another type throws an {@link ERR_INVALID_REQUEST_PASSWORD} error. The
4578
+ * function is not called for the entries whose password is already known.
4579
+ *
4580
+ * When several entries are read concurrently, e.g. by `{@link ZipDirectoryEntry}#export*()` with the
4581
+ * {@link ZipWriterConstructorOptions#bufferedWrite} option, only one call is pending at a time: the
4582
+ * other entries wait for its answer and try it before asking themselves. Cancelling the whole
4583
+ * operation from the function is done with the {@link ZipReaderOptions#signal} option, since giving
4584
+ * up fails the entry being read only.
4585
+ *
4586
+ * A value which is neither a function nor unset throws an {@link ERR_INVALID_REQUEST_PASSWORD}
4587
+ * error.
4588
+ *
4589
+ * @param entry The entry being read.
4590
+ * @param error The error raised by the last candidate, `undefined` when no candidate was tried.
4591
+ * @returns The password to try, or `undefined` to give up.
4592
+ */
4593
+ requestPassword?(
4594
+ entry: FileEntry,
4595
+ error?: Error
4596
+ ): Promise<string | undefined | null> | string | undefined | null;
4597
+ }
4598
+
4513
4599
  /**
4514
4600
  * Represents the options passed to `{@link ZipDirectoryEntry}#import*()`.
4515
4601
  */
4516
4602
  export interface ZipDirectoryEntryImportOptions
4517
- extends Omit<ZipReaderConstructorOptions, "passThrough"> {
4603
+ extends Omit<ZipReaderConstructorOptions, "passThrough">,
4604
+ PasswordCandidatesOptions {
4518
4605
  /**
4519
4606
  * `true` to import the entries of the zip file as-is, without decompressing and decrypting them
4520
4607
  *
@@ -4532,10 +4619,10 @@ export interface ZipDirectoryEntryImportOptions
4532
4619
  * path components ignored when building the tree (e.g. `"a/b.txt"` and `"./a/b.txt"`), or one can be
4533
4620
  * a file and the other a directory holding it (e.g. `"a"` and `"a/b.txt"`).
4534
4621
  *
4535
- * `"throw"` refuses the zip file with an {@link ERR_DUPLICATE_IMPORTED_ENTRY} error, whose `cause`
4536
- * property holds the {@link EntryMetaData} instance of the entry that could not be imported. The
4537
- * filesystem is left unchanged, i.e. the entries imported before the error are removed and the
4538
- * content held before the import is restored.
4622
+ * `"throw"` refuses the zip file with an {@link ERR_DUPLICATE_IMPORTED_ENTRY} error, whose
4623
+ * `cause.entry` property holds the {@link EntryMetaData} instance of the entry that could not be
4624
+ * imported. The filesystem is left unchanged, i.e. the entries imported before the error are
4625
+ * removed and the content held before the import is restored.
4539
4626
  *
4540
4627
  * `"keep-first"` ignores the entry claiming a node already taken, and `"keep-last"` replaces the
4541
4628
  * entry holding the node, which is the behavior of most zip tools. The entries that do not collide
@@ -4689,7 +4776,7 @@ export interface ZipDirectoryEntryExportOptions
4689
4776
  *
4690
4777
  * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
4691
4778
  */
4692
- readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean };
4779
+ readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean } & PasswordCandidatesOptions;
4693
4780
  }
4694
4781
 
4695
4782
  /**
@@ -4700,7 +4787,8 @@ export interface ZipDirectoryEntryExportOptions
4700
4787
  * file it creates and must close it for the data to be written.
4701
4788
  */
4702
4789
  export interface ZipDirectoryEntryExportFileSystemHandleOptions
4703
- extends EntryGetDataOptions {
4790
+ extends EntryGetDataOptions,
4791
+ PasswordCandidatesOptions {
4704
4792
  /**
4705
4793
  * `true` to write independent files concurrently instead of one after another.
4706
4794
  *
@@ -4722,7 +4810,7 @@ export interface ZipDirectoryEntryExportFileSystemHandleOptions
4722
4810
  *
4723
4811
  * A value which is neither an object nor unset throws an {@link ERR_INVALID_READER_OPTIONS} error.
4724
4812
  */
4725
- readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean };
4813
+ readerOptions?: Omit<ZipReaderConstructorOptions, "passThrough"> & { passThrough?: boolean } & PasswordCandidatesOptions;
4726
4814
  }
4727
4815
 
4728
4816
  /**
@@ -5276,6 +5364,19 @@ export const ERR_UNSUPPORTED_PASS_THROUGH_VALUE: string;
5276
5364
  * unknown property of a `readerOptions` object is still ignored, as everywhere else in the API.
5277
5365
  */
5278
5366
  export const ERR_INVALID_READER_OPTIONS: string;
5367
+ /**
5368
+ * Invalid passwords error (thrown by `{@link ZipDirectoryEntry}#import*()`, `{@link ZipDirectoryEntry}#export*()`,
5369
+ * {@link ZipDirectoryEntry#exportFileSystemHandle} and `{@link ZipFileEntry}#get*()` when the
5370
+ * {@link PasswordCandidatesOptions#passwords} option is neither an array of strings nor unset)
5371
+ */
5372
+ export const ERR_INVALID_PASSWORDS: string;
5373
+ /**
5374
+ * Invalid requestPassword error (thrown by `{@link ZipDirectoryEntry}#import*()`, `{@link ZipDirectoryEntry}#export*()`,
5375
+ * {@link ZipDirectoryEntry#exportFileSystemHandle} and `{@link ZipFileEntry}#get*()` when the
5376
+ * {@link PasswordCandidatesOptions#requestPassword} option is neither a function nor unset, and when it returns a
5377
+ * value which is neither a string, `undefined` nor `null`)
5378
+ */
5379
+ export const ERR_INVALID_REQUEST_PASSWORD: string;
5279
5380
  /**
5280
5381
  * Invalid entry error (thrown by {@link ZipWriter#add} when the {@link ZipWriterAddDataOptions#entry} option is
5281
5382
  * neither an entry nor unset)