archiver-node 8.0.3 → 8.0.4
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/cjs/Archiver.js +771 -679
- package/cjs/archivers/JsonArchive.js +35 -42
- package/cjs/archivers/TarArchive.js +35 -42
- package/cjs/archivers/ZipArchive.js +35 -42
- package/cjs/error.js +10 -38
- package/cjs/lazystream.js +97 -51
- package/cjs/plugins/json.js +106 -102
- package/cjs/plugins/tar.js +128 -131
- package/cjs/plugins/zip.js +90 -95
- package/cjs/readdir-glob.js +382 -0
- package/cjs/utils.js +27 -55
- package/package.json +5 -3
package/cjs/Archiver.js
CHANGED
|
@@ -1,183 +1,184 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var Archiver_exports = {};
|
|
29
|
-
__export(Archiver_exports, {
|
|
30
|
-
default: () => Archiver
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
31
5
|
});
|
|
32
|
-
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
6
|
+
exports["default"] = void 0;
|
|
7
|
+
var _fs = require("fs");
|
|
8
|
+
var _isStream = require("is-stream");
|
|
9
|
+
var _readdirGlob = require("./readdir-glob.js");
|
|
10
|
+
var _lazystream = require("./lazystream.js");
|
|
11
|
+
var _async = require("async");
|
|
12
|
+
var _path = require("path");
|
|
13
|
+
var _error = require("./error.js");
|
|
14
|
+
var _readableStream = require("readable-stream");
|
|
15
|
+
var _utils = require("./utils.js");
|
|
16
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
17
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
20
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
21
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
22
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
23
|
+
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
24
|
+
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
25
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
26
|
+
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
27
|
+
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
28
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
29
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
30
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
31
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // `readdir-glob` has different exports in `esm` and `cjs`:
|
|
32
|
+
// in `esm` it's a named export but in `cjs` it's a default export.
|
|
33
|
+
// https://github.com/Yqnn/node-readdir-glob/issues/28
|
|
34
|
+
// As a result, this package's code can't be transpiled properly.
|
|
35
|
+
// Copy-pasted `readdir-glob` code here to fix that.
|
|
36
|
+
var ReaddirGlob = _readdirGlob.readdirGlob.ReaddirGlob;
|
|
37
|
+
var win32 = process.platform === "win32";
|
|
38
|
+
var Archiver = exports["default"] = /*#__PURE__*/function (_Transform) {
|
|
39
|
+
/**
|
|
40
|
+
* @constructor
|
|
41
|
+
* @param {String} format The archive format to use.
|
|
42
|
+
* @param {(CoreOptions|TransformOptions)} options See also {@link ZipOptions} and {@link TarOptions}.
|
|
52
43
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
function Archiver(options) {
|
|
45
|
+
var _this;
|
|
46
|
+
_classCallCheck(this, Archiver);
|
|
47
|
+
options = _objectSpread({
|
|
55
48
|
highWaterMark: 1024 * 1024,
|
|
56
|
-
statConcurrency: 4
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this._statQueue.drain(this._onQueueDrain.bind(this));
|
|
76
|
-
this._state = {
|
|
49
|
+
statConcurrency: 4
|
|
50
|
+
}, options);
|
|
51
|
+
_this = _callSuper(this, Archiver, [options]);
|
|
52
|
+
_defineProperty(_this, "_supportsDirectory", false);
|
|
53
|
+
_defineProperty(_this, "_supportsSymlink", false);
|
|
54
|
+
_this.options = options;
|
|
55
|
+
_this._format = false;
|
|
56
|
+
_this._module = false;
|
|
57
|
+
_this._pending = 0;
|
|
58
|
+
_this._pointer = 0;
|
|
59
|
+
_this._entriesCount = 0;
|
|
60
|
+
_this._entriesProcessedCount = 0;
|
|
61
|
+
_this._fsEntriesTotalBytes = 0;
|
|
62
|
+
_this._fsEntriesProcessedBytes = 0;
|
|
63
|
+
_this._queue = (0, _async.queue)(_this._onQueueTask.bind(_this), 1);
|
|
64
|
+
_this._queue.drain(_this._onQueueDrain.bind(_this));
|
|
65
|
+
_this._statQueue = (0, _async.queue)(_this._onStatQueueTask.bind(_this), options.statConcurrency);
|
|
66
|
+
_this._statQueue.drain(_this._onQueueDrain.bind(_this));
|
|
67
|
+
_this._state = {
|
|
77
68
|
aborted: false,
|
|
78
69
|
finalize: false,
|
|
79
70
|
finalizing: false,
|
|
80
71
|
finalized: false,
|
|
81
72
|
modulePiped: false
|
|
82
73
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Internal logic for `abort`.
|
|
87
|
-
*
|
|
88
|
-
* @private
|
|
89
|
-
* @return void
|
|
90
|
-
*/
|
|
91
|
-
_abort() {
|
|
92
|
-
this._state.aborted = true;
|
|
93
|
-
this._queue.kill();
|
|
94
|
-
this._statQueue.kill();
|
|
95
|
-
if (this._queue.idle()) {
|
|
96
|
-
this._shutdown();
|
|
97
|
-
}
|
|
74
|
+
_this._streams = [];
|
|
75
|
+
return _this;
|
|
98
76
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* @
|
|
104
|
-
* @
|
|
105
|
-
* @return void
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Internal logic for `abort`.
|
|
80
|
+
*
|
|
81
|
+
* @private
|
|
82
|
+
* @return void
|
|
106
83
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
84
|
+
_inherits(Archiver, _Transform);
|
|
85
|
+
return _createClass(Archiver, [{
|
|
86
|
+
key: "_abort",
|
|
87
|
+
value: function _abort() {
|
|
88
|
+
this._state.aborted = true;
|
|
89
|
+
this._queue.kill();
|
|
90
|
+
this._statQueue.kill();
|
|
91
|
+
if (this._queue.idle()) {
|
|
92
|
+
this._shutdown();
|
|
93
|
+
}
|
|
115
94
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Internal helper for appending files.
|
|
97
|
+
*
|
|
98
|
+
* @private
|
|
99
|
+
* @param {String} filepath The source filepath.
|
|
100
|
+
* @param {EntryData} data The entry data.
|
|
101
|
+
* @return void
|
|
102
|
+
*/
|
|
103
|
+
}, {
|
|
104
|
+
key: "_append",
|
|
105
|
+
value: function _append(filepath, data) {
|
|
106
|
+
data = data || {};
|
|
107
|
+
var task = {
|
|
108
|
+
source: null,
|
|
109
|
+
filepath: filepath
|
|
110
|
+
};
|
|
111
|
+
if (!data.name) {
|
|
112
|
+
data.name = filepath;
|
|
113
|
+
}
|
|
114
|
+
data.sourcePath = filepath;
|
|
115
|
+
task.data = data;
|
|
116
|
+
this._entriesCount++;
|
|
117
|
+
if (data.stats && data.stats instanceof _fs.Stats) {
|
|
118
|
+
task = this._updateQueueTaskWithStats(task, data.stats);
|
|
119
|
+
if (task) {
|
|
120
|
+
if (data.stats.size) {
|
|
121
|
+
this._fsEntriesTotalBytes += data.stats.size;
|
|
122
|
+
}
|
|
123
|
+
this._queue.push(task);
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
} else {
|
|
126
|
+
this._statQueue.push(task);
|
|
126
127
|
}
|
|
127
|
-
} else {
|
|
128
|
-
this._statQueue.push(task);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Internal logic for `finalize`.
|
|
133
|
-
*
|
|
134
|
-
* @private
|
|
135
|
-
* @return void
|
|
136
|
-
*/
|
|
137
|
-
_finalize() {
|
|
138
|
-
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
139
|
-
return;
|
|
140
128
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Internal logic for `finalize`.
|
|
131
|
+
*
|
|
132
|
+
* @private
|
|
133
|
+
* @return void
|
|
134
|
+
*/
|
|
135
|
+
}, {
|
|
136
|
+
key: "_finalize",
|
|
137
|
+
value: function _finalize() {
|
|
138
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this._state.finalizing = true;
|
|
142
|
+
this._moduleFinalize();
|
|
143
|
+
this._state.finalizing = false;
|
|
144
|
+
this._state.finalized = true;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Checks the various state variables to determine if we can `finalize`.
|
|
148
|
+
*
|
|
149
|
+
* @private
|
|
150
|
+
* @return {Boolean}
|
|
151
|
+
*/
|
|
152
|
+
}, {
|
|
153
|
+
key: "_maybeFinalize",
|
|
154
|
+
value: function _maybeFinalize() {
|
|
155
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
159
|
+
this._finalize();
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
154
162
|
return false;
|
|
155
163
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
callback();
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
this._module.append(
|
|
178
|
-
source,
|
|
179
|
-
data,
|
|
180
|
-
function(err) {
|
|
164
|
+
/**
|
|
165
|
+
* Appends an entry to the module.
|
|
166
|
+
*
|
|
167
|
+
* @private
|
|
168
|
+
* @fires Archiver#entry
|
|
169
|
+
* @param {(Buffer|Stream)} source
|
|
170
|
+
* @param {EntryData} data
|
|
171
|
+
* @param {Function} callback
|
|
172
|
+
* @return void
|
|
173
|
+
*/
|
|
174
|
+
}, {
|
|
175
|
+
key: "_moduleAppend",
|
|
176
|
+
value: function _moduleAppend(source, data, callback) {
|
|
177
|
+
if (this._state.aborted) {
|
|
178
|
+
callback();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this._module.append(source, data, function (err) {
|
|
181
182
|
this._task = null;
|
|
182
183
|
if (this._state.aborted) {
|
|
183
184
|
this._shutdown();
|
|
@@ -188,11 +189,21 @@ class Archiver extends import_readable_stream.Transform {
|
|
|
188
189
|
setImmediate(callback);
|
|
189
190
|
return;
|
|
190
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Fires when the entry's input has been processed and appended to the archive.
|
|
194
|
+
*
|
|
195
|
+
* @event Archiver#entry
|
|
196
|
+
* @type {EntryData}
|
|
197
|
+
*/
|
|
191
198
|
this.emit("entry", data);
|
|
192
199
|
this._entriesProcessedCount++;
|
|
193
200
|
if (data.stats && data.stats.size) {
|
|
194
201
|
this._fsEntriesProcessedBytes += data.stats.size;
|
|
195
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* @event Archiver#progress
|
|
205
|
+
* @type {ProgressData}
|
|
206
|
+
*/
|
|
196
207
|
this.emit("progress", {
|
|
197
208
|
entries: {
|
|
198
209
|
total: this._entriesCount,
|
|
@@ -204,175 +215,197 @@ class Archiver extends import_readable_stream.Transform {
|
|
|
204
215
|
}
|
|
205
216
|
});
|
|
206
217
|
setImmediate(callback);
|
|
207
|
-
}.bind(this)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
this._module.finalize
|
|
219
|
-
|
|
220
|
-
this._module.end
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Pipes the module to our internal stream with error bubbling.
|
|
227
|
-
*
|
|
228
|
-
* @private
|
|
229
|
-
* @return void
|
|
230
|
-
*/
|
|
231
|
-
_modulePipe() {
|
|
232
|
-
this._module.on("error", this._onModuleError.bind(this));
|
|
233
|
-
this._module.pipe(this);
|
|
234
|
-
this._state.modulePiped = true;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Unpipes the module from our internal stream.
|
|
238
|
-
*
|
|
239
|
-
* @private
|
|
240
|
-
* @return void
|
|
241
|
-
*/
|
|
242
|
-
_moduleUnpipe() {
|
|
243
|
-
this._module.unpipe(this);
|
|
244
|
-
this._state.modulePiped = false;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Normalizes entry data with fallbacks for key properties.
|
|
248
|
-
*
|
|
249
|
-
* @private
|
|
250
|
-
* @param {Object} data
|
|
251
|
-
* @param {fs.Stats} stats
|
|
252
|
-
* @return {Object}
|
|
253
|
-
*/
|
|
254
|
-
_normalizeEntryData(data, stats) {
|
|
255
|
-
data = {
|
|
256
|
-
type: "file",
|
|
257
|
-
name: null,
|
|
258
|
-
date: null,
|
|
259
|
-
mode: null,
|
|
260
|
-
prefix: null,
|
|
261
|
-
sourcePath: null,
|
|
262
|
-
stats: false,
|
|
263
|
-
...data
|
|
264
|
-
};
|
|
265
|
-
if (stats && data.stats === false) {
|
|
266
|
-
data.stats = stats;
|
|
267
|
-
}
|
|
268
|
-
let isDir = data.type === "directory";
|
|
269
|
-
if (data.name) {
|
|
270
|
-
if (typeof data.prefix === "string" && "" !== data.prefix) {
|
|
271
|
-
data.name = data.prefix + "/" + data.name;
|
|
272
|
-
data.prefix = null;
|
|
273
|
-
}
|
|
274
|
-
data.name = (0, import_utils.sanitizePath)(data.name);
|
|
275
|
-
if (data.type !== "symlink" && data.name.slice(-1) === "/") {
|
|
276
|
-
isDir = true;
|
|
277
|
-
data.type = "directory";
|
|
278
|
-
} else if (isDir) {
|
|
279
|
-
data.name += "/";
|
|
218
|
+
}.bind(this));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Finalizes the module.
|
|
222
|
+
*
|
|
223
|
+
* @private
|
|
224
|
+
* @return void
|
|
225
|
+
*/
|
|
226
|
+
}, {
|
|
227
|
+
key: "_moduleFinalize",
|
|
228
|
+
value: function _moduleFinalize() {
|
|
229
|
+
if (typeof this._module.finalize === "function") {
|
|
230
|
+
this._module.finalize();
|
|
231
|
+
} else if (typeof this._module.end === "function") {
|
|
232
|
+
this._module.end();
|
|
233
|
+
} else {
|
|
234
|
+
this.emit("error", new _error.ArchiverError("NOENDMETHOD"));
|
|
280
235
|
}
|
|
281
236
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
237
|
+
/**
|
|
238
|
+
* Pipes the module to our internal stream with error bubbling.
|
|
239
|
+
*
|
|
240
|
+
* @private
|
|
241
|
+
* @return void
|
|
242
|
+
*/
|
|
243
|
+
}, {
|
|
244
|
+
key: "_modulePipe",
|
|
245
|
+
value: function _modulePipe() {
|
|
246
|
+
this._module.on("error", this._onModuleError.bind(this));
|
|
247
|
+
this._module.pipe(this);
|
|
248
|
+
this._state.modulePiped = true;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Unpipes the module from our internal stream.
|
|
252
|
+
*
|
|
253
|
+
* @private
|
|
254
|
+
* @return void
|
|
255
|
+
*/
|
|
256
|
+
}, {
|
|
257
|
+
key: "_moduleUnpipe",
|
|
258
|
+
value: function _moduleUnpipe() {
|
|
259
|
+
this._module.unpipe(this);
|
|
260
|
+
this._state.modulePiped = false;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Normalizes entry data with fallbacks for key properties.
|
|
264
|
+
*
|
|
265
|
+
* @private
|
|
266
|
+
* @param {Object} data
|
|
267
|
+
* @param {fs.Stats} stats
|
|
268
|
+
* @return {Object}
|
|
269
|
+
*/
|
|
270
|
+
}, {
|
|
271
|
+
key: "_normalizeEntryData",
|
|
272
|
+
value: function _normalizeEntryData(data, stats) {
|
|
273
|
+
data = _objectSpread({
|
|
274
|
+
type: "file",
|
|
275
|
+
name: null,
|
|
276
|
+
date: null,
|
|
277
|
+
mode: null,
|
|
278
|
+
prefix: null,
|
|
279
|
+
sourcePath: null,
|
|
280
|
+
stats: false
|
|
281
|
+
}, data);
|
|
282
|
+
if (stats && data.stats === false) {
|
|
283
|
+
data.stats = stats;
|
|
287
284
|
}
|
|
288
|
-
|
|
289
|
-
if (
|
|
290
|
-
data.
|
|
291
|
-
|
|
292
|
-
|
|
285
|
+
var isDir = data.type === "directory";
|
|
286
|
+
if (data.name) {
|
|
287
|
+
if (typeof data.prefix === "string" && "" !== data.prefix) {
|
|
288
|
+
data.name = data.prefix + "/" + data.name;
|
|
289
|
+
data.prefix = null;
|
|
290
|
+
}
|
|
291
|
+
data.name = (0, _utils.sanitizePath)(data.name);
|
|
292
|
+
if (data.type !== "symlink" && data.name.slice(-1) === "/") {
|
|
293
|
+
isDir = true;
|
|
294
|
+
data.type = "directory";
|
|
295
|
+
} else if (isDir) {
|
|
296
|
+
data.name += "/";
|
|
297
|
+
}
|
|
293
298
|
}
|
|
294
|
-
|
|
295
|
-
|
|
299
|
+
// 511 === 0777; 493 === 0755; 438 === 0666; 420 === 0644
|
|
300
|
+
if (typeof data.mode === "number") {
|
|
301
|
+
if (win32) {
|
|
302
|
+
data.mode &= 511;
|
|
303
|
+
} else {
|
|
304
|
+
data.mode &= 4095;
|
|
305
|
+
}
|
|
306
|
+
} else if (data.stats && data.mode === null) {
|
|
307
|
+
if (win32) {
|
|
308
|
+
data.mode = data.stats.mode & 511;
|
|
309
|
+
} else {
|
|
310
|
+
data.mode = data.stats.mode & 4095;
|
|
311
|
+
}
|
|
312
|
+
// stat isn't reliable on windows; force 0755 for dir
|
|
313
|
+
if (win32 && isDir) {
|
|
314
|
+
data.mode = 493;
|
|
315
|
+
}
|
|
316
|
+
} else if (data.mode === null) {
|
|
317
|
+
data.mode = isDir ? 493 : 420;
|
|
296
318
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
data.date = data.stats.mtime;
|
|
302
|
-
} else {
|
|
303
|
-
data.date = (0, import_utils.dateify)(data.date);
|
|
304
|
-
}
|
|
305
|
-
return data;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Error listener that re-emits error on to our internal stream.
|
|
309
|
-
*
|
|
310
|
-
* @private
|
|
311
|
-
* @param {Error} err
|
|
312
|
-
* @return void
|
|
313
|
-
*/
|
|
314
|
-
_onModuleError(err) {
|
|
315
|
-
this.emit("error", err);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Checks the various state variables after queue has drained to determine if
|
|
319
|
-
* we need to `finalize`.
|
|
320
|
-
*
|
|
321
|
-
* @private
|
|
322
|
-
* @return void
|
|
323
|
-
*/
|
|
324
|
-
_onQueueDrain() {
|
|
325
|
-
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
329
|
-
this._finalize();
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Appends each queue task to the module.
|
|
334
|
-
*
|
|
335
|
-
* @private
|
|
336
|
-
* @param {Object} task
|
|
337
|
-
* @param {Function} callback
|
|
338
|
-
* @return void
|
|
339
|
-
*/
|
|
340
|
-
_onQueueTask(task, callback) {
|
|
341
|
-
const fullCallback = () => {
|
|
342
|
-
if (task.data.callback) {
|
|
343
|
-
task.data.callback();
|
|
319
|
+
if (data.stats && data.date === null) {
|
|
320
|
+
data.date = data.stats.mtime;
|
|
321
|
+
} else {
|
|
322
|
+
data.date = (0, _utils.dateify)(data.date);
|
|
344
323
|
}
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
324
|
+
return data;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Error listener that re-emits error on to our internal stream.
|
|
328
|
+
*
|
|
329
|
+
* @private
|
|
330
|
+
* @param {Error} err
|
|
331
|
+
* @return void
|
|
332
|
+
*/
|
|
333
|
+
}, {
|
|
334
|
+
key: "_onModuleError",
|
|
335
|
+
value: function _onModuleError(err) {
|
|
336
|
+
/**
|
|
337
|
+
* @event Archiver#error
|
|
338
|
+
* @type {ErrorData}
|
|
339
|
+
*/
|
|
340
|
+
this.emit("error", err);
|
|
350
341
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Checks the various state variables after queue has drained to determine if
|
|
344
|
+
* we need to `finalize`.
|
|
345
|
+
*
|
|
346
|
+
* @private
|
|
347
|
+
* @return void
|
|
348
|
+
*/
|
|
349
|
+
}, {
|
|
350
|
+
key: "_onQueueDrain",
|
|
351
|
+
value: function _onQueueDrain() {
|
|
352
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
356
|
+
this._finalize();
|
|
357
|
+
}
|
|
366
358
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
359
|
+
/**
|
|
360
|
+
* Appends each queue task to the module.
|
|
361
|
+
*
|
|
362
|
+
* @private
|
|
363
|
+
* @param {Object} task
|
|
364
|
+
* @param {Function} callback
|
|
365
|
+
* @return void
|
|
366
|
+
*/
|
|
367
|
+
}, {
|
|
368
|
+
key: "_onQueueTask",
|
|
369
|
+
value: function _onQueueTask(task, callback) {
|
|
370
|
+
var fullCallback = function fullCallback() {
|
|
371
|
+
if (task.data.callback) {
|
|
372
|
+
task.data.callback();
|
|
373
|
+
}
|
|
374
|
+
callback();
|
|
375
|
+
};
|
|
376
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
377
|
+
fullCallback();
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
this._task = task;
|
|
381
|
+
this._moduleAppend(task.source, task.data, fullCallback);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Performs a file stat and reinjects the task back into the queue.
|
|
385
|
+
*
|
|
386
|
+
* @private
|
|
387
|
+
* @param {Object} task
|
|
388
|
+
* @param {Function} callback
|
|
389
|
+
* @return void
|
|
390
|
+
*/
|
|
391
|
+
}, {
|
|
392
|
+
key: "_onStatQueueTask",
|
|
393
|
+
value: function _onStatQueueTask(task, callback) {
|
|
394
|
+
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
|
|
395
|
+
callback();
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
(0, _fs.lstat)(task.filepath, function (err, stats) {
|
|
370
399
|
if (this._state.aborted) {
|
|
371
400
|
setImmediate(callback);
|
|
372
401
|
return;
|
|
373
402
|
}
|
|
374
403
|
if (err) {
|
|
375
404
|
this._entriesCount--;
|
|
405
|
+
/**
|
|
406
|
+
* @event Archiver#warning
|
|
407
|
+
* @type {ErrorData}
|
|
408
|
+
*/
|
|
376
409
|
this.emit("warning", err);
|
|
377
410
|
setImmediate(callback);
|
|
378
411
|
return;
|
|
@@ -385,382 +418,441 @@ class Archiver extends import_readable_stream.Transform {
|
|
|
385
418
|
this._queue.push(task);
|
|
386
419
|
}
|
|
387
420
|
setImmediate(callback);
|
|
388
|
-
}.bind(this)
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
(0,
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
this.emit(
|
|
450
|
-
"warning",
|
|
451
|
-
new import_error.ArchiverError("DIRECTORYNOTSUPPORTED", task.data)
|
|
452
|
-
);
|
|
453
|
-
} else if (stats.isSymbolicLink()) {
|
|
454
|
-
this.emit(
|
|
455
|
-
"warning",
|
|
456
|
-
new import_error.ArchiverError("SYMLINKNOTSUPPORTED", task.data)
|
|
457
|
-
);
|
|
421
|
+
}.bind(this));
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Unpipes the module and ends our internal stream.
|
|
425
|
+
*
|
|
426
|
+
* @private
|
|
427
|
+
* @return void
|
|
428
|
+
*/
|
|
429
|
+
}, {
|
|
430
|
+
key: "_shutdown",
|
|
431
|
+
value: function _shutdown() {
|
|
432
|
+
this._moduleUnpipe();
|
|
433
|
+
this.end();
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Tracks the bytes emitted by our internal stream.
|
|
437
|
+
*
|
|
438
|
+
* @private
|
|
439
|
+
* @param {Buffer} chunk
|
|
440
|
+
* @param {String} encoding
|
|
441
|
+
* @param {Function} callback
|
|
442
|
+
* @return void
|
|
443
|
+
*/
|
|
444
|
+
}, {
|
|
445
|
+
key: "_transform",
|
|
446
|
+
value: function _transform(chunk, encoding, callback) {
|
|
447
|
+
if (chunk) {
|
|
448
|
+
this._pointer += chunk.length;
|
|
449
|
+
}
|
|
450
|
+
callback(null, chunk);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Updates and normalizes a queue task using stats data.
|
|
454
|
+
*
|
|
455
|
+
* @private
|
|
456
|
+
* @param {Object} task
|
|
457
|
+
* @param {Stats} stats
|
|
458
|
+
* @return {Object}
|
|
459
|
+
*/
|
|
460
|
+
}, {
|
|
461
|
+
key: "_updateQueueTaskWithStats",
|
|
462
|
+
value: function _updateQueueTaskWithStats(task, stats) {
|
|
463
|
+
if (stats.isFile()) {
|
|
464
|
+
task.data.type = "file";
|
|
465
|
+
task.data.sourceType = "stream";
|
|
466
|
+
task.source = new _lazystream.Readable(function () {
|
|
467
|
+
return (0, _fs.createReadStream)(task.filepath);
|
|
468
|
+
});
|
|
469
|
+
} else if (stats.isDirectory() && this._supportsDirectory) {
|
|
470
|
+
task.data.name = (0, _utils.trailingSlashIt)(task.data.name);
|
|
471
|
+
task.data.type = "directory";
|
|
472
|
+
task.data.sourcePath = (0, _utils.trailingSlashIt)(task.filepath);
|
|
473
|
+
task.data.sourceType = "buffer";
|
|
474
|
+
task.source = Buffer.concat([]);
|
|
475
|
+
} else if (stats.isSymbolicLink() && this._supportsSymlink) {
|
|
476
|
+
var linkPath = (0, _fs.readlinkSync)(task.filepath);
|
|
477
|
+
var dirName = (0, _path.dirname)(task.filepath);
|
|
478
|
+
task.data.type = "symlink";
|
|
479
|
+
task.data.linkname = (0, _path.relative)(dirName, (0, _path.resolve)(dirName, linkPath));
|
|
480
|
+
task.data.sourceType = "buffer";
|
|
481
|
+
task.source = Buffer.concat([]);
|
|
458
482
|
} else {
|
|
459
|
-
|
|
483
|
+
if (stats.isDirectory()) {
|
|
484
|
+
this.emit("warning", new _error.ArchiverError("DIRECTORYNOTSUPPORTED", task.data));
|
|
485
|
+
} else if (stats.isSymbolicLink()) {
|
|
486
|
+
this.emit("warning", new _error.ArchiverError("SYMLINKNOTSUPPORTED", task.data));
|
|
487
|
+
} else {
|
|
488
|
+
this.emit("warning", new _error.ArchiverError("ENTRYNOTSUPPORTED", task.data));
|
|
489
|
+
}
|
|
490
|
+
return null;
|
|
460
491
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
return this;
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Appends an input source (text string, buffer, or stream) to the instance.
|
|
487
|
-
*
|
|
488
|
-
* When the instance has received, processed, and emitted the input, the `entry`
|
|
489
|
-
* event is fired.
|
|
490
|
-
*
|
|
491
|
-
* @fires Archiver#entry
|
|
492
|
-
* @param {(Buffer|Stream|String)} source The input source.
|
|
493
|
-
* @param {EntryData} data See also {@link ZipEntryData} and {@link TarEntryData}.
|
|
494
|
-
* @return {this}
|
|
495
|
-
*/
|
|
496
|
-
append(source, data) {
|
|
497
|
-
if (this._state.finalize || this._state.aborted) {
|
|
498
|
-
this.emit("error", new import_error.ArchiverError("QUEUECLOSED"));
|
|
499
|
-
return this;
|
|
500
|
-
}
|
|
501
|
-
data = this._normalizeEntryData(data);
|
|
502
|
-
if (typeof data.name !== "string" || data.name.length === 0) {
|
|
503
|
-
this.emit("error", new import_error.ArchiverError("ENTRYNAMEREQUIRED"));
|
|
504
|
-
return this;
|
|
505
|
-
}
|
|
506
|
-
if (data.type === "directory" && !this._supportsDirectory) {
|
|
507
|
-
this.emit(
|
|
508
|
-
"error",
|
|
509
|
-
new import_error.ArchiverError("DIRECTORYNOTSUPPORTED", { name: data.name })
|
|
510
|
-
);
|
|
511
|
-
return this;
|
|
512
|
-
}
|
|
513
|
-
source = (0, import_utils.normalizeInputSource)(source);
|
|
514
|
-
if (Buffer.isBuffer(source)) {
|
|
515
|
-
data.sourceType = "buffer";
|
|
516
|
-
} else if ((0, import_is_stream.isStream)(source)) {
|
|
517
|
-
data.sourceType = "stream";
|
|
518
|
-
} else {
|
|
519
|
-
this.emit(
|
|
520
|
-
"error",
|
|
521
|
-
new import_error.ArchiverError("INPUTSTEAMBUFFERREQUIRED", { name: data.name })
|
|
522
|
-
);
|
|
523
|
-
return this;
|
|
524
|
-
}
|
|
525
|
-
this._entriesCount++;
|
|
526
|
-
this._queue.push({
|
|
527
|
-
data,
|
|
528
|
-
source
|
|
529
|
-
});
|
|
530
|
-
return this;
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Appends a directory and its files, recursively, given its dirpath.
|
|
534
|
-
*
|
|
535
|
-
* @param {String} dirpath The source directory path.
|
|
536
|
-
* @param {String} destpath The destination path within the archive.
|
|
537
|
-
* @param {(EntryData|Function)} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
538
|
-
* [TarEntryData]{@link TarEntryData}.
|
|
539
|
-
* @return {this}
|
|
540
|
-
*/
|
|
541
|
-
directory(dirpath, destpath, data) {
|
|
542
|
-
if (this._state.finalize || this._state.aborted) {
|
|
543
|
-
this.emit("error", new import_error.ArchiverError("QUEUECLOSED"));
|
|
492
|
+
task.data = this._normalizeEntryData(task.data, stats);
|
|
493
|
+
return task;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Aborts the archiving process, taking a best-effort approach, by:
|
|
497
|
+
*
|
|
498
|
+
* - removing any pending queue tasks
|
|
499
|
+
* - allowing any active queue workers to finish
|
|
500
|
+
* - detaching internal module pipes
|
|
501
|
+
* - ending both sides of the Transform stream
|
|
502
|
+
*
|
|
503
|
+
* It will NOT drain any remaining sources.
|
|
504
|
+
*
|
|
505
|
+
* @return {this}
|
|
506
|
+
*/
|
|
507
|
+
}, {
|
|
508
|
+
key: "abort",
|
|
509
|
+
value: function abort() {
|
|
510
|
+
if (this._state.aborted || this._state.finalized) {
|
|
511
|
+
return this;
|
|
512
|
+
}
|
|
513
|
+
this._abort();
|
|
544
514
|
return this;
|
|
545
515
|
}
|
|
546
|
-
|
|
547
|
-
|
|
516
|
+
/**
|
|
517
|
+
* Appends an input source (text string, buffer, or stream) to the instance.
|
|
518
|
+
*
|
|
519
|
+
* When the instance has received, processed, and emitted the input, the `entry`
|
|
520
|
+
* event is fired.
|
|
521
|
+
*
|
|
522
|
+
* @fires Archiver#entry
|
|
523
|
+
* @param {(Buffer|Stream|String)} source The input source.
|
|
524
|
+
* @param {EntryData} data See also {@link ZipEntryData} and {@link TarEntryData}.
|
|
525
|
+
* @return {this}
|
|
526
|
+
*/
|
|
527
|
+
}, {
|
|
528
|
+
key: "append",
|
|
529
|
+
value: function append(source, data) {
|
|
530
|
+
if (this._state.finalize || this._state.aborted) {
|
|
531
|
+
this.emit("error", new _error.ArchiverError("QUEUECLOSED"));
|
|
532
|
+
return this;
|
|
533
|
+
}
|
|
534
|
+
data = this._normalizeEntryData(data);
|
|
535
|
+
if (typeof data.name !== "string" || data.name.length === 0) {
|
|
536
|
+
this.emit("error", new _error.ArchiverError("ENTRYNAMEREQUIRED"));
|
|
537
|
+
return this;
|
|
538
|
+
}
|
|
539
|
+
if (data.type === "directory" && !this._supportsDirectory) {
|
|
540
|
+
this.emit("error", new _error.ArchiverError("DIRECTORYNOTSUPPORTED", {
|
|
541
|
+
name: data.name
|
|
542
|
+
}));
|
|
543
|
+
return this;
|
|
544
|
+
}
|
|
545
|
+
source = (0, _utils.normalizeInputSource)(source);
|
|
546
|
+
if (Buffer.isBuffer(source)) {
|
|
547
|
+
data.sourceType = "buffer";
|
|
548
|
+
} else if ((0, _isStream.isStream)(source)) {
|
|
549
|
+
data.sourceType = "stream";
|
|
550
|
+
} else {
|
|
551
|
+
this.emit("error", new _error.ArchiverError("INPUTSTEAMBUFFERREQUIRED", {
|
|
552
|
+
name: data.name
|
|
553
|
+
}));
|
|
554
|
+
return this;
|
|
555
|
+
}
|
|
556
|
+
this._entriesCount++;
|
|
557
|
+
this._queue.push({
|
|
558
|
+
data: data,
|
|
559
|
+
source: source
|
|
560
|
+
});
|
|
548
561
|
return this;
|
|
549
562
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
563
|
+
/**
|
|
564
|
+
* Appends a directory and its files, recursively, given its dirpath.
|
|
565
|
+
*
|
|
566
|
+
* @param {String} dirpath The source directory path.
|
|
567
|
+
* @param {String} destpath The destination path within the archive.
|
|
568
|
+
* @param {(EntryData|Function)} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
569
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
570
|
+
* @return {this}
|
|
571
|
+
*/
|
|
572
|
+
}, {
|
|
573
|
+
key: "directory",
|
|
574
|
+
value: function directory(dirpath, destpath, data) {
|
|
575
|
+
if (this._state.finalize || this._state.aborted) {
|
|
576
|
+
this.emit("error", new _error.ArchiverError("QUEUECLOSED"));
|
|
577
|
+
return this;
|
|
578
|
+
}
|
|
579
|
+
if (typeof dirpath !== "string" || dirpath.length === 0) {
|
|
580
|
+
this.emit("error", new _error.ArchiverError("DIRECTORYDIRPATHREQUIRED"));
|
|
581
|
+
return this;
|
|
582
|
+
}
|
|
583
|
+
this._pending++;
|
|
584
|
+
if (destpath === false) {
|
|
585
|
+
destpath = "";
|
|
586
|
+
} else if (typeof destpath !== "string") {
|
|
587
|
+
destpath = dirpath;
|
|
588
|
+
}
|
|
589
|
+
var dataFunction = false;
|
|
590
|
+
if (typeof data === "function") {
|
|
591
|
+
dataFunction = data;
|
|
592
|
+
data = {};
|
|
593
|
+
} else if (_typeof(data) !== "object") {
|
|
594
|
+
data = {};
|
|
595
|
+
}
|
|
596
|
+
var globOptions = {
|
|
597
|
+
stat: true,
|
|
598
|
+
dot: true
|
|
599
|
+
};
|
|
600
|
+
function onGlobEnd() {
|
|
601
|
+
this._pending--;
|
|
602
|
+
this._maybeFinalize();
|
|
603
|
+
}
|
|
604
|
+
function onGlobError(err) {
|
|
605
|
+
this.emit("error", err);
|
|
606
|
+
}
|
|
607
|
+
function onGlobMatch(match) {
|
|
608
|
+
globber.pause();
|
|
609
|
+
var ignoreMatch = false;
|
|
610
|
+
var entryData = Object.assign({}, data);
|
|
611
|
+
entryData.name = match.relative;
|
|
612
|
+
entryData.prefix = destpath;
|
|
613
|
+
entryData.stats = match.stat;
|
|
614
|
+
entryData.callback = globber.resume.bind(globber);
|
|
615
|
+
try {
|
|
616
|
+
if (dataFunction) {
|
|
617
|
+
entryData = dataFunction(entryData);
|
|
618
|
+
if (entryData === false) {
|
|
619
|
+
ignoreMatch = true;
|
|
620
|
+
} else if (_typeof(entryData) !== "object") {
|
|
621
|
+
throw new _error.ArchiverError("DIRECTORYFUNCTIONINVALIDDATA", {
|
|
622
|
+
dirpath: dirpath
|
|
623
|
+
});
|
|
624
|
+
}
|
|
591
625
|
}
|
|
626
|
+
} catch (e) {
|
|
627
|
+
this.emit("error", e);
|
|
628
|
+
return;
|
|
592
629
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
globber.resume();
|
|
599
|
-
return;
|
|
630
|
+
if (ignoreMatch) {
|
|
631
|
+
globber.resume();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
this._append(match.absolute, entryData);
|
|
600
635
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
globber.on("match", onGlobMatch.bind(this));
|
|
606
|
-
globber.on("end", onGlobEnd.bind(this));
|
|
607
|
-
return this;
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Appends a file given its filepath using a
|
|
611
|
-
* [lazystream]{@link https://github.com/jpommerening/node-lazystream} wrapper to
|
|
612
|
-
* prevent issues with open file limits.
|
|
613
|
-
*
|
|
614
|
-
* When the instance has received, processed, and emitted the file, the `entry`
|
|
615
|
-
* event is fired.
|
|
616
|
-
*
|
|
617
|
-
* @param {String} filepath The source filepath.
|
|
618
|
-
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
619
|
-
* [TarEntryData]{@link TarEntryData}.
|
|
620
|
-
* @return {this}
|
|
621
|
-
*/
|
|
622
|
-
file(filepath, data) {
|
|
623
|
-
if (this._state.finalize || this._state.aborted) {
|
|
624
|
-
this.emit("error", new import_error.ArchiverError("QUEUECLOSED"));
|
|
625
|
-
return this;
|
|
626
|
-
}
|
|
627
|
-
if (typeof filepath !== "string" || filepath.length === 0) {
|
|
628
|
-
this.emit("error", new import_error.ArchiverError("FILEFILEPATHREQUIRED"));
|
|
636
|
+
var globber = (0, _readdirGlob.readdirGlob)(dirpath, globOptions);
|
|
637
|
+
globber.on("error", onGlobError.bind(this));
|
|
638
|
+
globber.on("match", onGlobMatch.bind(this));
|
|
639
|
+
globber.on("end", onGlobEnd.bind(this));
|
|
629
640
|
return this;
|
|
630
641
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
this.
|
|
656
|
-
}
|
|
657
|
-
function onGlobMatch(match) {
|
|
658
|
-
globber.pause();
|
|
659
|
-
const entryData = Object.assign({}, data);
|
|
660
|
-
entryData.callback = globber.resume.bind(globber);
|
|
661
|
-
entryData.stats = match.stat;
|
|
662
|
-
entryData.name = match.relative;
|
|
663
|
-
this._append(match.absolute, entryData);
|
|
664
|
-
}
|
|
665
|
-
const globber = new ReaddirGlob(options.cwd || ".", options);
|
|
666
|
-
globber.on("error", onGlobError.bind(this));
|
|
667
|
-
globber.on("match", onGlobMatch.bind(this));
|
|
668
|
-
globber.on("end", onGlobEnd.bind(this));
|
|
669
|
-
return this;
|
|
670
|
-
}
|
|
671
|
-
/**
|
|
672
|
-
* Finalizes the instance and prevents further appending to the archive
|
|
673
|
-
* structure (queue will continue til drained).
|
|
674
|
-
*
|
|
675
|
-
* The `end`, `close` or `finish` events on the destination stream may fire
|
|
676
|
-
* right after calling this method so you should set listeners beforehand to
|
|
677
|
-
* properly detect stream completion.
|
|
678
|
-
*
|
|
679
|
-
* @return {Promise}
|
|
680
|
-
*/
|
|
681
|
-
finalize() {
|
|
682
|
-
if (this._state.aborted) {
|
|
683
|
-
var abortedError = new import_error.ArchiverError("ABORTED");
|
|
684
|
-
this.emit("error", abortedError);
|
|
685
|
-
return Promise.reject(abortedError);
|
|
686
|
-
}
|
|
687
|
-
if (this._state.finalize) {
|
|
688
|
-
var finalizingError = new import_error.ArchiverError("FINALIZING");
|
|
689
|
-
this.emit("error", finalizingError);
|
|
690
|
-
return Promise.reject(finalizingError);
|
|
691
|
-
}
|
|
692
|
-
this._state.finalize = true;
|
|
693
|
-
if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
694
|
-
this._finalize();
|
|
695
|
-
}
|
|
696
|
-
var self = this;
|
|
697
|
-
return new Promise(function(resolve, reject) {
|
|
698
|
-
var errored;
|
|
699
|
-
self._module.on("end", function() {
|
|
700
|
-
if (!errored) {
|
|
701
|
-
resolve();
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
self._module.on("error", function(err) {
|
|
705
|
-
errored = true;
|
|
706
|
-
reject(err);
|
|
707
|
-
});
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Appends a symlink to the instance.
|
|
712
|
-
*
|
|
713
|
-
* This does NOT interact with filesystem and is used for programmatically creating symlinks.
|
|
714
|
-
*
|
|
715
|
-
* @param {String} filepath The symlink path (within archive).
|
|
716
|
-
* @param {String} target The target path (within archive).
|
|
717
|
-
* @param {Number} mode Sets the entry permissions.
|
|
718
|
-
* @return {this}
|
|
719
|
-
*/
|
|
720
|
-
symlink(filepath, target, mode) {
|
|
721
|
-
if (this._state.finalize || this._state.aborted) {
|
|
722
|
-
this.emit("error", new import_error.ArchiverError("QUEUECLOSED"));
|
|
642
|
+
/**
|
|
643
|
+
* Appends a file given its filepath using a
|
|
644
|
+
* [lazystream]{@link https://github.com/jpommerening/node-lazystream} wrapper to
|
|
645
|
+
* prevent issues with open file limits.
|
|
646
|
+
*
|
|
647
|
+
* When the instance has received, processed, and emitted the file, the `entry`
|
|
648
|
+
* event is fired.
|
|
649
|
+
*
|
|
650
|
+
* @param {String} filepath The source filepath.
|
|
651
|
+
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
652
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
653
|
+
* @return {this}
|
|
654
|
+
*/
|
|
655
|
+
}, {
|
|
656
|
+
key: "file",
|
|
657
|
+
value: function file(filepath, data) {
|
|
658
|
+
if (this._state.finalize || this._state.aborted) {
|
|
659
|
+
this.emit("error", new _error.ArchiverError("QUEUECLOSED"));
|
|
660
|
+
return this;
|
|
661
|
+
}
|
|
662
|
+
if (typeof filepath !== "string" || filepath.length === 0) {
|
|
663
|
+
this.emit("error", new _error.ArchiverError("FILEFILEPATHREQUIRED"));
|
|
664
|
+
return this;
|
|
665
|
+
}
|
|
666
|
+
this._append(filepath, data);
|
|
723
667
|
return this;
|
|
724
668
|
}
|
|
725
|
-
|
|
726
|
-
|
|
669
|
+
/**
|
|
670
|
+
* Appends multiple files that match a glob pattern.
|
|
671
|
+
*
|
|
672
|
+
* @param {String} pattern The [glob pattern]{@link https://github.com/isaacs/minimatch} to match.
|
|
673
|
+
* @param {Object} options See [node-readdir-glob]{@link https://github.com/yqnn/node-readdir-glob#options}.
|
|
674
|
+
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
|
|
675
|
+
* [TarEntryData]{@link TarEntryData}.
|
|
676
|
+
* @return {this}
|
|
677
|
+
*/
|
|
678
|
+
}, {
|
|
679
|
+
key: "glob",
|
|
680
|
+
value: function glob(pattern, options, data) {
|
|
681
|
+
this._pending++;
|
|
682
|
+
options = _objectSpread({
|
|
683
|
+
stat: true,
|
|
684
|
+
pattern: pattern
|
|
685
|
+
}, options);
|
|
686
|
+
function onGlobEnd() {
|
|
687
|
+
this._pending--;
|
|
688
|
+
this._maybeFinalize();
|
|
689
|
+
}
|
|
690
|
+
function onGlobError(err) {
|
|
691
|
+
this.emit("error", err);
|
|
692
|
+
}
|
|
693
|
+
function onGlobMatch(match) {
|
|
694
|
+
globber.pause();
|
|
695
|
+
var entryData = Object.assign({}, data);
|
|
696
|
+
entryData.callback = globber.resume.bind(globber);
|
|
697
|
+
entryData.stats = match.stat;
|
|
698
|
+
entryData.name = match.relative;
|
|
699
|
+
this._append(match.absolute, entryData);
|
|
700
|
+
}
|
|
701
|
+
var globber = new ReaddirGlob(options.cwd || ".", options);
|
|
702
|
+
globber.on("error", onGlobError.bind(this));
|
|
703
|
+
globber.on("match", onGlobMatch.bind(this));
|
|
704
|
+
globber.on("end", onGlobEnd.bind(this));
|
|
727
705
|
return this;
|
|
728
706
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
707
|
+
/**
|
|
708
|
+
* Finalizes the instance and prevents further appending to the archive
|
|
709
|
+
* structure (queue will continue til drained).
|
|
710
|
+
*
|
|
711
|
+
* The `end`, `close` or `finish` events on the destination stream may fire
|
|
712
|
+
* right after calling this method so you should set listeners beforehand to
|
|
713
|
+
* properly detect stream completion.
|
|
714
|
+
*
|
|
715
|
+
* @return {Promise}
|
|
716
|
+
*/
|
|
717
|
+
}, {
|
|
718
|
+
key: "finalize",
|
|
719
|
+
value: function finalize() {
|
|
720
|
+
if (this._state.aborted) {
|
|
721
|
+
var abortedError = new _error.ArchiverError("ABORTED");
|
|
722
|
+
this.emit("error", abortedError);
|
|
723
|
+
return Promise.reject(abortedError);
|
|
724
|
+
}
|
|
725
|
+
if (this._state.finalize) {
|
|
726
|
+
var finalizingError = new _error.ArchiverError("FINALIZING");
|
|
727
|
+
this.emit("error", finalizingError);
|
|
728
|
+
return Promise.reject(finalizingError);
|
|
729
|
+
}
|
|
730
|
+
this._state.finalize = true;
|
|
731
|
+
if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
|
|
732
|
+
this._finalize();
|
|
733
|
+
}
|
|
734
|
+
var self = this;
|
|
735
|
+
return new Promise(function (resolve, reject) {
|
|
736
|
+
var errored;
|
|
737
|
+
self._module.on("end", function () {
|
|
738
|
+
if (!errored) {
|
|
739
|
+
resolve();
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
self._module.on("error", function (err) {
|
|
743
|
+
errored = true;
|
|
744
|
+
reject(err);
|
|
745
|
+
});
|
|
746
|
+
});
|
|
735
747
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
748
|
+
/**
|
|
749
|
+
* Appends a symlink to the instance.
|
|
750
|
+
*
|
|
751
|
+
* This does NOT interact with filesystem and is used for programmatically creating symlinks.
|
|
752
|
+
*
|
|
753
|
+
* @param {String} filepath The symlink path (within archive).
|
|
754
|
+
* @param {String} target The target path (within archive).
|
|
755
|
+
* @param {Number} mode Sets the entry permissions.
|
|
756
|
+
* @return {this}
|
|
757
|
+
*/
|
|
758
|
+
}, {
|
|
759
|
+
key: "symlink",
|
|
760
|
+
value: function symlink(filepath, target, mode) {
|
|
761
|
+
if (this._state.finalize || this._state.aborted) {
|
|
762
|
+
this.emit("error", new _error.ArchiverError("QUEUECLOSED"));
|
|
763
|
+
return this;
|
|
764
|
+
}
|
|
765
|
+
if (typeof filepath !== "string" || filepath.length === 0) {
|
|
766
|
+
this.emit("error", new _error.ArchiverError("SYMLINKFILEPATHREQUIRED"));
|
|
767
|
+
return this;
|
|
768
|
+
}
|
|
769
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
770
|
+
this.emit("error", new _error.ArchiverError("SYMLINKTARGETREQUIRED", {
|
|
771
|
+
filepath: filepath
|
|
772
|
+
}));
|
|
773
|
+
return this;
|
|
774
|
+
}
|
|
775
|
+
if (!this._supportsSymlink) {
|
|
776
|
+
this.emit("error", new _error.ArchiverError("SYMLINKNOTSUPPORTED", {
|
|
777
|
+
filepath: filepath
|
|
778
|
+
}));
|
|
779
|
+
return this;
|
|
780
|
+
}
|
|
781
|
+
var data = {};
|
|
782
|
+
data.type = "symlink";
|
|
783
|
+
data.name = filepath.replace(/\\/g, "/");
|
|
784
|
+
data.linkname = target.replace(/\\/g, "/");
|
|
785
|
+
data.sourceType = "buffer";
|
|
786
|
+
if (typeof mode === "number") {
|
|
787
|
+
data.mode = mode;
|
|
788
|
+
}
|
|
789
|
+
this._entriesCount++;
|
|
790
|
+
this._queue.push({
|
|
791
|
+
data: data,
|
|
792
|
+
source: Buffer.concat([])
|
|
793
|
+
});
|
|
741
794
|
return this;
|
|
742
795
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
}
|
|
796
|
+
/**
|
|
797
|
+
* Returns the current length (in bytes) that has been emitted.
|
|
798
|
+
*
|
|
799
|
+
* @return {Number}
|
|
800
|
+
*/
|
|
801
|
+
}, {
|
|
802
|
+
key: "pointer",
|
|
803
|
+
value: function pointer() {
|
|
804
|
+
return this._pointer;
|
|
805
|
+
}
|
|
806
|
+
}]);
|
|
807
|
+
}(_readableStream.Transform);
|
|
808
|
+
/**
|
|
809
|
+
* @typedef {Object} CoreOptions
|
|
810
|
+
* @global
|
|
811
|
+
* @property {Number} [statConcurrency=4] Sets the number of workers used to
|
|
812
|
+
* process the internal fs stat queue.
|
|
813
|
+
*/
|
|
814
|
+
/**
|
|
815
|
+
* @typedef {Object} TransformOptions
|
|
816
|
+
* @property {Boolean} [allowHalfOpen=true] If set to false, then the stream
|
|
817
|
+
* will automatically end the readable side when the writable side ends and vice
|
|
818
|
+
* versa.
|
|
819
|
+
* @property {Boolean} [readableObjectMode=false] Sets objectMode for readable
|
|
820
|
+
* side of the stream. Has no effect if objectMode is true.
|
|
821
|
+
* @property {Boolean} [writableObjectMode=false] Sets objectMode for writable
|
|
822
|
+
* side of the stream. Has no effect if objectMode is true.
|
|
823
|
+
* @property {Boolean} [decodeStrings=true] Whether or not to decode strings
|
|
824
|
+
* into Buffers before passing them to _write(). `Writable`
|
|
825
|
+
* @property {String} [encoding=NULL] If specified, then buffers will be decoded
|
|
826
|
+
* to strings using the specified encoding. `Readable`
|
|
827
|
+
* @property {Number} [highWaterMark=16kb] The maximum number of bytes to store
|
|
828
|
+
* in the internal buffer before ceasing to read from the underlying resource.
|
|
829
|
+
* `Readable` `Writable`
|
|
830
|
+
* @property {Boolean} [objectMode=false] Whether this stream should behave as a
|
|
831
|
+
* stream of objects. Meaning that stream.read(n) returns a single value instead
|
|
832
|
+
* of a Buffer of size n. `Readable` `Writable`
|
|
833
|
+
*/
|
|
834
|
+
/**
|
|
835
|
+
* @typedef {Object} EntryData
|
|
836
|
+
* @property {String} name Sets the entry name including internal path.
|
|
837
|
+
* @property {(String|Date)} [date=NOW()] Sets the entry date.
|
|
838
|
+
* @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
|
|
839
|
+
* @property {String} [prefix] Sets a path prefix for the entry name. Useful
|
|
840
|
+
* when working with methods like `directory` or `glob`.
|
|
841
|
+
* @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
|
|
842
|
+
* for reduction of fs stat calls when stat data is already known.
|
|
843
|
+
*/
|
|
844
|
+
/**
|
|
845
|
+
* @typedef {Object} ErrorData
|
|
846
|
+
* @property {String} message The message of the error.
|
|
847
|
+
* @property {String} code The error code assigned to this error.
|
|
848
|
+
* @property {String} data Additional data provided for reporting or debugging (where available).
|
|
849
|
+
*/
|
|
850
|
+
/**
|
|
851
|
+
* @typedef {Object} ProgressData
|
|
852
|
+
* @property {Object} entries
|
|
853
|
+
* @property {Number} entries.total Number of entries that have been appended.
|
|
854
|
+
* @property {Number} entries.processed Number of entries that have been processed.
|
|
855
|
+
* @property {Object} fs
|
|
856
|
+
* @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)
|
|
857
|
+
* @property {Number} fs.processedBytes Number of bytes that have been processed. (based on fs.Stats)
|
|
858
|
+
*/
|