@tachybase/module-backup 0.23.8
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/.turbo/turbo-build.log +12 -0
- package/README.md +118 -0
- package/README.zh-CN.md +118 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/Configuration.d.ts +2 -0
- package/dist/client/DuplicatorProvider.d.ts +5 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.js +1 -0
- package/dist/client/locale/index.d.ts +4 -0
- package/dist/externalVersion.js +14 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -0
- package/dist/locale/en-US.json +44 -0
- package/dist/locale/ja-JP.d.ts +25 -0
- package/dist/locale/ja-JP.js +46 -0
- package/dist/locale/ko_KR.json +50 -0
- package/dist/locale/pt-BR.d.ts +26 -0
- package/dist/locale/pt-BR.js +48 -0
- package/dist/locale/zh-CN.json +50 -0
- package/dist/node_modules/@hapi/topo/lib/index.d.ts +60 -0
- package/dist/node_modules/@hapi/topo/lib/index.js +1 -0
- package/dist/node_modules/@hapi/topo/package.json +1 -0
- package/dist/node_modules/archiver/LICENSE +22 -0
- package/dist/node_modules/archiver/index.js +68 -0
- package/dist/node_modules/archiver/lib/core.js +974 -0
- package/dist/node_modules/archiver/lib/error.js +40 -0
- package/dist/node_modules/archiver/lib/plugins/json.js +110 -0
- package/dist/node_modules/archiver/lib/plugins/tar.js +167 -0
- package/dist/node_modules/archiver/lib/plugins/zip.js +120 -0
- package/dist/node_modules/archiver/package.json +1 -0
- package/dist/node_modules/decompress/index.js +16 -0
- package/dist/node_modules/decompress/license +9 -0
- package/dist/node_modules/decompress/package.json +1 -0
- package/dist/node_modules/mkdirp/LICENSE +21 -0
- package/dist/node_modules/mkdirp/bin/cmd.js +68 -0
- package/dist/node_modules/mkdirp/index.js +1 -0
- package/dist/node_modules/mkdirp/lib/find-made.js +29 -0
- package/dist/node_modules/mkdirp/lib/mkdirp-manual.js +64 -0
- package/dist/node_modules/mkdirp/lib/mkdirp-native.js +39 -0
- package/dist/node_modules/mkdirp/lib/opts-arg.js +23 -0
- package/dist/node_modules/mkdirp/lib/path-arg.js +29 -0
- package/dist/node_modules/mkdirp/lib/use-native.js +10 -0
- package/dist/node_modules/mkdirp/package.json +1 -0
- package/dist/node_modules/mkdirp/readme.markdown +266 -0
- package/dist/node_modules/semver/LICENSE +15 -0
- package/dist/node_modules/semver/bin/semver.js +188 -0
- package/dist/node_modules/semver/classes/comparator.js +141 -0
- package/dist/node_modules/semver/classes/index.js +5 -0
- package/dist/node_modules/semver/classes/range.js +554 -0
- package/dist/node_modules/semver/classes/semver.js +302 -0
- package/dist/node_modules/semver/functions/clean.js +6 -0
- package/dist/node_modules/semver/functions/cmp.js +52 -0
- package/dist/node_modules/semver/functions/coerce.js +60 -0
- package/dist/node_modules/semver/functions/compare-build.js +7 -0
- package/dist/node_modules/semver/functions/compare-loose.js +3 -0
- package/dist/node_modules/semver/functions/compare.js +5 -0
- package/dist/node_modules/semver/functions/diff.js +65 -0
- package/dist/node_modules/semver/functions/eq.js +3 -0
- package/dist/node_modules/semver/functions/gt.js +3 -0
- package/dist/node_modules/semver/functions/gte.js +3 -0
- package/dist/node_modules/semver/functions/inc.js +19 -0
- package/dist/node_modules/semver/functions/lt.js +3 -0
- package/dist/node_modules/semver/functions/lte.js +3 -0
- package/dist/node_modules/semver/functions/major.js +3 -0
- package/dist/node_modules/semver/functions/minor.js +3 -0
- package/dist/node_modules/semver/functions/neq.js +3 -0
- package/dist/node_modules/semver/functions/parse.js +16 -0
- package/dist/node_modules/semver/functions/patch.js +3 -0
- package/dist/node_modules/semver/functions/prerelease.js +6 -0
- package/dist/node_modules/semver/functions/rcompare.js +3 -0
- package/dist/node_modules/semver/functions/rsort.js +3 -0
- package/dist/node_modules/semver/functions/satisfies.js +10 -0
- package/dist/node_modules/semver/functions/sort.js +3 -0
- package/dist/node_modules/semver/functions/valid.js +6 -0
- package/dist/node_modules/semver/index.js +1 -0
- package/dist/node_modules/semver/internal/constants.js +35 -0
- package/dist/node_modules/semver/internal/debug.js +9 -0
- package/dist/node_modules/semver/internal/identifiers.js +23 -0
- package/dist/node_modules/semver/internal/lrucache.js +40 -0
- package/dist/node_modules/semver/internal/parse-options.js +15 -0
- package/dist/node_modules/semver/internal/re.js +217 -0
- package/dist/node_modules/semver/package.json +1 -0
- package/dist/node_modules/semver/preload.js +2 -0
- package/dist/node_modules/semver/range.bnf +16 -0
- package/dist/node_modules/semver/ranges/gtr.js +4 -0
- package/dist/node_modules/semver/ranges/intersects.js +7 -0
- package/dist/node_modules/semver/ranges/ltr.js +4 -0
- package/dist/node_modules/semver/ranges/max-satisfying.js +25 -0
- package/dist/node_modules/semver/ranges/min-satisfying.js +24 -0
- package/dist/node_modules/semver/ranges/min-version.js +61 -0
- package/dist/node_modules/semver/ranges/outside.js +80 -0
- package/dist/node_modules/semver/ranges/simplify.js +47 -0
- package/dist/node_modules/semver/ranges/subset.js +247 -0
- package/dist/node_modules/semver/ranges/to-comparators.js +8 -0
- package/dist/node_modules/semver/ranges/valid.js +11 -0
- package/dist/server/app-migrator.d.ts +16 -0
- package/dist/server/app-migrator.js +61 -0
- package/dist/server/collection-group-manager.d.ts +4 -0
- package/dist/server/collection-group-manager.js +29 -0
- package/dist/server/commands/restore-command.d.ts +2 -0
- package/dist/server/commands/restore-command.js +67 -0
- package/dist/server/dumper.d.ts +71 -0
- package/dist/server/dumper.js +421 -0
- package/dist/server/errors/restore-check-error.d.ts +3 -0
- package/dist/server/errors/restore-check-error.js +32 -0
- package/dist/server/field-value-writer.d.ts +9 -0
- package/dist/server/field-value-writer.js +99 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +33 -0
- package/dist/server/locale/zh-CN.d.ts +9 -0
- package/dist/server/locale/zh-CN.js +30 -0
- package/dist/server/resourcers/backup-files.d.ts +25 -0
- package/dist/server/resourcers/backup-files.js +206 -0
- package/dist/server/restorer.d.ts +35 -0
- package/dist/server/restorer.js +320 -0
- package/dist/server/server.d.ts +8 -0
- package/dist/server/server.js +52 -0
- package/dist/server/utils.d.ts +5 -0
- package/dist/server/utils.js +78 -0
- package/dist/swagger/index.d.ts +392 -0
- package/dist/swagger/index.js +447 -0
- package/package.json +48 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,974 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archiver Core
|
|
3
|
+
*
|
|
4
|
+
* @ignore
|
|
5
|
+
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
|
|
6
|
+
* @copyright (c) 2012-2014 Chris Talkington, contributors.
|
|
7
|
+
*/
|
|
8
|
+
var fs = require('fs');
|
|
9
|
+
var glob = require('readdir-glob');
|
|
10
|
+
var async = require('async');
|
|
11
|
+
var path = require('path');
|
|
12
|
+
var util = require('archiver-utils');
|
|
13
|
+
|
|
14
|
+
var inherits = require('util').inherits;
|
|
15
|
+
var ArchiverError = require('./error');
|
|
16
|
+
var Transform = require('readable-stream').Transform;
|
|
17
|
+
|
|
18
|
+
var win32 = process.platform === 'win32';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @constructor
|
|
22
|
+
* @param {String} format The archive format to use.
|
|
23
|
+
* @param {(CoreOptions|TransformOptions)} options See also {@link ZipOptions} and {@link TarOptions}.
|
|
24
|
+
*/
|
|
25
|
+
var Archiver = function(format, options) {
|
|
26
|
+
if (!(this instanceof Archiver)) {
|
|
27
|
+
return new Archiver(format, options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof format !== 'string') {
|
|
31
|
+
options = format;
|
|
32
|
+
format = 'zip';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
options = this.options = util.defaults(options, {
|
|
36
|
+
highWaterMark: 1024 * 1024,
|
|
37
|
+
statConcurrency: 4
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
Transform.call(this, options);
|
|
41
|
+
|
|
42
|
+
this._format = false;
|
|
43
|
+
this._module = false;
|
|
44
|
+
this._pending = 0;
|
|
45
|
+
this._pointer = 0;
|
|
46
|
+
|
|
47
|
+
this._entriesCount = 0;
|
|
48
|
+
this._entriesProcessedCount = 0;
|
|
49
|
+
this._fsEntriesTotalBytes = 0;
|
|
50
|
+
this._fsEntriesProcessedBytes = 0;
|
|
51
|
+
|
|
52
|
+
this._queue = async.queue(this._onQueueTask.bind(this), 1);
|
|
53
|
+
this._queue.drain(this._onQueueDrain.bind(this));
|
|
54
|
+
|
|
55
|
+
this._statQueue = async.queue(this._onStatQueueTask.bind(this), options.statConcurrency);
|
|
56
|
+
this._statQueue.drain(this._onQueueDrain.bind(this));
|
|
57
|
+
|
|
58
|
+
this._state = {
|
|
59
|
+
aborted: false,
|
|
60
|
+
finalize: false,
|
|
61
|
+
finalizing: false,
|
|
62
|
+
finalized: false,
|
|
63
|
+
modulePiped: false
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
this._streams = [];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
inherits(Archiver, Transform);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Internal logic for `abort`.
|
|
73
|
+
*
|
|
74
|
+
* @private
|
|
75
|
+
* @return void
|
|
76
|
+
*/
|
|
77
|
+
Archiver.prototype._abort = function() {
|
|
78
|
+
this._state.aborted = true;
|
|
79
|
+
this._queue.kill();
|
|
80
|
+
this._statQueue.kill();
|
|
81
|
+
|
|
82
|
+
if (this._queue.idle()) {
|
|
83
|
+
this._shutdown();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Internal helper for appending files.
|
|
89
|
+
*
|
|
90
|
+
* @private
|
|
91
|
+
* @param {String} filepath The source filepath.
|
|
92
|
+
* @param {EntryData} data The entry data.
|
|
93
|
+
* @return void
|
|
94
|
+
*/
|
|
95
|
+
Archiver.prototype._append = function(filepath, data) {
|
|
96
|
+
data = data || {};
|
|
97
|
+
|
|
98
|
+
var task = {
|
|
99
|
+
source: null,
|
|
100
|
+
filepath: filepath
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (!data.name) {
|
|
104
|
+
data.name = filepath;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
data.sourcePath = filepath;
|
|
108
|
+
task.data = data;
|
|
109
|
+
this._entriesCount++;
|
|
110
|
+
|
|
111
|
+
if (data.stats && data.stats instanceof fs.Stats) {
|
|
112
|
+
task = this._updateQueueTaskWithStats(task, data.stats);
|
|
113
|
+
if (task) {
|
|
114
|
+
if (data.stats.size) {
|
|
115
|
+
this._fsEntriesTotalBytes += data.stats.size;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this._queue.push(task);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
this._statQueue.push(task);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Internal logic for `finalize`.
|
|
127
|
+
*
|
|
128
|
+
* @private
|
|
129
|
+
* @return void
|
|
130
|
+
*/
|
|
131
|
+
Archiver.prototype._finalize = function() {
|
|
132
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this._state.finalizing = true;
|
|
137
|
+
|
|
138
|
+
this._moduleFinalize();
|
|
139
|
+
|
|
140
|
+
this._state.finalizing = false;
|
|
141
|
+
this._state.finalized = true;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Checks the various state variables to determine if we can `finalize`.
|
|
146
|
+
*
|
|
147
|
+
* @private
|
|
148
|
+
* @return {Boolean}
|
|
149
|
+
*/
|
|
150
|
+
Archiver.prototype._maybeFinalize = function() {
|
|
151
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
156
|
+
this._finalize();
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return false;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Appends an entry to the module.
|
|
165
|
+
*
|
|
166
|
+
* @private
|
|
167
|
+
* @fires Archiver#entry
|
|
168
|
+
* @param {(Buffer|Stream)} source
|
|
169
|
+
* @param {EntryData} data
|
|
170
|
+
* @param {Function} callback
|
|
171
|
+
* @return void
|
|
172
|
+
*/
|
|
173
|
+
Archiver.prototype._moduleAppend = function(source, data, callback) {
|
|
174
|
+
if (this._state.aborted) {
|
|
175
|
+
callback();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this._module.append(source, data, function(err) {
|
|
180
|
+
this._task = null;
|
|
181
|
+
|
|
182
|
+
if (this._state.aborted) {
|
|
183
|
+
this._shutdown();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (err) {
|
|
188
|
+
this.emit('error', err);
|
|
189
|
+
setImmediate(callback);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Fires when the entry's input has been processed and appended to the archive.
|
|
195
|
+
*
|
|
196
|
+
* @event Archiver#entry
|
|
197
|
+
* @type {EntryData}
|
|
198
|
+
*/
|
|
199
|
+
this.emit('entry', data);
|
|
200
|
+
this._entriesProcessedCount++;
|
|
201
|
+
|
|
202
|
+
if (data.stats && data.stats.size) {
|
|
203
|
+
this._fsEntriesProcessedBytes += data.stats.size;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @event Archiver#progress
|
|
208
|
+
* @type {ProgressData}
|
|
209
|
+
*/
|
|
210
|
+
this.emit('progress', {
|
|
211
|
+
entries: {
|
|
212
|
+
total: this._entriesCount,
|
|
213
|
+
processed: this._entriesProcessedCount
|
|
214
|
+
},
|
|
215
|
+
fs: {
|
|
216
|
+
totalBytes: this._fsEntriesTotalBytes,
|
|
217
|
+
processedBytes: this._fsEntriesProcessedBytes
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
setImmediate(callback);
|
|
222
|
+
}.bind(this));
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Finalizes the module.
|
|
227
|
+
*
|
|
228
|
+
* @private
|
|
229
|
+
* @return void
|
|
230
|
+
*/
|
|
231
|
+
Archiver.prototype._moduleFinalize = function() {
|
|
232
|
+
if (typeof this._module.finalize === 'function') {
|
|
233
|
+
this._module.finalize();
|
|
234
|
+
} else if (typeof this._module.end === 'function') {
|
|
235
|
+
this._module.end();
|
|
236
|
+
} else {
|
|
237
|
+
this.emit('error', new ArchiverError('NOENDMETHOD'));
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Pipes the module to our internal stream with error bubbling.
|
|
243
|
+
*
|
|
244
|
+
* @private
|
|
245
|
+
* @return void
|
|
246
|
+
*/
|
|
247
|
+
Archiver.prototype._modulePipe = function() {
|
|
248
|
+
this._module.on('error', this._onModuleError.bind(this));
|
|
249
|
+
this._module.pipe(this);
|
|
250
|
+
this._state.modulePiped = true;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Determines if the current module supports a defined feature.
|
|
255
|
+
*
|
|
256
|
+
* @private
|
|
257
|
+
* @param {String} key
|
|
258
|
+
* @return {Boolean}
|
|
259
|
+
*/
|
|
260
|
+
Archiver.prototype._moduleSupports = function(key) {
|
|
261
|
+
if (!this._module.supports || !this._module.supports[key]) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return this._module.supports[key];
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Unpipes the module from our internal stream.
|
|
270
|
+
*
|
|
271
|
+
* @private
|
|
272
|
+
* @return void
|
|
273
|
+
*/
|
|
274
|
+
Archiver.prototype._moduleUnpipe = function() {
|
|
275
|
+
this._module.unpipe(this);
|
|
276
|
+
this._state.modulePiped = false;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Normalizes entry data with fallbacks for key properties.
|
|
281
|
+
*
|
|
282
|
+
* @private
|
|
283
|
+
* @param {Object} data
|
|
284
|
+
* @param {fs.Stats} stats
|
|
285
|
+
* @return {Object}
|
|
286
|
+
*/
|
|
287
|
+
Archiver.prototype._normalizeEntryData = function(data, stats) {
|
|
288
|
+
data = util.defaults(data, {
|
|
289
|
+
type: 'file',
|
|
290
|
+
name: null,
|
|
291
|
+
date: null,
|
|
292
|
+
mode: null,
|
|
293
|
+
prefix: null,
|
|
294
|
+
sourcePath: null,
|
|
295
|
+
stats: false
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
if (stats && data.stats === false) {
|
|
299
|
+
data.stats = stats;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
var isDir = data.type === 'directory';
|
|
303
|
+
|
|
304
|
+
if (data.name) {
|
|
305
|
+
if (typeof data.prefix === 'string' && '' !== data.prefix) {
|
|
306
|
+
data.name = data.prefix + '/' + data.name;
|
|
307
|
+
data.prefix = null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
data.name = util.sanitizePath(data.name);
|
|
311
|
+
|
|
312
|
+
if (data.type !== 'symlink' && data.name.slice(-1) === '/') {
|
|
313
|
+
isDir = true;
|
|
314
|
+
data.type = 'directory';
|
|
315
|
+
} else if (isDir) {
|
|
316
|
+
data.name += '/';
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// 511 === 0777; 493 === 0755; 438 === 0666; 420 === 0644
|
|
321
|
+
if (typeof data.mode === 'number') {
|
|
322
|
+
if (win32) {
|
|
323
|
+
data.mode &= 511;
|
|
324
|
+
} else {
|
|
325
|
+
data.mode &= 4095
|
|
326
|
+
}
|
|
327
|
+
} else if (data.stats && data.mode === null) {
|
|
328
|
+
if (win32) {
|
|
329
|
+
data.mode = data.stats.mode & 511;
|
|
330
|
+
} else {
|
|
331
|
+
data.mode = data.stats.mode & 4095;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// stat isn't reliable on windows; force 0755 for dir
|
|
335
|
+
if (win32 && isDir) {
|
|
336
|
+
data.mode = 493;
|
|
337
|
+
}
|
|
338
|
+
} else if (data.mode === null) {
|
|
339
|
+
data.mode = isDir ? 493 : 420;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (data.stats && data.date === null) {
|
|
343
|
+
data.date = data.stats.mtime;
|
|
344
|
+
} else {
|
|
345
|
+
data.date = util.dateify(data.date);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return data;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Error listener that re-emits error on to our internal stream.
|
|
353
|
+
*
|
|
354
|
+
* @private
|
|
355
|
+
* @param {Error} err
|
|
356
|
+
* @return void
|
|
357
|
+
*/
|
|
358
|
+
Archiver.prototype._onModuleError = function(err) {
|
|
359
|
+
/**
|
|
360
|
+
* @event Archiver#error
|
|
361
|
+
* @type {ErrorData}
|
|
362
|
+
*/
|
|
363
|
+
this.emit('error', err);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Checks the various state variables after queue has drained to determine if
|
|
368
|
+
* we need to `finalize`.
|
|
369
|
+
*
|
|
370
|
+
* @private
|
|
371
|
+
* @return void
|
|
372
|
+
*/
|
|
373
|
+
Archiver.prototype._onQueueDrain = function() {
|
|
374
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
379
|
+
this._finalize();
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Appends each queue task to the module.
|
|
385
|
+
*
|
|
386
|
+
* @private
|
|
387
|
+
* @param {Object} task
|
|
388
|
+
* @param {Function} callback
|
|
389
|
+
* @return void
|
|
390
|
+
*/
|
|
391
|
+
Archiver.prototype._onQueueTask = function(task, callback) {
|
|
392
|
+
var fullCallback = () => {
|
|
393
|
+
if(task.data.callback) {
|
|
394
|
+
task.data.callback();
|
|
395
|
+
}
|
|
396
|
+
callback();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
400
|
+
fullCallback();
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
this._task = task;
|
|
405
|
+
this._moduleAppend(task.source, task.data, fullCallback);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Performs a file stat and reinjects the task back into the queue.
|
|
410
|
+
*
|
|
411
|
+
* @private
|
|
412
|
+
* @param {Object} task
|
|
413
|
+
* @param {Function} callback
|
|
414
|
+
* @return void
|
|
415
|
+
*/
|
|
416
|
+
Archiver.prototype._onStatQueueTask = function(task, callback) {
|
|
417
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
418
|
+
callback();
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
fs.lstat(task.filepath, function(err, stats) {
|
|
423
|
+
if (this._state.aborted) {
|
|
424
|
+
setImmediate(callback);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (err) {
|
|
429
|
+
this._entriesCount--;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @event Archiver#warning
|
|
433
|
+
* @type {ErrorData}
|
|
434
|
+
*/
|
|
435
|
+
this.emit('warning', err);
|
|
436
|
+
setImmediate(callback);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
task = this._updateQueueTaskWithStats(task, stats);
|
|
441
|
+
|
|
442
|
+
if (task) {
|
|
443
|
+
if (stats.size) {
|
|
444
|
+
this._fsEntriesTotalBytes += stats.size;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
this._queue.push(task);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
setImmediate(callback);
|
|
451
|
+
}.bind(this));
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Unpipes the module and ends our internal stream.
|
|
456
|
+
*
|
|
457
|
+
* @private
|
|
458
|
+
* @return void
|
|
459
|
+
*/
|
|
460
|
+
Archiver.prototype._shutdown = function() {
|
|
461
|
+
this._moduleUnpipe();
|
|
462
|
+
this.end();
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Tracks the bytes emitted by our internal stream.
|
|
467
|
+
*
|
|
468
|
+
* @private
|
|
469
|
+
* @param {Buffer} chunk
|
|
470
|
+
* @param {String} encoding
|
|
471
|
+
* @param {Function} callback
|
|
472
|
+
* @return void
|
|
473
|
+
*/
|
|
474
|
+
Archiver.prototype._transform = function(chunk, encoding, callback) {
|
|
475
|
+
if (chunk) {
|
|
476
|
+
this._pointer += chunk.length;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
callback(null, chunk);
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Updates and normalizes a queue task using stats data.
|
|
484
|
+
*
|
|
485
|
+
* @private
|
|
486
|
+
* @param {Object} task
|
|
487
|
+
* @param {fs.Stats} stats
|
|
488
|
+
* @return {Object}
|
|
489
|
+
*/
|
|
490
|
+
Archiver.prototype._updateQueueTaskWithStats = function(task, stats) {
|
|
491
|
+
if (stats.isFile()) {
|
|
492
|
+
task.data.type = 'file';
|
|
493
|
+
task.data.sourceType = 'stream';
|
|
494
|
+
task.source = util.lazyReadStream(task.filepath);
|
|
495
|
+
} else if (stats.isDirectory() && this._moduleSupports('directory')) {
|
|
496
|
+
task.data.name = util.trailingSlashIt(task.data.name);
|
|
497
|
+
task.data.type = 'directory';
|
|
498
|
+
task.data.sourcePath = util.trailingSlashIt(task.filepath);
|
|
499
|
+
task.data.sourceType = 'buffer';
|
|
500
|
+
task.source = Buffer.concat([]);
|
|
501
|
+
} else if (stats.isSymbolicLink() && this._moduleSupports('symlink')) {
|
|
502
|
+
var linkPath = fs.readlinkSync(task.filepath);
|
|
503
|
+
var dirName = path.dirname(task.filepath);
|
|
504
|
+
task.data.type = 'symlink';
|
|
505
|
+
task.data.linkname = path.relative(dirName, path.resolve(dirName, linkPath));
|
|
506
|
+
task.data.sourceType = 'buffer';
|
|
507
|
+
task.source = Buffer.concat([]);
|
|
508
|
+
} else {
|
|
509
|
+
if (stats.isDirectory()) {
|
|
510
|
+
this.emit('warning', new ArchiverError('DIRECTORYNOTSUPPORTED', task.data));
|
|
511
|
+
} else if (stats.isSymbolicLink()) {
|
|
512
|
+
this.emit('warning', new ArchiverError('SYMLINKNOTSUPPORTED', task.data));
|
|
513
|
+
} else {
|
|
514
|
+
this.emit('warning', new ArchiverError('ENTRYNOTSUPPORTED', task.data));
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
task.data = this._normalizeEntryData(task.data, stats);
|
|
521
|
+
|
|
522
|
+
return task;
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Aborts the archiving process, taking a best-effort approach, by:
|
|
527
|
+
*
|
|
528
|
+
* - removing any pending queue tasks
|
|
529
|
+
* - allowing any active queue workers to finish
|
|
530
|
+
* - detaching internal module pipes
|
|
531
|
+
* - ending both sides of the Transform stream
|
|
532
|
+
*
|
|
533
|
+
* It will NOT drain any remaining sources.
|
|
534
|
+
*
|
|
535
|
+
* @return {this}
|
|
536
|
+
*/
|
|
537
|
+
Archiver.prototype.abort = function() {
|
|
538
|
+
if (this._state.aborted || this._state.finalized) {
|
|
539
|
+
return this;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
this._abort();
|
|
543
|
+
|
|
544
|
+
return this;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Appends an input source (text string, buffer, or stream) to the instance.
|
|
549
|
+
*
|
|
550
|
+
* When the instance has received, processed, and emitted the input, the `entry`
|
|
551
|
+
* event is fired.
|
|
552
|
+
*
|
|
553
|
+
* @fires Archiver#entry
|
|
554
|
+
* @param {(Buffer|Stream|String)} source The input source.
|
|
555
|
+
* @param {EntryData} data See also {@link ZipEntryData} and {@link TarEntryData}.
|
|
556
|
+
* @return {this}
|
|
557
|
+
*/
|
|
558
|
+
Archiver.prototype.append = function(source, data) {
|
|
559
|
+
if (this._state.finalize || this._state.aborted) {
|
|
560
|
+
this.emit('error', new ArchiverError('QUEUECLOSED'));
|
|
561
|
+
return this;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
data = this._normalizeEntryData(data);
|
|
565
|
+
|
|
566
|
+
if (typeof data.name !== 'string' || data.name.length === 0) {
|
|
567
|
+
this.emit('error', new ArchiverError('ENTRYNAMEREQUIRED'));
|
|
568
|
+
return this;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (data.type === 'directory' && !this._moduleSupports('directory')) {
|
|
572
|
+
this.emit('error', new ArchiverError('DIRECTORYNOTSUPPORTED', { name: data.name }));
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
source = util.normalizeInputSource(source);
|
|
577
|
+
|
|
578
|
+
if (Buffer.isBuffer(source)) {
|
|
579
|
+
data.sourceType = 'buffer';
|
|
580
|
+
} else if (util.isStream(source)) {
|
|
581
|
+
data.sourceType = 'stream';
|
|
582
|
+
} else {
|
|
583
|
+
this.emit('error', new ArchiverError('INPUTSTEAMBUFFERREQUIRED', { name: data.name }));
|
|
584
|
+
return this;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
this._entriesCount++;
|
|
588
|
+
this._queue.push({
|
|
589
|
+
data: data,
|
|
590
|
+
source: source
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
return this;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Appends a directory and its files, recursively, given its dirpath.
|
|
598
|
+
*
|
|
599
|
+
* @param {String} dirpath The source directory path.
|
|
600
|
+
* @param {String} destpath The destination path within the archive.
|
|
601
|
+
* @param {(EntryData|Function)} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
602
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
603
|
+
* @return {this}
|
|
604
|
+
*/
|
|
605
|
+
Archiver.prototype.directory = function(dirpath, destpath, data) {
|
|
606
|
+
if (this._state.finalize || this._state.aborted) {
|
|
607
|
+
this.emit('error', new ArchiverError('QUEUECLOSED'));
|
|
608
|
+
return this;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (typeof dirpath !== 'string' || dirpath.length === 0) {
|
|
612
|
+
this.emit('error', new ArchiverError('DIRECTORYDIRPATHREQUIRED'));
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
this._pending++;
|
|
617
|
+
|
|
618
|
+
if (destpath === false) {
|
|
619
|
+
destpath = '';
|
|
620
|
+
} else if (typeof destpath !== 'string'){
|
|
621
|
+
destpath = dirpath;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
var dataFunction = false;
|
|
625
|
+
if (typeof data === 'function') {
|
|
626
|
+
dataFunction = data;
|
|
627
|
+
data = {};
|
|
628
|
+
} else if (typeof data !== 'object') {
|
|
629
|
+
data = {};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
var globOptions = {
|
|
633
|
+
stat: true,
|
|
634
|
+
dot: true
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
function onGlobEnd() {
|
|
638
|
+
this._pending--;
|
|
639
|
+
this._maybeFinalize();
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function onGlobError(err) {
|
|
643
|
+
this.emit('error', err);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
function onGlobMatch(match){
|
|
647
|
+
globber.pause();
|
|
648
|
+
|
|
649
|
+
var ignoreMatch = false;
|
|
650
|
+
var entryData = Object.assign({}, data);
|
|
651
|
+
entryData.name = match.relative;
|
|
652
|
+
entryData.prefix = destpath;
|
|
653
|
+
entryData.stats = match.stat;
|
|
654
|
+
entryData.callback = globber.resume.bind(globber);
|
|
655
|
+
|
|
656
|
+
try {
|
|
657
|
+
if (dataFunction) {
|
|
658
|
+
entryData = dataFunction(entryData);
|
|
659
|
+
|
|
660
|
+
if (entryData === false) {
|
|
661
|
+
ignoreMatch = true;
|
|
662
|
+
} else if (typeof entryData !== 'object') {
|
|
663
|
+
throw new ArchiverError('DIRECTORYFUNCTIONINVALIDDATA', { dirpath: dirpath });
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
} catch(e) {
|
|
667
|
+
this.emit('error', e);
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (ignoreMatch) {
|
|
672
|
+
globber.resume();
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
this._append(match.absolute, entryData);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
var globber = glob(dirpath, globOptions);
|
|
680
|
+
globber.on('error', onGlobError.bind(this));
|
|
681
|
+
globber.on('match', onGlobMatch.bind(this));
|
|
682
|
+
globber.on('end', onGlobEnd.bind(this));
|
|
683
|
+
|
|
684
|
+
return this;
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Appends a file given its filepath using a
|
|
689
|
+
* [lazystream]{@link https://github.com/jpommerening/node-lazystream} wrapper to
|
|
690
|
+
* prevent issues with open file limits.
|
|
691
|
+
*
|
|
692
|
+
* When the instance has received, processed, and emitted the file, the `entry`
|
|
693
|
+
* event is fired.
|
|
694
|
+
*
|
|
695
|
+
* @param {String} filepath The source filepath.
|
|
696
|
+
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
697
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
698
|
+
* @return {this}
|
|
699
|
+
*/
|
|
700
|
+
Archiver.prototype.file = function(filepath, data) {
|
|
701
|
+
if (this._state.finalize || this._state.aborted) {
|
|
702
|
+
this.emit('error', new ArchiverError('QUEUECLOSED'));
|
|
703
|
+
return this;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (typeof filepath !== 'string' || filepath.length === 0) {
|
|
707
|
+
this.emit('error', new ArchiverError('FILEFILEPATHREQUIRED'));
|
|
708
|
+
return this;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
this._append(filepath, data);
|
|
712
|
+
|
|
713
|
+
return this;
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Appends multiple files that match a glob pattern.
|
|
718
|
+
*
|
|
719
|
+
* @param {String} pattern The [glob pattern]{@link https://github.com/isaacs/minimatch} to match.
|
|
720
|
+
* @param {Object} options See [node-readdir-glob]{@link https://github.com/yqnn/node-readdir-glob#options}.
|
|
721
|
+
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
722
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
723
|
+
* @return {this}
|
|
724
|
+
*/
|
|
725
|
+
Archiver.prototype.glob = function(pattern, options, data) {
|
|
726
|
+
this._pending++;
|
|
727
|
+
|
|
728
|
+
options = util.defaults(options, {
|
|
729
|
+
stat: true,
|
|
730
|
+
pattern: pattern
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
function onGlobEnd() {
|
|
734
|
+
this._pending--;
|
|
735
|
+
this._maybeFinalize();
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
function onGlobError(err) {
|
|
739
|
+
this.emit('error', err);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function onGlobMatch(match){
|
|
743
|
+
globber.pause();
|
|
744
|
+
var entryData = Object.assign({}, data);
|
|
745
|
+
entryData.callback = globber.resume.bind(globber);
|
|
746
|
+
entryData.stats = match.stat;
|
|
747
|
+
entryData.name = match.relative;
|
|
748
|
+
|
|
749
|
+
this._append(match.absolute, entryData);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
var globber = glob(options.cwd || '.', options);
|
|
753
|
+
globber.on('error', onGlobError.bind(this));
|
|
754
|
+
globber.on('match', onGlobMatch.bind(this));
|
|
755
|
+
globber.on('end', onGlobEnd.bind(this));
|
|
756
|
+
|
|
757
|
+
return this;
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Finalizes the instance and prevents further appending to the archive
|
|
762
|
+
* structure (queue will continue til drained).
|
|
763
|
+
*
|
|
764
|
+
* The `end`, `close` or `finish` events on the destination stream may fire
|
|
765
|
+
* right after calling this method so you should set listeners beforehand to
|
|
766
|
+
* properly detect stream completion.
|
|
767
|
+
*
|
|
768
|
+
* @return {Promise}
|
|
769
|
+
*/
|
|
770
|
+
Archiver.prototype.finalize = function() {
|
|
771
|
+
if (this._state.aborted) {
|
|
772
|
+
var abortedError = new ArchiverError('ABORTED');
|
|
773
|
+
this.emit('error', abortedError);
|
|
774
|
+
return Promise.reject(abortedError);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (this._state.finalize) {
|
|
778
|
+
var finalizingError = new ArchiverError('FINALIZING');
|
|
779
|
+
this.emit('error', finalizingError);
|
|
780
|
+
return Promise.reject(finalizingError);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
this._state.finalize = true;
|
|
784
|
+
|
|
785
|
+
if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
786
|
+
this._finalize();
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
var self = this;
|
|
790
|
+
|
|
791
|
+
return new Promise(function(resolve, reject) {
|
|
792
|
+
var errored;
|
|
793
|
+
|
|
794
|
+
self._module.on('end', function() {
|
|
795
|
+
if (!errored) {
|
|
796
|
+
resolve();
|
|
797
|
+
}
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
self._module.on('error', function(err) {
|
|
801
|
+
errored = true;
|
|
802
|
+
reject(err);
|
|
803
|
+
})
|
|
804
|
+
})
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Sets the module format name used for archiving.
|
|
809
|
+
*
|
|
810
|
+
* @param {String} format The name of the format.
|
|
811
|
+
* @return {this}
|
|
812
|
+
*/
|
|
813
|
+
Archiver.prototype.setFormat = function(format) {
|
|
814
|
+
if (this._format) {
|
|
815
|
+
this.emit('error', new ArchiverError('FORMATSET'));
|
|
816
|
+
return this;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
this._format = format;
|
|
820
|
+
|
|
821
|
+
return this;
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Sets the module used for archiving.
|
|
826
|
+
*
|
|
827
|
+
* @param {Function} module The function for archiver to interact with.
|
|
828
|
+
* @return {this}
|
|
829
|
+
*/
|
|
830
|
+
Archiver.prototype.setModule = function(module) {
|
|
831
|
+
if (this._state.aborted) {
|
|
832
|
+
this.emit('error', new ArchiverError('ABORTED'));
|
|
833
|
+
return this;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (this._state.module) {
|
|
837
|
+
this.emit('error', new ArchiverError('MODULESET'));
|
|
838
|
+
return this;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
this._module = module;
|
|
842
|
+
this._modulePipe();
|
|
843
|
+
|
|
844
|
+
return this;
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Appends a symlink to the instance.
|
|
849
|
+
*
|
|
850
|
+
* This does NOT interact with filesystem and is used for programmatically creating symlinks.
|
|
851
|
+
*
|
|
852
|
+
* @param {String} filepath The symlink path (within archive).
|
|
853
|
+
* @param {String} target The target path (within archive).
|
|
854
|
+
* @param {Number} mode Sets the entry permissions.
|
|
855
|
+
* @return {this}
|
|
856
|
+
*/
|
|
857
|
+
Archiver.prototype.symlink = function(filepath, target, mode) {
|
|
858
|
+
if (this._state.finalize || this._state.aborted) {
|
|
859
|
+
this.emit('error', new ArchiverError('QUEUECLOSED'));
|
|
860
|
+
return this;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
if (typeof filepath !== 'string' || filepath.length === 0) {
|
|
864
|
+
this.emit('error', new ArchiverError('SYMLINKFILEPATHREQUIRED'));
|
|
865
|
+
return this;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (typeof target !== 'string' || target.length === 0) {
|
|
869
|
+
this.emit('error', new ArchiverError('SYMLINKTARGETREQUIRED', { filepath: filepath }));
|
|
870
|
+
return this;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
if (!this._moduleSupports('symlink')) {
|
|
874
|
+
this.emit('error', new ArchiverError('SYMLINKNOTSUPPORTED', { filepath: filepath }));
|
|
875
|
+
return this;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
var data = {};
|
|
879
|
+
data.type = 'symlink';
|
|
880
|
+
data.name = filepath.replace(/\\/g, '/');
|
|
881
|
+
data.linkname = target.replace(/\\/g, '/');
|
|
882
|
+
data.sourceType = 'buffer';
|
|
883
|
+
|
|
884
|
+
if (typeof mode === "number") {
|
|
885
|
+
data.mode = mode;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
this._entriesCount++;
|
|
889
|
+
this._queue.push({
|
|
890
|
+
data: data,
|
|
891
|
+
source: Buffer.concat([])
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
return this;
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Returns the current length (in bytes) that has been emitted.
|
|
899
|
+
*
|
|
900
|
+
* @return {Number}
|
|
901
|
+
*/
|
|
902
|
+
Archiver.prototype.pointer = function() {
|
|
903
|
+
return this._pointer;
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Middleware-like helper that has yet to be fully implemented.
|
|
908
|
+
*
|
|
909
|
+
* @private
|
|
910
|
+
* @param {Function} plugin
|
|
911
|
+
* @return {this}
|
|
912
|
+
*/
|
|
913
|
+
Archiver.prototype.use = function(plugin) {
|
|
914
|
+
this._streams.push(plugin);
|
|
915
|
+
return this;
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
module.exports = Archiver;
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* @typedef {Object} CoreOptions
|
|
922
|
+
* @global
|
|
923
|
+
* @property {Number} [statConcurrency=4] Sets the number of workers used to
|
|
924
|
+
* process the internal fs stat queue.
|
|
925
|
+
*/
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* @typedef {Object} TransformOptions
|
|
929
|
+
* @property {Boolean} [allowHalfOpen=true] If set to false, then the stream
|
|
930
|
+
* will automatically end the readable side when the writable side ends and vice
|
|
931
|
+
* versa.
|
|
932
|
+
* @property {Boolean} [readableObjectMode=false] Sets objectMode for readable
|
|
933
|
+
* side of the stream. Has no effect if objectMode is true.
|
|
934
|
+
* @property {Boolean} [writableObjectMode=false] Sets objectMode for writable
|
|
935
|
+
* side of the stream. Has no effect if objectMode is true.
|
|
936
|
+
* @property {Boolean} [decodeStrings=true] Whether or not to decode strings
|
|
937
|
+
* into Buffers before passing them to _write(). `Writable`
|
|
938
|
+
* @property {String} [encoding=NULL] If specified, then buffers will be decoded
|
|
939
|
+
* to strings using the specified encoding. `Readable`
|
|
940
|
+
* @property {Number} [highWaterMark=16kb] The maximum number of bytes to store
|
|
941
|
+
* in the internal buffer before ceasing to read from the underlying resource.
|
|
942
|
+
* `Readable` `Writable`
|
|
943
|
+
* @property {Boolean} [objectMode=false] Whether this stream should behave as a
|
|
944
|
+
* stream of objects. Meaning that stream.read(n) returns a single value instead
|
|
945
|
+
* of a Buffer of size n. `Readable` `Writable`
|
|
946
|
+
*/
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* @typedef {Object} EntryData
|
|
950
|
+
* @property {String} name Sets the entry name including internal path.
|
|
951
|
+
* @property {(String|Date)} [date=NOW()] Sets the entry date.
|
|
952
|
+
* @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
|
|
953
|
+
* @property {String} [prefix] Sets a path prefix for the entry name. Useful
|
|
954
|
+
* when working with methods like `directory` or `glob`.
|
|
955
|
+
* @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
|
|
956
|
+
* for reduction of fs stat calls when stat data is already known.
|
|
957
|
+
*/
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* @typedef {Object} ErrorData
|
|
961
|
+
* @property {String} message The message of the error.
|
|
962
|
+
* @property {String} code The error code assigned to this error.
|
|
963
|
+
* @property {String} data Additional data provided for reporting or debugging (where available).
|
|
964
|
+
*/
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* @typedef {Object} ProgressData
|
|
968
|
+
* @property {Object} entries
|
|
969
|
+
* @property {Number} entries.total Number of entries that have been appended.
|
|
970
|
+
* @property {Number} entries.processed Number of entries that have been processed.
|
|
971
|
+
* @property {Object} fs
|
|
972
|
+
* @property {Number} fs.totalBytes Number of bytes that have been appended. Calculated asynchronously and might not be accurate: it growth while entries are added. (based on fs.Stats)
|
|
973
|
+
* @property {Number} fs.processedBytes Number of bytes that have been processed. (based on fs.Stats)
|
|
974
|
+
*/
|