@myrialabs/zipkit 0.0.6

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 (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +329 -0
  3. package/dist/bench/corpus.d.ts +21 -0
  4. package/dist/bench/corpus.d.ts.map +1 -0
  5. package/dist/bench/corpus.js +92 -0
  6. package/dist/bench/corpus.js.map +1 -0
  7. package/dist/checksum.d.ts +29 -0
  8. package/dist/checksum.d.ts.map +1 -0
  9. package/dist/checksum.js +35 -0
  10. package/dist/checksum.js.map +1 -0
  11. package/dist/cli.d.ts +17 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +427 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codecs/brotli.d.ts +6 -0
  16. package/dist/codecs/brotli.d.ts.map +1 -0
  17. package/dist/codecs/brotli.js +15 -0
  18. package/dist/codecs/brotli.js.map +1 -0
  19. package/dist/codecs/bzip2.d.ts +6 -0
  20. package/dist/codecs/bzip2.d.ts.map +1 -0
  21. package/dist/codecs/bzip2.js +15 -0
  22. package/dist/codecs/bzip2.js.map +1 -0
  23. package/dist/codecs/deflate.d.ts +6 -0
  24. package/dist/codecs/deflate.d.ts.map +1 -0
  25. package/dist/codecs/deflate.js +25 -0
  26. package/dist/codecs/deflate.js.map +1 -0
  27. package/dist/codecs/gzip.d.ts +6 -0
  28. package/dist/codecs/gzip.d.ts.map +1 -0
  29. package/dist/codecs/gzip.js +25 -0
  30. package/dist/codecs/gzip.js.map +1 -0
  31. package/dist/codecs/image.d.ts +5 -0
  32. package/dist/codecs/image.d.ts.map +1 -0
  33. package/dist/codecs/image.js +16 -0
  34. package/dist/codecs/image.js.map +1 -0
  35. package/dist/codecs/index.d.ts +18 -0
  36. package/dist/codecs/index.d.ts.map +1 -0
  37. package/dist/codecs/index.js +18 -0
  38. package/dist/codecs/index.js.map +1 -0
  39. package/dist/codecs/lz4.d.ts +6 -0
  40. package/dist/codecs/lz4.d.ts.map +1 -0
  41. package/dist/codecs/lz4.js +17 -0
  42. package/dist/codecs/lz4.js.map +1 -0
  43. package/dist/codecs/lzma.d.ts +6 -0
  44. package/dist/codecs/lzma.d.ts.map +1 -0
  45. package/dist/codecs/lzma.js +15 -0
  46. package/dist/codecs/lzma.js.map +1 -0
  47. package/dist/codecs/snappy.d.ts +6 -0
  48. package/dist/codecs/snappy.d.ts.map +1 -0
  49. package/dist/codecs/snappy.js +14 -0
  50. package/dist/codecs/snappy.js.map +1 -0
  51. package/dist/codecs/video.d.ts +13 -0
  52. package/dist/codecs/video.d.ts.map +1 -0
  53. package/dist/codecs/video.js +26 -0
  54. package/dist/codecs/video.js.map +1 -0
  55. package/dist/codecs/xz.d.ts +6 -0
  56. package/dist/codecs/xz.d.ts.map +1 -0
  57. package/dist/codecs/xz.js +30 -0
  58. package/dist/codecs/xz.js.map +1 -0
  59. package/dist/codecs/zlib.d.ts +6 -0
  60. package/dist/codecs/zlib.d.ts.map +1 -0
  61. package/dist/codecs/zlib.js +15 -0
  62. package/dist/codecs/zlib.js.map +1 -0
  63. package/dist/codecs/zstd.d.ts +6 -0
  64. package/dist/codecs/zstd.d.ts.map +1 -0
  65. package/dist/codecs/zstd.js +24 -0
  66. package/dist/codecs/zstd.js.map +1 -0
  67. package/dist/compress.d.ts +20 -0
  68. package/dist/compress.d.ts.map +1 -0
  69. package/dist/compress.js +83 -0
  70. package/dist/compress.js.map +1 -0
  71. package/dist/delta.d.ts +30 -0
  72. package/dist/delta.d.ts.map +1 -0
  73. package/dist/delta.js +44 -0
  74. package/dist/delta.js.map +1 -0
  75. package/dist/detect.d.ts +46 -0
  76. package/dist/detect.d.ts.map +1 -0
  77. package/dist/detect.js +86 -0
  78. package/dist/detect.js.map +1 -0
  79. package/dist/dictionary.d.ts +37 -0
  80. package/dist/dictionary.d.ts.map +1 -0
  81. package/dist/dictionary.js +71 -0
  82. package/dist/dictionary.js.map +1 -0
  83. package/dist/engine.d.ts +102 -0
  84. package/dist/engine.d.ts.map +1 -0
  85. package/dist/engine.js +204 -0
  86. package/dist/engine.js.map +1 -0
  87. package/dist/fsa.d.ts +54 -0
  88. package/dist/fsa.d.ts.map +1 -0
  89. package/dist/fsa.js +45 -0
  90. package/dist/fsa.js.map +1 -0
  91. package/dist/index.d.ts +35 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +47 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/internal.d.ts +21 -0
  96. package/dist/internal.d.ts.map +1 -0
  97. package/dist/internal.js +42 -0
  98. package/dist/internal.js.map +1 -0
  99. package/dist/middleware/elysia.d.ts +15 -0
  100. package/dist/middleware/elysia.d.ts.map +1 -0
  101. package/dist/middleware/elysia.js +43 -0
  102. package/dist/middleware/elysia.js.map +1 -0
  103. package/dist/middleware/express.d.ts +17 -0
  104. package/dist/middleware/express.d.ts.map +1 -0
  105. package/dist/middleware/express.js +62 -0
  106. package/dist/middleware/express.js.map +1 -0
  107. package/dist/middleware/hono.d.ts +17 -0
  108. package/dist/middleware/hono.d.ts.map +1 -0
  109. package/dist/middleware/hono.js +41 -0
  110. package/dist/middleware/hono.js.map +1 -0
  111. package/dist/middleware/index.d.ts +14 -0
  112. package/dist/middleware/index.d.ts.map +1 -0
  113. package/dist/middleware/index.js +14 -0
  114. package/dist/middleware/index.js.map +1 -0
  115. package/dist/middleware/shared.d.ts +29 -0
  116. package/dist/middleware/shared.d.ts.map +1 -0
  117. package/dist/middleware/shared.js +47 -0
  118. package/dist/middleware/shared.js.map +1 -0
  119. package/dist/pack.d.ts +36 -0
  120. package/dist/pack.d.ts.map +1 -0
  121. package/dist/pack.js +75 -0
  122. package/dist/pack.js.map +1 -0
  123. package/dist/parallel/index.d.ts +56 -0
  124. package/dist/parallel/index.d.ts.map +1 -0
  125. package/dist/parallel/index.js +158 -0
  126. package/dist/parallel/index.js.map +1 -0
  127. package/dist/sevenzip/index.d.ts +45 -0
  128. package/dist/sevenzip/index.d.ts.map +1 -0
  129. package/dist/sevenzip/index.js +646 -0
  130. package/dist/sevenzip/index.js.map +1 -0
  131. package/dist/streams/index.d.ts +32 -0
  132. package/dist/streams/index.d.ts.map +1 -0
  133. package/dist/streams/index.js +74 -0
  134. package/dist/streams/index.js.map +1 -0
  135. package/dist/string.d.ts +38 -0
  136. package/dist/string.d.ts.map +1 -0
  137. package/dist/string.js +64 -0
  138. package/dist/string.js.map +1 -0
  139. package/dist/tar/index.d.ts +99 -0
  140. package/dist/tar/index.d.ts.map +1 -0
  141. package/dist/tar/index.js +380 -0
  142. package/dist/tar/index.js.map +1 -0
  143. package/dist/types.d.ts +59 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +22 -0
  146. package/dist/types.js.map +1 -0
  147. package/dist/workers/index.d.ts +58 -0
  148. package/dist/workers/index.d.ts.map +1 -0
  149. package/dist/workers/index.js +158 -0
  150. package/dist/workers/index.js.map +1 -0
  151. package/dist/workers/worker.d.ts +18 -0
  152. package/dist/workers/worker.d.ts.map +1 -0
  153. package/dist/workers/worker.js +45 -0
  154. package/dist/workers/worker.js.map +1 -0
  155. package/dist/zip/crypto/aes.d.ts +25 -0
  156. package/dist/zip/crypto/aes.d.ts.map +1 -0
  157. package/dist/zip/crypto/aes.js +156 -0
  158. package/dist/zip/crypto/aes.js.map +1 -0
  159. package/dist/zip/crypto/winzip.d.ts +28 -0
  160. package/dist/zip/crypto/winzip.d.ts.map +1 -0
  161. package/dist/zip/crypto/winzip.js +87 -0
  162. package/dist/zip/crypto/winzip.js.map +1 -0
  163. package/dist/zip/crypto/zipcrypto.d.ts +14 -0
  164. package/dist/zip/crypto/zipcrypto.d.ts.map +1 -0
  165. package/dist/zip/crypto/zipcrypto.js +65 -0
  166. package/dist/zip/crypto/zipcrypto.js.map +1 -0
  167. package/dist/zip/datetime.d.ts +9 -0
  168. package/dist/zip/datetime.d.ts.map +1 -0
  169. package/dist/zip/datetime.js +13 -0
  170. package/dist/zip/datetime.js.map +1 -0
  171. package/dist/zip/index.d.ts +134 -0
  172. package/dist/zip/index.d.ts.map +1 -0
  173. package/dist/zip/index.js +473 -0
  174. package/dist/zip/index.js.map +1 -0
  175. package/dist/zip/stream.d.ts +38 -0
  176. package/dist/zip/stream.d.ts.map +1 -0
  177. package/dist/zip/stream.js +240 -0
  178. package/dist/zip/stream.js.map +1 -0
  179. package/dist/zipkit.d.ts +74 -0
  180. package/dist/zipkit.d.ts.map +1 -0
  181. package/dist/zipkit.js +168 -0
  182. package/dist/zipkit.js.map +1 -0
  183. package/engine/dist/zipkit-engine.mjs +2 -0
  184. package/engine/dist/zipkit-engine.wasm +0 -0
  185. package/package.json +137 -0
@@ -0,0 +1,158 @@
1
+ /**
2
+ * A persistent, warm worker pool for non-blocking compression on Node and Bun.
3
+ *
4
+ * Spinning up a worker per call (and re-instantiating the 1.4 MB Wasm engine
5
+ * each time) is the cold-start tax fflate's async API pays. ZipKit keeps a
6
+ * fixed pool of workers, each with the engine already loaded, and round-robins
7
+ * jobs across them. Where workers aren't available (e.g. the browser without
8
+ * bundler support), it transparently falls back to running on the calling
9
+ * thread, so the API never breaks.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { WorkerPool } from '@myrialabs/zipkit/workers';
14
+ * const pool = new WorkerPool();
15
+ * const out = await pool.compress(bytes, 'zstd', { level: 19 });
16
+ * await pool.destroy();
17
+ * ```
18
+ */
19
+ import { AbortError } from '../types.js';
20
+ /** Worker file lives next to this module; `.ts` in source, `.js` once built. */
21
+ const WORKER_URL = new URL(import.meta.url.endsWith('.ts') ? './worker.ts' : './worker.js', import.meta.url);
22
+ /** Default pool size: one worker per CPU, capped to keep memory sane. */
23
+ function defaultSize() {
24
+ const cores = globalThis.navigator?.hardwareConcurrency ?? 4;
25
+ return Math.max(1, Math.min(cores, 8));
26
+ }
27
+ async function loadWorkerThreads() {
28
+ try {
29
+ return await import('node:worker_threads');
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ }
35
+ export class WorkerPool {
36
+ size;
37
+ workers = [];
38
+ pending = new Map();
39
+ next = 0;
40
+ seq = 0;
41
+ ready;
42
+ usable = true;
43
+ /**
44
+ * Workers are `unref`'d at rest so an idle pool never blocks process exit.
45
+ * While any job is in flight we `ref` them, so a script whose last action is
46
+ * `await pool.compress(...)` doesn't exit before the result arrives.
47
+ */
48
+ refWhileBusy() {
49
+ const busy = this.pending.size > 0;
50
+ for (const w of this.workers)
51
+ (busy ? w.ref : w.unref).call(w);
52
+ }
53
+ constructor(opts = {}) {
54
+ this.size = opts.size ?? defaultSize();
55
+ }
56
+ async ensure() {
57
+ if (this.ready)
58
+ return this.ready;
59
+ this.ready = (async () => {
60
+ const wt = await loadWorkerThreads();
61
+ if (!wt) {
62
+ // No worker_threads (e.g. a browser): fall back to inline execution.
63
+ this.usable = false;
64
+ return;
65
+ }
66
+ for (let i = 0; i < this.size; i++) {
67
+ const worker = new wt.Worker(WORKER_URL);
68
+ worker.on('message', (res) => this.settle(res));
69
+ worker.on('error', (err) => this.failAll(err));
70
+ worker.unref();
71
+ this.workers.push(worker);
72
+ }
73
+ })();
74
+ return this.ready;
75
+ }
76
+ settle(res) {
77
+ const p = this.pending.get(res.id);
78
+ if (!p)
79
+ return;
80
+ this.pending.delete(res.id);
81
+ this.refWhileBusy();
82
+ if (p.signal && p.onAbort)
83
+ p.signal.removeEventListener('abort', p.onAbort);
84
+ if (res.ok && res.result)
85
+ p.resolve(res.result);
86
+ else
87
+ p.reject(new Error(res.error ?? 'Worker operation failed'));
88
+ }
89
+ failAll(err) {
90
+ for (const [, p] of this.pending)
91
+ p.reject(err);
92
+ this.pending.clear();
93
+ this.refWhileBusy();
94
+ }
95
+ async run(kind, data, codec, level, mode, signal, method) {
96
+ if (signal?.aborted)
97
+ throw new AbortError();
98
+ await this.ensure();
99
+ // Fallback: run on this thread when no worker pool is available.
100
+ if (!this.usable) {
101
+ if (kind === 'zipCompress') {
102
+ const { getEngine } = await import('../engine.js');
103
+ const e = await getEngine();
104
+ return method === 'zstd' ? e.zstdCompress(data, level ?? 19) : e.deflateCompress(data, level ?? 6);
105
+ }
106
+ const { compress, decompressWith } = await import('../compress.js');
107
+ return kind === 'compress' ? compress(data, codec, { level, mode }) : decompressWith(data, codec);
108
+ }
109
+ const id = this.seq++;
110
+ const worker = this.workers[this.next++ % this.workers.length];
111
+ return new Promise((resolve, reject) => {
112
+ const pending = { resolve, reject, signal };
113
+ if (signal) {
114
+ pending.onAbort = () => {
115
+ this.pending.delete(id);
116
+ this.refWhileBusy();
117
+ reject(new AbortError());
118
+ };
119
+ signal.addEventListener('abort', pending.onAbort, { once: true });
120
+ }
121
+ this.pending.set(id, pending);
122
+ this.refWhileBusy();
123
+ // Copy the input so transferring its buffer can't detach the caller's view.
124
+ const payload = data.slice();
125
+ const req = { id, kind, codec, level, mode, method, data: payload };
126
+ worker.postMessage(req, [payload.buffer]);
127
+ });
128
+ }
129
+ /** Compress `data` with `codec` on a worker (or inline as a fallback). */
130
+ compress(data, codec, opts) {
131
+ return this.run('compress', data, codec, opts?.level, opts?.mode, opts?.signal);
132
+ }
133
+ /** Decompress `data` with `codec` on a worker (or inline as a fallback). */
134
+ decompress(data, codec, opts) {
135
+ return this.run('decompress', data, codec, undefined, undefined, opts?.signal);
136
+ }
137
+ /**
138
+ * Compress a ZIP entry on a worker using the raw libdeflate / zstd engine —
139
+ * denser than the native path and byte-identical to the inline container
140
+ * code, so a parallel archive matches a single-threaded one exactly.
141
+ */
142
+ zipCompress(data, method, level) {
143
+ return this.run('zipCompress', data, method, level, undefined, undefined, method);
144
+ }
145
+ /** Terminate all workers and reject any in-flight jobs. */
146
+ async destroy() {
147
+ this.failAll(new Error('Worker pool destroyed'));
148
+ await Promise.all(this.workers.map((w) => w.terminate()));
149
+ this.workers = [];
150
+ this.ready = undefined;
151
+ }
152
+ }
153
+ let shared;
154
+ /** A lazily-created, process-wide {@link WorkerPool}. */
155
+ export function sharedPool() {
156
+ return (shared ??= new WorkerPool());
157
+ }
158
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Codec, CompressionMode } from '../types.js';
2
+ export interface WorkerRequest {
3
+ id: number;
4
+ kind: 'compress' | 'decompress' | 'zipCompress';
5
+ codec: Codec;
6
+ mode?: CompressionMode;
7
+ level?: number;
8
+ /** ZIP entry method (`zipCompress` only) — raw libdeflate / zstd, no native dispatch. */
9
+ method?: 'deflate' | 'zstd';
10
+ data: Uint8Array;
11
+ }
12
+ export interface WorkerResponse {
13
+ id: number;
14
+ ok: boolean;
15
+ result?: Uint8Array;
16
+ error?: string;
17
+ }
18
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/workers/worker.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,CAAC;IAChD,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Worker entry point. Runs codec operations off the main thread, one Wasm
3
+ * engine per worker. Speaks the tiny message protocol in {@link WorkerRequest} /
4
+ * {@link WorkerResponse}; transfers buffers both ways for zero-copy handoff.
5
+ */
6
+ import { parentPort } from 'node:worker_threads';
7
+ import { getEngine } from '../engine.js';
8
+ import { compress, decompressWith } from '../compress.js';
9
+ if (parentPort) {
10
+ const port = parentPort;
11
+ // Warm the engine immediately so the first job doesn't pay instantiation.
12
+ void getEngine();
13
+ port.on('message', async (req) => {
14
+ try {
15
+ let result;
16
+ if (req.kind === 'zipCompress') {
17
+ // ZIP entries must use the raw libdeflate / zstd engine (denser than
18
+ // native, and byte-identical to the inline path), bypassing the
19
+ // codec's native dispatch.
20
+ const e = await getEngine();
21
+ result =
22
+ req.method === 'zstd'
23
+ ? e.zstdCompress(req.data, req.level ?? 19)
24
+ : e.deflateCompress(req.data, req.level ?? 6);
25
+ }
26
+ else if (req.kind === 'compress') {
27
+ result = await compress(req.data, req.codec, { mode: req.mode, level: req.level });
28
+ }
29
+ else {
30
+ result = await decompressWith(req.data, req.codec);
31
+ }
32
+ const res = { id: req.id, ok: true, result };
33
+ port.postMessage(res, [result.buffer]);
34
+ }
35
+ catch (err) {
36
+ const res = {
37
+ id: req.id,
38
+ ok: false,
39
+ error: err instanceof Error ? err.message : String(err)
40
+ };
41
+ port.postMessage(res);
42
+ }
43
+ });
44
+ }
45
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/workers/worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAqB1D,IAAI,UAAU,EAAE,CAAC;IAChB,MAAM,IAAI,GAAG,UAAU,CAAC;IACxB,0EAA0E;IAC1E,KAAK,SAAS,EAAE,CAAC;IAEjB,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,GAAkB,EAAE,EAAE;QAC/C,IAAI,CAAC;YACJ,IAAI,MAAkB,CAAC;YACvB,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAChC,qEAAqE;gBACrE,gEAAgE;gBAChE,2BAA2B;gBAC3B,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;gBAC5B,MAAM;oBACL,GAAG,CAAC,MAAM,KAAK,MAAM;wBACpB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;wBAC3C,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;YACjD,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACpC,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACP,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,GAAG,GAAmB,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC7D,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAqB,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,GAAmB;gBAC3B,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACvD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Compact AES (128/192/256) block cipher in CTR mode.
3
+ *
4
+ * WinZip AES-encrypted ZIP entries use AES in CTR mode with a 16-byte counter
5
+ * that increments **little-endian** starting at 1 — which the WebCrypto
6
+ * `AES-CTR` primitive (big-endian counter, no raw-block/ECB access) cannot
7
+ * produce. So the keystream is built here from a small, dependency-free,
8
+ * synchronous AES, while the standard parts (PBKDF2, HMAC-SHA1) still come from
9
+ * WebCrypto in the caller. Tables are derived once on first use.
10
+ */
11
+ /** An AES cipher with an expanded key, exposing single-block ECB encryption. */
12
+ export declare class Aes {
13
+ private rk;
14
+ private rounds;
15
+ constructor(key: Uint8Array);
16
+ /** Encrypt one 16-byte block of `src` at `srcOff` into `dst` at `dstOff`. */
17
+ encryptBlock(src: Uint8Array, srcOff: number, dst: Uint8Array, dstOff: number): void;
18
+ }
19
+ /**
20
+ * Encrypt/decrypt `data` with WinZip's AES-CTR: a 16-byte little-endian counter
21
+ * starting at 1, one keystream block per 16 bytes, XORed into the data. CTR is
22
+ * symmetric, so the same call decrypts.
23
+ */
24
+ export declare function aesCtrXor(cipher: Aes, data: Uint8Array): Uint8Array;
25
+ //# sourceMappingURL=aes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["../../../src/zip/crypto/aes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuDH,gFAAgF;AAChF,qBAAa,GAAG;IACf,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,GAAG,EAAE,UAAU;IAwB3B,6EAA6E;IAC7E,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAsCpF;AAMD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAkBnE"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Compact AES (128/192/256) block cipher in CTR mode.
3
+ *
4
+ * WinZip AES-encrypted ZIP entries use AES in CTR mode with a 16-byte counter
5
+ * that increments **little-endian** starting at 1 — which the WebCrypto
6
+ * `AES-CTR` primitive (big-endian counter, no raw-block/ECB access) cannot
7
+ * produce. So the keystream is built here from a small, dependency-free,
8
+ * synchronous AES, while the standard parts (PBKDF2, HMAC-SHA1) still come from
9
+ * WebCrypto in the caller. Tables are derived once on first use.
10
+ */
11
+ let SBOX;
12
+ let T0, T1, T2, T3;
13
+ const RCON = new Uint32Array([0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000]);
14
+ /** Build the S-box and the four encryption T-tables (GF(2^8) arithmetic). */
15
+ function buildTables() {
16
+ SBOX = new Uint8Array(256);
17
+ const inv = new Uint8Array(256);
18
+ let p = 1;
19
+ let q = 1;
20
+ // Generate multiplicative inverses via a generator (3) over GF(2^8).
21
+ do {
22
+ p = p ^ (p << 1) ^ (p & 0x80 ? 0x11b : 0);
23
+ p &= 0xff;
24
+ q ^= q << 1;
25
+ q ^= q << 2;
26
+ q ^= q << 4;
27
+ q &= 0xff;
28
+ if (q & 0x80)
29
+ q ^= 0x09;
30
+ q &= 0xff;
31
+ inv[p] = q;
32
+ } while (p !== 1);
33
+ SBOX[0] = 0x63;
34
+ for (let i = 0; i < 256; i++) {
35
+ let x = inv[i];
36
+ let s = x;
37
+ for (let k = 0; k < 4; k++) {
38
+ s = ((s << 1) | (s >>> 7)) & 0xff;
39
+ x ^= s;
40
+ }
41
+ x ^= 0x63;
42
+ SBOX[i] = i === 0 ? 0x63 : x;
43
+ }
44
+ T0 = new Uint32Array(256);
45
+ T1 = new Uint32Array(256);
46
+ T2 = new Uint32Array(256);
47
+ T3 = new Uint32Array(256);
48
+ for (let i = 0; i < 256; i++) {
49
+ const s = SBOX[i];
50
+ const s2 = xtime(s);
51
+ const s3 = s2 ^ s;
52
+ T0[i] = ((s2 << 24) | (s << 16) | (s << 8) | s3) >>> 0;
53
+ T1[i] = ((s3 << 24) | (s2 << 16) | (s << 8) | s) >>> 0;
54
+ T2[i] = ((s << 24) | (s3 << 16) | (s2 << 8) | s) >>> 0;
55
+ T3[i] = ((s << 24) | (s << 16) | (s3 << 8) | s2) >>> 0;
56
+ }
57
+ }
58
+ function xtime(a) {
59
+ return ((a << 1) ^ (a & 0x80 ? 0x11b : 0)) & 0xff;
60
+ }
61
+ /** An AES cipher with an expanded key, exposing single-block ECB encryption. */
62
+ export class Aes {
63
+ rk;
64
+ rounds;
65
+ constructor(key) {
66
+ if (!SBOX)
67
+ buildTables();
68
+ if (key.length !== 16 && key.length !== 24 && key.length !== 32) {
69
+ throw new Error(`AES key must be 16/24/32 bytes, got ${key.length}`);
70
+ }
71
+ const Nk = key.length / 4;
72
+ this.rounds = Nk + 6;
73
+ const total = 4 * (this.rounds + 1);
74
+ const rk = new Uint32Array(total);
75
+ for (let i = 0; i < Nk; i++) {
76
+ rk[i] = ((key[4 * i] << 24) | (key[4 * i + 1] << 16) | (key[4 * i + 2] << 8) | key[4 * i + 3]) >>> 0;
77
+ }
78
+ for (let i = Nk; i < total; i++) {
79
+ let temp = rk[i - 1];
80
+ if (i % Nk === 0) {
81
+ temp = (subWord((temp << 8) | (temp >>> 24)) ^ RCON[i / Nk - 1]) >>> 0;
82
+ }
83
+ else if (Nk > 6 && i % Nk === 4) {
84
+ temp = subWord(temp);
85
+ }
86
+ rk[i] = (rk[i - Nk] ^ temp) >>> 0;
87
+ }
88
+ this.rk = rk;
89
+ }
90
+ /** Encrypt one 16-byte block of `src` at `srcOff` into `dst` at `dstOff`. */
91
+ encryptBlock(src, srcOff, dst, dstOff) {
92
+ const rk = this.rk;
93
+ let s0 = ((src[srcOff] << 24) | (src[srcOff + 1] << 16) | (src[srcOff + 2] << 8) | src[srcOff + 3]) ^ rk[0];
94
+ let s1 = ((src[srcOff + 4] << 24) | (src[srcOff + 5] << 16) | (src[srcOff + 6] << 8) | src[srcOff + 7]) ^ rk[1];
95
+ let s2 = ((src[srcOff + 8] << 24) | (src[srcOff + 9] << 16) | (src[srcOff + 10] << 8) | src[srcOff + 11]) ^ rk[2];
96
+ let s3 = ((src[srcOff + 12] << 24) | (src[srcOff + 13] << 16) | (src[srcOff + 14] << 8) | src[srcOff + 15]) ^ rk[3];
97
+ let rki = 4;
98
+ for (let round = 1; round < this.rounds; round++) {
99
+ const t0 = (T0[(s0 >>> 24) & 0xff] ^ T1[(s1 >>> 16) & 0xff] ^ T2[(s2 >>> 8) & 0xff] ^ T3[s3 & 0xff] ^ rk[rki]) >>> 0;
100
+ const t1 = (T0[(s1 >>> 24) & 0xff] ^ T1[(s2 >>> 16) & 0xff] ^ T2[(s3 >>> 8) & 0xff] ^ T3[s0 & 0xff] ^ rk[rki + 1]) >>> 0;
101
+ const t2 = (T0[(s2 >>> 24) & 0xff] ^ T1[(s3 >>> 16) & 0xff] ^ T2[(s0 >>> 8) & 0xff] ^ T3[s1 & 0xff] ^ rk[rki + 2]) >>> 0;
102
+ const t3 = (T0[(s3 >>> 24) & 0xff] ^ T1[(s0 >>> 16) & 0xff] ^ T2[(s1 >>> 8) & 0xff] ^ T3[s2 & 0xff] ^ rk[rki + 3]) >>> 0;
103
+ s0 = t0;
104
+ s1 = t1;
105
+ s2 = t2;
106
+ s3 = t3;
107
+ rki += 4;
108
+ }
109
+ // Final round uses the S-box directly (no mix-columns).
110
+ dst[dstOff] = (SBOX[(s0 >>> 24) & 0xff] ^ (rk[rki] >>> 24)) & 0xff;
111
+ dst[dstOff + 1] = (SBOX[(s1 >>> 16) & 0xff] ^ (rk[rki] >>> 16)) & 0xff;
112
+ dst[dstOff + 2] = (SBOX[(s2 >>> 8) & 0xff] ^ (rk[rki] >>> 8)) & 0xff;
113
+ dst[dstOff + 3] = (SBOX[s3 & 0xff] ^ rk[rki]) & 0xff;
114
+ dst[dstOff + 4] = (SBOX[(s1 >>> 24) & 0xff] ^ (rk[rki + 1] >>> 24)) & 0xff;
115
+ dst[dstOff + 5] = (SBOX[(s2 >>> 16) & 0xff] ^ (rk[rki + 1] >>> 16)) & 0xff;
116
+ dst[dstOff + 6] = (SBOX[(s3 >>> 8) & 0xff] ^ (rk[rki + 1] >>> 8)) & 0xff;
117
+ dst[dstOff + 7] = (SBOX[s0 & 0xff] ^ rk[rki + 1]) & 0xff;
118
+ dst[dstOff + 8] = (SBOX[(s2 >>> 24) & 0xff] ^ (rk[rki + 2] >>> 24)) & 0xff;
119
+ dst[dstOff + 9] = (SBOX[(s3 >>> 16) & 0xff] ^ (rk[rki + 2] >>> 16)) & 0xff;
120
+ dst[dstOff + 10] = (SBOX[(s0 >>> 8) & 0xff] ^ (rk[rki + 2] >>> 8)) & 0xff;
121
+ dst[dstOff + 11] = (SBOX[s1 & 0xff] ^ rk[rki + 2]) & 0xff;
122
+ dst[dstOff + 12] = (SBOX[(s3 >>> 24) & 0xff] ^ (rk[rki + 3] >>> 24)) & 0xff;
123
+ dst[dstOff + 13] = (SBOX[(s0 >>> 16) & 0xff] ^ (rk[rki + 3] >>> 16)) & 0xff;
124
+ dst[dstOff + 14] = (SBOX[(s1 >>> 8) & 0xff] ^ (rk[rki + 3] >>> 8)) & 0xff;
125
+ dst[dstOff + 15] = (SBOX[s2 & 0xff] ^ rk[rki + 3]) & 0xff;
126
+ }
127
+ }
128
+ function subWord(w) {
129
+ return ((SBOX[(w >>> 24) & 0xff] << 24) | (SBOX[(w >>> 16) & 0xff] << 16) | (SBOX[(w >>> 8) & 0xff] << 8) | SBOX[w & 0xff]) >>> 0;
130
+ }
131
+ /**
132
+ * Encrypt/decrypt `data` with WinZip's AES-CTR: a 16-byte little-endian counter
133
+ * starting at 1, one keystream block per 16 bytes, XORed into the data. CTR is
134
+ * symmetric, so the same call decrypts.
135
+ */
136
+ export function aesCtrXor(cipher, data) {
137
+ const out = new Uint8Array(data.length);
138
+ const counter = new Uint8Array(16);
139
+ const keystream = new Uint8Array(16);
140
+ let nonce = 1; // little-endian counter, incremented per block
141
+ for (let off = 0; off < data.length; off += 16) {
142
+ // Write the little-endian counter into the low bytes (WinZip uses a 64-bit
143
+ // counter in practice; 32 bits is ample for any in-memory buffer).
144
+ counter[0] = nonce & 0xff;
145
+ counter[1] = (nonce >>> 8) & 0xff;
146
+ counter[2] = (nonce >>> 16) & 0xff;
147
+ counter[3] = (nonce >>> 24) & 0xff;
148
+ cipher.encryptBlock(counter, 0, keystream, 0);
149
+ const n = Math.min(16, data.length - off);
150
+ for (let i = 0; i < n; i++)
151
+ out[off + i] = data[off + i] ^ keystream[i];
152
+ nonce++;
153
+ }
154
+ return out;
155
+ }
156
+ //# sourceMappingURL=aes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aes.js","sourceRoot":"","sources":["../../../src/zip/crypto/aes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * WinZip AES (AE-2) encryption for ZIP entries — AES-256 by default.
3
+ *
4
+ * Layout of an encrypted entry's payload: `salt || pwdVerify(2) || ciphertext ||
5
+ * authCode(10)`. Keys come from PBKDF2-HMAC-SHA1 (1000 iterations) over the
6
+ * password and salt; the data is AES-CTR encrypted and authenticated with a
7
+ * truncated HMAC-SHA1. PBKDF2/HMAC use WebCrypto (standard, cross-runtime); the
8
+ * CTR keystream uses {@link Aes} because WebCrypto's counter endianness differs
9
+ * from WinZip's. Interoperates with 7-Zip / WinZip AES archives.
10
+ */
11
+ /** AES strength codes used in the 0x9901 extra field. */
12
+ export type AesStrength = 1 | 2 | 3;
13
+ /**
14
+ * Encrypt already-compressed `data` as a WinZip AE-2 payload. Returns the bytes
15
+ * that go where the compressed data would otherwise sit, plus the strength code
16
+ * for the entry's 0x9901 extra field.
17
+ */
18
+ export declare function aesEncrypt(data: Uint8Array, password: string, strength?: AesStrength): Promise<{
19
+ payload: Uint8Array;
20
+ strength: AesStrength;
21
+ }>;
22
+ /**
23
+ * Decrypt a WinZip AE-2 payload back to the compressed bytes. Throws
24
+ * {@link ZipKitError} on a wrong password (verifier mismatch) or a failed
25
+ * authentication check (tampered/corrupt data).
26
+ */
27
+ export declare function aesDecrypt(payload: Uint8Array, password: string, strength: AesStrength): Promise<Uint8Array>;
28
+ //# sourceMappingURL=winzip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"winzip.d.ts","sourceRoot":"","sources":["../../../src/zip/crypto/winzip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,yDAAyD;AACzD,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AA8CpC;;;;GAIG;AACH,wBAAsB,UAAU,CAC/B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,WAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,CAAC,CAYzD;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBlH"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * WinZip AES (AE-2) encryption for ZIP entries — AES-256 by default.
3
+ *
4
+ * Layout of an encrypted entry's payload: `salt || pwdVerify(2) || ciphertext ||
5
+ * authCode(10)`. Keys come from PBKDF2-HMAC-SHA1 (1000 iterations) over the
6
+ * password and salt; the data is AES-CTR encrypted and authenticated with a
7
+ * truncated HMAC-SHA1. PBKDF2/HMAC use WebCrypto (standard, cross-runtime); the
8
+ * CTR keystream uses {@link Aes} because WebCrypto's counter endianness differs
9
+ * from WinZip's. Interoperates with 7-Zip / WinZip AES archives.
10
+ */
11
+ import { Aes, aesCtrXor } from './aes.js';
12
+ import { ZipKitError } from '../../types.js';
13
+ const KEY_BYTES = { 1: 16, 2: 24, 3: 32 };
14
+ const SALT_BYTES = { 1: 8, 2: 12, 3: 16 };
15
+ const MAC_BYTES = 10; // truncated HMAC-SHA1
16
+ const PBKDF2_ITERATIONS = 1000;
17
+ function subtle() {
18
+ const c = globalThis.crypto;
19
+ if (!c?.subtle)
20
+ throw new ZipKitError('WebCrypto (crypto.subtle) is required for ZIP AES encryption');
21
+ return c.subtle;
22
+ }
23
+ function randomBytes(n) {
24
+ const c = globalThis.crypto;
25
+ if (!c?.getRandomValues)
26
+ throw new ZipKitError('crypto.getRandomValues is required to create encrypted ZIPs');
27
+ return c.getRandomValues(new Uint8Array(n));
28
+ }
29
+ /** Derive the AES key, MAC key, and 2-byte password verifier via PBKDF2. */
30
+ async function deriveKeys(password, salt, strength) {
31
+ const keyLen = KEY_BYTES[strength];
32
+ const baseKey = await subtle().importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, ['deriveBits']);
33
+ const bits = await subtle().deriveBits({ name: 'PBKDF2', salt: salt, iterations: PBKDF2_ITERATIONS, hash: 'SHA-1' }, baseKey, (keyLen * 2 + 2) * 8);
34
+ const out = new Uint8Array(bits);
35
+ return {
36
+ aesKey: out.subarray(0, keyLen),
37
+ macKey: out.subarray(keyLen, keyLen * 2),
38
+ verifier: out.subarray(keyLen * 2, keyLen * 2 + 2)
39
+ };
40
+ }
41
+ async function hmacSha1(macKey, data) {
42
+ const key = await subtle().importKey('raw', macKey, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']);
43
+ const sig = await subtle().sign('HMAC', key, data);
44
+ return new Uint8Array(sig).subarray(0, MAC_BYTES);
45
+ }
46
+ /**
47
+ * Encrypt already-compressed `data` as a WinZip AE-2 payload. Returns the bytes
48
+ * that go where the compressed data would otherwise sit, plus the strength code
49
+ * for the entry's 0x9901 extra field.
50
+ */
51
+ export async function aesEncrypt(data, password, strength = 3) {
52
+ const salt = randomBytes(SALT_BYTES[strength]);
53
+ const { aesKey, macKey, verifier } = await deriveKeys(password, salt, strength);
54
+ const ciphertext = aesCtrXor(new Aes(aesKey), data);
55
+ const mac = await hmacSha1(macKey, ciphertext);
56
+ const payload = new Uint8Array(salt.length + 2 + ciphertext.length + MAC_BYTES);
57
+ payload.set(salt, 0);
58
+ payload.set(verifier, salt.length);
59
+ payload.set(ciphertext, salt.length + 2);
60
+ payload.set(mac, salt.length + 2 + ciphertext.length);
61
+ return { payload, strength };
62
+ }
63
+ /**
64
+ * Decrypt a WinZip AE-2 payload back to the compressed bytes. Throws
65
+ * {@link ZipKitError} on a wrong password (verifier mismatch) or a failed
66
+ * authentication check (tampered/corrupt data).
67
+ */
68
+ export async function aesDecrypt(payload, password, strength) {
69
+ const saltLen = SALT_BYTES[strength];
70
+ if (payload.length < saltLen + 2 + MAC_BYTES)
71
+ throw new ZipKitError('Encrypted ZIP entry is too short to be valid AES');
72
+ const salt = payload.subarray(0, saltLen);
73
+ const storedVerifier = payload.subarray(saltLen, saltLen + 2);
74
+ const ciphertext = payload.subarray(saltLen + 2, payload.length - MAC_BYTES);
75
+ const storedMac = payload.subarray(payload.length - MAC_BYTES);
76
+ const { aesKey, macKey, verifier } = await deriveKeys(password, salt, strength);
77
+ if (verifier[0] !== storedVerifier[0] || verifier[1] !== storedVerifier[1]) {
78
+ throw new ZipKitError('Wrong password for encrypted ZIP entry');
79
+ }
80
+ const mac = await hmacSha1(macKey, ciphertext);
81
+ for (let i = 0; i < MAC_BYTES; i++) {
82
+ if (mac[i] !== storedMac[i])
83
+ throw new ZipKitError('Authentication failed for encrypted ZIP entry (corrupt or tampered)');
84
+ }
85
+ return aesCtrXor(new Aes(aesKey), ciphertext);
86
+ }
87
+ //# sourceMappingURL=winzip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"winzip.js","sourceRoot":"","sources":["../../../src/zip/crypto/winzip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK7C,MAAM,SAAS,GAAgC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AACvE,MAAM,UAAU,GAAgC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AACvE,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,sBAAsB;AAC5C,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAE/B,SAAS,MAAM;IACd,MAAM,CAAC,GAAI,UAAkC,CAAC,MAAM,CAAC;IACrD,IAAI,CAAC,CAAC,EAAE,MAAM;QAAE,MAAM,IAAI,WAAW,CAAC,8DAA8D,CAAC,CAAC;IACtG,OAAO,CAAC,CAAC,MAAM,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC7B,MAAM,CAAC,GAAI,UAAkC,CAAC,MAAM,CAAC;IACrD,IAAI,CAAC,CAAC,EAAE,eAAe;QAAE,MAAM,IAAI,WAAW,CAAC,6DAA6D,CAAC,CAAC;IAC9G,OAAO,CAAC,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,UAAU,CACxB,QAAgB,EAChB,IAAgB,EAChB,QAAqB;IAErB,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IACrH,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC,UAAU,CACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAoB,EAAE,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,EAAE,EAC5F,OAAO,EACP,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CACpB,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO;QACN,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;QACxC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;KAClD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,MAAkB,EAAE,IAAgB;IAC3D,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,MAAsB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACtH,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAoB,CAAC,CAAC;IACnE,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,IAAgB,EAChB,QAAgB,EAChB,WAAwB,CAAC;IAEzB,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAmB,EAAE,QAAgB,EAAE,QAAqB;IAC5F,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,GAAG,SAAS;QAAE,MAAM,IAAI,WAAW,CAAC,kDAAkD,CAAC,CAAC;IACxH,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE/D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChF,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,WAAW,CAAC,wCAAwC,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,qEAAqE,CAAC,CAAC;IAC3H,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Legacy PKWARE "ZipCrypto" — decryption only, for reading old encrypted
3
+ * archives. The cipher is weak and long deprecated, so ZipKit never *writes* it
4
+ * (new encrypted archives use WinZip AES, {@link import('./winzip.js')}); this
5
+ * exists purely for read compatibility with historical files.
6
+ */
7
+ /**
8
+ * Decrypt a ZipCrypto entry: the raw bytes are a 12-byte encryption header
9
+ * followed by the (still-compressed) ciphertext. `checkByte` is the expected
10
+ * high byte of the verification value — the CRC-32's top byte, or the DOS time's
11
+ * high byte when the entry used a data descriptor. Throws on a wrong password.
12
+ */
13
+ export declare function zipCryptoDecrypt(data: Uint8Array, password: string, checkByte: number): Uint8Array;
14
+ //# sourceMappingURL=zipcrypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zipcrypto.d.ts","sourceRoot":"","sources":["../../../src/zip/crypto/zipcrypto.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4CH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAmBlG"}