@appium/support 2.61.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/console.d.ts +1 -1
- package/build/lib/console.js +169 -105
- package/build/lib/console.js.map +1 -1
- package/build/lib/env.js +142 -117
- package/build/lib/env.js.map +1 -1
- package/build/lib/fs.d.ts +9 -2
- package/build/lib/fs.d.ts.map +1 -1
- package/build/lib/fs.js +358 -246
- package/build/lib/fs.js.map +1 -1
- package/build/lib/image-util.js +139 -124
- package/build/lib/image-util.js.map +1 -1
- package/build/lib/index.js +64 -103
- package/build/lib/index.js.map +1 -1
- package/build/lib/log-internal.d.ts +4 -27
- package/build/lib/log-internal.d.ts.map +1 -1
- package/build/lib/log-internal.js +141 -123
- package/build/lib/log-internal.js.map +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +5 -14
- package/build/lib/logger.js.map +1 -1
- package/build/lib/logging.d.ts +3 -4
- package/build/lib/logging.d.ts.map +1 -1
- package/build/lib/logging.js +139 -110
- package/build/lib/logging.js.map +1 -1
- package/build/lib/mjpeg.js +169 -141
- package/build/lib/mjpeg.js.map +1 -1
- package/build/lib/mkdirp.js +7 -13
- package/build/lib/mkdirp.js.map +1 -1
- package/build/lib/net.d.ts.map +1 -1
- package/build/lib/net.js +278 -254
- package/build/lib/net.js.map +1 -1
- package/build/lib/node.js +203 -192
- package/build/lib/node.js.map +1 -1
- package/build/lib/npm.d.ts +19 -4
- package/build/lib/npm.d.ts.map +1 -1
- package/build/lib/npm.js +277 -228
- package/build/lib/npm.js.map +1 -1
- package/build/lib/plist.js +145 -136
- package/build/lib/plist.js.map +1 -1
- package/build/lib/process.js +41 -42
- package/build/lib/process.js.map +1 -1
- package/build/lib/system.js +39 -56
- package/build/lib/system.js.map +1 -1
- package/build/lib/tempdir.js +112 -73
- package/build/lib/tempdir.js.map +1 -1
- package/build/lib/timing.js +99 -84
- package/build/lib/timing.js.map +1 -1
- package/build/lib/util.js +454 -356
- package/build/lib/util.js.map +1 -1
- package/build/lib/zip.js +469 -423
- package/build/lib/zip.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/fs.js +15 -1
- package/lib/log-internal.js +12 -16
- package/lib/logging.js +2 -3
- package/lib/net.js +15 -6
- package/lib/npm.js +28 -18
- package/package.json +20 -19
package/build/lib/net.js
CHANGED
|
@@ -1,272 +1,296 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
6
|
-
exports.downloadFile =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
require("
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var _util = require("./util");
|
|
18
|
-
|
|
19
|
-
var _logger = _interopRequireDefault(require("./logger"));
|
|
20
|
-
|
|
21
|
-
var _jsftp = _interopRequireDefault(require("jsftp"));
|
|
22
|
-
|
|
23
|
-
var _timing = _interopRequireDefault(require("./timing"));
|
|
24
|
-
|
|
25
|
-
var _axios = _interopRequireDefault(require("axios"));
|
|
26
|
-
|
|
27
|
-
var _formData = _interopRequireDefault(require("form-data"));
|
|
28
|
-
|
|
29
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
30
|
-
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.downloadFile = exports.uploadFile = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
const fs_1 = __importDefault(require("./fs"));
|
|
9
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
10
|
+
const util_1 = require("./util");
|
|
11
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
12
|
+
const jsftp_1 = __importDefault(require("jsftp"));
|
|
13
|
+
const timing_1 = __importDefault(require("./timing"));
|
|
14
|
+
const axios_1 = __importDefault(require("axios"));
|
|
15
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
31
16
|
const DEFAULT_TIMEOUT_MS = 4 * 60 * 1000;
|
|
32
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Type guard for param to {@linkcode toAxiosAuth}
|
|
19
|
+
* @param {any} value
|
|
20
|
+
* @returns {value is AuthCredentials | import('axios').AxiosBasicCredentials}
|
|
21
|
+
*/
|
|
22
|
+
function isAxiosAuth(value) {
|
|
23
|
+
return lodash_1.default.isPlainObject(value);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Converts {@linkcode AuthCredentials} to credentials understood by {@linkcode axios}.
|
|
27
|
+
* @param {AuthCredentials | import('axios').AxiosBasicCredentials} [auth]
|
|
28
|
+
* @returns {import('axios').AxiosBasicCredentials?}
|
|
29
|
+
*/
|
|
33
30
|
function toAxiosAuth(auth) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return axiosAuth.username && axiosAuth.password ? axiosAuth : null;
|
|
31
|
+
if (!isAxiosAuth(auth)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const axiosAuth = {
|
|
35
|
+
username: 'username' in auth ? auth.username : auth.user,
|
|
36
|
+
password: 'password' in auth ? auth.password : auth.pass,
|
|
37
|
+
};
|
|
38
|
+
return axiosAuth.username && axiosAuth.password ? axiosAuth : null;
|
|
43
39
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
auth,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
pairs = _lodash.default.toPairs(formFields);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
for (const [key, value] of pairs) {
|
|
84
|
-
if (_lodash.default.toLower(key) !== _lodash.default.toLower(fileFieldName)) {
|
|
85
|
-
form.append(key, value);
|
|
40
|
+
/**
|
|
41
|
+
* @param {NodeJS.ReadableStream} localFileStream
|
|
42
|
+
* @param {URL} parsedUri
|
|
43
|
+
* @param {HttpUploadOptions & NetOptions} [uploadOptions]
|
|
44
|
+
*/
|
|
45
|
+
async function uploadFileToHttp(localFileStream, parsedUri, uploadOptions = /** @type {HttpUploadOptions & NetOptions} */ ({})) {
|
|
46
|
+
const { method = 'POST', timeout = DEFAULT_TIMEOUT_MS, headers, auth, fileFieldName = 'file', formFields, } = uploadOptions;
|
|
47
|
+
const { href } = parsedUri;
|
|
48
|
+
/** @type {import('axios').AxiosRequestConfig} */
|
|
49
|
+
const requestOpts = {
|
|
50
|
+
url: href,
|
|
51
|
+
method,
|
|
52
|
+
timeout,
|
|
53
|
+
maxContentLength: Infinity,
|
|
54
|
+
maxBodyLength: Infinity,
|
|
55
|
+
};
|
|
56
|
+
const axiosAuth = toAxiosAuth(auth);
|
|
57
|
+
if (axiosAuth) {
|
|
58
|
+
requestOpts.auth = axiosAuth;
|
|
59
|
+
}
|
|
60
|
+
if (fileFieldName) {
|
|
61
|
+
const form = new form_data_1.default();
|
|
62
|
+
form.append(fileFieldName, localFileStream);
|
|
63
|
+
if (formFields) {
|
|
64
|
+
let pairs = [];
|
|
65
|
+
if (lodash_1.default.isArray(formFields)) {
|
|
66
|
+
pairs = formFields;
|
|
67
|
+
}
|
|
68
|
+
else if (lodash_1.default.isPlainObject(formFields)) {
|
|
69
|
+
pairs = lodash_1.default.toPairs(formFields);
|
|
70
|
+
}
|
|
71
|
+
for (const [key, value] of pairs) {
|
|
72
|
+
if (lodash_1.default.toLower(key) !== lodash_1.default.toLower(fileFieldName)) {
|
|
73
|
+
form.append(key, value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
86
76
|
}
|
|
87
|
-
|
|
77
|
+
requestOpts.headers = {
|
|
78
|
+
...(lodash_1.default.isPlainObject(headers) ? headers : {}),
|
|
79
|
+
...form.getHeaders(),
|
|
80
|
+
};
|
|
81
|
+
requestOpts.data = form;
|
|
88
82
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
} else {
|
|
95
|
-
if (_lodash.default.isPlainObject(headers)) {
|
|
96
|
-
requestOpts.headers = headers;
|
|
83
|
+
else {
|
|
84
|
+
if (lodash_1.default.isPlainObject(headers)) {
|
|
85
|
+
requestOpts.headers = headers;
|
|
86
|
+
}
|
|
87
|
+
requestOpts.data = localFileStream;
|
|
97
88
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
_logger.default.debug(`Performing ${method} to ${href} with options (excluding data): ` + JSON.stringify(_lodash.default.omit(requestOpts, ['data'])));
|
|
103
|
-
|
|
104
|
-
const {
|
|
105
|
-
status,
|
|
106
|
-
statusText
|
|
107
|
-
} = await (0, _axios.default)(requestOpts);
|
|
108
|
-
|
|
109
|
-
_logger.default.info(`Server response: ${status} ${statusText}`);
|
|
89
|
+
logger_1.default.debug(`Performing ${method} to ${href} with options (excluding data): ` +
|
|
90
|
+
JSON.stringify(lodash_1.default.omit(requestOpts, ['data'])));
|
|
91
|
+
const { status, statusText } = await (0, axios_1.default)(requestOpts);
|
|
92
|
+
logger_1.default.info(`Server response: ${status} ${statusText}`);
|
|
110
93
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
port,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
reject(err);
|
|
138
|
-
} else {
|
|
139
|
-
resolve();
|
|
140
|
-
}
|
|
94
|
+
/**
|
|
95
|
+
* @param {string | Buffer | NodeJS.ReadableStream} localFileStream
|
|
96
|
+
* @param {URL} parsedUri
|
|
97
|
+
* @param {NotHttpUploadOptions & NetOptions} [uploadOptions]
|
|
98
|
+
*/
|
|
99
|
+
async function uploadFileToFtp(localFileStream, parsedUri, uploadOptions = /** @type {NotHttpUploadOptions & NetOptions} */ ({})) {
|
|
100
|
+
const { auth } = uploadOptions;
|
|
101
|
+
const { hostname, port, protocol, pathname } = parsedUri;
|
|
102
|
+
const ftpOpts = {
|
|
103
|
+
host: hostname,
|
|
104
|
+
port: !lodash_1.default.isUndefined(port) ? lodash_1.default.parseInt(port) : 21,
|
|
105
|
+
};
|
|
106
|
+
if (auth?.user && auth?.pass) {
|
|
107
|
+
ftpOpts.user = auth.user;
|
|
108
|
+
ftpOpts.pass = auth.pass;
|
|
109
|
+
}
|
|
110
|
+
logger_1.default.debug(`${protocol} upload options: ${JSON.stringify(ftpOpts)}`);
|
|
111
|
+
return await new bluebird_1.default((resolve, reject) => {
|
|
112
|
+
new jsftp_1.default(ftpOpts).put(localFileStream, pathname, (err) => {
|
|
113
|
+
if (err) {
|
|
114
|
+
reject(err);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
resolve();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
141
120
|
});
|
|
142
|
-
});
|
|
143
121
|
}
|
|
144
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Returns `true` if params are valid for {@linkcode uploadFileToHttp}.
|
|
124
|
+
* @param {any} opts
|
|
125
|
+
* @param {URL} url
|
|
126
|
+
* @returns {opts is HttpUploadOptions & NetOptions}
|
|
127
|
+
*/
|
|
145
128
|
function isHttpUploadOptions(opts, url) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
129
|
+
try {
|
|
130
|
+
const { protocol } = url;
|
|
131
|
+
return protocol === 'http:' || protocol === 'https:';
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
154
136
|
}
|
|
155
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Returns `true` if params are valid for {@linkcode uploadFileToFtp}.
|
|
139
|
+
* @param {any} opts
|
|
140
|
+
* @param {URL} url
|
|
141
|
+
* @returns {opts is NotHttpUploadOptions & NetOptions}
|
|
142
|
+
*/
|
|
156
143
|
function isNotHttpUploadOptions(opts, url) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
144
|
+
try {
|
|
145
|
+
const { protocol } = url;
|
|
146
|
+
return protocol === 'ftp:';
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
165
151
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Uploads the given file to a remote location. HTTP(S) and FTP
|
|
154
|
+
* protocols are supported.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} localPath - The path to a file on the local storage.
|
|
157
|
+
* @param {string} remoteUri - The remote URI to upload the file to.
|
|
158
|
+
* @param {(HttpUploadOptions|NotHttpUploadOptions) & NetOptions} [uploadOptions]
|
|
159
|
+
* @returns {Promise<void>}
|
|
160
|
+
*/
|
|
161
|
+
async function uploadFile(localPath, remoteUri, uploadOptions = /** @type {(HttpUploadOptions|NotHttpUploadOptions) & NetOptions} */ ({})) {
|
|
162
|
+
if (!(await fs_1.default.exists(localPath))) {
|
|
163
|
+
throw new Error(`'${localPath}' does not exists or is not accessible`);
|
|
164
|
+
}
|
|
165
|
+
const { isMetered = true } = uploadOptions;
|
|
166
|
+
const url = new URL(remoteUri);
|
|
167
|
+
const { size } = await fs_1.default.stat(localPath);
|
|
168
|
+
if (isMetered) {
|
|
169
|
+
logger_1.default.info(`Uploading '${localPath}' of ${(0, util_1.toReadableSizeString)(size)} size to '${remoteUri}'`);
|
|
170
|
+
}
|
|
171
|
+
const timer = new timing_1.default().start();
|
|
172
|
+
if (isHttpUploadOptions(uploadOptions, url)) {
|
|
173
|
+
if (!uploadOptions.fileFieldName) {
|
|
174
|
+
uploadOptions.headers = {
|
|
175
|
+
...(lodash_1.default.isPlainObject(uploadOptions.headers) ? uploadOptions.headers : {}),
|
|
176
|
+
'Content-Length': size,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
await uploadFileToHttp(fs_1.default.createReadStream(localPath), url, uploadOptions);
|
|
180
|
+
}
|
|
181
|
+
else if (isNotHttpUploadOptions(uploadOptions, url)) {
|
|
182
|
+
await uploadFileToFtp(fs_1.default.createReadStream(localPath), url, uploadOptions);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
throw new Error(`Cannot upload the file at '${localPath}' to '${remoteUri}'. ` +
|
|
186
|
+
`Unsupported remote protocol '${url.protocol}'. ` +
|
|
187
|
+
`Only http/https and ftp/ftps protocols are supported.`);
|
|
188
|
+
}
|
|
189
|
+
if (isMetered) {
|
|
190
|
+
logger_1.default.info(`Uploaded '${localPath}' of ${(0, util_1.toReadableSizeString)(size)} size in ` +
|
|
191
|
+
`${timer.getDuration().asSeconds.toFixed(3)}s`);
|
|
191
192
|
}
|
|
192
|
-
|
|
193
|
-
await uploadFileToHttp(_fs.default.createReadStream(localPath), url, uploadOptions);
|
|
194
|
-
} else if (isNotHttpUploadOptions(uploadOptions, url)) {
|
|
195
|
-
await uploadFileToFtp(_fs.default.createReadStream(localPath), url, uploadOptions);
|
|
196
|
-
} else {
|
|
197
|
-
throw new Error(`Cannot upload the file at '${localPath}' to '${remoteUri}'. ` + `Unsupported remote protocol '${url.protocol}'. ` + `Only http/https and ftp/ftps protocols are supported.`);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (isMetered) {
|
|
201
|
-
_logger.default.info(`Uploaded '${localPath}' of ${(0, _util.toReadableSizeString)(size)} size in ` + `${timer.getDuration().asSeconds.toFixed(3)}s`);
|
|
202
|
-
}
|
|
203
193
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
_logger.default.debug(`${remoteUrl} (${(0, _util.toReadableSizeString)(size)}) ` + `has been downloaded to '${dstPath}' in ${secondsElapsed.toFixed(3)}s`);
|
|
264
|
-
|
|
265
|
-
if (secondsElapsed >= 2) {
|
|
266
|
-
const bytesPerSec = Math.floor(size / secondsElapsed);
|
|
267
|
-
|
|
268
|
-
_logger.default.debug(`Approximate download speed: ${(0, _util.toReadableSizeString)(bytesPerSec)}/s`);
|
|
194
|
+
exports.uploadFile = uploadFile;
|
|
195
|
+
/**
|
|
196
|
+
* Downloads the given file via HTTP(S)
|
|
197
|
+
*
|
|
198
|
+
* @param {string} remoteUrl - The remote url
|
|
199
|
+
* @param {string} dstPath - The local path to download the file to
|
|
200
|
+
* @param {DownloadOptions & NetOptions} [downloadOptions]
|
|
201
|
+
* @throws {Error} If download operation fails
|
|
202
|
+
*/
|
|
203
|
+
async function downloadFile(remoteUrl, dstPath, downloadOptions = /** @type {DownloadOptions & NetOptions} */ ({})) {
|
|
204
|
+
const { isMetered = true, auth, timeout = DEFAULT_TIMEOUT_MS, headers } = downloadOptions;
|
|
205
|
+
/**
|
|
206
|
+
* @type {import('axios').AxiosRequestConfig}
|
|
207
|
+
*/
|
|
208
|
+
const requestOpts = {
|
|
209
|
+
url: remoteUrl,
|
|
210
|
+
responseType: 'stream',
|
|
211
|
+
timeout,
|
|
212
|
+
};
|
|
213
|
+
const axiosAuth = toAxiosAuth(auth);
|
|
214
|
+
if (axiosAuth) {
|
|
215
|
+
requestOpts.auth = axiosAuth;
|
|
216
|
+
}
|
|
217
|
+
if (lodash_1.default.isPlainObject(headers)) {
|
|
218
|
+
requestOpts.headers = headers;
|
|
219
|
+
}
|
|
220
|
+
const timer = new timing_1.default().start();
|
|
221
|
+
let responseLength;
|
|
222
|
+
try {
|
|
223
|
+
const writer = fs_1.default.createWriteStream(dstPath);
|
|
224
|
+
const { data: responseStream, headers: responseHeaders } = await (0, axios_1.default)(requestOpts);
|
|
225
|
+
responseLength = parseInt(responseHeaders['content-length'] || '0', 10);
|
|
226
|
+
responseStream.pipe(writer);
|
|
227
|
+
await new bluebird_1.default((resolve, reject) => {
|
|
228
|
+
responseStream.once('error', reject);
|
|
229
|
+
writer.once('finish', resolve);
|
|
230
|
+
writer.once('error', (e) => {
|
|
231
|
+
responseStream.unpipe(writer);
|
|
232
|
+
reject(e);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
throw new Error(`Cannot download the file from ${remoteUrl}: ${err.message}`);
|
|
238
|
+
}
|
|
239
|
+
const { size } = await fs_1.default.stat(dstPath);
|
|
240
|
+
if (responseLength && size !== responseLength) {
|
|
241
|
+
await fs_1.default.rimraf(dstPath);
|
|
242
|
+
throw new Error(`The size of the file downloaded from ${remoteUrl} (${size} bytes) ` +
|
|
243
|
+
`differs from the one in Content-Length response header (${responseLength} bytes)`);
|
|
244
|
+
}
|
|
245
|
+
if (isMetered) {
|
|
246
|
+
const secondsElapsed = timer.getDuration().asSeconds;
|
|
247
|
+
logger_1.default.debug(`${remoteUrl} (${(0, util_1.toReadableSizeString)(size)}) ` +
|
|
248
|
+
`has been downloaded to '${dstPath}' in ${secondsElapsed.toFixed(3)}s`);
|
|
249
|
+
if (secondsElapsed >= 2) {
|
|
250
|
+
const bytesPerSec = Math.floor(size / secondsElapsed);
|
|
251
|
+
logger_1.default.debug(`Approximate download speed: ${(0, util_1.toReadableSizeString)(bytesPerSec)}/s`);
|
|
252
|
+
}
|
|
269
253
|
}
|
|
270
|
-
}
|
|
271
254
|
}
|
|
272
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJERUZBVUxUX1RJTUVPVVRfTVMiLCJ0b0F4aW9zQXV0aCIsImF1dGgiLCJfIiwiaXNQbGFpbk9iamVjdCIsImF4aW9zQXV0aCIsInVzZXJuYW1lIiwiZ2V0IiwicGFzc3dvcmQiLCJ1cGxvYWRGaWxlVG9IdHRwIiwibG9jYWxGaWxlU3RyZWFtIiwicGFyc2VkVXJpIiwidXBsb2FkT3B0aW9ucyIsIm1ldGhvZCIsInRpbWVvdXQiLCJoZWFkZXJzIiwiZmlsZUZpZWxkTmFtZSIsImZvcm1GaWVsZHMiLCJocmVmIiwicmVxdWVzdE9wdHMiLCJ1cmwiLCJtYXhDb250ZW50TGVuZ3RoIiwiSW5maW5pdHkiLCJtYXhCb2R5TGVuZ3RoIiwiZm9ybSIsIkZvcm1EYXRhIiwiYXBwZW5kIiwicGFpcnMiLCJpc0FycmF5IiwidG9QYWlycyIsImtleSIsInZhbHVlIiwidG9Mb3dlciIsImdldEhlYWRlcnMiLCJkYXRhIiwibG9nIiwiZGVidWciLCJKU09OIiwic3RyaW5naWZ5Iiwib21pdCIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJheGlvcyIsImluZm8iLCJ1cGxvYWRGaWxlVG9GdHAiLCJob3N0bmFtZSIsInBvcnQiLCJwcm90b2NvbCIsInBhdGhuYW1lIiwiZnRwT3B0cyIsImhvc3QiLCJpc1VuZGVmaW5lZCIsInBhcnNlSW50IiwidXNlciIsInBhc3MiLCJCIiwicmVzb2x2ZSIsInJlamVjdCIsIkZ0cCIsInB1dCIsImVyciIsImlzSHR0cFVwbG9hZE9wdGlvbnMiLCJvcHRzIiwiVVJMIiwiaXNOb3RIdHRwVXBsb2FkT3B0aW9ucyIsInVwbG9hZEZpbGUiLCJsb2NhbFBhdGgiLCJyZW1vdGVVcmkiLCJmcyIsImV4aXN0cyIsIkVycm9yIiwiaXNNZXRlcmVkIiwic2l6ZSIsInN0YXQiLCJ0b1JlYWRhYmxlU2l6ZVN0cmluZyIsInRpbWVyIiwiVGltZXIiLCJzdGFydCIsImNyZWF0ZVJlYWRTdHJlYW0iLCJnZXREdXJhdGlvbiIsImFzU2Vjb25kcyIsInRvRml4ZWQiLCJkb3dubG9hZEZpbGUiLCJyZW1vdGVVcmwiLCJkc3RQYXRoIiwiZG93bmxvYWRPcHRpb25zIiwicmVzcG9uc2VUeXBlIiwicmVzcG9uc2VMZW5ndGgiLCJ3cml0ZXIiLCJjcmVhdGVXcml0ZVN0cmVhbSIsInJlc3BvbnNlU3RyZWFtIiwicmVzcG9uc2VIZWFkZXJzIiwicGlwZSIsIm9uY2UiLCJlIiwidW5waXBlIiwibWVzc2FnZSIsInJpbXJhZiIsInNlY29uZHNFbGFwc2VkIiwiYnl0ZXNQZXJTZWMiLCJNYXRoIiwiZmxvb3IiXSwic291cmNlcyI6WyIuLi8uLi9saWIvbmV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZnMgZnJvbSAnLi9mcyc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQge3RvUmVhZGFibGVTaXplU3RyaW5nfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgRnRwIGZyb20gJ2pzZnRwJztcbmltcG9ydCBUaW1lciBmcm9tICcuL3RpbWluZyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IEZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5cbmNvbnN0IERFRkFVTFRfVElNRU9VVF9NUyA9IDQgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogQ29udmVydHMge0BsaW5rY29kZSBBdXRoQ3JlZGVudGlhbHN9IHRvIGNyZWRlbnRpYWxzIHVuZGVyc3Rvb2QgYnkge0BsaW5rY29kZSBheGlvc30uXG4gKiBAcGFyYW0ge0F1dGhDcmVkZW50aWFscyB8IGltcG9ydCgnYXhpb3MnKS5BeGlvc0Jhc2ljQ3JlZGVudGlhbHN9IFthdXRoXVxuICogQHJldHVybnMge2ltcG9ydCgnYXhpb3MnKS5BeGlvc0Jhc2ljQ3JlZGVudGlhbHM/fVxuICovXG5mdW5jdGlvbiB0b0F4aW9zQXV0aChhdXRoKSB7XG4gIGlmICghXy5pc1BsYWluT2JqZWN0KGF1dGgpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBheGlvc0F1dGggPSB7XG4gICAgdXNlcm5hbWU6IF8uZ2V0KGF1dGgsICd1c2VybmFtZScsIF8uZ2V0KGF1dGgsICd1c2VyJykpLFxuICAgIHBhc3N3b3JkOiBfLmdldChhdXRoLCAncGFzc3dvcmQnLCBfLmdldChhdXRoLCAncGFzcycpKSxcbiAgfTtcbiAgcmV0dXJuIGF4aW9zQXV0aC51c2VybmFtZSAmJiBheGlvc0F1dGgucGFzc3dvcmQgPyBheGlvc0F1dGggOiBudWxsO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZUpTLlJlYWRhYmxlU3RyZWFtfSBsb2NhbEZpbGVTdHJlYW1cbiAqIEBwYXJhbSB7VVJMfSBwYXJzZWRVcmlcbiAqIEBwYXJhbSB7SHR0cFVwbG9hZE9wdGlvbnMgJiBOZXRPcHRpb25zfSBbdXBsb2FkT3B0aW9uc11cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdXBsb2FkRmlsZVRvSHR0cChcbiAgbG9jYWxGaWxlU3RyZWFtLFxuICBwYXJzZWRVcmksXG4gIHVwbG9hZE9wdGlvbnMgPSAvKiogQHR5cGUge0h0dHBVcGxvYWRPcHRpb25zICYgTmV0T3B0aW9uc30gKi8gKHt9KVxuKSB7XG4gIGNvbnN0IHtcbiAgICBtZXRob2QgPSAnUE9TVCcsXG4gICAgdGltZW91dCA9IERFRkFVTFRfVElNRU9VVF9NUyxcbiAgICBoZWFkZXJzLFxuICAgIGF1dGgsXG4gICAgZmlsZUZpZWxkTmFtZSA9ICdmaWxlJyxcbiAgICBmb3JtRmllbGRzLFxuICB9ID0gdXBsb2FkT3B0aW9ucztcbiAgY29uc3Qge2hyZWZ9ID0gcGFyc2VkVXJpO1xuXG4gIC8qKiBAdHlwZSB7aW1wb3J0KCdheGlvcycpLkF4aW9zUmVxdWVzdENvbmZpZ30gKi9cbiAgY29uc3QgcmVxdWVzdE9wdHMgPSB7XG4gICAgdXJsOiBocmVmLFxuICAgIG1ldGhvZCxcbiAgICB0aW1lb3V0LFxuICAgIG1heENvbnRlbnRMZW5ndGg6IEluZmluaXR5LFxuICAgIG1heEJvZHlMZW5ndGg6IEluZmluaXR5LFxuICB9O1xuICBjb25zdCBheGlvc0F1dGggPSB0b0F4aW9zQXV0aChhdXRoKTtcbiAgaWYgKGF4aW9zQXV0aCkge1xuICAgIHJlcXVlc3RPcHRzLmF1dGggPSBheGlvc0F1dGg7XG4gIH1cbiAgaWYgKGZpbGVGaWVsZE5hbWUpIHtcbiAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgZm9ybS5hcHBlbmQoZmlsZUZpZWxkTmFtZSwgbG9jYWxGaWxlU3RyZWFtKTtcbiAgICBpZiAoZm9ybUZpZWxkcykge1xuICAgICAgbGV0IHBhaXJzID0gW107XG4gICAgICBpZiAoXy5pc0FycmF5KGZvcm1GaWVsZHMpKSB7XG4gICAgICAgIHBhaXJzID0gZm9ybUZpZWxkcztcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KGZvcm1GaWVsZHMpKSB7XG4gICAgICAgIHBhaXJzID0gXy50b1BhaXJzKGZvcm1GaWVsZHMpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgcGFpcnMpIHtcbiAgICAgICAgaWYgKF8udG9Mb3dlcihrZXkpICE9PSBfLnRvTG93ZXIoZmlsZUZpZWxkTmFtZSkpIHtcbiAgICAgICAgICBmb3JtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXF1ZXN0T3B0cy5oZWFkZXJzID0ge1xuICAgICAgLi4uKF8uaXNQbGFpbk9iamVjdChoZWFkZXJzKSA/IGhlYWRlcnMgOiB7fSksXG4gICAgICAuLi5mb3JtLmdldEhlYWRlcnMoKSxcbiAgICB9O1xuICAgIHJlcXVlc3RPcHRzLmRhdGEgPSBmb3JtO1xuICB9IGVsc2Uge1xuICAgIGlmIChfLmlzUGxhaW5PYmplY3QoaGVhZGVycykpIHtcbiAgICAgIHJlcXVlc3RPcHRzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIH1cbiAgICByZXF1ZXN0T3B0cy5kYXRhID0gbG9jYWxGaWxlU3RyZWFtO1xuICB9XG4gIGxvZy5kZWJ1ZyhcbiAgICBgUGVyZm9ybWluZyAke21ldGhvZH0gdG8gJHtocmVmfSB3aXRoIG9wdGlvbnMgKGV4Y2x1ZGluZyBkYXRhKTogYCArXG4gICAgICBKU09OLnN0cmluZ2lmeShfLm9taXQocmVxdWVzdE9wdHMsIFsnZGF0YSddKSlcbiAgKTtcblxuICBjb25zdCB7c3RhdHVzLCBzdGF0dXNUZXh0fSA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRzKTtcbiAgbG9nLmluZm8oYFNlcnZlciByZXNwb25zZTogJHtzdGF0dXN9ICR7c3RhdHVzVGV4dH1gKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZyB8IEJ1ZmZlciB8IE5vZGVKUy5SZWFkYWJsZVN0cmVhbX0gbG9jYWxGaWxlU3RyZWFtXG4gKiBAcGFyYW0ge1VSTH0gcGFyc2VkVXJpXG4gKiBAcGFyYW0ge05vdEh0dHBVcGxvYWRPcHRpb25zICYgTmV0T3B0aW9uc30gW3VwbG9hZE9wdGlvbnNdXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZEZpbGVUb0Z0cChcbiAgbG9jYWxGaWxlU3RyZWFtLFxuICBwYXJzZWRVcmksXG4gIHVwbG9hZE9wdGlvbnMgPSAvKiogQHR5cGUge05vdEh0dHBVcGxvYWRPcHRpb25zICYgTmV0T3B0aW9uc30gKi8gKHt9KVxuKSB7XG4gIGNvbnN0IHthdXRofSA9IHVwbG9hZE9wdGlvbnM7XG4gIGNvbnN0IHtob3N0bmFtZSwgcG9ydCwgcHJvdG9jb2wsIHBhdGhuYW1lfSA9IHBhcnNlZFVyaTtcblxuICBjb25zdCBmdHBPcHRzID0ge1xuICAgIGhvc3Q6IGhvc3RuYW1lLFxuICAgIHBvcnQ6ICFfLmlzVW5kZWZpbmVkKHBvcnQpID8gXy5wYXJzZUludChwb3J0KSA6IDIxLFxuICB9O1xuICBpZiAoYXV0aD8udXNlciAmJiBhdXRoPy5wYXNzKSB7XG4gICAgZnRwT3B0cy51c2VyID0gYXV0aC51c2VyO1xuICAgIGZ0cE9wdHMucGFzcyA9IGF1dGgucGFzcztcbiAgfVxuICBsb2cuZGVidWcoYCR7cHJvdG9jb2x9IHVwbG9hZCBvcHRpb25zOiAke0pTT04uc3RyaW5naWZ5KGZ0cE9wdHMpfWApO1xuICByZXR1cm4gYXdhaXQgbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIG5ldyBGdHAoZnRwT3B0cykucHV0KGxvY2FsRmlsZVN0cmVhbSwgcGF0aG5hbWUsIChlcnIpID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYHRydWVgIGlmIHBhcmFtcyBhcmUgdmFsaWQgZm9yIHtAbGlua2NvZGUgdXBsb2FkRmlsZVRvSHR0cH0uXG4gKiBAcGFyYW0ge2FueX0gb3B0c1xuICogQHBhcmFtIHtVUkx9IHVybFxuICogQHJldHVybnMge29wdHMgaXMgSHR0cFVwbG9hZE9wdGlvbnMgJiBOZXRPcHRpb25zfVxuICovXG5mdW5jdGlvbiBpc0h0dHBVcGxvYWRPcHRpb25zKG9wdHMsIHVybCkge1xuICB0cnkge1xuICAgIGNvbnN0IHtwcm90b2NvbH0gPSBuZXcgVVJMKHVybCk7XG4gICAgcmV0dXJuIHByb3RvY29sID09PSAnaHR0cDonIHx8IHByb3RvY29sID09PSAnaHR0cHM6JztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgcGFyYW1zIGFyZSB2YWxpZCBmb3Ige0BsaW5rY29kZSB1cGxvYWRGaWxlVG9GdHB9LlxuICogQHBhcmFtIHthbnl9IG9wdHNcbiAqIEBwYXJhbSB7VVJMfSB1cmxcbiAqIEByZXR1cm5zIHtvcHRzIGlzIE5vdEh0dHBVcGxvYWRPcHRpb25zICYgTmV0T3B0aW9uc31cbiAqL1xuZnVuY3Rpb24gaXNOb3RIdHRwVXBsb2FkT3B0aW9ucyhvcHRzLCB1cmwpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7cHJvdG9jb2x9ID0gbmV3IFVSTCh1cmwpO1xuICAgIHJldHVybiBwcm90b2NvbCA9PT0gJ2Z0cDonO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbi8qKlxuICogVXBsb2FkcyB0aGUgZ2l2ZW4gZmlsZSB0byBhIHJlbW90ZSBsb2NhdGlvbi4gSFRUUChTKSBhbmQgRlRQXG4gKiBwcm90b2NvbHMgYXJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxQYXRoIC0gVGhlIHBhdGggdG8gYSBmaWxlIG9uIHRoZSBsb2NhbCBzdG9yYWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlbW90ZVVyaSAtIFRoZSByZW1vdGUgVVJJIHRvIHVwbG9hZCB0aGUgZmlsZSB0by5cbiAqIEBwYXJhbSB7KEh0dHBVcGxvYWRPcHRpb25zfE5vdEh0dHBVcGxvYWRPcHRpb25zKSAmIE5ldE9wdGlvbnN9IFt1cGxvYWRPcHRpb25zXVxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZEZpbGUoXG4gIGxvY2FsUGF0aCxcbiAgcmVtb3RlVXJpLFxuICB1cGxvYWRPcHRpb25zID0gLyoqIEB0eXBlIHsoSHR0cFVwbG9hZE9wdGlvbnN8Tm90SHR0cFVwbG9hZE9wdGlvbnMpICYgTmV0T3B0aW9uc30gKi8gKHt9KVxuKSB7XG4gIGlmICghKGF3YWl0IGZzLmV4aXN0cyhsb2NhbFBhdGgpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJyR7bG9jYWxQYXRofScgZG9lcyBub3QgZXhpc3RzIG9yIGlzIG5vdCBhY2Nlc3NpYmxlYCk7XG4gIH1cblxuICBjb25zdCB7aXNNZXRlcmVkID0gdHJ1ZX0gPSB1cGxvYWRPcHRpb25zO1xuICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlbW90ZVVyaSk7XG4gIGNvbnN0IHtzaXplfSA9IGF3YWl0IGZzLnN0YXQobG9jYWxQYXRoKTtcbiAgaWYgKGlzTWV0ZXJlZCkge1xuICAgIGxvZy5pbmZvKGBVcGxvYWRpbmcgJyR7bG9jYWxQYXRofScgb2YgJHt0b1JlYWRhYmxlU2l6ZVN0cmluZyhzaXplKX0gc2l6ZSB0byAnJHtyZW1vdGVVcml9J2ApO1xuICB9XG4gIGNvbnN0IHRpbWVyID0gbmV3IFRpbWVyKCkuc3RhcnQoKTtcbiAgaWYgKGlzSHR0cFVwbG9hZE9wdGlvbnModXBsb2FkT3B0aW9ucywgdXJsKSkge1xuICAgIGlmICghdXBsb2FkT3B0aW9ucy5maWxlRmllbGROYW1lKSB7XG4gICAgICB1cGxvYWRPcHRpb25zLmhlYWRlcnMgPSB7XG4gICAgICAgIC4uLihfLmlzUGxhaW5PYmplY3QodXBsb2FkT3B0aW9ucy5oZWFkZXJzKSA/IHVwbG9hZE9wdGlvbnMuaGVhZGVycyA6IHt9KSxcbiAgICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogc2l6ZSxcbiAgICAgIH07XG4gICAgfVxuICAgIGF3YWl0IHVwbG9hZEZpbGVUb0h0dHAoZnMuY3JlYXRlUmVhZFN0cmVhbShsb2NhbFBhdGgpLCB1cmwsIHVwbG9hZE9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGlzTm90SHR0cFVwbG9hZE9wdGlvbnModXBsb2FkT3B0aW9ucywgdXJsKSkge1xuICAgIGF3YWl0IHVwbG9hZEZpbGVUb0Z0cChmcy5jcmVhdGVSZWFkU3RyZWFtKGxvY2FsUGF0aCksIHVybCwgdXBsb2FkT3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYENhbm5vdCB1cGxvYWQgdGhlIGZpbGUgYXQgJyR7bG9jYWxQYXRofScgdG8gJyR7cmVtb3RlVXJpfScuIGAgK1xuICAgICAgICBgVW5zdXBwb3J0ZWQgcmVtb3RlIHByb3RvY29sICcke3VybC5wcm90b2NvbH0nLiBgICtcbiAgICAgICAgYE9ubHkgaHR0cC9odHRwcyBhbmQgZnRwL2Z0cHMgcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQuYFxuICAgICk7XG4gIH1cbiAgaWYgKGlzTWV0ZXJlZCkge1xuICAgIGxvZy5pbmZvKFxuICAgICAgYFVwbG9hZGVkICcke2xvY2FsUGF0aH0nIG9mICR7dG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9IHNpemUgaW4gYCArXG4gICAgICAgIGAke3RpbWVyLmdldER1cmF0aW9uKCkuYXNTZWNvbmRzLnRvRml4ZWQoMyl9c2BcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogRG93bmxvYWRzIHRoZSBnaXZlbiBmaWxlIHZpYSBIVFRQKFMpXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHJlbW90ZVVybCAtIFRoZSByZW1vdGUgdXJsXG4gKiBAcGFyYW0ge3N0cmluZ30gZHN0UGF0aCAtIFRoZSBsb2NhbCBwYXRoIHRvIGRvd25sb2FkIHRoZSBmaWxlIHRvXG4gKiBAcGFyYW0ge0Rvd25sb2FkT3B0aW9ucyAmIE5ldE9wdGlvbnN9IFtkb3dubG9hZE9wdGlvbnNdXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZG93bmxvYWQgb3BlcmF0aW9uIGZhaWxzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkRmlsZShcbiAgcmVtb3RlVXJsLFxuICBkc3RQYXRoLFxuICBkb3dubG9hZE9wdGlvbnMgPSAvKiogQHR5cGUge0Rvd25sb2FkT3B0aW9ucyAmIE5ldE9wdGlvbnN9ICovICh7fSlcbikge1xuICBjb25zdCB7aXNNZXRlcmVkID0gdHJ1ZSwgYXV0aCwgdGltZW91dCA9IERFRkFVTFRfVElNRU9VVF9NUywgaGVhZGVyc30gPSBkb3dubG9hZE9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtpbXBvcnQoJ2F4aW9zJykuQXhpb3NSZXF1ZXN0Q29uZmlnfVxuICAgKi9cbiAgY29uc3QgcmVxdWVzdE9wdHMgPSB7XG4gICAgdXJsOiByZW1vdGVVcmwsXG4gICAgcmVzcG9uc2VUeXBlOiAnc3RyZWFtJyxcbiAgICB0aW1lb3V0LFxuICB9O1xuICBjb25zdCBheGlvc0F1dGggPSB0b0F4aW9zQXV0aChhdXRoKTtcbiAgaWYgKGF4aW9zQXV0aCkge1xuICAgIHJlcXVlc3RPcHRzLmF1dGggPSBheGlvc0F1dGg7XG4gIH1cbiAgaWYgKF8uaXNQbGFpbk9iamVjdChoZWFkZXJzKSkge1xuICAgIHJlcXVlc3RPcHRzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICB9XG5cbiAgY29uc3QgdGltZXIgPSBuZXcgVGltZXIoKS5zdGFydCgpO1xuICBsZXQgcmVzcG9uc2VMZW5ndGg7XG4gIHRyeSB7XG4gICAgY29uc3Qgd3JpdGVyID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oZHN0UGF0aCk7XG4gICAgY29uc3Qge2RhdGE6IHJlc3BvbnNlU3RyZWFtLCBoZWFkZXJzOiByZXNwb25zZUhlYWRlcnN9ID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdHMpO1xuICAgIHJlc3BvbnNlTGVuZ3RoID0gcGFyc2VJbnQocmVzcG9uc2VIZWFkZXJzWydjb250ZW50LWxlbmd0aCddLCAxMCk7XG4gICAgcmVzcG9uc2VTdHJlYW0ucGlwZSh3cml0ZXIpO1xuXG4gICAgYXdhaXQgbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcmVzcG9uc2VTdHJlYW0ub25jZSgnZXJyb3InLCByZWplY3QpO1xuICAgICAgd3JpdGVyLm9uY2UoJ2ZpbmlzaCcsIHJlc29sdmUpO1xuICAgICAgd3JpdGVyLm9uY2UoJ2Vycm9yJywgKGUpID0+IHtcbiAgICAgICAgcmVzcG9uc2VTdHJlYW0udW5waXBlKHdyaXRlcik7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkb3dubG9hZCB0aGUgZmlsZSBmcm9tICR7cmVtb3RlVXJsfTogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuXG4gIGNvbnN0IHtzaXplfSA9IGF3YWl0IGZzLnN0YXQoZHN0UGF0aCk7XG4gIGlmIChyZXNwb25zZUxlbmd0aCAmJiBzaXplICE9PSByZXNwb25zZUxlbmd0aCkge1xuICAgIGF3YWl0IGZzLnJpbXJhZihkc3RQYXRoKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVGhlIHNpemUgb2YgdGhlIGZpbGUgZG93bmxvYWRlZCBmcm9tICR7cmVtb3RlVXJsfSAoJHtzaXplfSBieXRlcykgYCArXG4gICAgICAgIGBkaWZmZXJzIGZyb20gdGhlIG9uZSBpbiBDb250ZW50LUxlbmd0aCByZXNwb25zZSBoZWFkZXIgKCR7cmVzcG9uc2VMZW5ndGh9IGJ5dGVzKWBcbiAgICApO1xuICB9XG4gIGlmIChpc01ldGVyZWQpIHtcbiAgICBjb25zdCBzZWNvbmRzRWxhcHNlZCA9IHRpbWVyLmdldER1cmF0aW9uKCkuYXNTZWNvbmRzO1xuICAgIGxvZy5kZWJ1ZyhcbiAgICAgIGAke3JlbW90ZVVybH0gKCR7dG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9KSBgICtcbiAgICAgICAgYGhhcyBiZWVuIGRvd25sb2FkZWQgdG8gJyR7ZHN0UGF0aH0nIGluICR7c2Vjb25kc0VsYXBzZWQudG9GaXhlZCgzKX1zYFxuICAgICk7XG4gICAgaWYgKHNlY29uZHNFbGFwc2VkID49IDIpIHtcbiAgICAgIGNvbnN0IGJ5dGVzUGVyU2VjID0gTWF0aC5mbG9vcihzaXplIC8gc2Vjb25kc0VsYXBzZWQpO1xuICAgICAgbG9nLmRlYnVnKGBBcHByb3hpbWF0ZSBkb3dubG9hZCBzcGVlZDogJHt0b1JlYWRhYmxlU2l6ZVN0cmluZyhieXRlc1BlclNlYyl9L3NgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHt1cGxvYWRGaWxlLCBkb3dubG9hZEZpbGV9O1xuXG4vKipcbiAqIENvbW1vbiBvcHRpb25zIGZvciB7QGxpbmtjb2RlIHVwbG9hZEZpbGV9IGFuZCB7QGxpbmtjb2RlIGRvd25sb2FkRmlsZX0uXG4gKiBAdHlwZWRlZiBOZXRPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtpc01ldGVyZWQ9dHJ1ZV0gLSBXaGV0aGVyIHRvIGxvZyB0aGUgYWN0dWFsIGRvd25sb2FkIHBlcmZvcm1hbmNlXG4gKiAoZS5nLiB0aW1pbmdzIGFuZCBzcGVlZClcbiAqIEBwcm9wZXJ0eSB7QXV0aENyZWRlbnRpYWxzfSBbYXV0aF0gLSBBdXRoZW50aWNhdGlvbiBjcmVkZW50aWFsc1xuICovXG5cbi8qKlxuICogU3BlY2lmaWMgb3B0aW9ucyBmb3Ige0BsaW5rY29kZSBkb3dubG9hZEZpbGV9LlxuICogQHR5cGVkZWYgRG93bmxvYWRPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbWVvdXRdIC0gVGhlIGFjdHVhbCByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzOyBkZWZhdWx0cyB0byB7QGxpbmtjb2RlIERFRkFVTFRfVElNRU9VVF9NU31cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZyxhbnk+fSBbaGVhZGVyc10gLSBSZXF1ZXN0IGhlYWRlcnMgbWFwcGluZ1xuICovXG5cbi8qKlxuICogQmFzaWMgYXV0aCBjcmVkZW50aWFsczsgdXNlZCBieSB7QGxpbmtjb2RlIE5ldE9wdGlvbnN9LlxuICogQHR5cGVkZWYgQXV0aENyZWRlbnRpYWxzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdXNlciAtIE5vbi1lbXB0eSB1c2VyIG5hbWVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwYXNzIC0gTm9uLWVtcHR5IHBhc3N3b3JkXG4gKi9cblxuLyoqXG4gKiBUaGlzIHR5cGUgaXMgdXNlZCBpbiB7QGxpbmtjb2RlIHVwbG9hZEZpbGV9IGlmIHRoZSByZW1vdGUgbG9jYXRpb24gdXNlcyB0aGUgYGZ0cGAgcHJvdG9jb2wsIGFuZCBkaXN0aW5ndWlzaGVzIHRoZSB0eXBlIGZyb20ge0BsaW5rY29kZSBIdHRwVXBsb2FkT3B0aW9uc30uXG4gKiBAdHlwZWRlZiBOb3RIdHRwVXBsb2FkT3B0aW9uc1xuICogQHByb3BlcnR5IHtuZXZlcn0gaGVhZGVyc1xuICogQHByb3BlcnR5IHtuZXZlcn0gbWV0aG9kXG4gKiBAcHJvcGVydHkge25ldmVyfSB0aW1lb3V0XG4gKiBAcHJvcGVydHkge25ldmVyfSBmaWxlRmllbGROYW1lXG4gKiBAcHJvcGVydHkge25ldmVyfSBmb3JtRmllbGRzXG4gKi9cblxuLyoqXG4gKiBTcGVjaWZpYyBvcHRpb25zIGZvciB7QGxpbmtjb2RlIHVwbG9hZEZpbGV9IGlmIHRoZSByZW1vdGUgbG9jYXRpb24gdXNlcyB0aGUgYGh0dHAocylgIHByb3RvY29sXG4gKiBAdHlwZWRlZiBIdHRwVXBsb2FkT3B0aW9uc1xuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLGFueT59IGhlYWRlcnMgLSBBZGRpdGlvbmFsIHJlcXVlc3QgaGVhZGVycyBtYXBwaW5nXG4gKiBAcHJvcGVydHkge2ltcG9ydCgnYXhpb3MnKS5NZXRob2R9IFttZXRob2Q9J1BPU1QnXSAtIFRoZSBIVFRQIG1ldGhvZCB1c2VkIGZvciBmaWxlIHVwbG9hZFxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aW1lb3V0XSAtIFRoZSBhY3R1YWwgcmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgZGVmYXVsdHMgdG8ge0BsaW5rY29kZSBERUZBVUxUX1RJTUVPVVRfTVN9XG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVGaWVsZE5hbWU9J2ZpbGUnXSAtIFRoZSBuYW1lIG9mIHRoZSBmb3JtIGZpZWxkIGNvbnRhaW5pbmcgdGhlIGZpbGVcbiAqIGNvbnRlbnQgdG8gYmUgdXBsb2FkZWQuIEFueSBmYWxzeSB2YWx1ZSBtYWtlIHRoZSByZXF1ZXN0IHRvIHVzZSBub24tbXVsdGlwYXJ0IHVwbG9hZFxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLGFueT59IFtmb3JtRmllbGRzXSAtIFRoZSBhZGRpdGlvbmFsIGZvcm0gZmllbGRzXG4gKiB0byBiZSBpbmNsdWRlZCBpbnRvIHRoZSB1cGxvYWQgcmVxdWVzdC4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGNvbnNpZGVyZWQgaWZcbiAqIGBmaWxlRmllbGROYW1lYCBpcyBzZXRcbiAqL1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxrQkFBa0IsR0FBRyxJQUFJLEVB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
|
|
255
|
+
exports.downloadFile = downloadFile;
|
|
256
|
+
/**
|
|
257
|
+
* Common options for {@linkcode uploadFile} and {@linkcode downloadFile}.
|
|
258
|
+
* @typedef NetOptions
|
|
259
|
+
* @property {boolean} [isMetered=true] - Whether to log the actual download performance
|
|
260
|
+
* (e.g. timings and speed)
|
|
261
|
+
* @property {AuthCredentials} [auth] - Authentication credentials
|
|
262
|
+
*/
|
|
263
|
+
/**
|
|
264
|
+
* Specific options for {@linkcode downloadFile}.
|
|
265
|
+
* @typedef DownloadOptions
|
|
266
|
+
* @property {number} [timeout] - The actual request timeout in milliseconds; defaults to {@linkcode DEFAULT_TIMEOUT_MS}
|
|
267
|
+
* @property {Record<string,any>} [headers] - Request headers mapping
|
|
268
|
+
*/
|
|
269
|
+
/**
|
|
270
|
+
* Basic auth credentials; used by {@linkcode NetOptions}.
|
|
271
|
+
* @typedef AuthCredentials
|
|
272
|
+
* @property {string} user - Non-empty user name
|
|
273
|
+
* @property {string} pass - Non-empty password
|
|
274
|
+
*/
|
|
275
|
+
/**
|
|
276
|
+
* This type is used in {@linkcode uploadFile} if the remote location uses the `ftp` protocol, and distinguishes the type from {@linkcode HttpUploadOptions}.
|
|
277
|
+
* @typedef NotHttpUploadOptions
|
|
278
|
+
* @property {never} headers
|
|
279
|
+
* @property {never} method
|
|
280
|
+
* @property {never} timeout
|
|
281
|
+
* @property {never} fileFieldName
|
|
282
|
+
* @property {never} formFields
|
|
283
|
+
*/
|
|
284
|
+
/**
|
|
285
|
+
* Specific options for {@linkcode uploadFile} if the remote location uses the `http(s)` protocol
|
|
286
|
+
* @typedef HttpUploadOptions
|
|
287
|
+
* @property {Record<string,any>} headers - Additional request headers mapping
|
|
288
|
+
* @property {import('axios').Method} [method='POST'] - The HTTP method used for file upload
|
|
289
|
+
* @property {number} [timeout] - The actual request timeout in milliseconds; defaults to {@linkcode DEFAULT_TIMEOUT_MS}
|
|
290
|
+
* @property {string} [fileFieldName='file'] - The name of the form field containing the file
|
|
291
|
+
* content to be uploaded. Any falsy value make the request to use non-multipart upload
|
|
292
|
+
* @property {Record<string,any>} [formFields] - The additional form fields
|
|
293
|
+
* to be included into the upload request. This property is only considered if
|
|
294
|
+
* `fileFieldName` is set
|
|
295
|
+
*/
|
|
296
|
+
//# sourceMappingURL=net.js.map
|