@zip.js/zip.js 2.6.12 → 2.6.15

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/README.md CHANGED
@@ -1,13 +1,74 @@
1
- zip.js is an open-source library (BSD-3-Clause license) to zip and unzip files
2
- supporting multi-core compression, compression streams, Zip64 and encryption.
1
+ # Introduction
2
+
3
+ zip.js is an open-source library (BSD-3-Clause license) implemented in
4
+ JavaScript to compress and decompress zip files. It has been designed to handle
5
+ large amounts of data and notably supports multi-core compression, compression
6
+ streams, Zip64 and encryption.
7
+
8
+ # Documentation
3
9
 
4
10
  See here for more info: https://gildas-lormeau.github.io/zip.js/
5
11
 
12
+ # Examples
13
+
14
+ ## Hello world
15
+
6
16
  ```js
17
+ import {
18
+ BlobReader,
19
+ BlobWriter,
20
+ TextReader,
21
+ TextWriter,
22
+ ZipReader,
23
+ ZipWriter,
24
+ } from "https://deno.land/x/zipjs/index.js";
25
+
7
26
  // ----
8
- // Hello world with zip.js (and Streams)
27
+ // Write the zip file
9
28
  // ----
10
29
 
30
+ // Creates a BlobWriter object where the zip content will be written.
31
+ const zipFileWriter = new BlobWriter();
32
+ // Creates a TextReader object storing the text of the entry to add in the zip
33
+ // (i.e. "Hello world!").
34
+ const helloWorldReader = new TextReader("Hello world!");
35
+
36
+ // Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
37
+ // "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
38
+ // closes the writer.
39
+ const zipWriter = new ZipWriter(zipFileWriter);
40
+ await zipWriter.add("hello.txt", helloWorldReader);
41
+ await zipWriter.close();
42
+
43
+ // Retrieves the Blob object containing the zip content into `zipFileBlob`. It
44
+ // is also returned by zipWriter.close() for more convenience.
45
+ const zipFileBlob = await zipFileWriter.getData();
46
+
47
+ // ----
48
+ // Read the zip file
49
+ // ----
50
+
51
+ // Creates a BlobReader object used to read `zipFileBlob`.
52
+ const zipFileReader = new BlobReader(zipFileBlob);
53
+ // Creates a TextWriter object where the content of the first entry in the zip
54
+ // will be written.
55
+ const helloWorldWriter = new TextWriter();
56
+
57
+ // Creates a ZipReader object reading the zip content via `zipFileReader`,
58
+ // retrieves metadata (name, dates, etc.) of the first entry, retrieves its
59
+ // content via `helloWorldWriter`, and closes the reader.
60
+ const zipReader = new ZipReader(zipFileReader);
61
+ const firstEntry = (await zipReader.getEntries()).shift();
62
+ const helloWorldText = await firstEntry.getData(helloWorldWriter);
63
+ await zipReader.close();
64
+
65
+ // Displays "Hello world!".
66
+ console.log(helloWorldText);
67
+ ```
68
+
69
+ ## Hello world with Streams
70
+
71
+ ```js
11
72
  import {
12
73
  BlobReader,
13
74
  ZipReader,
@@ -30,8 +91,8 @@ const zipFileBlobPromise = new Response(zipFileWriter.readable).blob();
30
91
  const helloWorldReader = { readable: new Blob(["Hello world!"]).stream() };
31
92
 
32
93
  // Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
33
- // "hello.txt" containing the text "Hello world!" via `helloWorldReader` in the
34
- // zip, and closes the writer.
94
+ // "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
95
+ // closes the writer.
35
96
  const zipWriter = new ZipWriter(zipFileWriter);
36
97
  await zipWriter.add("hello.txt", helloWorldReader);
37
98
  await zipWriter.close();
@@ -39,14 +100,6 @@ await zipWriter.close();
39
100
  // Retrieves the Blob object containing the zip content into `zipFileBlob`.
40
101
  const zipFileBlob = await zipFileBlobPromise;
41
102
 
42
- // Uncomment the following code to download the zip file (in a browser)
43
- //
44
- // const anchorElement = document.createElement("a");
45
- // anchorElement.href = URL.createObjectURL(zipFileBlob);
46
- // anchorElement.download = "hello.zip";
47
- // anchorElement.click();
48
- //
49
-
50
103
  // ----
51
104
  // Read the zip file
52
105
  // ----
@@ -36,7 +36,7 @@ async function displayUsage() {
36
36
  await stdout.write(" --data-descriptor-signature add data descriptor signatures (default: false)\n");
37
37
  await stdout.write(" --keep-order keep entries order (default: true)\n");
38
38
  await stdout.write(" --zip64 use Zip64 format (default: false)\n");
39
- await stdout.write(" --prevent-parent-directories remove occurences of \"../\" in filenames\n");
39
+ await stdout.write(" --prevent-parent-directories remove occurences of \"../\" in filenames (default: true)\n");
40
40
  await stdout.write("\n");
41
41
  Deno.exit(-1);
42
42
  }
@@ -7951,18 +7951,19 @@
7951
7951
 
7952
7952
  class Uint8ArrayWriter extends Writer {
7953
7953
 
7954
- constructor() {
7955
- super();
7956
- this.array = new Uint8Array();
7954
+ init(initSize = 0) {
7955
+ this.array = new Uint8Array(initSize);
7957
7956
  }
7958
7957
 
7959
7958
  writeUint8Array(array) {
7960
- super.writeUint8Array(array);
7961
7959
  const writer = this;
7962
- const previousArray = writer.array;
7963
- writer.array = new Uint8Array(previousArray.length + array.length);
7964
- writer.array.set(previousArray);
7965
- writer.array.set(array, previousArray.length);
7960
+ if (writer.size + array.length > writer.array.length) {
7961
+ const previousArray = writer.array;
7962
+ writer.array = new Uint8Array(previousArray.length + array.length);
7963
+ writer.array.set(previousArray);
7964
+ }
7965
+ writer.array.set(array, writer.size);
7966
+ super.writeUint8Array(array);
7966
7967
  }
7967
7968
 
7968
7969
  getData() {
@@ -7976,9 +7977,9 @@
7976
7977
  return protocol == "http:" || protocol == "https:";
7977
7978
  }
7978
7979
 
7979
- async function initStream(stream) {
7980
+ async function initStream(stream, initSize) {
7980
7981
  if (stream.init && !stream.initialized) {
7981
- await stream.init();
7982
+ await stream.init(initSize);
7982
7983
  }
7983
7984
  }
7984
7985
 
@@ -8080,14 +8081,21 @@
8080
8081
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8081
8082
  */
8082
8083
 
8084
+ /* global TextDecoder */
8085
+
8083
8086
  const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
8087
+ const VALID_CP437 = CP437.length == 256;
8084
8088
 
8085
- var decodeCP437 = stringValue => {
8086
- let result = "";
8087
- for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
8088
- result += CP437[stringValue[indexCharacter]];
8089
+ var decodeCP437 = (stringValue) => {
8090
+ if (VALID_CP437) {
8091
+ let result = "";
8092
+ for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
8093
+ result += CP437[stringValue[indexCharacter]];
8094
+ }
8095
+ return result;
8096
+ } else {
8097
+ return new TextDecoder().decode(stringValue);
8089
8098
  }
8090
- return result;
8091
8099
  };
8092
8100
 
8093
8101
  /*
@@ -8390,6 +8398,7 @@
8390
8398
  bitFlag,
8391
8399
  signature,
8392
8400
  rawLastModDate,
8401
+ uncompressedSize,
8393
8402
  compressedSize
8394
8403
  } = zipEntry;
8395
8404
  const localDirectory = zipEntry.localDirectory = {};
@@ -8430,7 +8439,7 @@
8430
8439
  readable.size = size;
8431
8440
  const { writable } = writer;
8432
8441
  const signal = getOptionValue$1(zipEntry, options, "signal");
8433
- await initStream(writer);
8442
+ await initStream(writer, uncompressedSize);
8434
8443
  const { onstart, onprogress, onend } = options;
8435
8444
  const workerOptions = {
8436
8445
  options: {
@@ -8978,8 +8987,9 @@
8978
8987
  let bufferedWrite;
8979
8988
  let releaseLockWriter;
8980
8989
  let releaseLockCurrentFileEntry;
8981
- let bufferedDataWritten;
8990
+ let writingBufferedData;
8982
8991
  let fileWriter;
8992
+ let fileWriterSize;
8983
8993
  files.set(name, fileEntry);
8984
8994
  try {
8985
8995
  let lockPreviousFileEntry;
@@ -8996,6 +9006,7 @@
8996
9006
  await initStream(writer);
8997
9007
  fileWriter = writer;
8998
9008
  }
9009
+ fileWriterSize = fileWriter.size;
8999
9010
  fileEntry = await createFileEntry(reader, fileEntry, fileWriter.writable, zipWriter.config, options);
9000
9011
  files.set(name, fileEntry);
9001
9012
  fileEntry.filename = name;
@@ -9003,7 +9014,7 @@
9003
9014
  let blob = fileWriter.getData();
9004
9015
  await lockPreviousFileEntry;
9005
9016
  await requestLockWriter();
9006
- bufferedDataWritten = true;
9017
+ writingBufferedData = true;
9007
9018
  const { writable } = writer;
9008
9019
  if (!dataDescriptor) {
9009
9020
  const headerLength = 26;
@@ -9023,7 +9034,7 @@
9023
9034
  blob = blob.slice(headerLength);
9024
9035
  }
9025
9036
  await blob.stream().pipeTo(writable, { preventClose: true, signal });
9026
- bufferedDataWritten = false;
9037
+ writingBufferedData = false;
9027
9038
  }
9028
9039
  fileEntry.offset = zipWriter.offset;
9029
9040
  if (fileEntry.zip64) {
@@ -9035,9 +9046,12 @@
9035
9046
  zipWriter.offset += fileEntry.length;
9036
9047
  return fileEntry;
9037
9048
  } catch (error) {
9038
- if ((bufferedWrite && bufferedDataWritten) || (!bufferedWrite && fileEntry.dataWritten)) {
9039
- error.corruptedEntry = zipWriter.hasCorruptedEntries = true;
9040
- zipWriter.offset += fileWriter.size;
9049
+ if ((bufferedWrite && writingBufferedData) || (!bufferedWrite && fileEntry.writingData)) {
9050
+ zipWriter.hasCorruptedEntries = true;
9051
+ if (error) {
9052
+ error.corruptedEntry = true;
9053
+ }
9054
+ zipWriter.offset += fileWriter.size - fileWriterSize;
9041
9055
  }
9042
9056
  files.delete(name);
9043
9057
  throw error;
@@ -9214,10 +9228,10 @@
9214
9228
  arraySet(localHeaderArray, rawExtraField, 30 + rawFilename.length + rawExtraFieldAES.length + rawExtraFieldExtendedTimestamp.length + rawExtraFieldNTFS.length);
9215
9229
  let result;
9216
9230
  let compressedSize = 0;
9231
+ fileEntry.writingData = pendingFileEntry.writingData = true;
9217
9232
  if (reader) {
9218
9233
  reader.chunkSize = getChunkSize(config);
9219
9234
  await writeData(writable, localHeaderArray);
9220
- fileEntry.dataWritten = pendingFileEntry.dataWritten = true;
9221
9235
  const size = () => reader.size;
9222
9236
  const readable = reader.readable;
9223
9237
  readable.size = size;
@@ -9244,7 +9258,6 @@
9244
9258
  compressedSize = result.size;
9245
9259
  } else {
9246
9260
  await writeData(writable, localHeaderArray);
9247
- fileEntry.dataWritten = pendingFileEntry.dataWritten = true;
9248
9261
  }
9249
9262
  let dataDescriptorArray = new Uint8Array();
9250
9263
  let dataDescriptorView, dataDescriptorOffset = 0;
@@ -9297,7 +9310,8 @@
9297
9310
  creationDate,
9298
9311
  lastAccessDate,
9299
9312
  encrypted,
9300
- length
9313
+ length,
9314
+ writingData: false
9301
9315
  });
9302
9316
  return fileEntry;
9303
9317
  }
@@ -9579,7 +9593,7 @@
9579
9593
  return zipEntry.data;
9580
9594
  } else {
9581
9595
  const reader = zipEntry.reader = new zipEntry.Reader(zipEntry.data, options);
9582
- await Promise.all([initStream(reader), initStream(writer)]);
9596
+ await Promise.all([initStream(reader), initStream(writer, zipEntry.data.uncompressedSize)]);
9583
9597
  zipEntry.uncompressedSize = reader.size;
9584
9598
  const readable = reader.readable;
9585
9599
  readable.size = () => reader.size;