@zip.js/zip.js 2.6.32 → 2.6.34
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/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +2441 -2287
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +1970 -1816
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +1969 -1815
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +1971 -1817
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +3 -1
- package/index.cjs +2441 -2287
- package/index.d.ts +36 -7
- package/index.js +3 -1
- package/lib/core/codec-pool.js +6 -5
- package/lib/core/codec-worker.js +321 -0
- package/lib/core/configuration.js +11 -8
- package/lib/core/constants.js +11 -5
- package/lib/core/io.js +150 -51
- package/lib/core/streams/aes-crypto-stream.js +2 -0
- package/lib/core/streams/codec-stream.js +60 -13
- package/lib/core/streams/codecs/sjcl.js +1 -1
- package/lib/core/streams/stream-adapter.js +55 -0
- package/lib/core/streams/zip-crypto-stream.js +1 -0
- package/lib/core/streams/zip-entry-stream.js +1 -0
- package/lib/core/util/stream-codec-shim.js +2 -0
- package/lib/core/z-worker-core.js +23 -12
- package/lib/core/zip-entry.js +2 -1
- package/lib/core/zip-fs-core.js +1 -0
- package/lib/core/zip-reader.js +16 -12
- package/lib/core/zip-writer.js +102 -54
- package/lib/z-worker-inline.js +1 -1
- package/lib/zip.js +1 -1
- package/package.json +5 -5
- package/rollup-es5.config.dev.js +199 -0
- package/rollup-es5.config.js +243 -0
- package/tests/all/test-http-split-zip.js +37 -0
- package/tests/all/test-readable-stream.js +1 -2
- package/tests/all/test-readable-zip-stream.js +1 -1
- package/tests/all/test-split-zip.js +25 -22
- package/tests/tests-data.js +2 -1
- package/lib/core/codec-interface.js +0 -115
- package/lib/core/codec-pool-worker.js +0 -289
package/lib/core/io.js
CHANGED
|
@@ -27,20 +27,26 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
/* global Blob, atob, btoa, XMLHttpRequest, URL, fetch, ReadableStream, WritableStream, FileReader, TransformStream, Response */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
30
31
|
|
|
31
32
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
32
33
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
34
|
+
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
33
35
|
|
|
34
36
|
const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
|
|
35
37
|
const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
|
|
36
38
|
const HTTP_HEADER_CONTENT_RANGE = "Content-Range";
|
|
37
39
|
const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
|
|
38
40
|
const HTTP_HEADER_RANGE = "Range";
|
|
41
|
+
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
39
42
|
const HTTP_METHOD_HEAD = "HEAD";
|
|
40
43
|
const HTTP_METHOD_GET = "GET";
|
|
41
44
|
const HTTP_RANGE_UNIT = "bytes";
|
|
42
45
|
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
43
46
|
|
|
47
|
+
const PROPERTY_NAME_WRITABLE = "writable";
|
|
48
|
+
|
|
49
|
+
import { UNDEFINED_VALUE } from "./constants.js";
|
|
44
50
|
import { getConfiguration } from "./configuration.js";
|
|
45
51
|
|
|
46
52
|
class Stream {
|
|
@@ -88,7 +94,7 @@ class Writer extends Stream {
|
|
|
88
94
|
return writer.writeUint8Array(chunk);
|
|
89
95
|
}
|
|
90
96
|
});
|
|
91
|
-
Object.defineProperty(writer,
|
|
97
|
+
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
92
98
|
get() {
|
|
93
99
|
return writable;
|
|
94
100
|
}
|
|
@@ -104,21 +110,26 @@ class Data64URIReader extends Reader {
|
|
|
104
110
|
|
|
105
111
|
constructor(dataURI) {
|
|
106
112
|
super();
|
|
107
|
-
const reader = this;
|
|
108
|
-
reader.dataURI = dataURI;
|
|
109
113
|
let dataEnd = dataURI.length;
|
|
110
114
|
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
111
115
|
dataEnd--;
|
|
112
116
|
}
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
const dataStart = dataURI.indexOf(",") + 1;
|
|
118
|
+
Object.assign(this, {
|
|
119
|
+
dataURI,
|
|
120
|
+
dataStart,
|
|
121
|
+
size: Math.floor((dataEnd - dataStart) * 0.75)
|
|
122
|
+
});
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
readUint8Array(offset, length) {
|
|
126
|
+
const {
|
|
127
|
+
dataStart,
|
|
128
|
+
dataURI
|
|
129
|
+
} = this;
|
|
118
130
|
const dataArray = new Uint8Array(length);
|
|
119
131
|
const start = Math.floor(offset / 3) * 4;
|
|
120
|
-
const
|
|
121
|
-
const bytes = atob(this.dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
|
|
132
|
+
const bytes = atob(dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
|
|
122
133
|
const delta = offset - Math.floor(start / 4) * 3;
|
|
123
134
|
for (let indexByte = delta; indexByte < delta + length; indexByte++) {
|
|
124
135
|
dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
|
|
@@ -131,8 +142,10 @@ class Data64URIWriter extends Writer {
|
|
|
131
142
|
|
|
132
143
|
constructor(contentType) {
|
|
133
144
|
super();
|
|
134
|
-
|
|
135
|
-
|
|
145
|
+
Object.assign(this, {
|
|
146
|
+
data: "data:" + (contentType || "") + ";base64,",
|
|
147
|
+
pending: []
|
|
148
|
+
});
|
|
136
149
|
}
|
|
137
150
|
|
|
138
151
|
writeUint8Array(array) {
|
|
@@ -163,8 +176,10 @@ class BlobReader extends Reader {
|
|
|
163
176
|
|
|
164
177
|
constructor(blob) {
|
|
165
178
|
super();
|
|
166
|
-
this
|
|
167
|
-
|
|
179
|
+
Object.assign(this, {
|
|
180
|
+
blob,
|
|
181
|
+
size: blob.size
|
|
182
|
+
});
|
|
168
183
|
}
|
|
169
184
|
|
|
170
185
|
async readUint8Array(offset, length) {
|
|
@@ -181,9 +196,9 @@ class BlobWriter extends Stream {
|
|
|
181
196
|
const transformStream = new TransformStream();
|
|
182
197
|
const headers = [];
|
|
183
198
|
if (contentType) {
|
|
184
|
-
headers.push([
|
|
199
|
+
headers.push([HTTP_HEADER_CONTENT_TYPE, contentType]);
|
|
185
200
|
}
|
|
186
|
-
Object.defineProperty(writer,
|
|
201
|
+
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
187
202
|
get() {
|
|
188
203
|
return transformStream.writable;
|
|
189
204
|
}
|
|
@@ -224,8 +239,10 @@ class TextWriter extends BlobWriter {
|
|
|
224
239
|
} else {
|
|
225
240
|
const reader = new FileReader();
|
|
226
241
|
return new Promise((resolve, reject) => {
|
|
227
|
-
reader
|
|
228
|
-
|
|
242
|
+
Object.assign(reader, {
|
|
243
|
+
onload: ({ target }) => resolve(target.result),
|
|
244
|
+
onerror: () => reject(reader.error)
|
|
245
|
+
});
|
|
229
246
|
reader.readAsText(blob, encoding);
|
|
230
247
|
});
|
|
231
248
|
}
|
|
@@ -236,16 +253,7 @@ class FetchReader extends Reader {
|
|
|
236
253
|
|
|
237
254
|
constructor(url, options) {
|
|
238
255
|
super();
|
|
239
|
-
|
|
240
|
-
reader.url = url;
|
|
241
|
-
reader.preventHeadRequest = options.preventHeadRequest;
|
|
242
|
-
reader.useRangeHeader = options.useRangeHeader;
|
|
243
|
-
reader.forceRangeRequests = options.forceRangeRequests;
|
|
244
|
-
reader.options = options = Object.assign({}, options);
|
|
245
|
-
delete options.preventHeadRequest;
|
|
246
|
-
delete options.useRangeHeader;
|
|
247
|
-
delete options.forceRangeRequests;
|
|
248
|
-
delete options.useXHR;
|
|
256
|
+
createHtpReader(this, url, options);
|
|
249
257
|
}
|
|
250
258
|
|
|
251
259
|
async init() {
|
|
@@ -262,12 +270,7 @@ class XHRReader extends Reader {
|
|
|
262
270
|
|
|
263
271
|
constructor(url, options) {
|
|
264
272
|
super();
|
|
265
|
-
|
|
266
|
-
reader.url = url;
|
|
267
|
-
reader.preventHeadRequest = options.preventHeadRequest;
|
|
268
|
-
reader.useRangeHeader = options.useRangeHeader;
|
|
269
|
-
reader.forceRangeRequests = options.forceRangeRequests;
|
|
270
|
-
reader.options = options;
|
|
273
|
+
createHtpReader(this, url, options);
|
|
271
274
|
}
|
|
272
275
|
|
|
273
276
|
async init() {
|
|
@@ -280,14 +283,39 @@ class XHRReader extends Reader {
|
|
|
280
283
|
}
|
|
281
284
|
}
|
|
282
285
|
|
|
286
|
+
function createHtpReader(httpReader, url, options) {
|
|
287
|
+
const {
|
|
288
|
+
preventHeadRequest,
|
|
289
|
+
useRangeHeader,
|
|
290
|
+
forceRangeRequests
|
|
291
|
+
} = options;
|
|
292
|
+
options = Object.assign({}, options);
|
|
293
|
+
delete options.preventHeadRequest;
|
|
294
|
+
delete options.useRangeHeader;
|
|
295
|
+
delete options.forceRangeRequests;
|
|
296
|
+
delete options.useXHR;
|
|
297
|
+
Object.assign(httpReader, {
|
|
298
|
+
url,
|
|
299
|
+
options,
|
|
300
|
+
preventHeadRequest,
|
|
301
|
+
useRangeHeader,
|
|
302
|
+
forceRangeRequests
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
283
306
|
async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
307
|
+
const {
|
|
308
|
+
url,
|
|
309
|
+
useRangeHeader,
|
|
310
|
+
forceRangeRequests
|
|
311
|
+
} = httpReader;
|
|
312
|
+
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests)) {
|
|
313
|
+
const { headers } = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader));
|
|
314
|
+
if (!forceRangeRequests && headers.get(HTTP_HEADER_ACCEPT_RANGES) != HTTP_RANGE_UNIT) {
|
|
287
315
|
throw new Error(ERR_HTTP_RANGE);
|
|
288
316
|
} else {
|
|
289
317
|
let contentSize;
|
|
290
|
-
const contentRangeHeader =
|
|
318
|
+
const contentRangeHeader = headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
291
319
|
if (contentRangeHeader) {
|
|
292
320
|
const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
|
|
293
321
|
if (splitHeader.length) {
|
|
@@ -297,7 +325,7 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
297
325
|
}
|
|
298
326
|
}
|
|
299
327
|
}
|
|
300
|
-
if (contentSize ===
|
|
328
|
+
if (contentSize === UNDEFINED_VALUE) {
|
|
301
329
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
302
330
|
} else {
|
|
303
331
|
httpReader.size = contentSize;
|
|
@@ -309,17 +337,23 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
309
337
|
}
|
|
310
338
|
|
|
311
339
|
async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest, getRequestData) {
|
|
312
|
-
|
|
340
|
+
const {
|
|
341
|
+
data,
|
|
342
|
+
useRangeHeader,
|
|
343
|
+
forceRangeRequests,
|
|
344
|
+
options
|
|
345
|
+
} = httpReader;
|
|
346
|
+
if (useRangeHeader || forceRangeRequests) {
|
|
313
347
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
314
348
|
if (response.status != 206) {
|
|
315
349
|
throw new Error(ERR_HTTP_RANGE);
|
|
316
350
|
}
|
|
317
351
|
return new Uint8Array(await response.arrayBuffer());
|
|
318
352
|
} else {
|
|
319
|
-
if (!
|
|
320
|
-
await getRequestData(httpReader,
|
|
353
|
+
if (!data) {
|
|
354
|
+
await getRequestData(httpReader, options);
|
|
321
355
|
}
|
|
322
|
-
return new Uint8Array(
|
|
356
|
+
return new Uint8Array(data.subarray(index, index + length));
|
|
323
357
|
}
|
|
324
358
|
}
|
|
325
359
|
|
|
@@ -327,8 +361,8 @@ function getRangeHeaders(httpReader, index = 0, length = 1) {
|
|
|
327
361
|
return Object.assign({}, getHeaders(httpReader), { [HTTP_HEADER_RANGE]: HTTP_RANGE_UNIT + "=" + index + "-" + (index + length - 1) });
|
|
328
362
|
}
|
|
329
363
|
|
|
330
|
-
function getHeaders(
|
|
331
|
-
const headers =
|
|
364
|
+
function getHeaders({ options }) {
|
|
365
|
+
const { headers } = options;
|
|
332
366
|
if (headers) {
|
|
333
367
|
if (Symbol.iterator in headers) {
|
|
334
368
|
return Object.fromEntries(headers);
|
|
@@ -413,9 +447,10 @@ class HttpReader extends Reader {
|
|
|
413
447
|
|
|
414
448
|
constructor(url, options = {}) {
|
|
415
449
|
super();
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
450
|
+
Object.assign(this, {
|
|
451
|
+
url,
|
|
452
|
+
reader: options.useXHR ? new XHRReader(url, options) : new FetchReader(url, options)
|
|
453
|
+
});
|
|
419
454
|
}
|
|
420
455
|
|
|
421
456
|
set size(value) {
|
|
@@ -449,8 +484,10 @@ class Uint8ArrayReader extends Reader {
|
|
|
449
484
|
|
|
450
485
|
constructor(array) {
|
|
451
486
|
super();
|
|
452
|
-
this
|
|
453
|
-
|
|
487
|
+
Object.assign(this, {
|
|
488
|
+
array,
|
|
489
|
+
size: array.length
|
|
490
|
+
});
|
|
454
491
|
}
|
|
455
492
|
|
|
456
493
|
readUint8Array(index, length) {
|
|
@@ -462,9 +499,10 @@ class Uint8ArrayWriter extends Writer {
|
|
|
462
499
|
|
|
463
500
|
init(initSize = 0) {
|
|
464
501
|
super.init();
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
502
|
+
Object.assign(this, {
|
|
503
|
+
offset: 0,
|
|
504
|
+
array: new Uint8Array(initSize)
|
|
505
|
+
});
|
|
468
506
|
}
|
|
469
507
|
|
|
470
508
|
writeUint8Array(array) {
|
|
@@ -529,6 +567,65 @@ class SplitZipReader extends Reader {
|
|
|
529
567
|
}
|
|
530
568
|
}
|
|
531
569
|
|
|
570
|
+
class SplitZipWriter extends Stream {
|
|
571
|
+
|
|
572
|
+
constructor(writerGenerator, maxSize = 4294967296) {
|
|
573
|
+
super();
|
|
574
|
+
const writer = this;
|
|
575
|
+
Object.assign(writer, {
|
|
576
|
+
diskNumber: 0,
|
|
577
|
+
diskOffset: 0,
|
|
578
|
+
size: 0,
|
|
579
|
+
availableSize: maxSize
|
|
580
|
+
});
|
|
581
|
+
let currentWriter, diskWritable, diskWriter;
|
|
582
|
+
const writable = new WritableStream({
|
|
583
|
+
async write(chunk) {
|
|
584
|
+
if (!diskWriter) {
|
|
585
|
+
const { value, done } = await writerGenerator.next();
|
|
586
|
+
if (done && !value) {
|
|
587
|
+
throw new Error(ERR_ITERATOR_COMPLETED_TOO_SOON);
|
|
588
|
+
} else {
|
|
589
|
+
currentWriter = value;
|
|
590
|
+
currentWriter.size = 0;
|
|
591
|
+
diskWritable = value.writable;
|
|
592
|
+
diskWriter = diskWritable.getWriter();
|
|
593
|
+
}
|
|
594
|
+
await this.write(chunk);
|
|
595
|
+
} else if (diskWriter && currentWriter.size + chunk.length > maxSize) {
|
|
596
|
+
await diskWriter.ready;
|
|
597
|
+
const chunkLength = maxSize - currentWriter.size;
|
|
598
|
+
await diskWriter.write(chunk.slice(0, chunkLength));
|
|
599
|
+
chunk = chunk.slice(chunkLength);
|
|
600
|
+
currentWriter.size += chunkLength;
|
|
601
|
+
writer.size += chunkLength;
|
|
602
|
+
writer.diskOffset += diskWritable.size = currentWriter.size;
|
|
603
|
+
writer.diskNumber++;
|
|
604
|
+
await diskWriter.close();
|
|
605
|
+
diskWriter = null;
|
|
606
|
+
await this.write(chunk);
|
|
607
|
+
} else {
|
|
608
|
+
await diskWriter.ready;
|
|
609
|
+
await diskWriter.write(chunk);
|
|
610
|
+
currentWriter.size += chunk.length;
|
|
611
|
+
writer.size += chunk.length;
|
|
612
|
+
}
|
|
613
|
+
writer.availableSize = maxSize - currentWriter.size;
|
|
614
|
+
},
|
|
615
|
+
async close() {
|
|
616
|
+
await diskWriter.ready;
|
|
617
|
+
diskWritable.size = currentWriter.size;
|
|
618
|
+
await diskWriter.close();
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
622
|
+
get() {
|
|
623
|
+
return writable;
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
532
629
|
function isHttpFamily(url) {
|
|
533
630
|
const { baseURL } = getConfiguration();
|
|
534
631
|
const { protocol } = new URL(url, baseURL);
|
|
@@ -561,5 +658,7 @@ export {
|
|
|
561
658
|
HttpReader,
|
|
562
659
|
HttpRangeReader,
|
|
563
660
|
SplitZipReader,
|
|
564
|
-
|
|
661
|
+
SplitZipWriter,
|
|
662
|
+
ERR_HTTP_RANGE,
|
|
663
|
+
ERR_ITERATOR_COMPLETED_TOO_SOON
|
|
565
664
|
};
|
|
@@ -56,6 +56,7 @@ const SIGNATURE_LENGTH = 10;
|
|
|
56
56
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
57
57
|
const UNDEFINED_TYPE = "undefined";
|
|
58
58
|
const FUNCTION_TYPE = "function";
|
|
59
|
+
// deno-lint-ignore valid-typeof
|
|
59
60
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
60
61
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
61
62
|
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
|
|
@@ -132,6 +133,7 @@ class AESDecryptionStream extends TransformStream {
|
|
|
132
133
|
class AESEncryptionStream extends TransformStream {
|
|
133
134
|
|
|
134
135
|
constructor(password, strength) {
|
|
136
|
+
// deno-lint-ignore prefer-const
|
|
135
137
|
let stream;
|
|
136
138
|
super({
|
|
137
139
|
start() {
|
|
@@ -34,25 +34,72 @@
|
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
/* global TransformStream */
|
|
37
|
+
// deno-lint-ignore-file no-this-alias
|
|
38
|
+
|
|
39
|
+
import {
|
|
40
|
+
ERR_INVALID_PASSWORD,
|
|
41
|
+
ERR_INVALID_SIGNATURE,
|
|
42
|
+
InflateStream,
|
|
43
|
+
DeflateStream
|
|
44
|
+
} from "./zip-entry-stream.js";
|
|
45
|
+
|
|
46
|
+
const MESSAGE_EVENT_TYPE = "message";
|
|
47
|
+
const MESSAGE_START = "start";
|
|
48
|
+
const MESSAGE_PULL = "pull";
|
|
49
|
+
const MESSAGE_DATA = "data";
|
|
50
|
+
const MESSAGE_ACK_DATA = "ack";
|
|
51
|
+
const MESSAGE_CLOSE = "close";
|
|
52
|
+
const CODEC_DEFLATE = "deflate";
|
|
53
|
+
const CODEC_INFLATE = "inflate";
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
CODEC_DEFLATE,
|
|
57
|
+
CODEC_INFLATE,
|
|
58
|
+
MESSAGE_EVENT_TYPE,
|
|
59
|
+
MESSAGE_START,
|
|
60
|
+
MESSAGE_PULL,
|
|
61
|
+
MESSAGE_DATA,
|
|
62
|
+
MESSAGE_ACK_DATA,
|
|
63
|
+
MESSAGE_CLOSE,
|
|
64
|
+
ERR_INVALID_PASSWORD,
|
|
65
|
+
ERR_INVALID_SIGNATURE,
|
|
66
|
+
CodecStream
|
|
67
|
+
};
|
|
37
68
|
|
|
38
69
|
class CodecStream extends TransformStream {
|
|
39
70
|
|
|
40
|
-
constructor(
|
|
41
|
-
|
|
42
|
-
|
|
71
|
+
constructor(options, config) {
|
|
72
|
+
super({});
|
|
73
|
+
const codec = this;
|
|
74
|
+
const { codecType } = options;
|
|
75
|
+
let Stream;
|
|
76
|
+
if (codecType.startsWith(CODEC_DEFLATE)) {
|
|
77
|
+
Stream = DeflateStream;
|
|
78
|
+
} else if (codecType.startsWith(CODEC_INFLATE)) {
|
|
79
|
+
Stream = InflateStream;
|
|
80
|
+
}
|
|
81
|
+
let size = 0;
|
|
82
|
+
const stream = new Stream(options, config);
|
|
83
|
+
const readable = super.readable;
|
|
84
|
+
const transformStream = new TransformStream({
|
|
43
85
|
transform(chunk, controller) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
flush(controller) {
|
|
47
|
-
const chunk = codec.flush();
|
|
48
|
-
if (chunk) {
|
|
86
|
+
if (chunk && chunk.length) {
|
|
87
|
+
size += chunk.length;
|
|
49
88
|
controller.enqueue(chunk);
|
|
50
89
|
}
|
|
90
|
+
},
|
|
91
|
+
flush() {
|
|
92
|
+
const { signature } = stream;
|
|
93
|
+
Object.assign(codec, {
|
|
94
|
+
signature,
|
|
95
|
+
size
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
Object.defineProperty(codec, "readable", {
|
|
100
|
+
get() {
|
|
101
|
+
return readable.pipeThrough(stream).pipeThrough(transformStream);
|
|
51
102
|
}
|
|
52
103
|
});
|
|
53
104
|
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export {
|
|
57
|
-
CodecStream
|
|
58
|
-
};
|
|
105
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// deno-lint-ignore-file no-this-alias
|
|
4
4
|
|
|
5
5
|
/*
|
|
6
6
|
* SJCL is open. You can use, modify and redistribute it under a BSD
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer in
|
|
12
|
+
the documentation and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
15
|
+
derived from this software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
18
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
20
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
23
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/* global TransformStream */
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
StreamAdapter
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class StreamAdapter {
|
|
36
|
+
|
|
37
|
+
constructor(Codec) {
|
|
38
|
+
return class extends TransformStream {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
const codec = new Codec(options);
|
|
41
|
+
super({
|
|
42
|
+
transform(chunk, controller) {
|
|
43
|
+
controller.enqueue(codec.append(chunk));
|
|
44
|
+
},
|
|
45
|
+
flush(controller) {
|
|
46
|
+
const chunk = codec.flush();
|
|
47
|
+
if (chunk) {
|
|
48
|
+
controller.enqueue(chunk);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -28,23 +28,24 @@
|
|
|
28
28
|
|
|
29
29
|
/* global self, importScripts, addEventListener, postMessage, ReadableStream, WritableStream */
|
|
30
30
|
|
|
31
|
+
import { UNDEFINED_VALUE } from "./constants.js";
|
|
32
|
+
import { StreamAdapter } from "./streams/stream-adapter.js";
|
|
31
33
|
import {
|
|
32
|
-
|
|
33
|
-
getCodecStreamClass,
|
|
34
|
+
CodecStream,
|
|
34
35
|
MESSAGE_EVENT_TYPE,
|
|
35
36
|
MESSAGE_START,
|
|
36
37
|
MESSAGE_PULL,
|
|
37
38
|
MESSAGE_DATA,
|
|
38
39
|
MESSAGE_ACK_DATA,
|
|
39
40
|
MESSAGE_CLOSE
|
|
40
|
-
} from "./codec-
|
|
41
|
+
} from "./streams/codec-stream.js";
|
|
41
42
|
|
|
42
43
|
const pendingPullMessages = new Map();
|
|
43
44
|
const pendingDataMessages = new Map();
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
let messageId = 0;
|
|
46
47
|
|
|
47
|
-
addEventListener(MESSAGE_EVENT_TYPE,
|
|
48
|
+
addEventListener(MESSAGE_EVENT_TYPE, event => {
|
|
48
49
|
const message = event.data;
|
|
49
50
|
const { type, messageId, data, done } = message;
|
|
50
51
|
try {
|
|
@@ -70,7 +71,7 @@ async function init(message) {
|
|
|
70
71
|
try {
|
|
71
72
|
const { options, scripts, config } = message;
|
|
72
73
|
if (scripts && scripts.length) {
|
|
73
|
-
importScripts.apply(
|
|
74
|
+
importScripts.apply(UNDEFINED_VALUE, scripts);
|
|
74
75
|
}
|
|
75
76
|
if (self.initCodec) {
|
|
76
77
|
self.initCodec();
|
|
@@ -78,15 +79,15 @@ async function init(message) {
|
|
|
78
79
|
config.CompressionStreamNative = self.CompressionStream;
|
|
79
80
|
config.DecompressionStreamNative = self.DecompressionStream;
|
|
80
81
|
if (self.Deflate) {
|
|
81
|
-
config.CompressionStream =
|
|
82
|
+
config.CompressionStream = new StreamAdapter(self.Deflate);
|
|
82
83
|
}
|
|
83
84
|
if (self.Inflate) {
|
|
84
|
-
config.DecompressionStream =
|
|
85
|
+
config.DecompressionStream = new StreamAdapter(self.Inflate);
|
|
85
86
|
}
|
|
86
87
|
const strategy = { highWaterMark: 1, size: () => config.chunkSize };
|
|
87
88
|
const readable = message.readable || new ReadableStream({
|
|
88
89
|
async pull(controller) {
|
|
89
|
-
|
|
90
|
+
const result = new Promise(resolve => pendingPullMessages.set(messageId, resolve));
|
|
90
91
|
sendMessage({ type: MESSAGE_PULL, messageId });
|
|
91
92
|
messageId = (messageId + 1) % Number.MAX_SAFE_INTEGER;
|
|
92
93
|
const { value, done } = await result;
|
|
@@ -106,14 +107,24 @@ async function init(message) {
|
|
|
106
107
|
await ackData;
|
|
107
108
|
}
|
|
108
109
|
}, strategy);
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
const codecStream = new CodecStream(options, config);
|
|
111
|
+
await readable.pipeThrough(codecStream).pipeTo(writable, { preventAbort: true });
|
|
111
112
|
try {
|
|
112
113
|
await writable.close();
|
|
113
114
|
} catch (_error) {
|
|
114
115
|
// ignored
|
|
115
116
|
}
|
|
116
|
-
|
|
117
|
+
const {
|
|
118
|
+
signature,
|
|
119
|
+
size
|
|
120
|
+
} = codecStream;
|
|
121
|
+
sendMessage({
|
|
122
|
+
type: MESSAGE_CLOSE,
|
|
123
|
+
result: {
|
|
124
|
+
signature,
|
|
125
|
+
size
|
|
126
|
+
}
|
|
127
|
+
});
|
|
117
128
|
} catch (error) {
|
|
118
129
|
sendErrorMessage(error);
|
|
119
130
|
}
|
package/lib/core/zip-entry.js
CHANGED
|
@@ -32,7 +32,8 @@ const PROPERTY_NAMES = [
|
|
|
32
32
|
"rawExtraField", "bitFlag", "extraFieldZip64", "extraFieldUnicodePath", "extraFieldUnicodeComment",
|
|
33
33
|
"extraFieldAES", "filenameUTF8", "commentUTF8", "offset", "zip64", "compressionMethod",
|
|
34
34
|
"extraFieldNTFS", "lastAccessDate", "creationDate", "extraFieldExtendedTimestamp",
|
|
35
|
-
"version", "versionMadeBy", "msDosCompatible", "internalFileAttribute", "externalFileAttribute"
|
|
35
|
+
"version", "versionMadeBy", "msDosCompatible", "internalFileAttribute", "externalFileAttribute",
|
|
36
|
+
"diskNumberStart"];
|
|
36
37
|
|
|
37
38
|
class Entry {
|
|
38
39
|
|