@node-projects/jszip 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/flate.js ADDED
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var USE_TYPEDARRAY = (typeof Uint8Array !== "undefined") && (typeof Uint16Array !== "undefined") && (typeof Uint32Array !== "undefined");
3
+
4
+ import pako from "pako";
5
+ import utils from "./utils.js";
6
+ import { GenericWorker } from "./stream/GenericWorker.js";
7
+
8
+ var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
9
+
10
+ export const magic = "\x08\x00";
11
+
12
+ class FlateWorker extends GenericWorker {
13
+ /**
14
+ * Create a worker that uses pako to inflate/deflate.
15
+ * @constructor
16
+ * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
17
+ * @param {Object} options the options to use when (de)compressing.
18
+ */
19
+ constructor(action, options) {
20
+ super("FlateWorker/" + action);
21
+
22
+ this._pako = null;
23
+ this._pakoAction = action;
24
+ this._pakoOptions = options;
25
+ // the `meta` object from the last chunk received
26
+ // this allow this worker to pass around metadata
27
+ this.meta = {};
28
+ }
29
+
30
+ /**
31
+ * @see GenericWorker.processChunk
32
+ */
33
+ processChunk(chunk) {
34
+ this.meta = chunk.meta;
35
+ if (this._pako === null) {
36
+ this._createPako();
37
+ }
38
+ this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
39
+ };
40
+
41
+ /**
42
+ * @see GenericWorker.flush
43
+ */
44
+ flush() {
45
+ GenericWorker.prototype.flush.call(this);
46
+ if (this._pako === null) {
47
+ this._createPako();
48
+ }
49
+ this._pako.push([], true);
50
+ };
51
+ /**
52
+ * @see GenericWorker.cleanUp
53
+ */
54
+ cleanUp() {
55
+ GenericWorker.prototype.cleanUp.call(this);
56
+ this._pako = null;
57
+ };
58
+
59
+ /**
60
+ * Create the _pako object.
61
+ * TODO: lazy-loading this object isn't the best solution but it's the
62
+ * quickest. The best solution is to lazy-load the worker list. See also the
63
+ * issue #446.
64
+ */
65
+ _createPako() {
66
+ this._pako = new pako[this._pakoAction]({
67
+ raw: true,
68
+ level: this._pakoOptions.level || -1 // default compression
69
+ });
70
+ var self = this;
71
+ this._pako.onData = function (data) {
72
+ self.push({
73
+ data: data,
74
+ meta: self.meta
75
+ });
76
+ };
77
+ };
78
+ }
79
+
80
+ export function compressWorker(compressionOptions) {
81
+ return new FlateWorker("Deflate", compressionOptions);
82
+ };
83
+
84
+ export function uncompressWorker() {
85
+ return new FlateWorker("Inflate", {});
86
+ };
87
+
88
+ export default {
89
+ magic, compressWorker, uncompressWorker
90
+ }
@@ -0,0 +1,535 @@
1
+ import utils from "../utils.js";
2
+ import { GenericWorker } from "../stream/GenericWorker.js";
3
+ import utf8 from "../utf8.js";
4
+ import crc32 from "../crc32.js";
5
+ import signature from "../signature.js";
6
+
7
+ /**
8
+ * Transform an integer into a string in hexadecimal.
9
+ * @private
10
+ * @param {number} dec the number to convert.
11
+ * @param {number} bytes the number of bytes to generate.
12
+ * @returns {string} the result.
13
+ */
14
+ var decToHex = function (dec, bytes) {
15
+ var hex = "", i;
16
+ for (i = 0; i < bytes; i++) {
17
+ hex += String.fromCharCode(dec & 0xff);
18
+ dec = dec >>> 8;
19
+ }
20
+ return hex;
21
+ };
22
+
23
+ /**
24
+ * Generate the UNIX part of the external file attributes.
25
+ * @param {Object} unixPermissions the unix permissions or null.
26
+ * @param {Boolean} isDir true if the entry is a directory, false otherwise.
27
+ * @return {Number} a 32 bit integer.
28
+ *
29
+ * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute :
30
+ *
31
+ * TTTTsstrwxrwxrwx0000000000ADVSHR
32
+ * ^^^^____________________________ file type, see zipinfo.c (UNX_*)
33
+ * ^^^_________________________ setuid, setgid, sticky
34
+ * ^^^^^^^^^________________ permissions
35
+ * ^^^^^^^^^^______ not used ?
36
+ * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only
37
+ */
38
+ var generateUnixExternalFileAttr = function (unixPermissions, isDir) {
39
+
40
+ var result = unixPermissions;
41
+ if (!unixPermissions) {
42
+ // I can't use octal values in strict mode, hence the hexa.
43
+ // 040775 => 0x41fd
44
+ // 0100664 => 0x81b4
45
+ result = isDir ? 0x41fd : 0x81b4;
46
+ }
47
+ return (result & 0xFFFF) << 16;
48
+ };
49
+
50
+ /**
51
+ * Generate the DOS part of the external file attributes.
52
+ * @param {Object} dosPermissions the dos permissions or null.
53
+ * @param {Boolean} isDir true if the entry is a directory, false otherwise.
54
+ * @return {Number} a 32 bit integer.
55
+ *
56
+ * Bit 0 Read-Only
57
+ * Bit 1 Hidden
58
+ * Bit 2 System
59
+ * Bit 3 Volume Label
60
+ * Bit 4 Directory
61
+ * Bit 5 Archive
62
+ */
63
+ var generateDosExternalFileAttr = function (dosPermissions) {
64
+ // the dir flag is already set for compatibility
65
+ return (dosPermissions || 0) & 0x3F;
66
+ };
67
+
68
+ /**
69
+ * Generate the various parts used in the construction of the final zip file.
70
+ * @param {Object} streamInfo the hash with information about the compressed file.
71
+ * @param {Boolean} streamedContent is the content streamed ?
72
+ * @param {Boolean} streamingEnded is the stream finished ?
73
+ * @param {number} offset the current offset from the start of the zip file.
74
+ * @param {String} platform let's pretend we are this platform (change platform dependents fields)
75
+ * @param {Function} encodeFileName the function to encode the file name / comment.
76
+ * @return {Object} the zip parts.
77
+ */
78
+ var generateZipParts = function (streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {
79
+ var file = streamInfo["file"],
80
+ compression = streamInfo["compression"],
81
+ useCustomEncoding = encodeFileName !== utf8.utf8encode,
82
+ encodedFileName = utils.transformTo("string", encodeFileName(file.name)),
83
+ utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
84
+ comment = file.comment,
85
+ encodedComment = utils.transformTo("string", encodeFileName(comment)),
86
+ utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
87
+ useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
88
+ useUTF8ForComment = utfEncodedComment.length !== comment.length,
89
+ dosTime,
90
+ dosDate,
91
+ extraFields = "",
92
+ unicodePathExtraField = "",
93
+ unicodeCommentExtraField = "",
94
+ dir = file.dir,
95
+ date = file.date;
96
+
97
+
98
+ var dataInfo = {
99
+ crc32: 0,
100
+ compressedSize: 0,
101
+ uncompressedSize: 0
102
+ };
103
+
104
+ // if the content is streamed, the sizes/crc32 are only available AFTER
105
+ // the end of the stream.
106
+ if (!streamedContent || streamingEnded) {
107
+ dataInfo.crc32 = streamInfo["crc32"];
108
+ dataInfo.compressedSize = streamInfo["compressedSize"];
109
+ dataInfo.uncompressedSize = streamInfo["uncompressedSize"];
110
+ }
111
+
112
+ var bitflag = 0;
113
+ if (streamedContent) {
114
+ // Bit 3: the sizes/crc32 are set to zero in the local header.
115
+ // The correct values are put in the data descriptor immediately
116
+ // following the compressed data.
117
+ bitflag |= 0x0008;
118
+ }
119
+ if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {
120
+ // Bit 11: Language encoding flag (EFS).
121
+ bitflag |= 0x0800;
122
+ }
123
+
124
+
125
+ var extFileAttr = 0;
126
+ var versionMadeBy = 0;
127
+ if (dir) {
128
+ // dos or unix, we set the dos dir flag
129
+ extFileAttr |= 0x00010;
130
+ }
131
+ if (platform === "UNIX") {
132
+ versionMadeBy = 0x031E; // UNIX, version 3.0
133
+ extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
134
+ } else { // DOS or other, fallback to DOS
135
+ versionMadeBy = 0x0014; // DOS, version 2.0
136
+ extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);
137
+ }
138
+
139
+ // date
140
+ // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
141
+ // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
142
+ // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
143
+
144
+ dosTime = date.getUTCHours();
145
+ dosTime = dosTime << 6;
146
+ dosTime = dosTime | date.getUTCMinutes();
147
+ dosTime = dosTime << 5;
148
+ dosTime = dosTime | date.getUTCSeconds() / 2;
149
+
150
+ dosDate = date.getUTCFullYear() - 1980;
151
+ dosDate = dosDate << 4;
152
+ dosDate = dosDate | (date.getUTCMonth() + 1);
153
+ dosDate = dosDate << 5;
154
+ dosDate = dosDate | date.getUTCDate();
155
+
156
+ if (useUTF8ForFileName) {
157
+ // set the unicode path extra field. unzip needs at least one extra
158
+ // field to correctly handle unicode path, so using the path is as good
159
+ // as any other information. This could improve the situation with
160
+ // other archive managers too.
161
+ // This field is usually used without the utf8 flag, with a non
162
+ // unicode path in the header (winrar, winzip). This helps (a bit)
163
+ // with the messy Windows' default compressed folders feature but
164
+ // breaks on p7zip which doesn't seek the unicode path extra field.
165
+ // So for now, UTF-8 everywhere !
166
+ unicodePathExtraField =
167
+ // Version
168
+ decToHex(1, 1) +
169
+ // NameCRC32
170
+ decToHex(crc32(encodedFileName), 4) +
171
+ // UnicodeName
172
+ utfEncodedFileName;
173
+
174
+ extraFields +=
175
+ // Info-ZIP Unicode Path Extra Field
176
+ "\x75\x70" +
177
+ // size
178
+ decToHex(unicodePathExtraField.length, 2) +
179
+ // content
180
+ unicodePathExtraField;
181
+ }
182
+
183
+ if (useUTF8ForComment) {
184
+
185
+ unicodeCommentExtraField =
186
+ // Version
187
+ decToHex(1, 1) +
188
+ // CommentCRC32
189
+ decToHex(crc32(encodedComment), 4) +
190
+ // UnicodeName
191
+ utfEncodedComment;
192
+
193
+ extraFields +=
194
+ // Info-ZIP Unicode Path Extra Field
195
+ "\x75\x63" +
196
+ // size
197
+ decToHex(unicodeCommentExtraField.length, 2) +
198
+ // content
199
+ unicodeCommentExtraField;
200
+ }
201
+
202
+ var header = "";
203
+
204
+ // version needed to extract
205
+ header += "\x0A\x00";
206
+ // general purpose bit flag
207
+ header += decToHex(bitflag, 2);
208
+ // compression method
209
+ header += compression.magic;
210
+ // last mod file time
211
+ header += decToHex(dosTime, 2);
212
+ // last mod file date
213
+ header += decToHex(dosDate, 2);
214
+ // crc-32
215
+ header += decToHex(dataInfo.crc32, 4);
216
+ // compressed size
217
+ header += decToHex(dataInfo.compressedSize, 4);
218
+ // uncompressed size
219
+ header += decToHex(dataInfo.uncompressedSize, 4);
220
+ // file name length
221
+ header += decToHex(encodedFileName.length, 2);
222
+ // extra field length
223
+ header += decToHex(extraFields.length, 2);
224
+
225
+
226
+ var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;
227
+
228
+ var dirRecord = signature.CENTRAL_FILE_HEADER +
229
+ // version made by (00: DOS)
230
+ decToHex(versionMadeBy, 2) +
231
+ // file header (common to file and central directory)
232
+ header +
233
+ // file comment length
234
+ decToHex(encodedComment.length, 2) +
235
+ // disk number start
236
+ "\x00\x00" +
237
+ // internal file attributes TODO
238
+ "\x00\x00" +
239
+ // external file attributes
240
+ decToHex(extFileAttr, 4) +
241
+ // relative offset of local header
242
+ decToHex(offset, 4) +
243
+ // file name
244
+ encodedFileName +
245
+ // extra field
246
+ extraFields +
247
+ // file comment
248
+ encodedComment;
249
+
250
+ return {
251
+ fileRecord: fileRecord,
252
+ dirRecord: dirRecord
253
+ };
254
+ };
255
+
256
+ /**
257
+ * Generate the EOCD record.
258
+ * @param {Number} entriesCount the number of entries in the zip file.
259
+ * @param {Number} centralDirLength the length (in bytes) of the central dir.
260
+ * @param {Number} localDirLength the length (in bytes) of the local dir.
261
+ * @param {String} comment the zip file comment as a binary string.
262
+ * @param {Function} encodeFileName the function to encode the comment.
263
+ * @return {String} the EOCD record.
264
+ */
265
+ var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {
266
+ var dirEnd = "";
267
+ var encodedComment = utils.transformTo("string", encodeFileName(comment));
268
+
269
+ // end of central dir signature
270
+ dirEnd = signature.CENTRAL_DIRECTORY_END +
271
+ // number of this disk
272
+ "\x00\x00" +
273
+ // number of the disk with the start of the central directory
274
+ "\x00\x00" +
275
+ // total number of entries in the central directory on this disk
276
+ decToHex(entriesCount, 2) +
277
+ // total number of entries in the central directory
278
+ decToHex(entriesCount, 2) +
279
+ // size of the central directory 4 bytes
280
+ decToHex(centralDirLength, 4) +
281
+ // offset of start of central directory with respect to the starting disk number
282
+ decToHex(localDirLength, 4) +
283
+ // .ZIP file comment length
284
+ decToHex(encodedComment.length, 2) +
285
+ // .ZIP file comment
286
+ encodedComment;
287
+
288
+ return dirEnd;
289
+ };
290
+
291
+ /**
292
+ * Generate data descriptors for a file entry.
293
+ * @param {Object} streamInfo the hash generated by a worker, containing information
294
+ * on the file entry.
295
+ * @return {String} the data descriptors.
296
+ */
297
+ var generateDataDescriptors = function (streamInfo) {
298
+ var descriptor = "";
299
+ descriptor = signature.DATA_DESCRIPTOR +
300
+ // crc-32 4 bytes
301
+ decToHex(streamInfo["crc32"], 4) +
302
+ // compressed size 4 bytes
303
+ decToHex(streamInfo["compressedSize"], 4) +
304
+ // uncompressed size 4 bytes
305
+ decToHex(streamInfo["uncompressedSize"], 4);
306
+
307
+ return descriptor;
308
+ };
309
+
310
+ export class ZipFileWorker extends GenericWorker {
311
+ /**
312
+ * A worker to concatenate other workers to create a zip file.
313
+ * @param {Boolean} streamFiles `true` to stream the content of the files,
314
+ * `false` to accumulate it.
315
+ * @param {String} comment the comment to use.
316
+ * @param {String} platform the platform to use, "UNIX" or "DOS".
317
+ * @param {Function} encodeFileName the function to encode file names and comments.
318
+ */
319
+ constructor(streamFiles, comment, platform, encodeFileName) {
320
+ super("ZipFileWorker");
321
+ // The number of bytes written so far. This doesn't count accumulated chunks.
322
+ this.bytesWritten = 0;
323
+ // The comment of the zip file
324
+ this.zipComment = comment;
325
+ // The platform "generating" the zip file.
326
+ this.zipPlatform = platform;
327
+ // the function to encode file names and comments.
328
+ this.encodeFileName = encodeFileName;
329
+ // Should we stream the content of the files ?
330
+ this.streamFiles = streamFiles;
331
+ // If `streamFiles` is false, we will need to accumulate the content of the
332
+ // files to calculate sizes / crc32 (and write them *before* the content).
333
+ // This boolean indicates if we are accumulating chunks (it will change a lot
334
+ // during the lifetime of this worker).
335
+ this.accumulate = false;
336
+ // The buffer receiving chunks when accumulating content.
337
+ this.contentBuffer = [];
338
+ // The list of generated directory records.
339
+ this.dirRecords = [];
340
+ // The offset (in bytes) from the beginning of the zip file for the current source.
341
+ this.currentSourceOffset = 0;
342
+ // The total number of entries in this zip file.
343
+ this.entriesCount = 0;
344
+ // the name of the file currently being added, null when handling the end of the zip file.
345
+ // Used for the emitted metadata.
346
+ this.currentFile = null;
347
+
348
+
349
+
350
+ this._sources = [];
351
+ }
352
+
353
+ /**
354
+ * @see GenericWorker.push
355
+ */
356
+ push(chunk) {
357
+
358
+ var currentFilePercent = chunk.meta.percent || 0;
359
+ var entriesCount = this.entriesCount;
360
+ var remainingFiles = this._sources.length;
361
+
362
+ if (this.accumulate) {
363
+ this.contentBuffer.push(chunk);
364
+ } else {
365
+ this.bytesWritten += chunk.data.length;
366
+
367
+ GenericWorker.prototype.push.call(this, {
368
+ data: chunk.data,
369
+ meta: {
370
+ currentFile: this.currentFile,
371
+ percent: entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100
372
+ }
373
+ });
374
+ }
375
+ };
376
+
377
+ /**
378
+ * The worker started a new source (an other worker).
379
+ * @param {Object} streamInfo the streamInfo object from the new source.
380
+ */
381
+ openedSource(streamInfo) {
382
+ this.currentSourceOffset = this.bytesWritten;
383
+ this.currentFile = streamInfo["file"].name;
384
+
385
+ var streamedContent = this.streamFiles && !streamInfo["file"].dir;
386
+
387
+ // don't stream folders (because they don't have any content)
388
+ if (streamedContent) {
389
+ var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
390
+ this.push({
391
+ data: record.fileRecord,
392
+ meta: { percent: 0 }
393
+ });
394
+ } else {
395
+ // we need to wait for the whole file before pushing anything
396
+ this.accumulate = true;
397
+ }
398
+ };
399
+
400
+ /**
401
+ * The worker finished a source (an other worker).
402
+ * @param {Object} streamInfo the streamInfo object from the finished source.
403
+ */
404
+ closedSource(streamInfo) {
405
+ this.accumulate = false;
406
+ var streamedContent = this.streamFiles && !streamInfo["file"].dir;
407
+ var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
408
+
409
+ this.dirRecords.push(record.dirRecord);
410
+ if (streamedContent) {
411
+ // after the streamed file, we put data descriptors
412
+ this.push({
413
+ data: generateDataDescriptors(streamInfo),
414
+ meta: { percent: 100 }
415
+ });
416
+ } else {
417
+ // the content wasn't streamed, we need to push everything now
418
+ // first the file record, then the content
419
+ this.push({
420
+ data: record.fileRecord,
421
+ meta: { percent: 0 }
422
+ });
423
+ while (this.contentBuffer.length) {
424
+ this.push(this.contentBuffer.shift());
425
+ }
426
+ }
427
+ this.currentFile = null;
428
+ };
429
+
430
+ /**
431
+ * @see GenericWorker.flush
432
+ */
433
+ flush() {
434
+
435
+ var localDirLength = this.bytesWritten;
436
+ for (var i = 0; i < this.dirRecords.length; i++) {
437
+ this.push({
438
+ data: this.dirRecords[i],
439
+ meta: { percent: 100 }
440
+ });
441
+ }
442
+ var centralDirLength = this.bytesWritten - localDirLength;
443
+
444
+ var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);
445
+
446
+ this.push({
447
+ data: dirEnd,
448
+ meta: { percent: 100 }
449
+ });
450
+ };
451
+
452
+ /**
453
+ * Prepare the next source to be read.
454
+ */
455
+ prepareNextSource() {
456
+ this.previous = this._sources.shift();
457
+ this.openedSource(this.previous.streamInfo);
458
+ if (this.isPaused) {
459
+ this.previous.pause();
460
+ } else {
461
+ this.previous.resume();
462
+ }
463
+ };
464
+
465
+ /**
466
+ * @see GenericWorker.registerPrevious
467
+ */
468
+ registerPrevious(previous) {
469
+ this._sources.push(previous);
470
+ var self = this;
471
+
472
+ previous.on("data", function (chunk) {
473
+ self.processChunk(chunk);
474
+ });
475
+ previous.on("end", function () {
476
+ self.closedSource(self.previous.streamInfo);
477
+ if (self._sources.length) {
478
+ self.prepareNextSource();
479
+ } else {
480
+ self.end();
481
+ }
482
+ });
483
+ previous.on("error", function (e) {
484
+ self.error(e);
485
+ });
486
+ return this;
487
+ };
488
+
489
+ /**
490
+ * @see GenericWorker.resume
491
+ */
492
+ resume() {
493
+ if (!GenericWorker.prototype.resume.call(this)) {
494
+ return false;
495
+ }
496
+
497
+ if (!this.previous && this._sources.length) {
498
+ this.prepareNextSource();
499
+ return true;
500
+ }
501
+ if (!this.previous && !this._sources.length && !this.generatedError) {
502
+ this.end();
503
+ return true;
504
+ }
505
+ };
506
+
507
+ /**
508
+ * @see GenericWorker.error
509
+ */
510
+ error(e) {
511
+ var sources = this._sources;
512
+ if (!GenericWorker.prototype.error.call(this, e)) {
513
+ return false;
514
+ }
515
+ for (var i = 0; i < sources.length; i++) {
516
+ try {
517
+ sources[i].error(e);
518
+ } catch (e) {
519
+ // the `error` exploded, nothing to do
520
+ }
521
+ }
522
+ return true;
523
+ };
524
+
525
+ /**
526
+ * @see GenericWorker.lock
527
+ */
528
+ lock() {
529
+ GenericWorker.prototype.lock.call(this);
530
+ var sources = this._sources;
531
+ for (var i = 0; i < sources.length; i++) {
532
+ sources[i].lock();
533
+ }
534
+ };
535
+ }
@@ -0,0 +1,59 @@
1
+ import compressions from "../compressions.js";
2
+ import { ZipFileWorker } from "./ZipFileWorker.js";
3
+
4
+ /**
5
+ * Find the compression to use.
6
+ * @param {String} fileCompression the compression defined at the file level, if any.
7
+ * @param {String} zipCompression the compression defined at the load() level.
8
+ * @return {Object} the compression object to use.
9
+ */
10
+ var getCompression = function (fileCompression, zipCompression) {
11
+
12
+ var compressionName = fileCompression || zipCompression;
13
+ var compression = compressions[compressionName];
14
+ if (!compression) {
15
+ throw new Error(compressionName + " is not a valid compression method !");
16
+ }
17
+ return compression;
18
+ };
19
+
20
+ /**
21
+ * Create a worker to generate a zip file.
22
+ * @param {JSZip} zip the JSZip instance at the right root level.
23
+ * @param {Object} options to generate the zip file.
24
+ * @param {String} comment the comment to use.
25
+ */
26
+ export function generateWorker(zip, options, comment) {
27
+
28
+ var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);
29
+ var entriesCount = 0;
30
+ try {
31
+
32
+ zip.forEach(function (relativePath, file) {
33
+ entriesCount++;
34
+ var compression = getCompression(file.options.compression, options.compression);
35
+ var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
36
+ var dir = file.dir, date = file.date;
37
+
38
+ file._compressWorker(compression, compressionOptions)
39
+ .withStreamInfo("file", {
40
+ name : relativePath,
41
+ dir : dir,
42
+ date : date,
43
+ comment : file.comment || "",
44
+ unixPermissions : file.unixPermissions,
45
+ dosPermissions : file.dosPermissions
46
+ })
47
+ .pipe(zipFileWorker);
48
+ });
49
+ zipFileWorker.entriesCount = entriesCount;
50
+ } catch (e) {
51
+ zipFileWorker.error(e);
52
+ }
53
+
54
+ return zipFileWorker;
55
+ };
56
+
57
+ export default {
58
+ generateWorker
59
+ }