zip-writer 1.0.0 → 1.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.
Files changed (46) hide show
  1. package/README.md +427 -0
  2. package/dist/constants.d.ts +21 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/{src/constants.ts → dist/constants.js} +1 -5
  5. package/dist/constants.js.map +1 -0
  6. package/{src/crc.ts → dist/crc-browser.d.ts} +2 -39
  7. package/dist/crc-browser.d.ts.map +1 -0
  8. package/dist/crc-browser.js +82 -0
  9. package/dist/crc-browser.js.map +1 -0
  10. package/dist/crc-node.d.ts +2 -0
  11. package/dist/crc-node.d.ts.map +1 -0
  12. package/dist/crc-node.js +3 -0
  13. package/dist/crc-node.js.map +1 -0
  14. package/dist/index.d.ts +138 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +298 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/utils.d.ts +4 -0
  19. package/dist/utils.d.ts.map +1 -0
  20. package/dist/utils.js +12 -0
  21. package/dist/utils.js.map +1 -0
  22. package/dist/write-central-directory.d.ts +14 -0
  23. package/dist/write-central-directory.d.ts.map +1 -0
  24. package/dist/write-central-directory.js +279 -0
  25. package/dist/write-central-directory.js.map +1 -0
  26. package/dist/write-entry.d.ts +26 -0
  27. package/dist/write-entry.d.ts.map +1 -0
  28. package/dist/write-entry.js +172 -0
  29. package/dist/write-entry.js.map +1 -0
  30. package/package.json +32 -5
  31. package/.claude/settings.local.json +0 -11
  32. package/.github/workflows/test.yml +0 -36
  33. package/.husky/pre-commit +0 -1
  34. package/eslint.config.mjs +0 -9
  35. package/src/crc-lookup.ts +0 -27
  36. package/src/index.ts +0 -342
  37. package/src/utils.ts +0 -17
  38. package/src/write-central-directory.ts +0 -405
  39. package/src/write-entry.ts +0 -246
  40. package/test/commands.ts +0 -47
  41. package/test/crc.test.ts +0 -45
  42. package/test/integration.test.ts +0 -483
  43. package/test/utils.ts +0 -40
  44. package/tsconfig.json +0 -36
  45. package/tsconfig.node.json +0 -10
  46. package/vitest.config.ts +0 -46
@@ -0,0 +1,138 @@
1
+ export interface EntryOptions {
2
+ /** Entry name including internal path */
3
+ name: string;
4
+ /** Entry comment */
5
+ comment?: string;
6
+ /** Entry date */
7
+ date?: Date;
8
+ /** Entry permissions */
9
+ mode?: number;
10
+ /** Compression method to `STORE` (defaults to `DEFLATE`) */
11
+ store?: boolean;
12
+ }
13
+ export interface EntryInfoZip64 extends EntryOptions {
14
+ /** Byte offset of the local file header within the ZIP archive */
15
+ startOffset: bigint;
16
+ /** CRC32 checksum of the uncompressed data */
17
+ crc32: number;
18
+ /** Uncompressed size in bytes */
19
+ uncompressedSize: bigint;
20
+ /** Compressed size in bytes */
21
+ compressedSize: bigint;
22
+ /** Entry information is in ZIP64 format */
23
+ zip64: true;
24
+ }
25
+ export type EntryInfoStandard = {
26
+ [K in keyof EntryInfoZip64]: EntryInfoZip64[K] extends bigint ? number : K extends "zip64" ? false : EntryInfoZip64[K];
27
+ };
28
+ export type EntryInfo = EntryInfoZip64 | EntryInfoStandard;
29
+ export declare class ZipWriter<TIsZip64 extends boolean = false> {
30
+ #private;
31
+ /**
32
+ * @param crc Optional CRC32 function to use. Defaults to zlib.crc32 on Node and a pure JS implementation in browsers.
33
+ */
34
+ constructor({ crc32, }?: {
35
+ crc32?: (data: Uint8Array<ArrayBuffer>, value?: number) => number;
36
+ });
37
+ get readable(): ReadableStream<ArrayBufferView<ArrayBufferLike>>;
38
+ get entries(): ReadonlyArray<Readonly<EntryInfo>>;
39
+ /**
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.
59
+ */
60
+ createEntry(data: Uint8Array<ArrayBuffer>, options: EntryOptions): Promise<EntryInfo>;
61
+ /**
62
+ * Create a new entry in the Zip archive. Use the returned
63
+ * entryWriter.writable to write data to the entry. You can await
64
+ * entryWriter.getEntryInfo() to get the entry info once all data has been written.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const response = await fetch(imageUrl);
69
+ * response.body!.pipeTo(
70
+ * zipWriter.entry({ name: "path/to/file.png" }).writable
71
+ * );
72
+ * ```
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const entryWriter = zipWriter.entry({ name: "hello.txt" });
77
+ * const writer = entryWriter.writable.getWriter();
78
+ * await writer.write(
79
+ * new TextEncoder().encode("Hello, World!")
80
+ * );
81
+ * await writer.close();
82
+ * console.log(await entryWriter.getEntryInfo()); // Entry info
83
+ * ```
84
+ *
85
+ * @param options Entry options
86
+ */
87
+ createEntryStream(options: EntryOptions): EntryWriter;
88
+ /**
89
+ * Finalize the ZIP archive by writing the central directory and end of
90
+ * central directory records. You may not add any more entries after calling
91
+ * this method. This will await any pending entries to finish writing before
92
+ * finalizing.
93
+ *
94
+ * @param options.entries (Advanced) Optionally override the entries to write
95
+ * in the central directory. This can be used to reorder, remove, or rename
96
+ * entries before finalizing the archive, however you cannot add invalid
97
+ * entries, add additional entries, or modify their crc32, offsets or sizes.
98
+ * Use zipWriter.entries or entryWriter.getEntryInfo() to get the current
99
+ * entries for sorting or filtering.
100
+ *
101
+ * @returns Information about the finalized archive.
102
+ */
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>;
136
+ }
137
+ export {};
138
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
package/dist/index.js ADDED
@@ -0,0 +1,298 @@
1
+ import { writeZipEntry } from "./write-entry.js";
2
+ import { getCDFH, getEOCDZip64, getEOCDStandard, } from "./write-central-directory.js";
3
+ import { ZIP64_LIMIT } from "./constants.js";
4
+ import { noop } from "./utils.js";
5
+ import { crc32 as crc32Default } from "#crc32";
6
+ const BUFFER_SIZE = 16 * 1024; // 16 KB
7
+ const bufferedQueue = new ByteLengthQueuingStrategy({
8
+ highWaterMark: BUFFER_SIZE,
9
+ });
10
+ export class ZipWriter {
11
+ #offset = BigInt(0);
12
+ #zipStream = new TransformStream({
13
+ transform: (chunk, controller) => {
14
+ controller.enqueue(chunk);
15
+ this.#offset += BigInt(chunk.byteLength);
16
+ },
17
+ },
18
+ // default buffer on the writable side, we already queue entries
19
+ bufferedQueue,
20
+ // Readable buffer, so that temporary delays on writable consumers don't
21
+ // block the zip writing.
22
+ bufferedQueue);
23
+ #entries = [];
24
+ #queued = Promise.resolve();
25
+ #entryCount = 0;
26
+ #finalized = false;
27
+ #crc32;
28
+ /**
29
+ * @param crc Optional CRC32 function to use. Defaults to zlib.crc32 on Node and a pure JS implementation in browsers.
30
+ */
31
+ constructor({ crc32 = crc32Default, } = {}) {
32
+ this.#crc32 = crc32;
33
+ }
34
+ get readable() {
35
+ return this.#zipStream.readable;
36
+ }
37
+ get entries() {
38
+ return this.#entries;
39
+ }
40
+ /**
41
+ * Wait until all currently queued entries have been written.
42
+ */
43
+ async onceQueueEmpty() {
44
+ while (this.#entries.length < this.#entryCount) {
45
+ await this.#queued;
46
+ }
47
+ }
48
+ /**
49
+ * Convenience wrapper around `createEntryStream` to write all data at once.
50
+ * Use `createEntryStream` for more efficient streaming writes. Calls to
51
+ * createEntry() will be queued internally and each will resolve once it's
52
+ * written to the archive.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const data = new TextEncoder().encode("Hello, World!");
57
+ * const entryInfo = await zipWriter.createEntry(data, { name: "hello.txt" });
58
+ * console.log(entryInfo);
59
+ * ```
60
+ *
61
+ * @param data Entry data
62
+ * @param options Entry filename, comment, compression method, etc.
63
+ * @returns Entry information once the entry has been written.
64
+ */
65
+ async createEntry(data, options) {
66
+ const entryWriter = this.createEntryStream(options);
67
+ const writer = entryWriter.writable.getWriter();
68
+ try {
69
+ await writer.write(data);
70
+ }
71
+ finally {
72
+ await writer.close();
73
+ }
74
+ return entryWriter.getEntryInfo();
75
+ }
76
+ /**
77
+ * Create a new entry in the Zip archive. Use the returned
78
+ * entryWriter.writable to write data to the entry. You can await
79
+ * entryWriter.getEntryInfo() to get the entry info once all data has been written.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const response = await fetch(imageUrl);
84
+ * response.body!.pipeTo(
85
+ * zipWriter.entry({ name: "path/to/file.png" }).writable
86
+ * );
87
+ * ```
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * const entryWriter = zipWriter.entry({ name: "hello.txt" });
92
+ * const writer = entryWriter.writable.getWriter();
93
+ * await writer.write(
94
+ * new TextEncoder().encode("Hello, World!")
95
+ * );
96
+ * await writer.close();
97
+ * console.log(await entryWriter.getEntryInfo()); // Entry info
98
+ * ```
99
+ *
100
+ * @param options Entry options
101
+ */
102
+ createEntryStream(options) {
103
+ if (this.#finalized) {
104
+ throw new TypeError("Cannot add entry after finalize() has been called");
105
+ }
106
+ this.#entryCount++;
107
+ // Capture the previous queue position
108
+ const prevQueued = this.#queued;
109
+ // Create a promise that will be resolved when this entry completes
110
+ let entryDone;
111
+ let entryError;
112
+ this.#queued = new Promise((resolve, reject) => {
113
+ entryDone = resolve;
114
+ entryError = reject;
115
+ });
116
+ // prevent unhandled rejection, but we still want this.#queued to reject
117
+ // when awaited if there's an error
118
+ this.#queued.catch(noop);
119
+ return new EntryWriter(async (readable) => {
120
+ // Wait for previous entry to complete
121
+ await prevQueued;
122
+ const writer = this.#zipStream.writable.getWriter();
123
+ const reader = readable.getReader();
124
+ try {
125
+ const entryInfo = await writeZipEntry({
126
+ crc32: this.#crc32,
127
+ writer,
128
+ reader,
129
+ entryOptions: options,
130
+ startOffset: this.#offset,
131
+ });
132
+ this.#entries.push(entryInfo);
133
+ entryDone();
134
+ return entryInfo;
135
+ }
136
+ catch (err) {
137
+ entryError(err);
138
+ await reader.cancel(err);
139
+ // Abort the zip stream - it's corrupted after a partial entry write
140
+ this.#zipStream.writable.abort(err);
141
+ // Don't call entryDone() - leave subsequent entries waiting forever
142
+ // since the zip stream is corrupted
143
+ // This error is handled in the EntryWriter constructor, and used to
144
+ // abort the entry writable stream
145
+ throw err;
146
+ }
147
+ finally {
148
+ reader.releaseLock();
149
+ writer.releaseLock();
150
+ }
151
+ });
152
+ }
153
+ /**
154
+ * Set the entries of the Zip archive. This can be used to reorder,
155
+ * remove, or rename entries before finalizing the archive.
156
+ *
157
+ * @param entries New entries array
158
+ */
159
+ #setEntries(entries) {
160
+ const currentEntriesByOffset = new Map();
161
+ for (const entry of this.#entries) {
162
+ currentEntriesByOffset.set(BigInt(entry.startOffset), entry);
163
+ }
164
+ // Entries can't have their offset, crc32, compressed size, or uncompressed
165
+ // size changed, but they can be removed, reordered, or have the name and
166
+ // comment changed.
167
+ for (const entry of entries) {
168
+ const existingEntry = currentEntriesByOffset.get(BigInt(entry.startOffset));
169
+ if (!existingEntry) {
170
+ throw new Error(`Cannot set entries: entry at offset ${entry.startOffset} does not exist`);
171
+ }
172
+ if (existingEntry.crc32 !== entry.crc32) {
173
+ throw new Error(`Cannot set entries: entry at offset ${entry.startOffset} has different CRC32`);
174
+ }
175
+ if (existingEntry.uncompressedSize !== entry.uncompressedSize) {
176
+ throw new Error(`Cannot set entries: entry at offset ${entry.startOffset} has different uncompressed size`);
177
+ }
178
+ if (existingEntry.compressedSize !== entry.compressedSize) {
179
+ throw new Error(`Cannot set entries: entry at offset ${entry.startOffset} has different compressed size`);
180
+ }
181
+ }
182
+ this.#entries = entries.map((entry) => ({ ...entry }));
183
+ }
184
+ /**
185
+ * Finalize the ZIP archive by writing the central directory and end of
186
+ * central directory records. You may not add any more entries after calling
187
+ * this method. This will await any pending entries to finish writing before
188
+ * finalizing.
189
+ *
190
+ * @param options.entries (Advanced) Optionally override the entries to write
191
+ * in the central directory. This can be used to reorder, remove, or rename
192
+ * entries before finalizing the archive, however you cannot add invalid
193
+ * entries, add additional entries, or modify their crc32, offsets or sizes.
194
+ * Use zipWriter.entries or entryWriter.getEntryInfo() to get the current
195
+ * entries for sorting or filtering.
196
+ *
197
+ * @returns Information about the finalized archive.
198
+ */
199
+ async finalize({ entries, } = {}) {
200
+ if (this.#finalized) {
201
+ throw new TypeError("finalize() has already been called");
202
+ }
203
+ this.#finalized = true;
204
+ if (entries) {
205
+ this.#setEntries(entries);
206
+ }
207
+ // We do this as an IIFE to avoid an unhandled error, so that a user can
208
+ // call finalize() without needing to await and catch an error. Any error
209
+ // will be propagated to the stream output, but the user can optionally
210
+ // await finalize() to also see the error.
211
+ const finalizePromise = (async () => {
212
+ await this.onceQueueEmpty();
213
+ // Write central directory headers for all entries
214
+ const centralDirectoryStart = this.#offset;
215
+ const writer = this.#zipStream.writable.getWriter();
216
+ try {
217
+ let entryUsesZip64 = false;
218
+ let uncompressedEntriesSize = BigInt(0);
219
+ let compressedEntriesSize = BigInt(0);
220
+ for (const entry of this.#entries) {
221
+ if (entry.zip64) {
222
+ entryUsesZip64 = true;
223
+ }
224
+ uncompressedEntriesSize += BigInt(entry.uncompressedSize);
225
+ compressedEntriesSize += BigInt(entry.compressedSize);
226
+ await writer.write(getCDFH(entry));
227
+ }
228
+ const centralDirectorySize = this.#offset - centralDirectoryStart;
229
+ // Determine if the archive needs ZIP64 based on entries or central directory
230
+ const eocdNeedsZip64 = this.#entries.length > 0xffff ||
231
+ centralDirectoryStart > ZIP64_LIMIT ||
232
+ centralDirectorySize > ZIP64_LIMIT;
233
+ let eocd;
234
+ if (eocdNeedsZip64) {
235
+ eocd = getEOCDZip64(BigInt(this.#entries.length), centralDirectoryStart, centralDirectorySize);
236
+ }
237
+ else {
238
+ eocd = getEOCDStandard(this.#entries.length, Number(centralDirectoryStart), Number(centralDirectorySize));
239
+ }
240
+ await writer.write(eocd);
241
+ // Close the zip stream
242
+ await writer.close();
243
+ return {
244
+ zip64: eocdNeedsZip64 || entryUsesZip64,
245
+ uncompressedEntriesSize,
246
+ compressedEntriesSize,
247
+ fileSize: this.#offset,
248
+ };
249
+ }
250
+ catch (err) {
251
+ await writer.abort(err);
252
+ throw err;
253
+ }
254
+ finally {
255
+ writer.releaseLock();
256
+ }
257
+ })();
258
+ finalizePromise.catch(noop); // prevent unhandled rejection
259
+ return finalizePromise;
260
+ }
261
+ }
262
+ class EntryWriter {
263
+ #entryStream = new TransformStream(undefined, bufferedQueue, bufferedQueue);
264
+ #written;
265
+ /**
266
+ * @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.
267
+ */
268
+ constructor(enqueueAndPipe) {
269
+ // We could try to pass the zipstream writable to EntryWriter, but then
270
+ // EntryWriter would not know when the entry has finished writing, and would
271
+ // not have a way to get the entry info.
272
+ this.#written = enqueueAndPipe(this.#entryStream.readable);
273
+ // abort the writable quickly if there is an error, and ensure we don't
274
+ // throw an uncaught error.
275
+ this.#written.catch((reason) => {
276
+ this.#entryStream.writable.abort(reason);
277
+ });
278
+ }
279
+ /**
280
+ * Writable stream to write entry data to.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * ReadableStream.from([new TextEncoder().encode("Hello, World!")])
285
+ * .pipeTo(entryWriter.writable);
286
+ * ```
287
+ */
288
+ get writable() {
289
+ return this.#entryStream.writable;
290
+ }
291
+ /**
292
+ * Get entry info. Resolves once all data has been written to the Zip stream.
293
+ */
294
+ async getEntryInfo() {
295
+ return this.#written;
296
+ }
297
+ }
298
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,OAAO,EACP,YAAY,EACZ,eAAe,GAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE/C,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ;AACvC,MAAM,aAAa,GAAG,IAAI,yBAAyB,CAAC;IAClD,aAAa,EAAE,WAAW;CAC3B,CAAC,CAAC;AAsCH,MAAM,OAAO,SAAS;IACpB,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,UAAU,GAAG,IAAI,eAAe,CAC9B;QACE,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;YAC/B,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;KACF;IACD,gEAAgE;IAChE,aAAa;IACb,wEAAwE;IACxE,yBAAyB;IACzB,aAAa,CACd,CAAC;IACF,QAAQ,GAAgB,EAAE,CAAC;IAC3B,OAAO,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC9C,WAAW,GAAG,CAAC,CAAC;IAChB,UAAU,GAAG,KAAK,CAAC;IACnB,MAAM,CAAC;IAEP;;OAEG;IACH,YAAY,EACV,KAAK,GAAG,YAAY,MAGlB,EAAE;QACJ,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;IAClC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,IAAI,CAAC,OAAO,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,WAAW,CAAC,IAA6B,EAAE,OAAqB;QACpE,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,WAAW,CAAC,YAAY,EAAE,CAAC;IACpC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,iBAAiB,CAAC,OAAqB;QACrC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,sCAAsC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;QAEhC,mEAAmE;QACnE,IAAI,SAAqB,CAAC;QAC1B,IAAI,UAAqC,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,SAAS,GAAG,OAAO,CAAC;YACpB,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,wEAAwE;QACxE,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEzB,OAAO,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACxC,sCAAsC;YACtC,MAAM,UAAU,CAAC;YAEjB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC;oBACpC,KAAK,EAAE,IAAI,CAAC,MAAM;oBAClB,MAAM;oBACN,MAAM;oBACN,YAAY,EAAE,OAAO;oBACrB,WAAW,EAAE,IAAI,CAAC,OAAO;iBAC1B,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC9B,SAAS,EAAE,CAAC;gBACZ,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,GAAG,CAAC,CAAC;gBAChB,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACzB,oEAAoE;gBACpE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpC,oEAAoE;gBACpE,oCAAoC;gBACpC,oEAAoE;gBACpE,kCAAkC;gBAClC,MAAM,GAAG,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,OAA2C;QACrD,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC5D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;QACD,2EAA2E;QAC3E,yEAAyE;QACzE,mBAAmB;QACnB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAC9C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAC1B,CAAC;YACF,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,WAAW,iBAAiB,CAC1E,CAAC;YACJ,CAAC;YACD,IAAI,aAAa,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,WAAW,sBAAsB,CAC/E,CAAC;YACJ,CAAC;YACD,IAAI,aAAa,CAAC,gBAAgB,KAAK,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC9D,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,WAAW,kCAAkC,CAC3F,CAAC;YACJ,CAAC;YACD,IAAI,aAAa,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,WAAW,gCAAgC,CACzF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,QAAQ,CAAC,EACb,OAAO,MAC6C,EAAE;QAUtD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,0CAA0C;QAC1C,MAAM,eAAe,GAAG,CAAC,KAAK,IAAI,EAAE;YAClC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAE5B,kDAAkD;YAClD,MAAM,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAEpD,IAAI,CAAC;gBACH,IAAI,cAAc,GAAG,KAAK,CAAC;gBAC3B,IAAI,uBAAuB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,qBAAqB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBAChB,cAAc,GAAG,IAAI,CAAC;oBACxB,CAAC;oBACD,uBAAuB,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;oBAC1D,qBAAqB,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;oBACtD,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrC,CAAC;gBAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,GAAG,qBAAqB,CAAC;gBAElE,6EAA6E;gBAC7E,MAAM,cAAc,GAClB,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM;oBAC7B,qBAAqB,GAAG,WAAW;oBACnC,oBAAoB,GAAG,WAAW,CAAC;gBAErC,IAAI,IAA6B,CAAC;gBAClC,IAAI,cAAc,EAAE,CAAC;oBACnB,IAAI,GAAG,YAAY,CACjB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC5B,qBAAqB,EACrB,oBAAoB,CACrB,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,eAAe,CACpB,IAAI,CAAC,QAAQ,CAAC,MAAM,EACpB,MAAM,CAAC,qBAAqB,CAAC,EAC7B,MAAM,CAAC,oBAAoB,CAAC,CAC7B,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEzB,uBAAuB;gBACvB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBAErB,OAAO;oBACL,KAAK,EAAE,cAAc,IAAI,cAAc;oBACvC,uBAAuB;oBACvB,qBAAqB;oBACrB,QAAQ,EAAE,IAAI,CAAC,OAAO;iBACvB,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM,GAAG,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,8BAA8B;QAC3D,OAAO,eAAe,CAAC;IACzB,CAAC;CACF;AAED,MAAM,WAAW;IACf,YAAY,GAAG,IAAI,eAAe,CAChC,SAAS,EACT,aAAa,EACb,aAAa,CACd,CAAC;IACF,QAAQ,CAAqB;IAE7B;;OAEG;IACH,YACE,cAEuB;QAEvB,uEAAuE;QACvE,4EAA4E;QAC5E,wCAAwC;QACxC,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC3D,uEAAuE;QACvE,2BAA2B;QAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export declare function getDosTime(date: Date): number;
2
+ export declare function getDosDate(date: Date): number;
3
+ export declare function noop(): void;
4
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAM7C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAM7C;AAED,wBAAgB,IAAI,SAAK"}
package/dist/utils.js ADDED
@@ -0,0 +1,12 @@
1
+ export function getDosTime(date) {
2
+ return ((date.getHours() << 11) |
3
+ (date.getMinutes() << 5) |
4
+ (date.getSeconds() >> 1));
5
+ }
6
+ export function getDosDate(date) {
7
+ return (((date.getFullYear() - 1980) << 9) |
8
+ ((date.getMonth() + 1) << 5) |
9
+ date.getDate());
10
+ }
11
+ export function noop() { }
12
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,CACL,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACxB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,CACL,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE,CACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI,KAAI,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { EntryInfo } from "./index.js";
2
+ /**
3
+ * Generate the Central Directory File Header for the given entry info.
4
+ */
5
+ export declare function getCDFH(entryInfo: EntryInfo): Uint8Array<ArrayBuffer>;
6
+ /**
7
+ * Generate the End of Central Directory record with zip64 support.
8
+ */
9
+ export declare function getEOCDStandard(entriesCount: number, centralDirectoryOffset: number, centralDirectorySize: number): Uint8Array<ArrayBuffer>;
10
+ /**
11
+ * Generate the ZIP64 End of Central Directory record.
12
+ */
13
+ export declare function getEOCDZip64(entriesCount: bigint, centralDirectoryOffset: bigint, centralDirectorySize: bigint): Uint8Array<ArrayBuffer>;
14
+ //# sourceMappingURL=write-central-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-central-directory.d.ts","sourceRoot":"","sources":["../src/write-central-directory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAqC,MAAM,YAAY,CAAC;AAsB/E;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAMrE;AAsND;;GAEG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,sBAAsB,EAAE,MAAM,EAC9B,oBAAoB,EAAE,MAAM,GAC3B,UAAU,CAAC,WAAW,CAAC,CAsCzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,sBAAsB,EAAE,MAAM,EAC9B,oBAAoB,EAAE,MAAM,GAC3B,UAAU,CAAC,WAAW,CAAC,CAyGzB"}