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 +2 -2
- package/lib/unzip.js +23 -11
- package/lib/zip.d.ts +1 -4
- package/lib/zip.js +63 -58
- package/package.json +1 -1
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
|
[](https://www.npmjs.org/package/zip-lib)
|
|
5
5
|
[](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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
|
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
|
-
|
|
266
|
-
|
|
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.
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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
|
-
|
|
119
|
+
zipStream.once("error", (err) => {
|
|
109
120
|
settle.reject(this.wrapError(err, token.isCancelled));
|
|
110
121
|
resolve();
|
|
111
122
|
});
|
|
112
|
-
|
|
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
|
-
|
|
123
|
-
|
|
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
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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.
|
|
282
|
-
this.
|
|
283
|
-
this.isChunk = false;
|
|
287
|
+
if (!activeArchive || this.activeArchive === activeArchive) {
|
|
288
|
+
this.activeArchive = null;
|
|
284
289
|
}
|
|
285
290
|
}
|
|
286
291
|
followSymlink() {
|