zip-lib 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # zip-lib
2
- A zip and unzip library for Node.js.
2
+ A zip and unzip library for Node.js with promise-based APIs, support for compressing to `Buffer` or extracting from `Buffer`, and advanced features like entry filtering, cancellation, and symlink-aware handling.
3
3
 
4
4
  [![npm Package](https://img.shields.io/npm/v/zip-lib.svg)](https://www.npmjs.org/package/zip-lib)
5
5
  [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/fpsqdb/zip-lib/blob/master/LICENSE)
@@ -470,4 +470,4 @@ interface IEntryEvent {
470
470
  - `entryCount`: The total number of entries in the archive.
471
471
  - `preventDefault()`: Skips the current entry.
472
472
  # License
473
- Licensed under the [MIT](https://github.com/fpsqdb/zip-lib/blob/master/LICENSE) license.
473
+ Licensed under the [MIT](https://github.com/fpsqdb/zip-lib/blob/master/LICENSE) license.
package/lib/unzip.js CHANGED
@@ -137,9 +137,16 @@ class Unzip extends cancelable_1.Cancelable {
137
137
  async extract(zipFileOrBuffer, targetFolder) {
138
138
  const token = new cancelable_1.CancellationToken();
139
139
  this.token = token;
140
- const { zfile, realTargetFolder } = await this.prepareExtraction(zipFileOrBuffer, targetFolder, token);
141
- this.zipFile = zfile;
142
- await this.processEntries(zfile, targetFolder, realTargetFolder, token);
140
+ try {
141
+ const { zfile, realTargetFolder } = await this.prepareExtraction(zipFileOrBuffer, targetFolder, token);
142
+ this.zipFile = zfile;
143
+ await this.processEntries(zfile, targetFolder, realTargetFolder, token);
144
+ }
145
+ finally {
146
+ if (this.token === token) {
147
+ this.token = null;
148
+ }
149
+ }
143
150
  }
144
151
  async prepareExtraction(zipFileOrBuffer, targetFolder, token) {
145
152
  if (this.isOverwrite()) {
@@ -162,18 +169,20 @@ class Unzip extends cancelable_1.Cancelable {
162
169
  const entryEvent = new EntryEvent(total);
163
170
  const settle = this.createPromiseSettler(resolve, reject);
164
171
  const disposeCancel = token.onCancelled(() => {
165
- this.closeZip();
172
+ this.closeZip(zfile);
166
173
  settle.reject(this.canceledError());
167
174
  });
168
175
  zfile.once("error", (err) => {
169
176
  disposeCancel();
170
177
  anyError = this.wrapError(err, token.isCancelled);
171
- this.closeZip();
178
+ this.closeZip(zfile);
172
179
  settle.reject(anyError);
173
180
  });
174
181
  zfile.once("close", () => {
175
182
  disposeCancel();
176
- this.zipFile = null;
183
+ if (this.zipFile === zfile) {
184
+ this.zipFile = null;
185
+ }
177
186
  if (anyError) {
178
187
  settle.reject(this.wrapError(anyError, token.isCancelled));
179
188
  }
@@ -195,7 +204,7 @@ class Unzip extends cancelable_1.Cancelable {
195
204
  }
196
205
  catch (error) {
197
206
  anyError = this.wrapError(error, token.isCancelled);
198
- this.closeZip();
207
+ this.closeZip(zfile);
199
208
  settle.reject(anyError);
200
209
  }
201
210
  });
@@ -204,7 +213,7 @@ class Unzip extends cancelable_1.Cancelable {
204
213
  }
205
214
  readNextEntry(zfile, token) {
206
215
  if (token.isCancelled) {
207
- this.closeZip();
216
+ this.closeZip(zfile);
208
217
  return;
209
218
  }
210
219
  zfile.readEntry();
@@ -261,9 +270,12 @@ class Unzip extends cancelable_1.Cancelable {
261
270
  }
262
271
  this.closeZip();
263
272
  }
264
- closeZip() {
265
- if (this.zipFile) {
266
- this.zipFile.close();
273
+ closeZip(zfile) {
274
+ const target = zfile !== null && zfile !== void 0 ? zfile : this.zipFile;
275
+ if (target) {
276
+ target.close();
277
+ }
278
+ if (!zfile || this.zipFile === zfile) {
267
279
  this.zipFile = null;
268
280
  }
269
281
  }
package/lib/zip.d.ts CHANGED
@@ -28,13 +28,10 @@ export declare class Zip extends Cancelable {
28
28
  *
29
29
  */
30
30
  constructor(options?: IZipOptions | undefined);
31
- private yazlFile;
32
- private isPipe;
33
- private isChunk;
34
- private zipStream;
35
31
  private zipFiles;
36
32
  private zipFolders;
37
33
  private token;
34
+ private activeArchive;
38
35
  /**
39
36
  * Adds a file from the file system at `realPath` to the zip file as `metadataPath`.
40
37
  * @param file
package/lib/zip.js CHANGED
@@ -17,8 +17,7 @@ class Zip extends cancelable_1.Cancelable {
17
17
  constructor(options) {
18
18
  super();
19
19
  this.options = options;
20
- this.isPipe = false;
21
- this.isChunk = false;
20
+ this.activeArchive = null;
22
21
  this.zipFiles = [];
23
22
  this.zipFolders = [];
24
23
  }
@@ -54,62 +53,74 @@ class Zip extends cancelable_1.Cancelable {
54
53
  const token = new cancelable_1.CancellationToken();
55
54
  this.token = token;
56
55
  const zip = await this.prepareArchive(zipFile);
57
- return await new Promise((resolve, reject) => {
58
- let disposeCancel = () => {
59
- // noop
60
- };
61
- const settle = this.createPromiseSettler((value) => {
62
- disposeCancel();
63
- resolve(value);
64
- }, (error) => {
65
- disposeCancel();
66
- reject(error);
67
- });
68
- disposeCancel = token.onCancelled(() => {
69
- this.stop(this.canceledError());
70
- settle.reject(this.canceledError());
71
- });
72
- this.bindArchiveOutput(zip, zipFile, token, settle);
73
- this.addQueuedEntries(zip, token)
74
- .catch((error) => {
75
- settle.reject(this.wrapError(error, token.isCancelled));
76
- })
77
- .finally(() => {
78
- zip.end();
56
+ const activeArchive = {
57
+ zip,
58
+ mode: zipFile ? "file" : "buffer",
59
+ };
60
+ this.activeArchive = activeArchive;
61
+ try {
62
+ return await new Promise((resolve, reject) => {
63
+ let disposeCancel = () => {
64
+ // noop
65
+ };
66
+ const settle = this.createPromiseSettler((value) => {
67
+ disposeCancel();
68
+ resolve(value);
69
+ }, (error) => {
70
+ disposeCancel();
71
+ reject(error);
72
+ });
73
+ disposeCancel = token.onCancelled(() => {
74
+ this.stop(this.canceledError(), activeArchive);
75
+ settle.reject(this.canceledError());
76
+ });
77
+ this.bindArchiveOutput(zip, zipFile, token, settle, activeArchive);
78
+ this.addQueuedEntries(zip, token)
79
+ .catch((error) => {
80
+ settle.reject(this.wrapError(error, token.isCancelled));
81
+ })
82
+ .finally(() => {
83
+ zip.end();
84
+ });
79
85
  });
80
- });
86
+ }
87
+ finally {
88
+ if (this.token === token) {
89
+ this.token = null;
90
+ }
91
+ if (this.activeArchive === activeArchive) {
92
+ this.activeArchive = null;
93
+ }
94
+ }
81
95
  }
82
96
  async prepareArchive(zipFile) {
83
- this.isPipe = false;
84
- this.isChunk = false;
85
97
  if (zipFile) {
86
98
  await exfs.ensureFolder(path.dirname(zipFile));
87
99
  }
88
100
  // Re-instantiate yazl every time the archive method is called to ensure that files are not added repeatedly.
89
101
  // This will also make the Zip class reusable.
90
- this.yazlFile = new yazl.ZipFile();
91
- return this.yazlFile;
102
+ return new yazl.ZipFile();
92
103
  }
93
- bindArchiveOutput(zip, zipFile, token, settle) {
104
+ bindArchiveOutput(zip, zipFile, token, settle, activeArchive) {
94
105
  if (zipFile) {
95
- void this.archiveToFile(zip, zipFile, token, settle);
106
+ void this.archiveToFile(zip, zipFile, token, settle, activeArchive);
96
107
  return;
97
108
  }
98
109
  void this.archiveToBuffer(zip, token, settle);
99
110
  }
100
- async archiveToFile(zip, zipFile, token, settle) {
101
- this.zipStream = (0, node_fs_1.createWriteStream)(zipFile);
102
- this.isPipe = true;
111
+ async archiveToFile(zip, zipFile, token, settle, activeArchive) {
112
+ const zipStream = (0, node_fs_1.createWriteStream)(zipFile);
113
+ activeArchive.zipStream = zipStream;
103
114
  const archivePromise = new Promise((resolve) => {
104
115
  zip.once("error", (err) => {
105
116
  settle.reject(this.wrapError(err, token.isCancelled));
106
117
  resolve();
107
118
  });
108
- this.zipStream.once("error", (err) => {
119
+ zipStream.once("error", (err) => {
109
120
  settle.reject(this.wrapError(err, token.isCancelled));
110
121
  resolve();
111
122
  });
112
- this.zipStream.once("close", () => {
123
+ zipStream.once("close", () => {
113
124
  if (token.isCancelled) {
114
125
  settle.reject(this.canceledError());
115
126
  }
@@ -119,17 +130,11 @@ class Zip extends cancelable_1.Cancelable {
119
130
  resolve();
120
131
  });
121
132
  });
122
- try {
123
- zip.outputStream.pipe(this.zipStream);
124
- await archivePromise;
125
- }
126
- finally {
127
- this.isPipe = false;
128
- }
133
+ zip.outputStream.pipe(zipStream);
134
+ await archivePromise;
129
135
  }
130
136
  async archiveToBuffer(zip, token, settle) {
131
137
  const chunks = [];
132
- this.isChunk = true;
133
138
  const archivePromise = new Promise((resolve) => {
134
139
  zip.once("error", (err) => {
135
140
  settle.reject(this.wrapError(err, token.isCancelled));
@@ -147,12 +152,7 @@ class Zip extends cancelable_1.Cancelable {
147
152
  resolve();
148
153
  });
149
154
  });
150
- try {
151
- await archivePromise;
152
- }
153
- finally {
154
- this.isChunk = false;
155
- }
155
+ await archivePromise;
156
156
  }
157
157
  createPromiseSettler(resolve, reject) {
158
158
  let settled = false;
@@ -272,15 +272,20 @@ class Zip extends cancelable_1.Cancelable {
272
272
  }
273
273
  }
274
274
  }
275
- stop(err) {
276
- if (this.isPipe) {
277
- this.yazlFile.outputStream.unpipe(this.zipStream);
278
- this.zipStream.destroy(err);
279
- this.isPipe = false;
275
+ stop(err, activeArchive) {
276
+ const archive = activeArchive !== null && activeArchive !== void 0 ? activeArchive : this.activeArchive;
277
+ if (!archive) {
278
+ return;
279
+ }
280
+ if (archive.mode === "file" && archive.zipStream) {
281
+ archive.zip.outputStream.unpipe(archive.zipStream);
282
+ archive.zipStream.destroy(err);
283
+ }
284
+ if (archive.mode === "buffer") {
285
+ archive.zip.outputStream.destroy(err);
280
286
  }
281
- if (this.isChunk) {
282
- this.yazlFile.outputStream.destroy(err);
283
- this.isChunk = false;
287
+ if (!activeArchive || this.activeArchive === activeArchive) {
288
+ this.activeArchive = null;
284
289
  }
285
290
  }
286
291
  followSymlink() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zip-lib",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "A zip and unzip library for Node.js.",
5
5
  "main": "lib/index.js",
6
6
  "types": "./lib/index.d.ts",