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 +154 -132
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +32 -59
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +139 -148
- package/dist/index.js.map +1 -1
- package/dist/readable-from-bytes.d.ts +8 -0
- package/dist/readable-from-bytes.d.ts.map +1 -0
- package/dist/readable-from-bytes.js +25 -0
- package/dist/readable-from-bytes.js.map +1 -0
- package/dist/utils.d.ts +17 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +49 -0
- package/dist/utils.js.map +1 -1
- package/dist/write-central-directory.d.ts +7 -3
- package/dist/write-central-directory.d.ts.map +1 -1
- package/dist/write-central-directory.js +97 -131
- package/dist/write-central-directory.js.map +1 -1
- package/dist/write-entry.d.ts +4 -23
- package/dist/write-entry.d.ts.map +1 -1
- package/dist/write-entry.js +13 -114
- package/dist/write-entry.js.map +1 -1
- package/package.json +31 -6
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# zip-writable
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/zip-writer)
|
|
4
|
+
[](https://github.com/gmaclennan/zip-writer/actions/workflows/test.yml)
|
|
5
|
+
[](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
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
- **
|
|
15
|
-
|
|
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
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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:
|
|
140
|
+
##### `entries(): Promise<EntryInfo[]>`
|
|
87
141
|
|
|
88
|
-
|
|
89
|
-
metadata like size, CRC32,
|
|
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
|
-
##### `
|
|
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
|
-
|
|
120
|
-
|
|
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
|
-
- `
|
|
125
|
-
|
|
126
|
-
- `
|
|
127
|
-
- `
|
|
128
|
-
- `
|
|
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
|
-
//
|
|
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
|
-
|
|
143
|
-
|
|
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.
|
|
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
|
-
})
|
|
192
|
+
});
|
|
152
193
|
|
|
153
194
|
// Disable compression for already-compressed files
|
|
154
|
-
zipWriter.
|
|
195
|
+
await zipWriter.addEntry({
|
|
196
|
+
readable: videoStream,
|
|
155
197
|
name: "video.mp4",
|
|
156
198
|
store: true, // no compression
|
|
157
|
-
})
|
|
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 =
|
|
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
|
-
### `
|
|
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
|
-
|
|
256
|
+
Returned by `ZipWriter.addEntry()`. Contains metadata about a written entry.
|
|
259
257
|
|
|
260
|
-
**
|
|
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
|
-
|
|
274
|
-
const entryWriter = zipWriter.createEntryStream({ name: "test.txt" });
|
|
275
|
-
await someStream.pipeTo(entryWriter.writable);
|
|
271
|
+
**Example:**
|
|
276
272
|
|
|
277
|
-
|
|
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
|
|
297
|
+
// Add a text file
|
|
298
298
|
const data1 = new TextEncoder().encode("This is a readme");
|
|
299
|
-
await zipWriter.
|
|
300
|
-
|
|
301
|
-
|
|
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
|
|
304
|
-
|
|
305
|
-
|
|
311
|
+
await zipWriter.addEntry({
|
|
312
|
+
readable: imageResponse.body,
|
|
313
|
+
name: "images/photo.png",
|
|
314
|
+
});
|
|
306
315
|
|
|
307
|
-
// Add a JSON file
|
|
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.
|
|
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.
|
|
314
|
-
console.log(`Added ${
|
|
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
|
-
|
|
334
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
package/dist/constants.d.ts
CHANGED
|
@@ -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 */
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -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;
|
|
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:
|
|
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 */
|
package/dist/constants.js.map
CHANGED
|
@@ -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,
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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?:
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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"}
|