zip-writer 1.1.2 → 2.1.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/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # zip-writable
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/zip-writer.svg)](https://www.npmjs.com/package/zip-writer)
4
+ [![GitHub CI](https://github.com/gmaclennan/zip-writer/actions/workflows/test.yml/badge.svg)](https://github.com/gmaclennan/zip-writer/actions/workflows/test.yml)
5
+ [![bundle size](https://deno.bundlejs.com/badge?q=zip-writer&treeshake=[*])](https://bundlejs.com/?q=zip-writer&treeshake=%5B*%5D)
6
+
3
7
  A modern streaming ZIP archive writer for JavaScript that uses the
4
8
  [Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
5
9
  and
@@ -7,12 +11,17 @@ and
7
11
 
8
12
  ## Features
9
13
 
10
- - **Streaming API** - Write ZIP archives using Web Streams
11
- - **Memory efficient** - Process large files without loading them entirely into
12
- memory
14
+ - **Streaming API** - Write ZIP archives without buffering entries our the
15
+ output zip into memory
16
+ - **Browser & Node.js** - Works in both environments with the same API
17
+ - **Small bundle size** - ~3KB minified and gzipped
18
+ - **Minimal dependencies** - Only depends on
19
+ [p-mutex](https://www.npmjs.com/package/p-mutex) for mutex locking (adds ~390
20
+ bytes)
13
21
  - **ZIP64 support** - Automatic handling of large files and archives
14
- - **Modern JavaScript** - Built with TypeScript, uses native Web Streams API
15
- - **Flexible** - Reorder, rename, or remove entries before finalizing
22
+ - **Editable Central Directory** - Reorder, rename, or remove entries before
23
+ finalizing
24
+ - **100% test coverage** - Output validated against standard ZIP tools
16
25
 
17
26
  ## Installation
18
27
 
@@ -31,19 +40,64 @@ const zipWriter = new ZipWriter();
31
40
  zipWriter.readable.pipeTo(writableStream);
32
41
 
33
42
  // Add entries to the ZIP
34
- const entryWriter = zipWriter.createEntryStream({ name: "hello.txt" });
35
- const writer = entryWriter.writable.getWriter();
36
- await writer.write(new TextEncoder().encode("Hello, World!"));
37
- await writer.close();
38
-
39
- // Get entry info after writing
40
- const info = await entryWriter.getEntryInfo();
43
+ const data = new TextEncoder().encode("Hello, World!");
44
+ const info = await zipWriter.addEntry({
45
+ readable: new ReadableStream({
46
+ start(controller) {
47
+ controller.enqueue(data);
48
+ controller.close();
49
+ },
50
+ }),
51
+ name: "hello.txt",
52
+ });
41
53
  console.log(info);
42
54
 
43
55
  // Finalize the ZIP archive
44
56
  await zipWriter.finalize();
45
57
  ```
46
58
 
59
+ ## Helper Functions
60
+
61
+ ### `readableFromBytes()`
62
+
63
+ A helper function for creating a `ReadableStream` from a `Uint8Array` with
64
+ proper backpressure handling. This is useful when you need to convert byte data
65
+ into a stream for use with `addEntry()`. On supported platforms, you can use
66
+ [`ReadableStream.from()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/from_static)
67
+ instead.
68
+
69
+ This is not included in the main bundle to keep the size small.
70
+
71
+ **Import:**
72
+
73
+ ```ts
74
+ import { readableFromBytes } from "zip-writable/readable-from-bytes";
75
+ ```
76
+
77
+ **Parameters:**
78
+
79
+ - `data: Uint8Array` - The byte array to convert to a stream
80
+
81
+ **Returns:** `ReadableStream<Uint8Array>` - A readable stream that chunks the
82
+ data with proper backpressure
83
+
84
+ **Example:**
85
+
86
+ ```ts
87
+ import { ZipWriter } from "zip-writable";
88
+ import { readableFromBytes } from "zip-writable/readable-from-bytes";
89
+
90
+ const zipWriter = new ZipWriter();
91
+
92
+ const data = new TextEncoder().encode("Hello, World!");
93
+ await zipWriter.addEntry({
94
+ readable: readableFromBytes(data),
95
+ name: "hello.txt",
96
+ });
97
+
98
+ await zipWriter.finalize();
99
+ ```
100
+
47
101
  ## API Reference
48
102
 
49
103
  ### `ZipWriter`
@@ -83,93 +137,66 @@ return new Response(zipWriter.readable, {
83
137
  });
84
138
  ```
85
139
 
86
- ##### `entries: ReadonlyArray<Readonly<EntryInfo>>`
140
+ ##### `entries(): Promise<EntryInfo[]>`
87
141
 
88
- Array of all entries that have been written to the archive. Each entry contains
89
- metadata like size, CRC32, compression info, etc.
142
+ Returns a promise that resolves to an array of all entries that have been
143
+ written to the archive. Each entry contains metadata like size, CRC32,
144
+ compression info, etc.
90
145
 
91
146
  #### Methods
92
147
 
93
- ##### `createEntry(data: Uint8Array, options: EntryOptions): Promise<EntryInfo>`
94
-
95
- Convenience method to add a buffer as an entry to the zip archive. Returns a
96
- promise that resolves to the entry info once written. For more efficient
97
- streaming writes, use `createEntryStream()`.
98
-
99
- **Parameters:**
100
-
101
- - `data: Uint8Array` - Entry data to write
102
- - `options.name: string` - Entry name including internal path (required)
103
- - `options.comment?: string` - Entry comment
104
- - `options.date?: Date` - Entry date (defaults to current date)
105
- - `options.mode?: number` - Entry permissions (Unix-style mode)
106
- - `options.store?: boolean` - Set to `true` to disable compression (defaults to
107
- `false`, using DEFLATE compression)
108
-
109
- **Example:**
110
-
111
- ```ts
112
- const data = new TextEncoder().encode("Hello, World!");
113
- const entryInfo = await zipWriter.createEntry(data, { name: "hello.txt" });
114
- console.log(entryInfo);
115
- ```
116
-
117
- ##### `createEntryStream(options: EntryOptions): EntryWriter`
148
+ ##### `addEntry(entry: Entry): Promise<EntryInfo>`
118
149
 
119
- Create a new entry in the ZIP archive. Returns an `EntryWriter` that you can
120
- write data to via streams.
150
+ Add an entry to the ZIP archive. Returns a promise that resolves to the entry
151
+ info once written.
121
152
 
122
153
  **Parameters:**
123
154
 
124
- - `options.name: string` - Entry name including internal path (required)
125
- - `options.comment?: string` - Entry comment
126
- - `options.date?: Date` - Entry date (defaults to current date)
127
- - `options.mode?: number` - Entry permissions (Unix-style mode)
128
- - `options.store?: boolean` - Set to `true` to disable compression (defaults to
155
+ - `entry.readable: ReadableStream<ArrayBufferView>` - Readable stream of entry
156
+ data
157
+ - `entry.name: string` - Entry name including internal path (required)
158
+ - `entry.comment?: string` - Entry comment
159
+ - `entry.date?: Date` - Entry date (defaults to current date)
160
+ - `entry.mode?: number` - Entry permissions (Unix-style mode)
161
+ - `entry.store?: boolean` - Set to `true` to disable compression (defaults to
129
162
  `false`, using DEFLATE compression)
130
163
 
131
164
  **Examples:**
132
165
 
133
166
  ```ts
134
- // Simple text file
135
- const entry = zipWriter.createEntryStream({ name: "readme.txt" });
136
- const writer = entry.writable.getWriter();
137
- await writer.write(new TextEncoder().encode("Hello!"));
138
- await writer.close();
139
-
140
- // Stream a fetch response
167
+ // Stream from a fetch response
141
168
  const response = await fetch(imageUrl);
142
- response.body.pipeTo(
143
- zipWriter.createEntryStream({ name: "images/photo.jpg" }).writable,
144
- );
169
+ await zipWriter.addEntry({
170
+ readable: response.body,
171
+ name: "images/photo.jpg",
172
+ });
173
+
174
+ // Stream from a Uint8Array
175
+ const data = new TextEncoder().encode("Hello, World!");
176
+ await zipWriter.addEntry({
177
+ readable: new ReadableStream({
178
+ start(controller) {
179
+ controller.enqueue(data);
180
+ controller.close();
181
+ },
182
+ }),
183
+ name: "hello.txt",
184
+ });
145
185
 
146
186
  // With custom date and permissions
147
- zipWriter.createEntryStream({
187
+ await zipWriter.addEntry({
188
+ readable: scriptStream,
148
189
  name: "script.sh",
149
190
  date: new Date("2024-01-01"),
150
191
  mode: 0o755, // executable
151
- }).writable;
192
+ });
152
193
 
153
194
  // Disable compression for already-compressed files
154
- zipWriter.createEntryStream({
195
+ await zipWriter.addEntry({
196
+ readable: videoStream,
155
197
  name: "video.mp4",
156
198
  store: true, // no compression
157
- }).writable;
158
- ```
159
-
160
- ##### `onceQueueEmpty(): Promise<void>`
161
-
162
- Wait until all currently queued entries have been written. Useful when you need
163
- to ensure entries are complete before continuing.
164
-
165
- ```ts
166
- // Add multiple entries
167
- zipWriter.createEntryStream({ name: "file1.txt" }).writable;
168
- zipWriter.createEntryStream({ name: "file2.txt" }).writable;
169
-
170
- // Wait for all to complete
171
- await zipWriter.onceQueueEmpty();
172
- console.log(`Wrote ${zipWriter.entries.length} entries`);
199
+ });
173
200
  ```
174
201
 
175
202
  ##### `finalize(options?): Promise<{ zip64: boolean, uncompressedEntriesSize: bigint, compressedEntriesSize: bigint, fileSize: bigint }>`
@@ -205,11 +232,8 @@ console.log(
205
232
  **Example with entries option:**
206
233
 
207
234
  ```ts
208
- // Wait for all entries to be written
209
- await zipWriter.onceQueueEmpty();
210
-
211
235
  // Get current entries and modify them
212
- const entries = [...zipWriter.entries];
236
+ const entries = await zipWriter.entries();
213
237
 
214
238
  // Remove an entry
215
239
  const filtered = entries.filter((e) => e.name !== "temp.txt");
@@ -227,37 +251,11 @@ const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
227
251
  await zipWriter.finalize({ entries: sorted });
228
252
  ```
229
253
 
230
- ### `EntryWriter`
231
-
232
- Returned by `ZipWriter.createEntryStream()`. Provides a writable stream to write
233
- entry data.
234
-
235
- #### Properties
236
-
237
- ##### `writable: WritableStream<Uint8Array>`
238
-
239
- The writable stream to write entry data to. Close this stream when done writing.
240
-
241
- ```ts
242
- const entryWriter = zipWriter.createEntryStream({ name: "data.txt" });
243
-
244
- // Using a writer
245
- const writer = entryWriter.writable.getWriter();
246
- await writer.write(new TextEncoder().encode("chunk 1"));
247
- await writer.write(new TextEncoder().encode("chunk 2"));
248
- await writer.close();
249
-
250
- // Using pipeTo
251
- someReadableStream.pipeTo(entryWriter.writable);
252
- ```
253
-
254
- #### Methods
255
-
256
- ##### `getEntryInfo(): Promise<EntryInfo>`
254
+ ### `EntryInfo`
257
255
 
258
- Get entry info. Resolves once all data has been written to the ZIP stream.
256
+ Returned by `ZipWriter.addEntry()`. Contains metadata about a written entry.
259
257
 
260
- **Returns `EntryInfo`:**
258
+ **Properties:**
261
259
 
262
260
  - `name: string` - Entry name
263
261
  - `comment?: string` - Entry comment
@@ -270,11 +268,13 @@ Get entry info. Resolves once all data has been written to the ZIP stream.
270
268
  - `compressedSize: bigint | number` - Compressed size in bytes
271
269
  - `zip64: boolean` - Whether this entry uses ZIP64 format
272
270
 
273
- ```ts
274
- const entryWriter = zipWriter.createEntryStream({ name: "test.txt" });
275
- await someStream.pipeTo(entryWriter.writable);
271
+ **Example:**
276
272
 
277
- const info = await entryWriter.getEntryInfo();
273
+ ```ts
274
+ const info = await zipWriter.addEntry({
275
+ readable: dataStream,
276
+ name: "test.txt",
277
+ });
278
278
  console.log(
279
279
  `Wrote ${info.name}: ${info.uncompressedSize} bytes (compressed to ${info.compressedSize})`,
280
280
  );
@@ -294,24 +294,41 @@ async function createZip() {
294
294
  const fileStream = Writable.toWeb(createWriteStream("output.zip"));
295
295
  zipWriter.readable.pipeTo(fileStream);
296
296
 
297
- // Add a text file using createEntry
297
+ // Add a text file
298
298
  const data1 = new TextEncoder().encode("This is a readme");
299
- await zipWriter.createEntry(data1, { name: "readme.txt" });
300
-
301
- // Add files from URLs using createEntryStream
299
+ await zipWriter.addEntry({
300
+ readable: new ReadableStream({
301
+ start(controller) {
302
+ controller.enqueue(data1);
303
+ controller.close();
304
+ },
305
+ }),
306
+ name: "readme.txt",
307
+ });
308
+
309
+ // Add files from URLs
302
310
  const imageResponse = await fetch("https://example.com/image.png");
303
- await imageResponse.body.pipeTo(
304
- zipWriter.createEntryStream({ name: "images/photo.png" }).writable,
305
- );
311
+ await zipWriter.addEntry({
312
+ readable: imageResponse.body,
313
+ name: "images/photo.png",
314
+ });
306
315
 
307
- // Add a JSON file using createEntry
316
+ // Add a JSON file
308
317
  const data = { hello: "world" };
309
318
  const jsonData = new TextEncoder().encode(JSON.stringify(data, null, 2));
310
- await zipWriter.createEntry(jsonData, { name: "data.json" });
319
+ await zipWriter.addEntry({
320
+ readable: new ReadableStream({
321
+ start(controller) {
322
+ controller.enqueue(jsonData);
323
+ controller.close();
324
+ },
325
+ }),
326
+ name: "data.json",
327
+ });
311
328
 
312
329
  // Wait for all entries and check results
313
- await zipWriter.onceQueueEmpty();
314
- console.log(`Added ${zipWriter.entries.length} entries`);
330
+ const entries = await zipWriter.entries();
331
+ console.log(`Added ${entries.length} entries`);
315
332
 
316
333
  // Finalize the archive
317
334
  const result = await zipWriter.finalize();
@@ -329,9 +346,16 @@ const zipWriter = new ZipWriter();
329
346
 
330
347
  // Add entries...
331
348
  const data = new TextEncoder().encode("Hello");
332
- zipWriter
333
- .createEntry(data, { name: "file.txt" })
334
- .then(() => zipWriter.finalize());
349
+ await zipWriter.addEntry({
350
+ readable: new ReadableStream({
351
+ start(controller) {
352
+ controller.enqueue(data);
353
+ controller.close();
354
+ },
355
+ }),
356
+ name: "file.txt",
357
+ });
358
+ await zipWriter.finalize();
335
359
 
336
360
  // Create download link
337
361
  const blob = await new Response(zipWriter.readable).blob();
@@ -410,17 +434,15 @@ No special configuration is needed - it's handled automatically.
410
434
 
411
435
  ```ts
412
436
  try {
413
- const entryWriter = zipWriter.entry({ name: "test.txt" });
414
- await someStream.pipeTo(entryWriter.writable);
415
- await entryWriter.getEntryInfo();
437
+ await zipWriter.addEntry({ readable: someStream, name: "test.txt" });
416
438
  } catch (error) {
417
439
  console.error("Failed to write entry:", error);
418
440
  // The ZIP stream is aborted on error - cannot add more entries
419
441
  }
420
442
  ```
421
443
 
422
- Once an error occurs during entry writing, the ZIP stream is corrupted and
423
- cannot be recovered. You must create a new `ZipWriter` instance.
444
+ Once an error occurs during entry writing, the ZIP stream is in the errored
445
+ state and cannot be recovered. You must create a new `ZipWriter` instance.
424
446
 
425
447
  ## License
426
448
 
@@ -18,6 +18,8 @@ export declare const EOCD_SIZE = 22;
18
18
  export declare const EOCD64_SIZE = 56;
19
19
  export declare const EOCD64_LOCATOR_SIZE = 20;
20
20
  export declare const ZIP64_LIMIT: bigint;
21
+ export declare const MAX_2_BYTE = 65535;
22
+ export declare const MAX_4_BYTE = 4294967295;
21
23
  /** Little-endian for DataView methods */
22
24
  export declare const LITTLE_ENDIAN = true;
23
25
  /** Big-endian for DataView methods */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,yBAAyB,aAAa,CAAC;AACpD,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,4BAA4B,aAAa,CAAC;AACvD,eAAO,MAAM,kCAAkC,aAAa,CAAC;AAC7D,eAAO,MAAM,0CAA0C,aAAa,CAAC;AAGrE,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,eAAO,MAAM,qBAAqB,OAAwB,CAAC;AAG3D,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAG5C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAGtC,eAAO,MAAM,WAAW,QAAqB,CAAC;AAE9C,yCAAyC;AACzC,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,sCAAsC;AACtC,eAAO,MAAM,UAAU,QAAQ,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,yBAAyB,aAAa,CAAC;AACpD,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,4BAA4B,aAAa,CAAC;AACvD,eAAO,MAAM,kCAAkC,aAAa,CAAC;AAC7D,eAAO,MAAM,0CAA0C,aAAa,CAAC;AAGrE,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,eAAO,MAAM,qBAAqB,OAAwB,CAAC;AAG3D,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAG5C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAGtC,eAAO,MAAM,WAAW,QAAqB,CAAC;AAC9C,eAAO,MAAM,UAAU,QAAS,CAAC;AACjC,eAAO,MAAM,UAAU,aAAa,CAAC;AAErC,yCAAyC;AACzC,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,sCAAsC;AACtC,eAAO,MAAM,UAAU,QAAQ,CAAC"}
package/dist/constants.js CHANGED
@@ -10,7 +10,7 @@ export const VERSION_MADE_BY = 45; // Version 4.5 (ZIP64 support)
10
10
  export const VERSION_NEEDED_STANDARD = 20; // Version 2.0
11
11
  export const VERSION_NEEDED_ZIP64 = 45; // Version 4.5 for ZIP64
12
12
  // Flags
13
- export const GENERAL_PURPOSE_FLAGS = 0b0000_1000_0000_1000; // Bit 3: data descriptor, Bit 11: UTF-8
13
+ export const GENERAL_PURPOSE_FLAGS = 0b0000_1000_0000_1000; // Bit 3: crc and file-sizes unknown when header was written, Bit 11: UTF-8
14
14
  // Compression methods
15
15
  export const COMPRESSION_METHOD_STORE = 0;
16
16
  export const COMPRESSION_METHOD_DEFLATE = 8;
@@ -24,6 +24,8 @@ export const EOCD64_SIZE = 56;
24
24
  export const EOCD64_LOCATOR_SIZE = 20;
25
25
  // Limits
26
26
  export const ZIP64_LIMIT = BigInt(0xffffffff);
27
+ export const MAX_2_BYTE = 0xffff;
28
+ export const MAX_4_BYTE = 0xffffffff;
27
29
  /** Little-endian for DataView methods */
28
30
  export const LITTLE_ENDIAN = true;
29
31
  /** Big-endian for DataView methods */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,CAAC,MAAM,2BAA2B,GAAG,UAAU,CAAC,CAAC,eAAe;AACtE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC,CAAC,eAAe;AACpE,MAAM,CAAC,MAAM,2BAA2B,GAAG,UAAU,CAAC,CAAC,eAAe;AACtE,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC,CAAC,eAAe;AACvE,MAAM,CAAC,MAAM,kCAAkC,GAAG,UAAU,CAAC,CAAC,eAAe;AAC7E,MAAM,CAAC,MAAM,0CAA0C,GAAG,UAAU,CAAC,CAAC,eAAe;AAErF,oBAAoB;AACpB,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC,8BAA8B;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC,CAAC,cAAc;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC,CAAC,wBAAwB;AAEhE,QAAQ;AACR,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,CAAC,wCAAwC;AAEpG,sBAAsB;AACtB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,iBAAiB;AACjB,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,SAAS;AACT,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE9C,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,sCAAsC;AACtC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,CAAC,MAAM,2BAA2B,GAAG,UAAU,CAAC,CAAC,eAAe;AACtE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC,CAAC,eAAe;AACpE,MAAM,CAAC,MAAM,2BAA2B,GAAG,UAAU,CAAC,CAAC,eAAe;AACtE,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC,CAAC,eAAe;AACvE,MAAM,CAAC,MAAM,kCAAkC,GAAG,UAAU,CAAC,CAAC,eAAe;AAC7E,MAAM,CAAC,MAAM,0CAA0C,GAAG,UAAU,CAAC,CAAC,eAAe;AAErF,oBAAoB;AACpB,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC,8BAA8B;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC,CAAC,cAAc;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC,CAAC,wBAAwB;AAEhE,QAAQ;AACR,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,CAAC,2EAA2E;AAEvI,sBAAsB;AACtB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,iBAAiB;AACjB,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,SAAS;AACT,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;AAErC,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,sCAAsC;AACtC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC"}
package/dist/index.d.ts CHANGED
@@ -10,7 +10,17 @@ export interface EntryOptions {
10
10
  /** Compression method to `STORE` (defaults to `DEFLATE`) */
11
11
  store?: boolean;
12
12
  }
13
- export interface EntryInfoZip64 extends EntryOptions {
13
+ export interface EntryOptionsInternal extends EntryOptions {
14
+ /** Encoded entry name */
15
+ nameBytes: Uint8Array;
16
+ /** Encoded entry comment */
17
+ commentBytes: Uint8Array;
18
+ }
19
+ export interface Entry extends EntryOptions {
20
+ /** Readable stream of entry data */
21
+ readable: ReadableStream<ArrayBufferView<ArrayBufferLike>>;
22
+ }
23
+ export interface EntryInfoInternal extends EntryOptionsInternal {
14
24
  /** Byte offset of the local file header within the ZIP archive */
15
25
  startOffset: bigint;
16
26
  /** CRC32 checksum of the uncompressed data */
@@ -20,13 +30,26 @@ export interface EntryInfoZip64 extends EntryOptions {
20
30
  /** Compressed size in bytes */
21
31
  compressedSize: bigint;
22
32
  /** Entry information is in ZIP64 format */
23
- zip64: true;
33
+ zip64: boolean;
34
+ }
35
+ export interface ZipInfo {
36
+ /** Does the archive use ZIP64 format? */
37
+ zip64: boolean;
38
+ /** Total uncompressed size of all entries */
39
+ uncompressedEntriesSize: bigint;
40
+ /** Total compressed size of all entries */
41
+ compressedEntriesSize: bigint;
42
+ /** Total size of the ZIP file */
43
+ fileSize: bigint;
24
44
  }
45
+ export type EntryInfoZip64 = Omit<EntryInfoInternal, "nameBytes" | "commentBytes" | "zip64"> & {
46
+ zip64: true;
47
+ };
25
48
  export type EntryInfoStandard = {
26
49
  [K in keyof EntryInfoZip64]: EntryInfoZip64[K] extends bigint ? number : K extends "zip64" ? false : EntryInfoZip64[K];
27
50
  };
28
51
  export type EntryInfo = EntryInfoZip64 | EntryInfoStandard;
29
- export declare class ZipWriter<TIsZip64 extends boolean = false> {
52
+ export declare class ZipWriter {
30
53
  #private;
31
54
  /**
32
55
  * @param crc Optional CRC32 function to use. Defaults to zlib.crc32 on Node and a pure JS implementation in browsers.
@@ -35,29 +58,10 @@ export declare class ZipWriter<TIsZip64 extends boolean = false> {
35
58
  crc32?: (data: Uint8Array<ArrayBuffer>, value?: number) => number;
36
59
  });
37
60
  get readable(): ReadableStream<ArrayBufferView<ArrayBufferLike>>;
38
- get entries(): ReadonlyArray<Readonly<EntryInfo>>;
39
61
  /**
40
- * Wait until all currently queued entries have been written.
41
- */
42
- onceQueueEmpty(): Promise<void>;
43
- /**
44
- * Convenience wrapper around `createEntryStream` to write all data at once.
45
- * Use `createEntryStream` for more efficient streaming writes. Calls to
46
- * createEntry() will be queued internally and each will resolve once it's
47
- * written to the archive.
48
- *
49
- * @example
50
- * ```ts
51
- * const data = new TextEncoder().encode("Hello, World!");
52
- * const entryInfo = await zipWriter.createEntry(data, { name: "hello.txt" });
53
- * console.log(entryInfo);
54
- * ```
55
- *
56
- * @param data Entry data
57
- * @param options Entry filename, comment, compression method, etc.
58
- * @returns Entry information once the entry has been written.
62
+ * Get an array of entry information for all entries added so far to the ZIP archive.
59
63
  */
60
- createEntry(data: Uint8Array<ArrayBuffer>, options: EntryOptions): Promise<EntryInfo>;
64
+ entries(): Promise<EntryInfo[]>;
61
65
  /**
62
66
  * Create a new entry in the Zip archive. Use the returned
63
67
  * entryWriter.writable to write data to the entry. You can await
@@ -84,7 +88,7 @@ export declare class ZipWriter<TIsZip64 extends boolean = false> {
84
88
  *
85
89
  * @param options Entry options
86
90
  */
87
- createEntryStream(options: EntryOptions): EntryWriter;
91
+ addEntry({ readable, ...entryOptions }: Entry): Promise<EntryInfo>;
88
92
  /**
89
93
  * Finalize the ZIP archive by writing the central directory and end of
90
94
  * central directory records. You may not add any more entries after calling
@@ -100,39 +104,8 @@ export declare class ZipWriter<TIsZip64 extends boolean = false> {
100
104
  *
101
105
  * @returns Information about the finalized archive.
102
106
  */
103
- finalize({ entries, }?: {
104
- entries?: ReadonlyArray<Readonly<EntryInfo>>;
105
- }): Promise<{
106
- /** Does the archive use ZIP64 format? */
107
- zip64: boolean;
108
- /** Total uncompressed size of all entries */
109
- uncompressedEntriesSize: bigint;
110
- /** Total compressed size of all entries */
111
- compressedEntriesSize: bigint;
112
- /** Total size of the ZIP file */
113
- fileSize: bigint;
114
- }>;
115
- }
116
- declare class EntryWriter {
117
- #private;
118
- /**
119
- * @param enqueueAndPipe Function that enqueues the entry data readable, pipes it to the Zip stream, and returns a promise that resolves to the entry info once done.
120
- */
121
- constructor(enqueueAndPipe: (readable: ReadableStream<Uint8Array<ArrayBuffer>>) => Promise<EntryInfo>);
122
- /**
123
- * Writable stream to write entry data to.
124
- *
125
- * @example
126
- * ```ts
127
- * ReadableStream.from([new TextEncoder().encode("Hello, World!")])
128
- * .pipeTo(entryWriter.writable);
129
- * ```
130
- */
131
- get writable(): WritableStream<Uint8Array<ArrayBuffer>>;
132
- /**
133
- * Get entry info. Resolves once all data has been written to the Zip stream.
134
- */
135
- getEntryInfo(): Promise<EntryInfo>;
107
+ finalize({ entries }?: {
108
+ entries?: EntryInfo[];
109
+ }): Promise<ZipInfo>;
136
110
  }
137
- export {};
138
111
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,KAAK,EAAE,IAAI,CAAC;CACb;AAED,MAAM,MAAM,iBAAiB,GAAG;KAC7B,CAAC,IAAI,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,MAAM,GACzD,MAAM,GACN,CAAC,SAAS,OAAO,GACf,KAAK,GACL,cAAc,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,iBAAiB,CAAC;AAE3D,qBAAa,SAAS,CAAC,QAAQ,SAAS,OAAO,GAAG,KAAK;;IAqBrD;;OAEG;gBACS,EACV,KAAoB,GACrB,GAAE;QACD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;KAC9D;IAIN,IAAI,QAAQ,qDAEX;IAED,IAAI,OAAO,IAAI,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAEhD;IAED;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrC;;;;;;;;;;;;;;;;OAgBG;IACG,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,YAAY;IAWtE;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,iBAAiB,CAAC,OAAO,EAAE,YAAY;IAgGvC;;;;;;;;;;;;;;OAcG;IACG,QAAQ,CAAC,EACb,OAAO,GACR,GAAE;QAAE,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAA;KAAO,GAAG,OAAO,CAAC;QACjE,yCAAyC;QACzC,KAAK,EAAE,OAAO,CAAC;QACf,6CAA6C;QAC7C,uBAAuB,EAAE,MAAM,CAAC;QAChC,2CAA2C;QAC3C,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iCAAiC;QACjC,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CA6EH;AAED,cAAM,WAAW;;IAQf;;OAEG;gBAED,cAAc,EAAE,CACd,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,KAC9C,OAAO,CAAC,SAAS,CAAC;IAazB;;;;;;;;OAQG;IACH,IAAI,QAAQ,4CAEX;IAED;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;CAGzC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,yBAAyB;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,4BAA4B;IAC5B,YAAY,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,WAAW,KAAM,SAAQ,YAAY;IACzC,oCAAoC;IACpC,QAAQ,EAAE,cAAc,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,uBAAuB,EAAE,MAAM,CAAC;IAChC,2CAA2C;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,iBAAiB,EACjB,WAAW,GAAG,cAAc,GAAG,OAAO,CACvC,GAAG;IACF,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;KAC7B,CAAC,IAAI,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,MAAM,GACzD,MAAM,GACN,CAAC,SAAS,OAAO,GACf,KAAK,GACL,cAAc,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,iBAAiB,CAAC;AAI3D,qBAAa,SAAS;;IAoBpB;;OAEG;gBACS,EACV,KAAoB,GACrB,GAAE;QACD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;KAC9D;IAIN,IAAI,QAAQ,qDAEX;IAED;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAM/B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC;IA4JlE;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAE;QAAE,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;KAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAiExE"}