@e-mc/file-manager 0.9.7 → 0.10.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/README.md +42 -23
- package/index.d.ts +5 -5
- package/index.js +1733 -1187
- package/package.json +13 -11
package/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
2
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const stream = require("stream");
|
|
6
6
|
const pm = require("picomatch");
|
|
7
|
+
const diff = require("diff");
|
|
7
8
|
const chalk = require("chalk");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const util_2 = require("@e-mc/document/util");
|
|
11
|
-
const types_1 = require("@e-mc/types");
|
|
9
|
+
const stripansi = require("strip-ansi");
|
|
10
|
+
const url_1 = require("url");
|
|
12
11
|
const core_1 = require("@e-mc/core");
|
|
13
12
|
const request_1 = require("@e-mc/request");
|
|
14
13
|
const document_1 = require("@e-mc/document");
|
|
@@ -17,6 +16,10 @@ const image_1 = require("@e-mc/image");
|
|
|
17
16
|
const watch_1 = require("@e-mc/watch");
|
|
18
17
|
const compress_1 = require("@e-mc/compress");
|
|
19
18
|
const cloud_1 = require("@e-mc/cloud");
|
|
19
|
+
const types_1 = require("@e-mc/types");
|
|
20
|
+
const asset_1 = require("@e-mc/document/asset");
|
|
21
|
+
const util_1 = require("@e-mc/document/util");
|
|
22
|
+
const util_2 = require("@e-mc/request/util");
|
|
20
23
|
const kBaseDirectory = Symbol('baseDirectory');
|
|
21
24
|
const kIncremental = Symbol('incremental');
|
|
22
25
|
const kRestarting = Symbol('restarting');
|
|
@@ -31,10 +34,11 @@ const kQueuedTasks = Symbol('queuedTasks');
|
|
|
31
34
|
const kScheduler = Symbol('scheduler');
|
|
32
35
|
const kProcessTimeout = Symbol('processTimeout');
|
|
33
36
|
const kDownloadStats = Symbol('downloadStats');
|
|
37
|
+
const kDiffSource = Symbol('diffSource');
|
|
34
38
|
const kReplaceMap = Symbol('replaceMap');
|
|
35
|
-
const PLATFORM_WIN32 = process.platform === 'win32';
|
|
36
39
|
const PROCESS_STDOUT = process.stdout;
|
|
37
|
-
const
|
|
40
|
+
const PROCESS_STDIN = process.stdin;
|
|
41
|
+
const STDOUT_CURSOR = typeof PROCESS_STDOUT.moveCursor === 'function';
|
|
38
42
|
const PROCESS_TIMEOUT = { filemanager: 0, compress: 0 };
|
|
39
43
|
const CACHE_ETAG = {};
|
|
40
44
|
const DISK = {
|
|
@@ -58,6 +62,27 @@ const MEMORY = {
|
|
|
58
62
|
DISK_MIN: Infinity,
|
|
59
63
|
DISK_MAX: 0
|
|
60
64
|
};
|
|
65
|
+
const LOGGER = {
|
|
66
|
+
TITLE_SEP: '|',
|
|
67
|
+
TITLE_WIDTH: 6,
|
|
68
|
+
VALUE_WIDTH: 71,
|
|
69
|
+
MIN_WIDTH: 0,
|
|
70
|
+
MESSAGE_WIDTH: 0,
|
|
71
|
+
STAT_WIDTH: 0,
|
|
72
|
+
PERCENT_WIDTH: 0,
|
|
73
|
+
MESSAGE_SEP: ' | ',
|
|
74
|
+
MESSAGE_SEP_START: 1,
|
|
75
|
+
PROGRESS_SCROLLBUFFER: 5,
|
|
76
|
+
PROGRESS_MAXWIDTH: Infinity,
|
|
77
|
+
PROGRESS_USECOLOR: true,
|
|
78
|
+
PROGRESS_RAWMODE: false,
|
|
79
|
+
PROGRESS_TEXTWRAP: 'nowrap',
|
|
80
|
+
PROGRESS_COLOR: null,
|
|
81
|
+
PROGRESS_BGCOLOR: null,
|
|
82
|
+
PROGRESS_BOXCHAR: '■',
|
|
83
|
+
PROGRESS_SPACER: chalk.blackBright('|'),
|
|
84
|
+
PROGRESS_COMPLETE: chalk.green('100%')
|
|
85
|
+
};
|
|
61
86
|
let SESSION_ID = 0;
|
|
62
87
|
let SESSION_LIMIT = 1000;
|
|
63
88
|
let ASSET_ID = 0;
|
|
@@ -65,7 +90,6 @@ let RECURSION_LIMIT = 10;
|
|
|
65
90
|
let PROCESS_SUB_LIMIT = Math.max(require('os').cpus().length, 1) * 2;
|
|
66
91
|
let LOG_TIMEELAPSED = true;
|
|
67
92
|
let LOG_TIMEPROCESS = true;
|
|
68
|
-
let LOG_FORMAT = null;
|
|
69
93
|
const HTTP_CLIENT = {
|
|
70
94
|
timeout: 60000,
|
|
71
95
|
connectTimeout: 20 * 1000,
|
|
@@ -77,7 +101,7 @@ const HTTP_CLIENT = {
|
|
|
77
101
|
function applyTimeout(target, options) {
|
|
78
102
|
for (const name in options) {
|
|
79
103
|
const value = parseTimeout(options[name]);
|
|
80
|
-
if (value !==
|
|
104
|
+
if (value !== -1) {
|
|
81
105
|
target[name] = value;
|
|
82
106
|
}
|
|
83
107
|
}
|
|
@@ -89,23 +113,23 @@ function parseTimeout(value) {
|
|
|
89
113
|
if ((value = (0, types_1.parseTime)(value)) > 0) {
|
|
90
114
|
return value;
|
|
91
115
|
}
|
|
116
|
+
return -1;
|
|
92
117
|
}
|
|
93
118
|
function withinSizeRange(uri, value, pattern) {
|
|
94
119
|
const match = (pattern || /\(\s*(\d+)\s*(?:,\s*(\d+|\*)\s*)?\)/).exec(value);
|
|
95
120
|
const [minSize, maxSize] = match && !match[1] ? [+match[2], !match[3] || match[3] === '*' ? Infinity : +match[3]] : [0, Infinity];
|
|
96
121
|
if (minSize > 0 || maxSize < Infinity) {
|
|
97
|
-
const fileSize = (0,
|
|
122
|
+
const fileSize = (0, util_2.getSize)(uri);
|
|
98
123
|
if (fileSize === 0 || fileSize < minSize || fileSize > maxSize) {
|
|
99
124
|
return false;
|
|
100
125
|
}
|
|
101
126
|
}
|
|
102
127
|
return true;
|
|
103
128
|
}
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.assets.forEach(item => unsetContent(item));
|
|
129
|
+
function clearAssets(host) {
|
|
130
|
+
for (const item of host.assets) {
|
|
131
|
+
unsetContent(item);
|
|
132
|
+
}
|
|
109
133
|
}
|
|
110
134
|
function unsetContent(item) {
|
|
111
135
|
if ('buffer' in item) {
|
|
@@ -115,7 +139,7 @@ function unsetContent(item) {
|
|
|
115
139
|
item.sourceUTF8 = '';
|
|
116
140
|
}
|
|
117
141
|
}
|
|
118
|
-
function bundleTorrent(files, mimeType, encoding) {
|
|
142
|
+
function bundleTorrent(host, files, mimeType, encoding) {
|
|
119
143
|
let output = '';
|
|
120
144
|
for (const file of files) {
|
|
121
145
|
if (core_1.Host.lookupMime(file) === mimeType) {
|
|
@@ -123,15 +147,15 @@ function bundleTorrent(files, mimeType, encoding) {
|
|
|
123
147
|
output += fs.readFileSync(file, encoding);
|
|
124
148
|
}
|
|
125
149
|
catch (err) {
|
|
126
|
-
|
|
150
|
+
host.writeFail(["Unable to read file", path.basename(file)], err, 32);
|
|
127
151
|
}
|
|
128
152
|
}
|
|
129
153
|
}
|
|
130
154
|
return output;
|
|
131
155
|
}
|
|
132
|
-
function resetAssets() {
|
|
133
|
-
|
|
134
|
-
FileManager.sanitizeAssets(
|
|
156
|
+
function resetAssets(host) {
|
|
157
|
+
host.reset();
|
|
158
|
+
FileManager.sanitizeAssets(host.assets);
|
|
135
159
|
}
|
|
136
160
|
function recurseDir(output, subDirs, options) {
|
|
137
161
|
const { ignore, sortBy, recursive } = options;
|
|
@@ -162,7 +186,7 @@ function recurseDir(output, subDirs, options) {
|
|
|
162
186
|
}
|
|
163
187
|
return output;
|
|
164
188
|
}
|
|
165
|
-
function checkHash(localUri, output, options, data) {
|
|
189
|
+
function checkHash(host, localUri, output, options, data) {
|
|
166
190
|
let algorithm, digest, value;
|
|
167
191
|
if ((0, types_1.isObject)(options)) {
|
|
168
192
|
({ algorithm, digest, value } = options);
|
|
@@ -172,21 +196,21 @@ function checkHash(localUri, output, options, data) {
|
|
|
172
196
|
}
|
|
173
197
|
if ((0, types_1.isString)(value)) {
|
|
174
198
|
algorithm || (algorithm = "sha256");
|
|
175
|
-
if (!data) {
|
|
199
|
+
if (!data && localUri) {
|
|
176
200
|
try {
|
|
177
201
|
data = fs.readFileSync(localUri);
|
|
178
202
|
}
|
|
179
203
|
catch (err) {
|
|
180
204
|
if (output && core_1.Host.isErrorCode(err, 'ENOENT')) {
|
|
181
|
-
|
|
205
|
+
host.addLog(host.statusType.WARN, algorithm + ': ENOENT -> No checksum performed', path.basename(localUri), value);
|
|
182
206
|
return true;
|
|
183
207
|
}
|
|
184
|
-
|
|
208
|
+
host.addLog(host.statusType.WARN, err, path.basename(localUri), value);
|
|
185
209
|
return false;
|
|
186
210
|
}
|
|
187
211
|
}
|
|
188
|
-
if ((value = value.toLowerCase()) === core_1.Host.asHash(data,
|
|
189
|
-
|
|
212
|
+
if (data && (value = value.toLowerCase()) === core_1.Host.asHash(data, algorithm, digest)) {
|
|
213
|
+
host.formatMessage(32, algorithm, ["Checksum matched" + (output ? ' (output)' : ''), localUri && path.basename(localUri)], value, { ...core_1.Host.LOG_STYLE_INFO, queue: true });
|
|
190
214
|
return true;
|
|
191
215
|
}
|
|
192
216
|
return false;
|
|
@@ -194,7 +218,7 @@ function checkHash(localUri, output, options, data) {
|
|
|
194
218
|
return true;
|
|
195
219
|
}
|
|
196
220
|
function validatePaths(values, patterns, include, dot) {
|
|
197
|
-
const items = patterns.map(value =>
|
|
221
|
+
const items = patterns.map(value => isMatchRoot(value) ? [core_1.Permission.toPosix(path.resolve(value)), { nocase: core_1.Host.PLATFORM_WIN32, dot }] : [sanitizePath(value), { matchBase: true, nocase: core_1.Host.PLATFORM_WIN32, dot }]);
|
|
198
222
|
return values.filter(value => {
|
|
199
223
|
for (const [pattern, options] of items) {
|
|
200
224
|
if (pm.isMatch(core_1.Permission.toPosix(value), pattern, options)) {
|
|
@@ -223,130 +247,527 @@ function filterPaths(values, include, exclude, dot) {
|
|
|
223
247
|
}
|
|
224
248
|
return values;
|
|
225
249
|
}
|
|
226
|
-
function abortedHost() {
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return
|
|
250
|
+
function abortedHost(host) {
|
|
251
|
+
if (host.finalizeState === 6) {
|
|
252
|
+
host.restarting = false;
|
|
253
|
+
host.performFinalize(true);
|
|
254
|
+
return host.done;
|
|
231
255
|
}
|
|
232
256
|
return false;
|
|
233
257
|
}
|
|
234
258
|
function formatMinutes(elapsed) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const h = Math.floor(elapsed / 3600000);
|
|
238
|
-
elapsed -= h * 3600000;
|
|
239
|
-
result = h + ':';
|
|
259
|
+
if (elapsed < 1000) {
|
|
260
|
+
return elapsed + 'ms';
|
|
240
261
|
}
|
|
241
|
-
if (elapsed
|
|
242
|
-
|
|
243
|
-
elapsed -= m * 60000;
|
|
244
|
-
result += padStart(m, result ? '0' : ' ') + ':';
|
|
262
|
+
if (elapsed < 60000) {
|
|
263
|
+
return (elapsed / 1000).toPrecision(3) + 's';
|
|
245
264
|
}
|
|
246
|
-
|
|
247
|
-
result += ' 0:';
|
|
248
|
-
}
|
|
249
|
-
if (elapsed >= 1000) {
|
|
250
|
-
const s = Math.floor(elapsed / 1000);
|
|
251
|
-
result += padStart(s, '0');
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
result += '00';
|
|
255
|
-
}
|
|
256
|
-
return result;
|
|
265
|
+
return (0, types_1.formatTime)(elapsed, ':');
|
|
257
266
|
}
|
|
258
|
-
function observeFile(instance) {
|
|
259
|
-
instance.on('file:delete', (value, options) =>
|
|
260
|
-
instance.on('file:copy', value =>
|
|
267
|
+
function observeFile(host, instance) {
|
|
268
|
+
instance.on('file:delete', (value, options) => host.delete(value, !!options?.emptyDir));
|
|
269
|
+
instance.on('file:copy', value => host.add(value));
|
|
261
270
|
instance.on('file:move', (value, options) => {
|
|
262
|
-
|
|
271
|
+
host.add(value);
|
|
263
272
|
const src = options?.outSrc;
|
|
264
273
|
if (src) {
|
|
265
|
-
|
|
274
|
+
host.delete(src);
|
|
266
275
|
}
|
|
267
276
|
});
|
|
268
277
|
instance.on('dir:remove', value => {
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
value = value.toLowerCase();
|
|
272
|
-
}
|
|
278
|
+
if (host.removeCwd(value)) {
|
|
279
|
+
value = matchPathname(value);
|
|
273
280
|
if (!value.endsWith(path.sep)) {
|
|
274
281
|
value += path.sep;
|
|
275
282
|
}
|
|
276
|
-
for (const name of
|
|
277
|
-
if ((
|
|
278
|
-
|
|
283
|
+
for (const name of host.files) {
|
|
284
|
+
if (matchPathname(name).startsWith(value)) {
|
|
285
|
+
host.files.delete(name);
|
|
279
286
|
}
|
|
280
287
|
}
|
|
281
288
|
}
|
|
282
289
|
});
|
|
283
290
|
}
|
|
284
|
-
function
|
|
291
|
+
function clearModule(instance, items) {
|
|
292
|
+
const { moduleName, errors } = instance;
|
|
293
|
+
if (errors.length > 0) {
|
|
294
|
+
for (const value of errors) {
|
|
295
|
+
items.push(`[${moduleName}] ` + (core_1.Host.asString(value) || "Unknown"));
|
|
296
|
+
}
|
|
297
|
+
errors.length = 0;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function collectErrors(host) {
|
|
285
301
|
const result = [];
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
this.subProcesses.forEach(instance => clearModule(instance));
|
|
295
|
-
clearModule(this);
|
|
296
|
-
if (!this.restarting) {
|
|
302
|
+
for (const instance of host.modules) {
|
|
303
|
+
clearModule(instance, result);
|
|
304
|
+
}
|
|
305
|
+
for (const instance of host.subProcesses) {
|
|
306
|
+
clearModule(instance, result);
|
|
307
|
+
}
|
|
308
|
+
clearModule(host, result);
|
|
309
|
+
if (!host.restarting) {
|
|
297
310
|
queueMicrotask(() => {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
311
|
+
if (!host.silent) {
|
|
312
|
+
host.flushLog();
|
|
313
|
+
}
|
|
314
|
+
for (const instance of host.modules) {
|
|
315
|
+
if (!instance.silent) {
|
|
316
|
+
instance.flushLog();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
for (const instance of host.subProcesses) {
|
|
320
|
+
if (!instance.silent) {
|
|
321
|
+
instance.flushLog();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
host.close();
|
|
325
|
+
clearAssets(host);
|
|
303
326
|
});
|
|
304
327
|
}
|
|
305
328
|
else {
|
|
306
|
-
clearAssets
|
|
329
|
+
clearAssets(host);
|
|
307
330
|
}
|
|
308
331
|
return result;
|
|
309
332
|
}
|
|
310
|
-
function
|
|
311
|
-
|
|
333
|
+
function setHttpCacheLimit(value, type, disk) {
|
|
334
|
+
if (value === undefined) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (typeof value === 'string') {
|
|
338
|
+
value = (0, types_1.formatSize)(value);
|
|
339
|
+
}
|
|
340
|
+
if (value >= 0) {
|
|
341
|
+
switch (type) {
|
|
342
|
+
case 1:
|
|
343
|
+
(disk ? DISK : MEMORY).LIMIT = value;
|
|
344
|
+
break;
|
|
345
|
+
case 2:
|
|
346
|
+
MEMORY.LIMIT_ALL = value;
|
|
347
|
+
break;
|
|
348
|
+
case 3:
|
|
349
|
+
MEMORY.DISK_MIN = value;
|
|
350
|
+
break;
|
|
351
|
+
case 4:
|
|
352
|
+
MEMORY.DISK_MAX = value;
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else if (value === -1) {
|
|
357
|
+
switch (type) {
|
|
358
|
+
case 3:
|
|
359
|
+
MEMORY.DISK_MIN = Infinity;
|
|
360
|
+
break;
|
|
361
|
+
case 4:
|
|
362
|
+
MEMORY.DISK_MAX = 0;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
function rejectModule(instance, err, type, hint) {
|
|
368
|
+
instance.writeFail(["Handled rejection", instance.moduleName + (hint ? ': ' + hint : '')], err, type);
|
|
369
|
+
}
|
|
370
|
+
function errorAsset(instance, err, localUri, type = 4) {
|
|
371
|
+
rejectModule(instance, err, type, path.basename(localUri));
|
|
372
|
+
}
|
|
373
|
+
function removeFiles(host, items) {
|
|
374
|
+
if (items.size > 0) {
|
|
375
|
+
for (const value of items) {
|
|
376
|
+
host.deleteFile(value, { emptyDir: true });
|
|
377
|
+
}
|
|
378
|
+
items.clear();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
function createImageInstance(host, mimeMap, mimeType, constructor, ...params) {
|
|
382
|
+
const instance = new constructor(...params);
|
|
383
|
+
instance.host = host;
|
|
384
|
+
instance.init(host.config);
|
|
385
|
+
observeFile(host, instance);
|
|
386
|
+
mimeMap.set(mimeType, { constructor, instance, params });
|
|
387
|
+
return instance;
|
|
388
|
+
}
|
|
389
|
+
function clearQueue(data, attr) {
|
|
390
|
+
if (attr && data[attr]) {
|
|
391
|
+
for (const item of data[attr]) {
|
|
392
|
+
item.invalid = true;
|
|
393
|
+
}
|
|
394
|
+
data[attr] = undefined;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function hasEtag(item, cacheable, fallback) {
|
|
398
|
+
if (!cacheable || !(0, types_1.existsFlag)(item.flags)) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
switch (item.incremental) {
|
|
402
|
+
case false:
|
|
403
|
+
case "none":
|
|
404
|
+
case "exists":
|
|
405
|
+
case "staging":
|
|
406
|
+
return false;
|
|
407
|
+
case "etag":
|
|
408
|
+
return true;
|
|
409
|
+
default:
|
|
410
|
+
return fallback;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function processHeaders(item, headers, lastModified, mainEtag) {
|
|
414
|
+
const contentLength = parseInt(headers['content-length']);
|
|
415
|
+
if (contentLength > 0) {
|
|
416
|
+
item.contentLength = contentLength;
|
|
417
|
+
}
|
|
418
|
+
else if ('contentLength' in item) {
|
|
419
|
+
item.contentLength = undefined;
|
|
420
|
+
}
|
|
421
|
+
const etag = headers.etag;
|
|
422
|
+
if (etag) {
|
|
423
|
+
if (mainEtag) {
|
|
424
|
+
CACHE_ETAG[item.uri] = etag;
|
|
425
|
+
}
|
|
426
|
+
return item.etag = etag;
|
|
427
|
+
}
|
|
428
|
+
if (lastModified) {
|
|
429
|
+
return item.lastModified = headers['last-modified'];
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function errorPermission(host, item) {
|
|
433
|
+
host.writeFail(["Unable to read file", item.uri], (0, types_1.errorValue)("Operation not permitted", item.uri || "Unknown"), 8192);
|
|
434
|
+
item.invalid = true;
|
|
435
|
+
}
|
|
436
|
+
function copyDownload(host, item, queued) {
|
|
437
|
+
const uriMap = new Map();
|
|
438
|
+
for (const file of queued) {
|
|
439
|
+
const destUri = file.localUri;
|
|
440
|
+
let items = uriMap.get(destUri);
|
|
441
|
+
if (!items) {
|
|
442
|
+
const pathname = path.dirname(destUri);
|
|
443
|
+
if (!core_1.Host.createDir(pathname)) {
|
|
444
|
+
file.invalid = true;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
uriMap.set(destUri, items = []);
|
|
448
|
+
}
|
|
449
|
+
file.etag = item.etag;
|
|
450
|
+
file.lastModified = item.lastModified;
|
|
451
|
+
items.push(file);
|
|
452
|
+
}
|
|
453
|
+
const buffer = item.sourceUTF8 || item.buffer;
|
|
454
|
+
for (const [destUri, items] of uriMap) {
|
|
455
|
+
try {
|
|
456
|
+
if (buffer) {
|
|
457
|
+
fs.writeFileSync(destUri, buffer);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
fs.copyFileSync(item.localUri, destUri);
|
|
461
|
+
}
|
|
462
|
+
for (const queue of items) {
|
|
463
|
+
host.performAsyncTask();
|
|
464
|
+
void host.transformAsset(new FileThread(host, queue, 1));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
catch (err) {
|
|
468
|
+
for (const queue of items) {
|
|
469
|
+
queue.invalid = true;
|
|
470
|
+
}
|
|
471
|
+
host.writeFail([buffer ? "Unable to write buffer" : "Unable to copy file", path.basename(item.localUri)], err, 32);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function setBufferTarget(item, buffer) {
|
|
476
|
+
if (typeof buffer === 'string') {
|
|
477
|
+
item.sourceUTF8 = buffer;
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
item.buffer = buffer;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function writeBufferCache(host, localUri, buffer, encoding) {
|
|
484
|
+
fs.writeFileSync(localUri, buffer);
|
|
485
|
+
host.addDownload(Buffer.byteLength(buffer, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
486
|
+
}
|
|
487
|
+
function nextScheduled(scheduler, pid) {
|
|
488
|
+
if (pid > 0) {
|
|
489
|
+
const found = scheduler.status.find(item => item.id === pid);
|
|
490
|
+
if (found) {
|
|
491
|
+
found.endTime || (found.endTime = Date.now());
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
--scheduler.count;
|
|
495
|
+
if (scheduler.queue.length > 0) {
|
|
496
|
+
const params = scheduler.queue.pop();
|
|
497
|
+
void this.scheduleTask(...params);
|
|
498
|
+
}
|
|
499
|
+
else if (scheduler.transform.length > 0) {
|
|
500
|
+
do {
|
|
501
|
+
const args = scheduler.transform.shift();
|
|
502
|
+
void this.transformAsset(args[0], args[1], true);
|
|
503
|
+
} while (scheduler.transform.length > 0 && scheduler.queue.length === 0);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
async function doVerifyChecksum(root, from, options, nested) {
|
|
507
|
+
if ((0, types_1.isObject)(from)) {
|
|
508
|
+
options = from;
|
|
509
|
+
from = undefined;
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
options || (options = {});
|
|
513
|
+
}
|
|
514
|
+
const { digest, sortBy = 0, recursive = false, ignore = [], include, exclude, verbose = true, joinRoot } = options;
|
|
515
|
+
const parent = recursive === 1 && typeof verbose !== 'number';
|
|
516
|
+
let algorithm = options.algorithm;
|
|
517
|
+
from || (from = checksumFile(algorithm));
|
|
518
|
+
if (!algorithm) {
|
|
519
|
+
switch (algorithm = path.extname(from).substring(1).toLowerCase()) {
|
|
520
|
+
case 'md5':
|
|
521
|
+
case 'sha1':
|
|
522
|
+
case 'sha224':
|
|
523
|
+
case 'sha256':
|
|
524
|
+
case 'sha384':
|
|
525
|
+
case 'sha512':
|
|
526
|
+
case 'ripemd':
|
|
527
|
+
case 'ripemd-160':
|
|
528
|
+
break;
|
|
529
|
+
default:
|
|
530
|
+
algorithm = undefined;
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (verbose) {
|
|
535
|
+
(0, types_1.setLogCurrent)(null);
|
|
536
|
+
}
|
|
537
|
+
let pass = 0, fail = [], missing = [];
|
|
538
|
+
try {
|
|
539
|
+
const filename = path.basename(from);
|
|
540
|
+
const files = [];
|
|
541
|
+
from = joinRoot ? path.join(root, filename) : path.resolve(from);
|
|
542
|
+
recurseDir(files, [root], { ignore: [...ignore, from], sortBy, recursive });
|
|
543
|
+
const items = fs.readFileSync(from, 'utf-8').split('\n').map(item => {
|
|
544
|
+
const index = item.indexOf(' ');
|
|
545
|
+
return [item.substring(0, index), path.join(root, item.substring(index + 1))];
|
|
546
|
+
});
|
|
547
|
+
const checked = include || exclude ? filterPaths(items.map(item => item[1]), include, exclude, options.dot) : null;
|
|
548
|
+
let valid;
|
|
549
|
+
for (const [previous, pathname] of items) {
|
|
550
|
+
if (checked !== null && !checked.includes(pathname) || recursive === 1 && path.basename(pathname) === filename) {
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
if (files.includes(pathname)) {
|
|
554
|
+
const hash = await FileManager.readHash(pathname, { algorithm, digest });
|
|
555
|
+
if (hash !== previous) {
|
|
556
|
+
fail.push(pathname);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
if (verbose) {
|
|
560
|
+
process.stdout.write("+" + ' ' + pathname + '\n');
|
|
561
|
+
}
|
|
562
|
+
++pass;
|
|
563
|
+
}
|
|
564
|
+
valid = true;
|
|
565
|
+
}
|
|
566
|
+
else if (!ignore.includes(pathname)) {
|
|
567
|
+
missing.push(pathname);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
if (parent) {
|
|
571
|
+
const checksum = files.filter(value => path.basename(value) === filename);
|
|
572
|
+
if (checksum.length > 0) {
|
|
573
|
+
const current = items.map(item => item[1]);
|
|
574
|
+
const tasks = checksum.map(async (pathname) => doVerifyChecksum(path.dirname(pathname), filename, { ...options, ignore: current, joinRoot: true }, true));
|
|
575
|
+
await Promise.all(tasks).then(group => {
|
|
576
|
+
for (const item of group) {
|
|
577
|
+
if (item) {
|
|
578
|
+
const [f, m, p] = item;
|
|
579
|
+
if (f.length > 0) {
|
|
580
|
+
fail.push(...f);
|
|
581
|
+
}
|
|
582
|
+
if (m.length > 0) {
|
|
583
|
+
missing.push(...m);
|
|
584
|
+
}
|
|
585
|
+
pass += p;
|
|
586
|
+
valid = true;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
if (valid) {
|
|
593
|
+
options.outPath = from;
|
|
594
|
+
}
|
|
595
|
+
else if (options.throwsEmpty) {
|
|
596
|
+
throw checksumError(algorithm);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
catch (err) {
|
|
600
|
+
if (options.throwsEmpty) {
|
|
601
|
+
throw err;
|
|
602
|
+
}
|
|
603
|
+
FileManager.writeFail(["Unable to read directory", root], err, 32);
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
if (parent) {
|
|
607
|
+
if (fail.length > 0) {
|
|
608
|
+
fail = Array.from(new Set(fail));
|
|
609
|
+
}
|
|
610
|
+
if (missing.length > 0) {
|
|
611
|
+
missing = Array.from(new Set(missing));
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
if (verbose && !nested) {
|
|
615
|
+
const max = Math.max(...fail.concat(missing).map(item => item.length));
|
|
616
|
+
writeLog(fail, "-", max);
|
|
617
|
+
writeLog(missing, "?", max);
|
|
618
|
+
}
|
|
619
|
+
return [fail, missing, pass];
|
|
620
|
+
}
|
|
621
|
+
function writeLog(items, symbol, max) {
|
|
622
|
+
const [bg, fg] = symbol === "-" ? ['\x1b[31m', '\x1b[89m'] : ['\x1b[33m', '\x1b[89m'];
|
|
623
|
+
items.forEach((value, index) => {
|
|
624
|
+
process.stdout.write(bg + symbol + ` ${value.padEnd(max)} (${(index + 1).toString()})${fg}\n`);
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
function writeProgressBar(bars, length) {
|
|
628
|
+
if (bars > 0) {
|
|
629
|
+
const leading = bars < length ? (--bars, 1) : 0;
|
|
630
|
+
let result = bars > 0 ? LOGGER.PROGRESS_USECOLOR ? chalk.yellow.bold(LOGGER.PROGRESS_BOXCHAR).repeat(bars) : '#'.repeat(bars) : '';
|
|
631
|
+
if (leading > 0) {
|
|
632
|
+
result += chalk.grey(LOGGER.PROGRESS_BOXCHAR.repeat(length - bars));
|
|
633
|
+
}
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
636
|
+
return '';
|
|
637
|
+
}
|
|
638
|
+
function formatSegment(endTime, ...values) {
|
|
639
|
+
if (endTime === -1) {
|
|
640
|
+
values[0] = chalk.red(values[0]);
|
|
641
|
+
values[1] = chalk.grey.bold(values[1]);
|
|
642
|
+
values[2] = chalk.grey.bold(values[2]);
|
|
643
|
+
}
|
|
644
|
+
else if (endTime) {
|
|
645
|
+
values[0] = chalk.yellow.bold(values[0]);
|
|
646
|
+
values[1] = chalk.cyan.bold(values[1]);
|
|
647
|
+
values[2] = chalk.cyan(values[2]);
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
values[0] = chalk.yellow(values[0]);
|
|
651
|
+
}
|
|
652
|
+
return values;
|
|
653
|
+
}
|
|
654
|
+
function tryPackage(host, target, type) {
|
|
655
|
+
if ((0, types_1.isString)(target)) {
|
|
656
|
+
try {
|
|
657
|
+
return require(target);
|
|
658
|
+
}
|
|
659
|
+
catch (err) {
|
|
660
|
+
host.checkPackage(err, target, ["Unable to load handler", host.moduleName], type);
|
|
661
|
+
}
|
|
662
|
+
return null;
|
|
663
|
+
}
|
|
664
|
+
return target;
|
|
665
|
+
}
|
|
666
|
+
function setLogMinWidth() {
|
|
667
|
+
LOGGER.MIN_WIDTH = LOGGER.TITLE_WIDTH + 2 + LOGGER.VALUE_WIDTH + 1;
|
|
668
|
+
LOGGER.MESSAGE_WIDTH = LOGGER.MIN_WIDTH + LOGGER.MESSAGE_SEP_START;
|
|
669
|
+
LOGGER.PERCENT_WIDTH = LOGGER.MIN_WIDTH + 8;
|
|
670
|
+
LOGGER.STAT_WIDTH = LOGGER.PERCENT_WIDTH + 11 + 13;
|
|
312
671
|
}
|
|
313
|
-
const
|
|
672
|
+
const closeResponse = (client) => client?.destroy();
|
|
673
|
+
const isCacheable = (item) => item.initialValue?.cacheable !== false;
|
|
674
|
+
const isMatchRoot = (value) => !value.startsWith('*') && /[\\/]/.test(value);
|
|
675
|
+
const hasIncremental = (value) => value === "etag" || value === "exists";
|
|
676
|
+
const matchPathname = (value) => core_1.Host.PLATFORM_WIN32 ? value.toLowerCase() : value;
|
|
677
|
+
const sanitizePath = (value) => value.replace(/(?:^\\|\\+)/g, '/');
|
|
678
|
+
const equalAddress = (value, other) => value === other || decodeURIComponent(value) === decodeURIComponent(other);
|
|
679
|
+
const formatPercent = (value) => Math.round(value).toString().padStart(3) + '%';
|
|
680
|
+
const checkEOF = (value) => /\n$/.test(value) ? value : value + '\n';
|
|
314
681
|
const checksumFile = (algorithm) => "checksum" + '.' + ((0, types_1.isString)(algorithm) ? algorithm.toLowerCase() : "sha256");
|
|
315
682
|
const checksumError = (algorithm) => new Error("Invalid parameters" + ` (${algorithm || "sha256"})`);
|
|
316
683
|
const isFunction = (value) => typeof value === 'function';
|
|
317
684
|
const ignoreAsset = (item, exists) => item.invalid || (0, types_1.hasBit)(item.flags, 1 | (!exists ? 128 : 0));
|
|
685
|
+
const validateChecksum = (host, item, buffer, localUri = item.localUri) => !item.checksum || checkHash(host, localUri, false, item.checksum, buffer);
|
|
686
|
+
const errorAbsolute = (hint) => (0, types_1.errorValue)("Path is not absolute", hint);
|
|
318
687
|
class Scheduler {
|
|
319
688
|
constructor() {
|
|
320
689
|
this.id = 0;
|
|
321
690
|
this.count = 0;
|
|
322
|
-
this.
|
|
691
|
+
this.statusHeight = 0;
|
|
692
|
+
this.scrollHeight = 0;
|
|
693
|
+
this.pending = 0;
|
|
323
694
|
this.updated = 0;
|
|
324
|
-
this.titleWidth = 6;
|
|
325
|
-
this.valueWidth = 71;
|
|
326
695
|
this.limit = PROCESS_SUB_LIMIT;
|
|
327
696
|
this.queue = [];
|
|
328
697
|
this.transform = [];
|
|
329
698
|
this.status = [];
|
|
699
|
+
this.scroll = [];
|
|
330
700
|
this.logCurrent = null;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
701
|
+
this.screenReset = false;
|
|
702
|
+
this.listener = null;
|
|
703
|
+
this._columns = -1;
|
|
335
704
|
}
|
|
336
705
|
add(id, url) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
url = url.substring(0, valueWidth - 3) + '...';
|
|
706
|
+
if (url.length > LOGGER.VALUE_WIDTH) {
|
|
707
|
+
url = url.substring(0, LOGGER.VALUE_WIDTH - 3) + '...';
|
|
340
708
|
}
|
|
341
709
|
else {
|
|
342
|
-
url = url.padEnd(
|
|
710
|
+
url = url.padEnd(LOGGER.VALUE_WIDTH);
|
|
343
711
|
}
|
|
344
712
|
this.status.push(new TaskStatus(id, url));
|
|
345
713
|
}
|
|
346
714
|
reset() {
|
|
347
715
|
this.status = [];
|
|
348
|
-
this.
|
|
716
|
+
this.scroll = [];
|
|
717
|
+
this.statusHeight = 0;
|
|
718
|
+
this.scrollHeight = 0;
|
|
349
719
|
this.logCurrent = null;
|
|
720
|
+
this._columns = -1;
|
|
721
|
+
if (this.listener) {
|
|
722
|
+
PROCESS_STDIN.setRawMode(false);
|
|
723
|
+
PROCESS_STDIN.removeListener('keypress', this.listener);
|
|
724
|
+
this.listener = null;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
section(redraw) {
|
|
728
|
+
if (redraw) {
|
|
729
|
+
PROCESS_STDOUT.write(chalk.blackBright('-'.repeat(PROCESS_STDOUT.columns)) + '\n');
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
PROCESS_STDOUT.moveCursor(0, 1);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
get barLength() {
|
|
736
|
+
if (this.rawMode) {
|
|
737
|
+
if (this._columns === -1) {
|
|
738
|
+
PROCESS_STDIN.setRawMode(true);
|
|
739
|
+
this.listener = (ch, key) => {
|
|
740
|
+
if (key.ctrl) {
|
|
741
|
+
PROCESS_STDIN.setRawMode(false);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
PROCESS_STDIN.on('keypress', this.listener);
|
|
745
|
+
}
|
|
746
|
+
PROCESS_STDIN.pause();
|
|
747
|
+
PROCESS_STDIN.resume();
|
|
748
|
+
}
|
|
749
|
+
const columns = PROCESS_STDOUT.columns;
|
|
750
|
+
if (columns !== this._columns) {
|
|
751
|
+
if (this._columns !== -1) {
|
|
752
|
+
for (const item of this.status) {
|
|
753
|
+
item.current = '';
|
|
754
|
+
item.finished = '';
|
|
755
|
+
}
|
|
756
|
+
this.scroll = [];
|
|
757
|
+
this.logCurrent = null;
|
|
758
|
+
PROCESS_STDOUT.write('\x1bc');
|
|
759
|
+
this.screenReset = true;
|
|
760
|
+
}
|
|
761
|
+
this._columns = columns;
|
|
762
|
+
}
|
|
763
|
+
const width = columns - LOGGER.STAT_WIDTH;
|
|
764
|
+
if (width < 0) {
|
|
765
|
+
return columns >= LOGGER.PERCENT_WIDTH ? 1 : NaN;
|
|
766
|
+
}
|
|
767
|
+
return width >= 10 ? Math.max(Math.min(width, LOGGER.PROGRESS_MAXWIDTH), 10) : -1;
|
|
768
|
+
}
|
|
769
|
+
get rawMode() {
|
|
770
|
+
return core_1.Host.PLATFORM_WIN32 && LOGGER.PROGRESS_RAWMODE;
|
|
350
771
|
}
|
|
351
772
|
}
|
|
352
773
|
class TaskStatus {
|
|
@@ -359,7 +780,8 @@ class TaskStatus {
|
|
|
359
780
|
this.startTime = Date.now();
|
|
360
781
|
this.endTime = 0;
|
|
361
782
|
this.dataTime = null;
|
|
362
|
-
this.
|
|
783
|
+
this.current = '';
|
|
784
|
+
this.finished = '';
|
|
363
785
|
}
|
|
364
786
|
}
|
|
365
787
|
class HttpDiskCache {
|
|
@@ -373,10 +795,10 @@ class HttpDiskCache {
|
|
|
373
795
|
this._excludeExt = [];
|
|
374
796
|
this._includeExt = [];
|
|
375
797
|
this._items = [];
|
|
376
|
-
this
|
|
798
|
+
this.enabled = enabled;
|
|
377
799
|
}
|
|
378
800
|
has(uri) {
|
|
379
|
-
if (!this
|
|
801
|
+
if (!this.enabled) {
|
|
380
802
|
return false;
|
|
381
803
|
}
|
|
382
804
|
try {
|
|
@@ -391,7 +813,7 @@ class HttpDiskCache {
|
|
|
391
813
|
if (flags === 0) {
|
|
392
814
|
return true;
|
|
393
815
|
}
|
|
394
|
-
if (flags &
|
|
816
|
+
if (flags & (2 | 8)) {
|
|
395
817
|
const ext = path.extname(uri.pathname).substring(1);
|
|
396
818
|
if (ext) {
|
|
397
819
|
if (flags & 2) {
|
|
@@ -404,9 +826,12 @@ class HttpDiskCache {
|
|
|
404
826
|
}
|
|
405
827
|
}
|
|
406
828
|
}
|
|
407
|
-
|
|
829
|
+
if ((flags & 1) && !this._include.includes(uri.origin) || (flags & 4) && this._exclude.includes(uri.origin)) {
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
return true;
|
|
408
833
|
}
|
|
409
|
-
add(uri, etag, target, { buffer, contentLength = (0,
|
|
834
|
+
add(uri, etag, target, { buffer, contentLength = (0, util_2.getSize)(target) } = {}) {
|
|
410
835
|
let tempDir;
|
|
411
836
|
if (contentLength <= this.limit && (tempDir = this.host.getCacheDir(uri))) {
|
|
412
837
|
const baseDir = path.join(tempDir, etag);
|
|
@@ -423,7 +848,9 @@ class HttpDiskCache {
|
|
|
423
848
|
}
|
|
424
849
|
const expires = this.expires;
|
|
425
850
|
if (expires > 0 && expires < Infinity) {
|
|
426
|
-
setTimeout(() =>
|
|
851
|
+
setTimeout(() => {
|
|
852
|
+
this.clear(target);
|
|
853
|
+
}, Math.min(expires, core_1.Host.MAX_TIMEOUT));
|
|
427
854
|
}
|
|
428
855
|
}
|
|
429
856
|
catch {
|
|
@@ -461,7 +888,7 @@ class HttpDiskCache {
|
|
|
461
888
|
}
|
|
462
889
|
}
|
|
463
890
|
else {
|
|
464
|
-
this._flags &= ~
|
|
891
|
+
this._flags &= ~(1 | 2);
|
|
465
892
|
}
|
|
466
893
|
}
|
|
467
894
|
get include() {
|
|
@@ -483,7 +910,7 @@ class HttpDiskCache {
|
|
|
483
910
|
}
|
|
484
911
|
}
|
|
485
912
|
else {
|
|
486
|
-
this._flags &= ~
|
|
913
|
+
this._flags &= ~(4 | 8);
|
|
487
914
|
}
|
|
488
915
|
}
|
|
489
916
|
get exclude() {
|
|
@@ -511,7 +938,9 @@ class HttpMemoryCache extends HttpDiskCache {
|
|
|
511
938
|
}
|
|
512
939
|
this._items.push(MEMORY.CACHE[uri] = [Date.now(), buffer, encoding, contentLength, uri, etag]);
|
|
513
940
|
if (this.expires < Infinity) {
|
|
514
|
-
setTimeout(() =>
|
|
941
|
+
setTimeout(() => {
|
|
942
|
+
this.clear(uri);
|
|
943
|
+
}, Math.min(this.expires, core_1.Host.MAX_TIMEOUT));
|
|
515
944
|
}
|
|
516
945
|
++MEMORY.TOTAL;
|
|
517
946
|
return;
|
|
@@ -556,7 +985,7 @@ class HttpMemoryCache extends HttpDiskCache {
|
|
|
556
985
|
}
|
|
557
986
|
}
|
|
558
987
|
purge(percent, limit) {
|
|
559
|
-
FileManager.purgeMemory(percent, limit);
|
|
988
|
+
void FileManager.purgeMemory(percent, limit);
|
|
560
989
|
}
|
|
561
990
|
withinDisk(value) {
|
|
562
991
|
if (typeof value !== 'number') {
|
|
@@ -565,6 +994,397 @@ class HttpMemoryCache extends HttpDiskCache {
|
|
|
565
994
|
return value >= this.toDisk[0] && value <= this.toDisk[1];
|
|
566
995
|
}
|
|
567
996
|
}
|
|
997
|
+
class ProcessGroup {
|
|
998
|
+
constructor() {
|
|
999
|
+
this.emptied = [];
|
|
1000
|
+
this.completed = Object.create(null);
|
|
1001
|
+
this.processing = Object.create(null);
|
|
1002
|
+
this.downloading = Object.create(null);
|
|
1003
|
+
this.appending = Object.create(null);
|
|
1004
|
+
this.bundling = Object.create(null);
|
|
1005
|
+
this.originCount = Object.create(null);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
class ProcessFile {
|
|
1009
|
+
constructor(host, file, localUri, groupData) {
|
|
1010
|
+
this.host = host;
|
|
1011
|
+
this.file = file;
|
|
1012
|
+
this.localUri = localUri;
|
|
1013
|
+
this.groupData = groupData;
|
|
1014
|
+
}
|
|
1015
|
+
createFolder(pathname, emptyDir) {
|
|
1016
|
+
const emptied = this.groupData.emptied;
|
|
1017
|
+
if (!emptied.includes(pathname)) {
|
|
1018
|
+
if (emptyDir && core_1.Host.removeDir(pathname, true)) {
|
|
1019
|
+
emptied.push(pathname);
|
|
1020
|
+
}
|
|
1021
|
+
else if (core_1.Host.createDir(pathname)) {
|
|
1022
|
+
emptied.push(pathname);
|
|
1023
|
+
}
|
|
1024
|
+
else {
|
|
1025
|
+
this.file.invalid = true;
|
|
1026
|
+
this.host.writeFail("Unable to create directory", (0, types_1.errorValue)("Path not found", pathname));
|
|
1027
|
+
return false;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
return true;
|
|
1031
|
+
}
|
|
1032
|
+
queued(pathname, emptyDir, content) {
|
|
1033
|
+
var _p, _q, _r;
|
|
1034
|
+
if (!this.createFolder(pathname, emptyDir)) {
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
const { host, groupData: group, file, localUri } = this;
|
|
1038
|
+
const { bundleId, bundleIndex = -1 } = file;
|
|
1039
|
+
if (!(0, types_1.isEmpty)(bundleId) && bundleIndex >= 0) {
|
|
1040
|
+
const items = (_p = group.appending)[localUri] || (_p[localUri] = []);
|
|
1041
|
+
(_q = group.bundling)[_r = file.uri] || (_q[_r] = []);
|
|
1042
|
+
if (bundleIndex > 0) {
|
|
1043
|
+
items[bundleIndex - 1] = file;
|
|
1044
|
+
const url = file.url;
|
|
1045
|
+
if (file.fetchType === 1 && (host.cacheToDisk.has(url) || host.cacheToMemory.has(url))) {
|
|
1046
|
+
const parent = host.assets.find(item => item.bundleIndex === 0 && item.bundleId === bundleId);
|
|
1047
|
+
if (parent) {
|
|
1048
|
+
(parent.bundleQueue || (parent.bundleQueue = [])).push(new Promise(resolve => {
|
|
1049
|
+
host.Request.open(url, { method: 'HEAD', httpVersion: 1 })
|
|
1050
|
+
.on('response', res => {
|
|
1051
|
+
if (res.statusCode < 300) {
|
|
1052
|
+
processHeaders(file, res.headers, false, false);
|
|
1053
|
+
}
|
|
1054
|
+
resolve(file);
|
|
1055
|
+
})
|
|
1056
|
+
.on('error', () => {
|
|
1057
|
+
resolve(file);
|
|
1058
|
+
})
|
|
1059
|
+
.on('timeout', () => {
|
|
1060
|
+
resolve(file);
|
|
1061
|
+
});
|
|
1062
|
+
}));
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
return true;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
else if (!content && file.filename) {
|
|
1069
|
+
const previous = group.completed[localUri];
|
|
1070
|
+
if (previous) {
|
|
1071
|
+
if (file.uri === previous.uri) {
|
|
1072
|
+
file.etag = previous.etag;
|
|
1073
|
+
file.lastModified = previous.lastModified;
|
|
1074
|
+
}
|
|
1075
|
+
void host.transformAsset(new FileThread(host, file, 1));
|
|
1076
|
+
return true;
|
|
1077
|
+
}
|
|
1078
|
+
const queue = group.processing[localUri];
|
|
1079
|
+
if (queue) {
|
|
1080
|
+
queue.push(file);
|
|
1081
|
+
return true;
|
|
1082
|
+
}
|
|
1083
|
+
group.processing[localUri] = [file];
|
|
1084
|
+
}
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
received(err, incremental, fetched, binary, checked) {
|
|
1088
|
+
const { host, file } = this;
|
|
1089
|
+
const localUri = this.localUri;
|
|
1090
|
+
if (err) {
|
|
1091
|
+
file.invalid = true;
|
|
1092
|
+
host.completeAsyncTask(err, localUri);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
if (file.checksum && !checked && !checkHash(host, localUri, false, file.checksum, file.buffer)) {
|
|
1096
|
+
file.invalid = true;
|
|
1097
|
+
host.filesToRemove.add(localUri);
|
|
1098
|
+
host.completeAsyncTask();
|
|
1099
|
+
host.writeFail(["Checksum did not match", path.basename(localUri)], (0, types_1.errorValue)(file.uri || localUri, "Invalid checksum"), { type: 32, queue: true });
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
if (fetched) {
|
|
1103
|
+
host.fetchedAssets.push(file);
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
host.copiedAssets.push(file);
|
|
1107
|
+
}
|
|
1108
|
+
if (binary) {
|
|
1109
|
+
void host.transformAsset(new FileThread(host, file, 1));
|
|
1110
|
+
}
|
|
1111
|
+
else {
|
|
1112
|
+
void this.finalize(incremental);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
async finalize(incremental) {
|
|
1116
|
+
const { host, file, localUri, groupData } = this;
|
|
1117
|
+
const bundleStart = file.bundleIndex === 0 && !(0, types_1.isEmpty)(file.bundleId) ? host.incremental !== "staging" && host[kRecursionLimit] === RECURSION_LIMIT ? 2 : 1 : 0;
|
|
1118
|
+
groupData.completed[localUri] = file;
|
|
1119
|
+
if (bundleStart > 0) {
|
|
1120
|
+
host.setAssetContent(file, host.getUTF8String(file, localUri));
|
|
1121
|
+
let success = true, error, checkEtag = !file.trailingContent && hasEtag(file, bundleStart === 2, incremental === "etag");
|
|
1122
|
+
if (file.bundleQueue) {
|
|
1123
|
+
error = await Promise.all(file.bundleQueue).then(() => null).catch((err) => err);
|
|
1124
|
+
delete file.bundleQueue;
|
|
1125
|
+
}
|
|
1126
|
+
const items = groupData.appending[localUri];
|
|
1127
|
+
if (items) {
|
|
1128
|
+
if (error) {
|
|
1129
|
+
for (const queue of items) {
|
|
1130
|
+
queue.invalid = true;
|
|
1131
|
+
}
|
|
1132
|
+
success = false;
|
|
1133
|
+
}
|
|
1134
|
+
else {
|
|
1135
|
+
const tasks = [];
|
|
1136
|
+
for (const queue of items) {
|
|
1137
|
+
const encoding = queue.encoding || (queue.encoding = 'utf-8');
|
|
1138
|
+
const { uri, fetchType: type } = queue;
|
|
1139
|
+
let tempFile;
|
|
1140
|
+
if (checkEtag && queue.trailingContent) {
|
|
1141
|
+
checkEtag = false;
|
|
1142
|
+
}
|
|
1143
|
+
const verifyBundle = (value, etag, checked) => {
|
|
1144
|
+
if (!queue.invalid) {
|
|
1145
|
+
if (!checked && !validateChecksum(host, queue, value, localUri)) {
|
|
1146
|
+
queue.invalid = true;
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (value instanceof Buffer) {
|
|
1150
|
+
value = value.toString(encoding);
|
|
1151
|
+
}
|
|
1152
|
+
const url = queue.url;
|
|
1153
|
+
if (etag && host.cacheToMemory.has(url)) {
|
|
1154
|
+
host.cacheToMemory.add(url, encodeURIComponent(etag), value, {
|
|
1155
|
+
encoding,
|
|
1156
|
+
contentLength: queue.contentLength,
|
|
1157
|
+
toDisk: !tempFile && isCacheable(queue) ? queue.filename || queue.localUri && path.basename(queue.localUri) : ''
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
host.setAssetContent(queue, value, { localUri, bundleIndex: queue.bundleIndex, bundleReplace: queue.bundleReplace });
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
if (queue.content) {
|
|
1164
|
+
verifyBundle(queue.content);
|
|
1165
|
+
checkEtag = false;
|
|
1166
|
+
}
|
|
1167
|
+
else if (uri) {
|
|
1168
|
+
if (type === 1 || type === 2) {
|
|
1169
|
+
const url = queue.url;
|
|
1170
|
+
const options = {
|
|
1171
|
+
url,
|
|
1172
|
+
encoding,
|
|
1173
|
+
statusMessage: uri + ` (${queue.bundleIndex})`
|
|
1174
|
+
};
|
|
1175
|
+
let etag, pipeTo;
|
|
1176
|
+
if (type === 2) {
|
|
1177
|
+
options.socketPath = queue.socketPath;
|
|
1178
|
+
options.httpVersion = 1;
|
|
1179
|
+
}
|
|
1180
|
+
else if (url) {
|
|
1181
|
+
if (etag = queue.etag) {
|
|
1182
|
+
const valid = incremental !== false || file.incremental === true;
|
|
1183
|
+
const cached = valid && MEMORY.CACHE[uri];
|
|
1184
|
+
const etagDir = encodeURIComponent(etag);
|
|
1185
|
+
if (cached) {
|
|
1186
|
+
if (etagDir === cached[5]) {
|
|
1187
|
+
const source = cached[1];
|
|
1188
|
+
if (validateChecksum(host, queue, source, localUri)) {
|
|
1189
|
+
verifyBundle(typeof source === 'string' ? source : source.toString(encoding), '', true);
|
|
1190
|
+
host.addDownload(Buffer.byteLength(source, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
else {
|
|
1195
|
+
host.cacheToMemory.clear(uri);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
if (host.cacheToDisk.has(url) && isCacheable(queue)) {
|
|
1199
|
+
const baseDir = path.join(host.getCacheDir(url), etagDir);
|
|
1200
|
+
pipeTo = path.join(baseDir, path.basename(localUri));
|
|
1201
|
+
try {
|
|
1202
|
+
if (valid && (0, util_2.hasSize)(pipeTo)) {
|
|
1203
|
+
const buffer = fs.readFileSync(pipeTo, { encoding });
|
|
1204
|
+
if (validateChecksum(host, queue, localUri, buffer)) {
|
|
1205
|
+
verifyBundle(buffer, etag, true);
|
|
1206
|
+
host.addDownload(Buffer.byteLength(buffer, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
1207
|
+
continue;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if (!fs.existsSync(baseDir)) {
|
|
1211
|
+
fs.mkdirSync(baseDir);
|
|
1212
|
+
}
|
|
1213
|
+
tempFile = path.join(baseDir, (0, types_1.incrementUUID)());
|
|
1214
|
+
options.pipeTo = tempFile;
|
|
1215
|
+
}
|
|
1216
|
+
catch {
|
|
1217
|
+
pipeTo = undefined;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
if ((groupData.originCount[url.origin] || 0) <= 1) {
|
|
1222
|
+
options.httpVersion = 1;
|
|
1223
|
+
}
|
|
1224
|
+
options.connected = (headers) => {
|
|
1225
|
+
etag = processHeaders(queue, headers, !!host.Watch, false);
|
|
1226
|
+
return true;
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
tasks.push(new Promise((resolve, reject) => {
|
|
1230
|
+
void host.scheduleTask(url || uri, options, (data) => {
|
|
1231
|
+
if (data) {
|
|
1232
|
+
verifyBundle(data, etag);
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
queue.invalid = true;
|
|
1236
|
+
}
|
|
1237
|
+
const downloaded = groupData.bundling[uri];
|
|
1238
|
+
if ((0, types_1.isArray)(downloaded)) {
|
|
1239
|
+
if (data && !queue.invalid) {
|
|
1240
|
+
if (typeof data === 'string') {
|
|
1241
|
+
queue.sourceUTF8 = data;
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
queue.buffer = data;
|
|
1245
|
+
}
|
|
1246
|
+
copyDownload(host, queue, downloaded);
|
|
1247
|
+
}
|
|
1248
|
+
else {
|
|
1249
|
+
for (const item of downloaded) {
|
|
1250
|
+
item.invalid = true;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
if (tempFile && (!pipeTo || core_1.Host.isPath(pipeTo) || !core_1.Host.renameFile(tempFile, pipeTo, false))) {
|
|
1255
|
+
queueMicrotask(() => {
|
|
1256
|
+
fs.unlink(tempFile, () => { });
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
resolve();
|
|
1260
|
+
}, (err) => {
|
|
1261
|
+
queue.invalid = true;
|
|
1262
|
+
if (tempFile) {
|
|
1263
|
+
queueMicrotask(() => {
|
|
1264
|
+
fs.unlink(tempFile, () => { });
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
reject(err);
|
|
1268
|
+
}, 1);
|
|
1269
|
+
}));
|
|
1270
|
+
}
|
|
1271
|
+
else if (type) {
|
|
1272
|
+
const mimeType = queue.mimeType || file.mimeType;
|
|
1273
|
+
const pathname = host.getTempDir({ uuidDir: true });
|
|
1274
|
+
if (!pathname || !mimeType) {
|
|
1275
|
+
queue.invalid = true;
|
|
1276
|
+
tasks.push(Promise.reject(!pathname ? new Error("Unable to create temp directory") : (0, types_1.errorValue)("MIME not found", uri)));
|
|
1277
|
+
break;
|
|
1278
|
+
}
|
|
1279
|
+
tasks.push(new Promise((resolve, reject) => {
|
|
1280
|
+
void host.scheduleTask(queue.url || uri, { pathname, binOpts: queue.binOpts || file.binOpts }, (result) => {
|
|
1281
|
+
if (result.length > 0) {
|
|
1282
|
+
verifyBundle(bundleTorrent(host, result, mimeType, encoding));
|
|
1283
|
+
}
|
|
1284
|
+
else {
|
|
1285
|
+
queue.invalid = true;
|
|
1286
|
+
}
|
|
1287
|
+
queueMicrotask(() => {
|
|
1288
|
+
core_1.Host.removeDir(pathname);
|
|
1289
|
+
});
|
|
1290
|
+
resolve();
|
|
1291
|
+
}, (err) => {
|
|
1292
|
+
queue.invalid = true;
|
|
1293
|
+
queueMicrotask(() => {
|
|
1294
|
+
core_1.Host.removeDir(pathname);
|
|
1295
|
+
});
|
|
1296
|
+
reject(err);
|
|
1297
|
+
}, 4);
|
|
1298
|
+
}));
|
|
1299
|
+
}
|
|
1300
|
+
else if (host.canRead(uri)) {
|
|
1301
|
+
tasks.push(fs.promises.readFile(uri, encoding)
|
|
1302
|
+
.then(data => {
|
|
1303
|
+
verifyBundle(data);
|
|
1304
|
+
host.addDownload(Buffer.byteLength(data, encoding), types_1.DOWNLOAD_TYPE.DISK);
|
|
1305
|
+
})
|
|
1306
|
+
.catch(() => {
|
|
1307
|
+
queue.invalid = true;
|
|
1308
|
+
}));
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
checkEtag = false;
|
|
1312
|
+
errorPermission(host, file);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
if (tasks.length > 0) {
|
|
1317
|
+
success = await Promise.all(tasks)
|
|
1318
|
+
.then(() => true)
|
|
1319
|
+
.catch((err) => {
|
|
1320
|
+
host.writeFail(["Unable to download file", 'bundle: ' + path.basename(localUri)], err, 1024);
|
|
1321
|
+
return false;
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
else if (checkEtag && core_1.Host.isPath(localUri)) {
|
|
1325
|
+
host.completeAsyncTask();
|
|
1326
|
+
groupData.appending[localUri] = undefined;
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
if (success) {
|
|
1332
|
+
if (!host.fetchedAssets.includes(file)) {
|
|
1333
|
+
host.fetchedAssets.push(file);
|
|
1334
|
+
}
|
|
1335
|
+
void host.transformAsset(new FileThread(host, file, 1));
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
file.invalid = true;
|
|
1339
|
+
unsetContent(file);
|
|
1340
|
+
host.completeAsyncTask(error);
|
|
1341
|
+
queueMicrotask(() => {
|
|
1342
|
+
host.deleteFile(localUri, { emptyDir: true });
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
groupData.appending[localUri] = undefined;
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
const { downloading, processing } = groupData;
|
|
1349
|
+
const uri = file.uri;
|
|
1350
|
+
const processed = processing[localUri];
|
|
1351
|
+
const downloaded = downloading[uri];
|
|
1352
|
+
if ((0, types_1.isArray)(downloaded)) {
|
|
1353
|
+
copyDownload(host, file, downloaded);
|
|
1354
|
+
}
|
|
1355
|
+
if (processed) {
|
|
1356
|
+
for (const item of processed) {
|
|
1357
|
+
if (item !== file) {
|
|
1358
|
+
if (item.uri === file.uri) {
|
|
1359
|
+
item.etag = file.etag;
|
|
1360
|
+
item.lastModified = file.lastModified;
|
|
1361
|
+
}
|
|
1362
|
+
host.performAsyncTask();
|
|
1363
|
+
}
|
|
1364
|
+
void host.transformAsset(new FileThread(host, item, 1));
|
|
1365
|
+
}
|
|
1366
|
+
processing[localUri] = undefined;
|
|
1367
|
+
}
|
|
1368
|
+
else {
|
|
1369
|
+
void host.transformAsset(new FileThread(host, file, 1));
|
|
1370
|
+
}
|
|
1371
|
+
if (downloaded) {
|
|
1372
|
+
downloading[uri] = undefined;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
abort(err, preceding) {
|
|
1376
|
+
const { host, file, localUri, groupData } = this;
|
|
1377
|
+
const uri = file.uri;
|
|
1378
|
+
clearQueue(groupData.processing, localUri);
|
|
1379
|
+
clearQueue(groupData.downloading, uri);
|
|
1380
|
+
clearQueue(groupData.appending, localUri);
|
|
1381
|
+
file.invalid = true;
|
|
1382
|
+
if (!preceding) {
|
|
1383
|
+
host.completeAsyncTask();
|
|
1384
|
+
}
|
|
1385
|
+
host.writeFail(["Unable to download file", uri], err, err instanceof Error && err.message.startsWith("Timeout was exceeded") ? 16384 : 1024);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
568
1388
|
class FileThread extends core_1.AbortComponent {
|
|
569
1389
|
constructor(host, file, threadCount) {
|
|
570
1390
|
super();
|
|
@@ -644,15 +1464,15 @@ class FileManager extends core_1.Host {
|
|
|
644
1464
|
return false;
|
|
645
1465
|
}
|
|
646
1466
|
const { process: proc, download, request, error, logger } = settings;
|
|
647
|
-
if (proc
|
|
648
|
-
const limit = (0,
|
|
1467
|
+
if (proc?.thread) {
|
|
1468
|
+
const limit = (0, util_2.asInt)(proc.thread.sub_limit);
|
|
649
1469
|
if (limit > 0) {
|
|
650
1470
|
PROCESS_SUB_LIMIT = limit;
|
|
651
1471
|
}
|
|
652
1472
|
}
|
|
653
1473
|
if ((0, types_1.isPlainObject)(request)) {
|
|
654
1474
|
let { timeout, disk, buffer, connect } = request;
|
|
655
|
-
if ((timeout = (0,
|
|
1475
|
+
if ((timeout = (0, util_2.fromSeconds)(timeout)) >= 0) {
|
|
656
1476
|
HTTP_CLIENT.timeout = timeout;
|
|
657
1477
|
}
|
|
658
1478
|
if (disk) {
|
|
@@ -667,7 +1487,7 @@ class FileManager extends core_1.Host {
|
|
|
667
1487
|
request_1.loadSettings({ process: settings.process, request, download }, password);
|
|
668
1488
|
}
|
|
669
1489
|
if (error) {
|
|
670
|
-
const limit = (0,
|
|
1490
|
+
const limit = (0, util_2.asInt)(error.recursion_limit);
|
|
671
1491
|
if (limit >= 0 && limit < Infinity) {
|
|
672
1492
|
RECURSION_LIMIT = limit;
|
|
673
1493
|
}
|
|
@@ -680,16 +1500,63 @@ class FileManager extends core_1.Host {
|
|
|
680
1500
|
else if (id && (id = +id) > 0) {
|
|
681
1501
|
SESSION_LIMIT = Math.pow(10, id);
|
|
682
1502
|
}
|
|
1503
|
+
if (logger.progress) {
|
|
1504
|
+
let { scroll_buffer, max_width, use_color, text_wrap, color, bg_color, raw_mode, box_char } = logger.progress;
|
|
1505
|
+
if ((scroll_buffer = (0, util_2.asInt)(scroll_buffer)) >= 0 && scroll_buffer <= 16) {
|
|
1506
|
+
LOGGER.PROGRESS_SCROLLBUFFER = scroll_buffer;
|
|
1507
|
+
}
|
|
1508
|
+
if (max_width === 'auto' || max_width === '100%') {
|
|
1509
|
+
LOGGER.PROGRESS_MAXWIDTH = Infinity;
|
|
1510
|
+
}
|
|
1511
|
+
else if ((max_width = (0, util_2.asInt)(max_width)) >= 10) {
|
|
1512
|
+
LOGGER.PROGRESS_MAXWIDTH = max_width;
|
|
1513
|
+
}
|
|
1514
|
+
if (typeof use_color === 'boolean') {
|
|
1515
|
+
LOGGER.PROGRESS_USECOLOR = use_color;
|
|
1516
|
+
}
|
|
1517
|
+
switch (text_wrap) {
|
|
1518
|
+
case 'ellipsis':
|
|
1519
|
+
case 'nowrap':
|
|
1520
|
+
case 'ellipsis-end':
|
|
1521
|
+
case 'nowrap-end':
|
|
1522
|
+
LOGGER.PROGRESS_TEXTWRAP = text_wrap;
|
|
1523
|
+
break;
|
|
1524
|
+
}
|
|
1525
|
+
if ((0, types_1.isString)(color)) {
|
|
1526
|
+
LOGGER.PROGRESS_COLOR = color;
|
|
1527
|
+
}
|
|
1528
|
+
if ((0, types_1.isString)(bg_color)) {
|
|
1529
|
+
LOGGER.PROGRESS_BGCOLOR = bg_color;
|
|
1530
|
+
}
|
|
1531
|
+
if ((0, types_1.isString)(box_char) && box_char.length === 1) {
|
|
1532
|
+
LOGGER.PROGRESS_BOXCHAR = box_char;
|
|
1533
|
+
}
|
|
1534
|
+
if (typeof raw_mode === 'boolean') {
|
|
1535
|
+
LOGGER.PROGRESS_RAWMODE = raw_mode;
|
|
1536
|
+
if (raw_mode && core_1.Host.PLATFORM_WIN32) {
|
|
1537
|
+
require('readline').emitKeypressEvents(PROCESS_STDIN);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
683
1541
|
}
|
|
684
|
-
|
|
1542
|
+
const { title, value, message } = this.LOG_FORMAT;
|
|
1543
|
+
LOGGER.TITLE_WIDTH = title.width;
|
|
1544
|
+
LOGGER.TITLE_SEP = title.braces;
|
|
1545
|
+
LOGGER.VALUE_WIDTH = value.width;
|
|
1546
|
+
const [L, R] = message.braces;
|
|
1547
|
+
const Lch = L.trim();
|
|
1548
|
+
const Rch = R.trim();
|
|
1549
|
+
LOGGER.MESSAGE_SEP = Lch.length + Rch.length === 1 ? ` ${Rch + Lch} ` : (R ? R[0] === ' ' ? R : ' ' + R.trimEnd() : '') + (L ? L[L.length - 1] === ' ' ? L : L.trimStart() + ' ' : '');
|
|
1550
|
+
LOGGER.MESSAGE_SEP_START = Lch.trimEnd().length;
|
|
685
1551
|
LOG_TIMEELAPSED = this.hasLogType(128);
|
|
686
1552
|
LOG_TIMEPROCESS = this.hasLogType(256);
|
|
1553
|
+
setLogMinWidth();
|
|
687
1554
|
return true;
|
|
688
1555
|
}
|
|
689
1556
|
static sanitizeAssets(assets, exclusions = []) {
|
|
690
|
-
|
|
1557
|
+
for (const item of assets) {
|
|
691
1558
|
if ((0, types_1.ignoreFlag)(item.flags)) {
|
|
692
|
-
|
|
1559
|
+
continue;
|
|
693
1560
|
}
|
|
694
1561
|
const initialValue = item.initialValue;
|
|
695
1562
|
for (const attr in initialValue) {
|
|
@@ -725,7 +1592,7 @@ class FileManager extends core_1.Host {
|
|
|
725
1592
|
break;
|
|
726
1593
|
}
|
|
727
1594
|
}
|
|
728
|
-
}
|
|
1595
|
+
}
|
|
729
1596
|
return assets;
|
|
730
1597
|
}
|
|
731
1598
|
static async writeChecksum(root, to, options) {
|
|
@@ -748,13 +1615,13 @@ class FileManager extends core_1.Host {
|
|
|
748
1615
|
if (recursive === 1 && path.basename(pathname) === filename) {
|
|
749
1616
|
continue;
|
|
750
1617
|
}
|
|
751
|
-
const current = await this.readHash(pathname, { algorithm, digest }) + ' ' + (path.sep === '\\' ? pathname
|
|
1618
|
+
const current = await this.readHash(pathname, { algorithm, digest }) + ' ' + (path.sep === '\\' ? sanitizePath(pathname) : pathname).substring(root.length).replace(/^\//, '');
|
|
752
1619
|
if (verbose) {
|
|
753
1620
|
process.stdout.write(current + '\n');
|
|
754
1621
|
}
|
|
755
1622
|
output.push(current);
|
|
756
1623
|
}
|
|
757
|
-
if (output.length) {
|
|
1624
|
+
if (output.length > 0) {
|
|
758
1625
|
fs.writeFileSync(to, output.join('\n'), 'utf-8');
|
|
759
1626
|
options.outPath = to;
|
|
760
1627
|
}
|
|
@@ -777,118 +1644,7 @@ class FileManager extends core_1.Host {
|
|
|
777
1644
|
return result;
|
|
778
1645
|
}
|
|
779
1646
|
static async verifyChecksum(root, from, options) {
|
|
780
|
-
|
|
781
|
-
options = from;
|
|
782
|
-
from = undefined;
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
options || (options = {});
|
|
786
|
-
}
|
|
787
|
-
const { digest, sortBy = 0, recursive = false, ignore = [], include, exclude, verbose = true, joinRoot } = options;
|
|
788
|
-
const parent = recursive === 1 && typeof verbose !== 'number';
|
|
789
|
-
let algorithm = options.algorithm;
|
|
790
|
-
from || (from = checksumFile(algorithm));
|
|
791
|
-
if (!algorithm) {
|
|
792
|
-
switch (algorithm = path.extname(from).substring(1).toLowerCase()) {
|
|
793
|
-
case 'md5':
|
|
794
|
-
case 'sha1':
|
|
795
|
-
case 'sha224':
|
|
796
|
-
case 'sha256':
|
|
797
|
-
case 'sha384':
|
|
798
|
-
case 'sha512':
|
|
799
|
-
break;
|
|
800
|
-
default:
|
|
801
|
-
algorithm = undefined;
|
|
802
|
-
break;
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
let pass = 0, fail = [], missing = [];
|
|
806
|
-
try {
|
|
807
|
-
const filename = path.basename(from);
|
|
808
|
-
const files = [];
|
|
809
|
-
from = joinRoot ? path.join(root, filename) : path.resolve(from);
|
|
810
|
-
recurseDir(files, [root], { ignore: [...ignore, from], sortBy, recursive });
|
|
811
|
-
const items = fs.readFileSync(from, 'utf-8').split('\n').map(item => {
|
|
812
|
-
const index = item.indexOf(' ');
|
|
813
|
-
return [item.substring(0, index), path.join(root, item.substring(index + 1))];
|
|
814
|
-
});
|
|
815
|
-
const checked = include || exclude ? filterPaths(items.map(item => item[1]), include, exclude, options.dot) : null;
|
|
816
|
-
let valid;
|
|
817
|
-
for (const [previous, pathname] of items) {
|
|
818
|
-
if (checked !== null && !checked.includes(pathname) || recursive === 1 && path.basename(pathname) === filename) {
|
|
819
|
-
continue;
|
|
820
|
-
}
|
|
821
|
-
if (files.includes(pathname)) {
|
|
822
|
-
const hash = await this.readHash(pathname, { algorithm, digest });
|
|
823
|
-
if (hash !== previous) {
|
|
824
|
-
fail.push(pathname);
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
if (verbose) {
|
|
828
|
-
process.stdout.write("+" + ' ' + pathname + '\n');
|
|
829
|
-
}
|
|
830
|
-
++pass;
|
|
831
|
-
}
|
|
832
|
-
valid = true;
|
|
833
|
-
}
|
|
834
|
-
else if (!ignore.includes(pathname)) {
|
|
835
|
-
missing.push(pathname);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
if (parent) {
|
|
839
|
-
const nested = files.filter(value => path.basename(value) === filename);
|
|
840
|
-
if (nested.length) {
|
|
841
|
-
const current = items.map(item => item[1]);
|
|
842
|
-
const tasks = nested.map(async (pathname) => this.verifyChecksum(path.dirname(pathname), filename, { ...options, ignore: current, joinRoot: true, verbose: (verbose ? 1 : 0) }));
|
|
843
|
-
await Promise.all(tasks).then(group => {
|
|
844
|
-
for (const item of group) {
|
|
845
|
-
if (item) {
|
|
846
|
-
const [f, m, p] = item;
|
|
847
|
-
if (f.length) {
|
|
848
|
-
fail.push(...f);
|
|
849
|
-
}
|
|
850
|
-
if (m.length) {
|
|
851
|
-
missing.push(...m);
|
|
852
|
-
}
|
|
853
|
-
pass += p;
|
|
854
|
-
valid = true;
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
});
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
if (valid) {
|
|
861
|
-
options.outPath = from;
|
|
862
|
-
}
|
|
863
|
-
else if (options.throwsEmpty) {
|
|
864
|
-
throw checksumError(algorithm);
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
catch (err) {
|
|
868
|
-
if (options.throwsEmpty) {
|
|
869
|
-
throw err;
|
|
870
|
-
}
|
|
871
|
-
this.writeFail(["Unable to read directory", root], err, 32);
|
|
872
|
-
return null;
|
|
873
|
-
}
|
|
874
|
-
if (parent) {
|
|
875
|
-
if (fail.length) {
|
|
876
|
-
fail = Array.from(new Set(fail));
|
|
877
|
-
}
|
|
878
|
-
if (missing.length) {
|
|
879
|
-
missing = Array.from(new Set(missing));
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
if (verbose === true) {
|
|
883
|
-
const max = Math.max(...fail.concat(missing).map(item => item.length));
|
|
884
|
-
const writeLog = (items, symbol) => {
|
|
885
|
-
const [bg, fg] = symbol === "-" ? ['\x1b[31m', '\x1b[89m'] : ['\x1b[33m', '\x1b[89m'];
|
|
886
|
-
items.forEach((value, index) => process.stdout.write(bg + symbol + ` ${value.padEnd(max)} (${(index + 1).toString()})${fg}\n`));
|
|
887
|
-
};
|
|
888
|
-
writeLog(fail, "-");
|
|
889
|
-
writeLog(missing, "?");
|
|
890
|
-
}
|
|
891
|
-
return [fail, missing, pass];
|
|
1647
|
+
return doVerifyChecksum(root, from, options, false);
|
|
892
1648
|
}
|
|
893
1649
|
static createFileThread(host, file) {
|
|
894
1650
|
return new FileThread(host, file, 0);
|
|
@@ -896,7 +1652,7 @@ class FileManager extends core_1.Host {
|
|
|
896
1652
|
static setTimeout(options) {
|
|
897
1653
|
applyTimeout(PROCESS_TIMEOUT, options);
|
|
898
1654
|
}
|
|
899
|
-
static defineHttpCache({ enabled, expires, limit, limit_all, include, exclude, to_disk, purge_amount }, disk) {
|
|
1655
|
+
static defineHttpCache({ enabled, expires, limit, limit_all, include, exclude, to_disk, purge_amount }, disk = false) {
|
|
900
1656
|
const cache = disk ? DISK : MEMORY;
|
|
901
1657
|
if (typeof enabled === 'boolean') {
|
|
902
1658
|
cache.ENABLED = enabled;
|
|
@@ -904,70 +1660,37 @@ class FileManager extends core_1.Host {
|
|
|
904
1660
|
cache.EXPIRES = expires ? (0, types_1.parseExpires)(expires) : 0;
|
|
905
1661
|
cache.INCLUDE = (0, types_1.isArray)(include) ? include.slice(0) : [];
|
|
906
1662
|
cache.EXCLUDE = (0, types_1.isArray)(exclude) ? exclude.slice(0) : [];
|
|
907
|
-
|
|
908
|
-
if (value !== undefined) {
|
|
909
|
-
if (typeof value === 'string') {
|
|
910
|
-
value = (0, types_1.formatSize)(value);
|
|
911
|
-
}
|
|
912
|
-
if (value >= 0) {
|
|
913
|
-
switch (type) {
|
|
914
|
-
case 1:
|
|
915
|
-
(disk ? DISK : MEMORY).LIMIT = value;
|
|
916
|
-
break;
|
|
917
|
-
case 2:
|
|
918
|
-
MEMORY.LIMIT_ALL = value;
|
|
919
|
-
break;
|
|
920
|
-
case 3:
|
|
921
|
-
MEMORY.DISK_MIN = value;
|
|
922
|
-
break;
|
|
923
|
-
case 4:
|
|
924
|
-
MEMORY.DISK_MAX = value;
|
|
925
|
-
break;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
else if (value === -1) {
|
|
929
|
-
switch (type) {
|
|
930
|
-
case 3:
|
|
931
|
-
MEMORY.DISK_MIN = Infinity;
|
|
932
|
-
break;
|
|
933
|
-
case 4:
|
|
934
|
-
MEMORY.DISK_MAX = 0;
|
|
935
|
-
break;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
};
|
|
940
|
-
setLimit(limit, 1);
|
|
1663
|
+
setHttpCacheLimit(limit, 1, disk);
|
|
941
1664
|
if (disk) {
|
|
942
1665
|
return;
|
|
943
1666
|
}
|
|
944
|
-
|
|
1667
|
+
setHttpCacheLimit(limit_all, 2, disk);
|
|
945
1668
|
if (to_disk) {
|
|
946
1669
|
let limit_disk;
|
|
947
1670
|
if (Array.isArray(to_disk)) {
|
|
948
1671
|
[to_disk, limit_disk] = to_disk;
|
|
949
1672
|
}
|
|
950
|
-
|
|
951
|
-
|
|
1673
|
+
setHttpCacheLimit(to_disk, 3, disk);
|
|
1674
|
+
setHttpCacheLimit(limit_disk, 4, disk);
|
|
952
1675
|
}
|
|
953
|
-
if ((purge_amount = (0,
|
|
1676
|
+
if ((purge_amount = (0, util_2.asFloat)(purge_amount)) > 0) {
|
|
954
1677
|
MEMORY.PURGE = Math.min(purge_amount, 1);
|
|
955
1678
|
}
|
|
956
1679
|
}
|
|
957
1680
|
static defineHttpConnect({ timeout, retry_wait, retry_after, retry_limit, redirect_limit }) {
|
|
958
|
-
if ((timeout = (0,
|
|
1681
|
+
if ((timeout = (0, util_2.fromSeconds)(timeout)) >= 0) {
|
|
959
1682
|
HTTP_CLIENT.connectTimeout = timeout;
|
|
960
1683
|
}
|
|
961
|
-
if ((retry_wait = (0,
|
|
1684
|
+
if ((retry_wait = (0, util_2.fromSeconds)(retry_wait)) >= 0) {
|
|
962
1685
|
HTTP_CLIENT.retryWait = Math.min(retry_wait, 600 * 1000);
|
|
963
1686
|
}
|
|
964
|
-
if ((retry_after = (0,
|
|
1687
|
+
if ((retry_after = (0, util_2.fromSeconds)(retry_after)) >= 0) {
|
|
965
1688
|
HTTP_CLIENT.retryAfter = Math.min(retry_after, this.MAX_TIMEOUT);
|
|
966
1689
|
}
|
|
967
|
-
if ((retry_limit = (0,
|
|
1690
|
+
if ((retry_limit = (0, util_2.asInt)(retry_limit)) >= 0) {
|
|
968
1691
|
HTTP_CLIENT.retryLimit = retry_limit;
|
|
969
1692
|
}
|
|
970
|
-
if ((redirect_limit = (0,
|
|
1693
|
+
if ((redirect_limit = (0, util_2.asInt)(redirect_limit)) >= 0) {
|
|
971
1694
|
HTTP_CLIENT.redirectLimit = redirect_limit;
|
|
972
1695
|
}
|
|
973
1696
|
}
|
|
@@ -1003,9 +1726,10 @@ class FileManager extends core_1.Host {
|
|
|
1003
1726
|
this[_g] = null;
|
|
1004
1727
|
this[_h] = RECURSION_LIMIT;
|
|
1005
1728
|
this[_j] = new Scheduler();
|
|
1006
|
-
this[_k] =
|
|
1007
|
-
this[_l] =
|
|
1729
|
+
this[_k] = [[0, 0], [0, 0], [0, 0]];
|
|
1730
|
+
this[_l] = null;
|
|
1008
1731
|
this[_m] = {};
|
|
1732
|
+
this[_o] = null;
|
|
1009
1733
|
if (isFunction(permission)) {
|
|
1010
1734
|
postFinalize = permission;
|
|
1011
1735
|
permission = undefined;
|
|
@@ -1055,15 +1779,26 @@ class FileManager extends core_1.Host {
|
|
|
1055
1779
|
}
|
|
1056
1780
|
this.cacheToDisk = new HttpDiskCache(this, DISK.ENABLED);
|
|
1057
1781
|
this.cacheToMemory = new HttpMemoryCache(this, MEMORY.ENABLED);
|
|
1058
|
-
if (MEMORY.INCLUDE.length) {
|
|
1782
|
+
if (MEMORY.INCLUDE.length > 0) {
|
|
1059
1783
|
this.cacheToMemory.include = MEMORY.INCLUDE;
|
|
1060
1784
|
}
|
|
1061
|
-
|
|
1785
|
+
if (MEMORY.EXCLUDE.length > 0) {
|
|
1062
1786
|
this.cacheToMemory.exclude = MEMORY.EXCLUDE;
|
|
1063
1787
|
}
|
|
1064
1788
|
if (threads) {
|
|
1065
1789
|
this.setTaskLimit(threads);
|
|
1066
1790
|
}
|
|
1791
|
+
if ((0, types_1.isPlainObject)(config.log) && (0, types_1.isArray)(config.log.showDiff) && this.incremental !== "staging") {
|
|
1792
|
+
this[kDiffSource] = [
|
|
1793
|
+
config.log.showDiff.map(item => {
|
|
1794
|
+
if (!(0, types_1.hasGlob)(item)) {
|
|
1795
|
+
return item;
|
|
1796
|
+
}
|
|
1797
|
+
return isMatchRoot(item) ? pm(core_1.Permission.toPosix(item), { nocase: core_1.Host.PLATFORM_WIN32 }) : pm(sanitizePath(item), { matchBase: true, nocase: core_1.Host.PLATFORM_WIN32 });
|
|
1798
|
+
}),
|
|
1799
|
+
{}
|
|
1800
|
+
];
|
|
1801
|
+
}
|
|
1067
1802
|
const request = new request_1();
|
|
1068
1803
|
request.host = this;
|
|
1069
1804
|
this.Request = request;
|
|
@@ -1073,11 +1808,11 @@ class FileManager extends core_1.Host {
|
|
|
1073
1808
|
else {
|
|
1074
1809
|
request.init(config).apply({ client: HTTP_CLIENT });
|
|
1075
1810
|
if (!this.queued) {
|
|
1076
|
-
startMessage
|
|
1811
|
+
this.startMessage();
|
|
1077
1812
|
}
|
|
1078
1813
|
}
|
|
1079
1814
|
}
|
|
1080
|
-
*[(_b = Symbol.toStringTag, _c = kRestarting, _d = kDelayed, _e = kCleared, _f = kFinalizedState, _g = KTimerMain, _h = kRecursionLimit, _j = kScheduler, _k =
|
|
1815
|
+
*[(_b = Symbol.toStringTag, _c = kRestarting, _d = kDelayed, _e = kCleared, _f = kFinalizedState, _g = KTimerMain, _h = kRecursionLimit, _j = kScheduler, _k = kDownloadStats, _l = kReplaceMap, _m = kProcessTimeout, _o = kDiffSource, Symbol.iterator)]() {
|
|
1081
1816
|
for (const file of this.files) {
|
|
1082
1817
|
yield file;
|
|
1083
1818
|
}
|
|
@@ -1183,7 +1918,7 @@ class FileManager extends core_1.Host {
|
|
|
1183
1918
|
for (const { instance } of this.Document) {
|
|
1184
1919
|
instance.restart();
|
|
1185
1920
|
}
|
|
1186
|
-
startMessage
|
|
1921
|
+
this.startMessage();
|
|
1187
1922
|
this.processAssets(emptyDir);
|
|
1188
1923
|
}
|
|
1189
1924
|
else {
|
|
@@ -1205,7 +1940,7 @@ class FileManager extends core_1.Host {
|
|
|
1205
1940
|
const instance = new cloud_1(args[0], args[1]);
|
|
1206
1941
|
instance.host = this;
|
|
1207
1942
|
instance.init(this.config);
|
|
1208
|
-
observeFile
|
|
1943
|
+
observeFile(this, instance);
|
|
1209
1944
|
return this.Cloud = instance;
|
|
1210
1945
|
}
|
|
1211
1946
|
}
|
|
@@ -1230,16 +1965,20 @@ class FileManager extends core_1.Host {
|
|
|
1230
1965
|
this.contentToReplace.clear();
|
|
1231
1966
|
this.processing.length = 0;
|
|
1232
1967
|
this.Request.reset();
|
|
1233
|
-
|
|
1968
|
+
for (const instance of this.modules) {
|
|
1969
|
+
instance.reset();
|
|
1970
|
+
}
|
|
1234
1971
|
this.emptyDir.clear();
|
|
1235
1972
|
if (!this.restarting) {
|
|
1236
1973
|
this.close();
|
|
1237
1974
|
this._pendingResult = null;
|
|
1238
1975
|
}
|
|
1239
|
-
clearAssets
|
|
1976
|
+
clearAssets(this);
|
|
1240
1977
|
this.cleared = false;
|
|
1241
1978
|
this[kDelayed] = 0;
|
|
1242
1979
|
this[kScheduler] = new Scheduler();
|
|
1980
|
+
this[kDownloadStats] = [[0, 0], [0, 0], [0, 0]];
|
|
1981
|
+
this.clearStorage();
|
|
1243
1982
|
this.finalizeState = 0;
|
|
1244
1983
|
return true;
|
|
1245
1984
|
}
|
|
@@ -1253,8 +1992,12 @@ class FileManager extends core_1.Host {
|
|
|
1253
1992
|
if (options.all) {
|
|
1254
1993
|
value = path.resolve(value);
|
|
1255
1994
|
(options.id ? [this.assets.find(item => item.id === options.id)].filter(item => item) : this.assets.filter(item => item.localUri === value)).forEach(asset => {
|
|
1256
|
-
asset.transforms?.forEach(file =>
|
|
1257
|
-
|
|
1995
|
+
asset.transforms?.forEach(file => {
|
|
1996
|
+
this.deleteFile(file, emptyDir);
|
|
1997
|
+
});
|
|
1998
|
+
asset.descendants?.forEach(file => {
|
|
1999
|
+
this.deleteFile(file, emptyDir);
|
|
2000
|
+
});
|
|
1258
2001
|
});
|
|
1259
2002
|
}
|
|
1260
2003
|
}
|
|
@@ -1270,89 +2013,62 @@ class FileManager extends core_1.Host {
|
|
|
1270
2013
|
return;
|
|
1271
2014
|
}
|
|
1272
2015
|
this.finalizeState = 5;
|
|
1273
|
-
startMessage
|
|
2016
|
+
this.startMessage();
|
|
1274
2017
|
this.processAssets(...options.args);
|
|
1275
2018
|
}
|
|
1276
2019
|
install(name, ...args) {
|
|
1277
2020
|
if (this.aborted) {
|
|
1278
2021
|
return;
|
|
1279
2022
|
}
|
|
1280
|
-
let
|
|
2023
|
+
let Target = args.shift();
|
|
1281
2024
|
switch (name) {
|
|
1282
2025
|
case 'document':
|
|
1283
|
-
if ((
|
|
1284
|
-
|
|
1285
|
-
target = require(target);
|
|
1286
|
-
}
|
|
1287
|
-
catch (err) {
|
|
1288
|
-
this.checkPackage(err, target, ["Unable to load handler", this.moduleName], 4);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
if (isFunction(target) && target.prototype instanceof document_1) {
|
|
1292
|
-
const instance = new target(...args);
|
|
2026
|
+
if (isFunction(Target = tryPackage(this, Target, 4)) && Target.prototype instanceof document_1) {
|
|
2027
|
+
const instance = new Target(...args);
|
|
1293
2028
|
instance.host = this;
|
|
1294
2029
|
instance.init(this.getDocumentAssets(instance), this.config);
|
|
1295
|
-
observeFile
|
|
1296
|
-
this.Document.push({ instance, constructor:
|
|
2030
|
+
observeFile(this, instance);
|
|
2031
|
+
this.Document.push({ instance, constructor: Target, params: args });
|
|
1297
2032
|
return instance;
|
|
1298
2033
|
}
|
|
1299
2034
|
break;
|
|
1300
2035
|
case 'task':
|
|
1301
|
-
if ((0, types_1.
|
|
1302
|
-
|
|
1303
|
-
target = require(target);
|
|
1304
|
-
}
|
|
1305
|
-
catch (err) {
|
|
1306
|
-
this.checkPackage(err, target, ["Unable to load handler", this.moduleName], 4);
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
if (isFunction(target) && target.prototype instanceof task_1 && (0, types_1.isPlainObject)(args[0])) {
|
|
1310
|
-
const instance = new target(...args);
|
|
2036
|
+
if (isFunction(Target = tryPackage(this, Target, 4)) && Target.prototype instanceof task_1 && (0, types_1.isPlainObject)(args[0])) {
|
|
2037
|
+
const instance = new Target(...args);
|
|
1311
2038
|
instance.host = this;
|
|
1312
2039
|
instance.init(this.config);
|
|
1313
|
-
observeFile
|
|
1314
|
-
this.Task.push({ instance, constructor:
|
|
2040
|
+
observeFile(this, instance);
|
|
2041
|
+
this.Task.push({ instance, constructor: Target, params: args });
|
|
1315
2042
|
return instance;
|
|
1316
2043
|
}
|
|
1317
2044
|
break;
|
|
1318
2045
|
case 'cloud': {
|
|
1319
2046
|
const database = this.dataSourceItems.filter(item => item.source === 'cloud');
|
|
1320
2047
|
let instance;
|
|
1321
|
-
if ((0, types_1.isString)(
|
|
2048
|
+
if ((0, types_1.isString)(Target)) {
|
|
1322
2049
|
const module = args.shift();
|
|
1323
2050
|
if ((0, types_1.isObject)(module)) {
|
|
1324
|
-
if (
|
|
2051
|
+
if (Target === "@e-mc/cloud") {
|
|
1325
2052
|
instance = new cloud_1(module, database);
|
|
1326
2053
|
}
|
|
1327
|
-
else {
|
|
1328
|
-
|
|
1329
|
-
const Handler = require(target);
|
|
1330
|
-
if (isFunction(Handler) && Handler.prototype instanceof core_1.ClientDb) {
|
|
1331
|
-
instance = new Handler(module, database);
|
|
1332
|
-
}
|
|
1333
|
-
else {
|
|
1334
|
-
throw (0, types_1.errorMessage)(this.moduleName, "Not a Cloud constructor", target);
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
catch (err) {
|
|
1338
|
-
this.checkPackage(err, target, ["Unable to load handler", this.moduleName], 64);
|
|
1339
|
-
}
|
|
2054
|
+
else if (isFunction(Target = tryPackage(this, Target, 64)) && Target.prototype instanceof core_1.ClientDb) {
|
|
2055
|
+
instance = new Target(module, database);
|
|
1340
2056
|
}
|
|
1341
2057
|
}
|
|
1342
2058
|
}
|
|
1343
|
-
else if ((0, types_1.isObject)(
|
|
1344
|
-
instance = new cloud_1(
|
|
2059
|
+
else if ((0, types_1.isObject)(Target)) {
|
|
2060
|
+
instance = new cloud_1(Target, database);
|
|
1345
2061
|
}
|
|
1346
2062
|
if (instance) {
|
|
1347
2063
|
instance.host = this;
|
|
1348
2064
|
instance.init(this.config);
|
|
1349
|
-
observeFile
|
|
2065
|
+
observeFile(this, instance);
|
|
1350
2066
|
return this.Cloud = instance;
|
|
1351
2067
|
}
|
|
1352
2068
|
break;
|
|
1353
2069
|
}
|
|
1354
2070
|
case 'watch': {
|
|
1355
|
-
const instance = (0, types_1.isObject)(
|
|
2071
|
+
const instance = (0, types_1.isObject)(Target) ? new watch_1(Target) : new watch_1({ interval: Target, port: args[0], secure: { port: args[1] }, extensions: args[2] });
|
|
1356
2072
|
instance.host = this;
|
|
1357
2073
|
instance.init(this.config);
|
|
1358
2074
|
instance.whenModified = (assets, sanitize, postFinalize) => {
|
|
@@ -1395,7 +2111,7 @@ class FileManager extends core_1.Host {
|
|
|
1395
2111
|
}
|
|
1396
2112
|
mimeMap.set(mimeType, constructor);
|
|
1397
2113
|
}
|
|
1398
|
-
if (mimeMap.size) {
|
|
2114
|
+
if (mimeMap.size > 0) {
|
|
1399
2115
|
manager.install('image', mimeMap, ...params);
|
|
1400
2116
|
}
|
|
1401
2117
|
}
|
|
@@ -1417,47 +2133,29 @@ class FileManager extends core_1.Host {
|
|
|
1417
2133
|
return manager;
|
|
1418
2134
|
};
|
|
1419
2135
|
return this.Watch = instance;
|
|
1420
|
-
}
|
|
1421
|
-
case 'image': {
|
|
1422
|
-
|
|
1423
|
-
const instance = new constructor(...params);
|
|
1424
|
-
instance.host = this;
|
|
1425
|
-
instance.init(this.config);
|
|
1426
|
-
observeFile.call(this, instance);
|
|
1427
|
-
mimeMap.set(mimeType, { constructor, instance, params });
|
|
1428
|
-
return instance;
|
|
1429
|
-
};
|
|
1430
|
-
if (target instanceof Map) {
|
|
2136
|
+
}
|
|
2137
|
+
case 'image': {
|
|
2138
|
+
if (Target instanceof Map) {
|
|
1431
2139
|
const mimeMap = new Map();
|
|
1432
|
-
for (const [mimeType, constructor] of
|
|
2140
|
+
for (const [mimeType, constructor] of Target) {
|
|
1433
2141
|
if (constructor.prototype instanceof image_1) {
|
|
1434
|
-
|
|
2142
|
+
createImageInstance(this, mimeMap, mimeType, constructor, args[0]);
|
|
1435
2143
|
}
|
|
1436
2144
|
}
|
|
1437
|
-
if (mimeMap.size) {
|
|
2145
|
+
if (mimeMap.size > 0) {
|
|
1438
2146
|
this.Image = mimeMap;
|
|
1439
2147
|
}
|
|
1440
2148
|
}
|
|
1441
|
-
else {
|
|
1442
|
-
|
|
1443
|
-
try {
|
|
1444
|
-
target = require(target);
|
|
1445
|
-
}
|
|
1446
|
-
catch (err) {
|
|
1447
|
-
this.checkPackage(err, target, ["Unable to load handler", this.moduleName], 2048);
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
if (isFunction(target) && target.prototype instanceof image_1) {
|
|
1451
|
-
return createInstance(this.Image ?? (this.Image = new Map()), 'handler', target, ...args);
|
|
1452
|
-
}
|
|
2149
|
+
else if (isFunction(Target = tryPackage(this, Target, 2048)) && Target.prototype instanceof image_1) {
|
|
2150
|
+
return createImageInstance(this, this.Image ?? (this.Image = new Map()), 'handler', Target, ...args);
|
|
1453
2151
|
}
|
|
1454
2152
|
break;
|
|
1455
2153
|
}
|
|
1456
2154
|
case 'compress': {
|
|
1457
|
-
const instance = new compress_1(
|
|
2155
|
+
const instance = new compress_1(Target);
|
|
1458
2156
|
instance.host = this;
|
|
1459
2157
|
instance.init();
|
|
1460
|
-
observeFile
|
|
2158
|
+
observeFile(this, instance);
|
|
1461
2159
|
return this.Compress = instance;
|
|
1462
2160
|
}
|
|
1463
2161
|
}
|
|
@@ -1487,7 +2185,6 @@ class FileManager extends core_1.Host {
|
|
|
1487
2185
|
if (!(0, types_1.isString)(value)) {
|
|
1488
2186
|
return;
|
|
1489
2187
|
}
|
|
1490
|
-
const isSame = (a, b) => a === b || decodeURIComponent(a) === decodeURIComponent(b);
|
|
1491
2188
|
const result = (assets || this.assets).filter(item => {
|
|
1492
2189
|
const { uri, flags } = item;
|
|
1493
2190
|
if (uri && (!instance || this.hasDocument(instance, item.document)) && (!item.invalid || assets || (0, types_1.mainFlag)(flags) || (0, types_1.usingFlag)(flags) || (0, types_1.cloneFlag)(flags) || (0, types_1.watchFlag)(flags))) {
|
|
@@ -1505,35 +2202,37 @@ class FileManager extends core_1.Host {
|
|
|
1505
2202
|
return true;
|
|
1506
2203
|
}
|
|
1507
2204
|
}
|
|
1508
|
-
if (
|
|
2205
|
+
if (equalAddress(uri, value)) {
|
|
1509
2206
|
return true;
|
|
1510
2207
|
}
|
|
1511
2208
|
const indexA = uri.indexOf('#');
|
|
1512
2209
|
const indexB = value.indexOf('#');
|
|
1513
2210
|
if (indexA !== -1 || indexB !== -1) {
|
|
1514
|
-
return
|
|
2211
|
+
return equalAddress(indexA !== -1 ? uri.substring(0, indexA) : uri, indexB !== -1 ? value.substring(0, indexB) : value);
|
|
1515
2212
|
}
|
|
1516
2213
|
}
|
|
1517
2214
|
return false;
|
|
1518
2215
|
});
|
|
1519
2216
|
if (replaced) {
|
|
1520
2217
|
const map = this[kReplaceMap];
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
const
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
2218
|
+
if (map) {
|
|
2219
|
+
const target = pathname || core_1.Host.toPosix(value);
|
|
2220
|
+
const found = [];
|
|
2221
|
+
for (const relative in map) {
|
|
2222
|
+
const item = map[relative];
|
|
2223
|
+
if (origin && item.url && item.url.origin !== origin) {
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
if (path.basename(relative) === path.basename(target) && path.dirname(target).endsWith(path.dirname(relative))) {
|
|
2227
|
+
found.push([item, relative]);
|
|
2228
|
+
}
|
|
1530
2229
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
2230
|
+
if (found.length > 0) {
|
|
2231
|
+
if (result.length === 0) {
|
|
2232
|
+
return found.sort((a, b) => b[1].length - a[1].length)[0][0];
|
|
2233
|
+
}
|
|
2234
|
+
result.push(...found.map(item => item[0]));
|
|
1535
2235
|
}
|
|
1536
|
-
result.push(...found.map(item => item[0]));
|
|
1537
2236
|
}
|
|
1538
2237
|
}
|
|
1539
2238
|
return result.sort((a, b) => {
|
|
@@ -1566,7 +2265,7 @@ class FileManager extends core_1.Host {
|
|
|
1566
2265
|
removeCwd(value) {
|
|
1567
2266
|
if (typeof value === 'string') {
|
|
1568
2267
|
let baseDir = this.baseDirectory + path.sep, leading = value.substring(0, baseDir.length);
|
|
1569
|
-
if (PLATFORM_WIN32) {
|
|
2268
|
+
if (core_1.Host.PLATFORM_WIN32) {
|
|
1570
2269
|
baseDir = baseDir.toLowerCase();
|
|
1571
2270
|
leading = leading.toLowerCase();
|
|
1572
2271
|
}
|
|
@@ -1621,7 +2320,7 @@ class FileManager extends core_1.Host {
|
|
|
1621
2320
|
if (localUri && !this.assets.find(item => item.localUri === localUri && !item.invalid)) {
|
|
1622
2321
|
this.filesToRemove.add(localUri);
|
|
1623
2322
|
}
|
|
1624
|
-
this[kReplaceMap][core_1.Host.joinPath(file.pathname, file.filename)] = file;
|
|
2323
|
+
(this[kReplaceMap] || (this[kReplaceMap] = {}))[core_1.Host.joinPath(file.pathname, file.filename)] = file;
|
|
1625
2324
|
}
|
|
1626
2325
|
}
|
|
1627
2326
|
unsetContent(file);
|
|
@@ -1691,7 +2390,8 @@ class FileManager extends core_1.Host {
|
|
|
1691
2390
|
this.finalizeState = 1;
|
|
1692
2391
|
this.finalize()
|
|
1693
2392
|
.then(() => {
|
|
1694
|
-
|
|
2393
|
+
this.diffMessage();
|
|
2394
|
+
const errors = collectErrors(this);
|
|
1695
2395
|
const files = Array.from(this.files).sort((a, b) => {
|
|
1696
2396
|
const sep = path.sep;
|
|
1697
2397
|
if (a.includes(sep) && !b.includes(sep)) {
|
|
@@ -1702,9 +2402,7 @@ class FileManager extends core_1.Host {
|
|
|
1702
2402
|
}
|
|
1703
2403
|
return a < b ? -1 : 1;
|
|
1704
2404
|
});
|
|
1705
|
-
|
|
1706
|
-
this.writeTimeElapsed('END', this.baseDirectory, this.startTime, errors.length > 0 ? { failed: true, ...core_1.Host.LOG_STYLE_FAIL } : { ...core_1.Host.LOG_STYLE_SUCCESS });
|
|
1707
|
-
}
|
|
2405
|
+
this.endMessage(errors);
|
|
1708
2406
|
this.resetState();
|
|
1709
2407
|
const log = this.config.log;
|
|
1710
2408
|
let useNumeric, showSize;
|
|
@@ -1712,19 +2410,46 @@ class FileManager extends core_1.Host {
|
|
|
1712
2410
|
({ useNumeric, showSize } = log);
|
|
1713
2411
|
}
|
|
1714
2412
|
const items = showSize === false ? files : files.map(name => {
|
|
1715
|
-
const size = (0,
|
|
2413
|
+
const size = (0, util_2.getSize)(path.join(this.baseDirectory, name));
|
|
1716
2414
|
return { name, size: useNumeric ? size : (0, types_1.formatSize)(size) };
|
|
1717
2415
|
});
|
|
1718
2416
|
this.emit('end', items, errors, this.collectLog());
|
|
1719
2417
|
this.done = true;
|
|
1720
2418
|
})
|
|
1721
|
-
.catch((err) =>
|
|
2419
|
+
.catch((err) => {
|
|
2420
|
+
this.abortFinalize(err);
|
|
2421
|
+
});
|
|
1722
2422
|
}
|
|
1723
2423
|
}
|
|
1724
2424
|
hasDocument(instance, document) {
|
|
1725
2425
|
const moduleName = instance.moduleName;
|
|
1726
2426
|
return document === moduleName || Array.isArray(document) && document.includes(moduleName);
|
|
1727
2427
|
}
|
|
2428
|
+
checkFilename(file, pathname = '') {
|
|
2429
|
+
let filename = file.filename;
|
|
2430
|
+
if (filename) {
|
|
2431
|
+
if (!pathname) {
|
|
2432
|
+
pathname = file.pathname || '';
|
|
2433
|
+
}
|
|
2434
|
+
const assets = this.assets;
|
|
2435
|
+
let target = matchPathname(path.join(pathname, filename)), modified;
|
|
2436
|
+
for (let i = 0, j = 1, length = assets.length; i < length; ++i) {
|
|
2437
|
+
const item = assets[i];
|
|
2438
|
+
if (item !== file && item.filename && target === matchPathname(path.join(item.pathname || '', item.filename))) {
|
|
2439
|
+
const ext = path.extname(filename);
|
|
2440
|
+
filename = path.basename(filename, ext) + '_' + j + ext;
|
|
2441
|
+
target = matchPathname(path.join(pathname, filename));
|
|
2442
|
+
modified = true;
|
|
2443
|
+
i = -1;
|
|
2444
|
+
++j;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
if (modified) {
|
|
2448
|
+
return file.filename = filename;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
return '';
|
|
2452
|
+
}
|
|
1728
2453
|
setLocalUri(file, replace) {
|
|
1729
2454
|
let uri = file.uri, type;
|
|
1730
2455
|
if (uri && !file.url && !file.content && !file.base64 && !file.dataView) {
|
|
@@ -1737,13 +2462,12 @@ class FileManager extends core_1.Host {
|
|
|
1737
2462
|
file.uri = file.url.toString();
|
|
1738
2463
|
}
|
|
1739
2464
|
catch (err) {
|
|
1740
|
-
this.writeFail([
|
|
2465
|
+
this.writeFail(["Unable to resolve file", uri], err, { type: 1024, fatal: !!file.document });
|
|
1741
2466
|
return { pathname: '', localUri: '' };
|
|
1742
2467
|
}
|
|
1743
2468
|
}
|
|
1744
2469
|
else {
|
|
1745
2470
|
try {
|
|
1746
|
-
const errorAbsolute = (value) => (0, types_1.errorValue)("Path is not absolute", value);
|
|
1747
2471
|
if (!(file.uri = core_1.Host.resolveFile(uri))) {
|
|
1748
2472
|
throw errorAbsolute(uri);
|
|
1749
2473
|
}
|
|
@@ -1760,12 +2484,15 @@ class FileManager extends core_1.Host {
|
|
|
1760
2484
|
}
|
|
1761
2485
|
}
|
|
1762
2486
|
catch (err) {
|
|
1763
|
-
this.writeFail(['Unable to resolve file location', uri], err, 32);
|
|
2487
|
+
this.writeFail(['Unable to resolve file location', uri], err, { type: 32, fatal: !!file.document });
|
|
1764
2488
|
return { pathname: '', localUri: '' };
|
|
1765
2489
|
}
|
|
1766
2490
|
}
|
|
1767
2491
|
}
|
|
1768
2492
|
const url = file.url;
|
|
2493
|
+
if (file.pathname) {
|
|
2494
|
+
file.pathname = core_1.Host.toPosix(file.pathname);
|
|
2495
|
+
}
|
|
1769
2496
|
if (url) {
|
|
1770
2497
|
if (url.protocol.startsWith('http')) {
|
|
1771
2498
|
type = 1;
|
|
@@ -1776,12 +2503,32 @@ class FileManager extends core_1.Host {
|
|
|
1776
2503
|
else if (core_1.Host.isFile(url, 's/ftp')) {
|
|
1777
2504
|
type = 3;
|
|
1778
2505
|
}
|
|
2506
|
+
let filename = file.filename;
|
|
2507
|
+
if (!filename && !file.document && type !== 4) {
|
|
2508
|
+
filename = url.pathname.split('/').pop();
|
|
2509
|
+
if (filename.includes('.')) {
|
|
2510
|
+
const mimeType = file.mimeType || core_1.Host.lookupMime(filename);
|
|
2511
|
+
if (mimeType) {
|
|
2512
|
+
file.filename = filename;
|
|
2513
|
+
file.mimeType = mimeType;
|
|
2514
|
+
this.checkFilename(file);
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
else if (file.mimeType && filename) {
|
|
2518
|
+
const ext = core_1.Host.lookupMime(file.mimeType, true);
|
|
2519
|
+
if (ext) {
|
|
2520
|
+
filename += '.' + ext;
|
|
2521
|
+
file.filename = filename;
|
|
2522
|
+
this.checkFilename(file);
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
1779
2526
|
}
|
|
1780
2527
|
file.fetchType = type;
|
|
1781
2528
|
if (file.document) {
|
|
1782
2529
|
for (const { instance } of this.Document) {
|
|
1783
|
-
if (this.hasDocument(instance, file.document)) {
|
|
1784
|
-
instance.setLocalUri
|
|
2530
|
+
if (instance.setLocalUri && this.hasDocument(instance, file.document)) {
|
|
2531
|
+
instance.setLocalUri(file, replace);
|
|
1785
2532
|
}
|
|
1786
2533
|
}
|
|
1787
2534
|
}
|
|
@@ -1869,7 +2616,7 @@ class FileManager extends core_1.Host {
|
|
|
1869
2616
|
return this.getTempDir({ pathname: url.hostname + '_' + (url.port || (url.protocol === 'https:' ? '443' : '80')), moduleDir: true, createDir });
|
|
1870
2617
|
}
|
|
1871
2618
|
setAssetContent(file, content, options) {
|
|
1872
|
-
let trailing = (0,
|
|
2619
|
+
let trailing = (0, util_1.concatString)(file.trailingContent);
|
|
1873
2620
|
if (file.document) {
|
|
1874
2621
|
for (const { instance } of this.Document) {
|
|
1875
2622
|
if (instance.resolveUri && this.hasDocument(instance, file.document)) {
|
|
@@ -1912,8 +2659,8 @@ class FileManager extends core_1.Host {
|
|
|
1912
2659
|
return content;
|
|
1913
2660
|
}
|
|
1914
2661
|
let replacing, newline;
|
|
1915
|
-
const getSeparator = (value) => newline || (newline = (0,
|
|
1916
|
-
if (content && (replacing = this.contentToReplace.get(localUri)) && replacing.length) {
|
|
2662
|
+
const getSeparator = (value) => newline || (newline = (0, util_1.getNewline)(value));
|
|
2663
|
+
if (content && (replacing = this.contentToReplace.get(localUri)) && replacing.length > 0) {
|
|
1917
2664
|
for (let i = 0, value, match; i < replacing.length; ++i) {
|
|
1918
2665
|
if ((0, types_1.isString)(value = appending[i])) {
|
|
1919
2666
|
if (replacing[i] && (match = new RegExp(replacing[i], 'i').exec(content))) {
|
|
@@ -1944,7 +2691,7 @@ class FileManager extends core_1.Host {
|
|
|
1944
2691
|
const localUri = file.localUri;
|
|
1945
2692
|
if (buffer && localUri) {
|
|
1946
2693
|
try {
|
|
1947
|
-
this.writeFile(localUri, buffer, { ...options, throwsPermission: true });
|
|
2694
|
+
void this.writeFile(localUri, buffer, { ...options, throwsPermission: true });
|
|
1948
2695
|
return file.buffer = buffer;
|
|
1949
2696
|
}
|
|
1950
2697
|
catch (err) {
|
|
@@ -2079,8 +2826,10 @@ class FileManager extends core_1.Host {
|
|
|
2079
2826
|
tasks.push(instance.tryFile(file.buffer || localUri, output, options).then(() => {
|
|
2080
2827
|
const outFile = options.outFile;
|
|
2081
2828
|
if (outFile) {
|
|
2082
|
-
if (condition?.includes('%') && (0,
|
|
2083
|
-
queueMicrotask(() =>
|
|
2829
|
+
if (condition?.includes('%') && (0, util_2.getSize)(outFile) >= (0, util_2.getSize)(localUri)) {
|
|
2830
|
+
queueMicrotask(() => {
|
|
2831
|
+
this.deleteFile(outFile);
|
|
2832
|
+
});
|
|
2084
2833
|
}
|
|
2085
2834
|
else {
|
|
2086
2835
|
this.add(outFile, file, types_1.FILE_TYPE.COMPRESSED);
|
|
@@ -2097,7 +2846,7 @@ class FileManager extends core_1.Host {
|
|
|
2097
2846
|
}
|
|
2098
2847
|
}
|
|
2099
2848
|
}
|
|
2100
|
-
if (tasks.length) {
|
|
2849
|
+
if (tasks.length > 0) {
|
|
2101
2850
|
return Promise.all(tasks);
|
|
2102
2851
|
}
|
|
2103
2852
|
}
|
|
@@ -2109,7 +2858,7 @@ class FileManager extends core_1.Host {
|
|
|
2109
2858
|
if (!this.aborted) {
|
|
2110
2859
|
if (!override) {
|
|
2111
2860
|
const processTask = this[kScheduler];
|
|
2112
|
-
if (processTask.queue.length) {
|
|
2861
|
+
if (processTask.queue.length > 0) {
|
|
2113
2862
|
processTask.transform.push([data, parent]);
|
|
2114
2863
|
return false;
|
|
2115
2864
|
}
|
|
@@ -2120,7 +2869,6 @@ class FileManager extends core_1.Host {
|
|
|
2120
2869
|
file.mimeType = mimeType;
|
|
2121
2870
|
data.mimeType = mimeType;
|
|
2122
2871
|
}
|
|
2123
|
-
const errorAsset = (instance, err, type = 4) => rejectModule.call(instance, err, type, path.basename(localUri));
|
|
2124
2872
|
if (file.tasks) {
|
|
2125
2873
|
const taskName = [];
|
|
2126
2874
|
let handler;
|
|
@@ -2132,12 +2880,16 @@ class FileManager extends core_1.Host {
|
|
|
2132
2880
|
if (this.openThread(instance, data, this.getProcessTimeout(handler))) {
|
|
2133
2881
|
instance.using(data)
|
|
2134
2882
|
.finally(() => this.closeThread(instance, data))
|
|
2135
|
-
.catch((err) =>
|
|
2883
|
+
.catch((err) => {
|
|
2884
|
+
errorAsset(instance, err, localUri);
|
|
2885
|
+
});
|
|
2136
2886
|
}
|
|
2137
2887
|
}
|
|
2138
2888
|
else if (!this.aborted) {
|
|
2139
2889
|
this.addProcessTimeout(instance, file, this.getProcessTimeout(handler));
|
|
2140
|
-
await instance.using(data).catch((err) =>
|
|
2890
|
+
await instance.using(data).catch((err) => {
|
|
2891
|
+
errorAsset(instance, err, localUri);
|
|
2892
|
+
});
|
|
2141
2893
|
}
|
|
2142
2894
|
taskName.push(moduleName);
|
|
2143
2895
|
}
|
|
@@ -2155,12 +2907,16 @@ class FileManager extends core_1.Host {
|
|
|
2155
2907
|
if (this.openThread(instance, data, this.getProcessTimeout(handler))) {
|
|
2156
2908
|
instance.using(data, command)
|
|
2157
2909
|
.finally(() => this.closeThread(instance, data))
|
|
2158
|
-
.catch((err) =>
|
|
2910
|
+
.catch((err) => {
|
|
2911
|
+
errorAsset(instance, err, localUri, 2048);
|
|
2912
|
+
});
|
|
2159
2913
|
}
|
|
2160
2914
|
}
|
|
2161
2915
|
else if (!this.aborted) {
|
|
2162
2916
|
this.addProcessTimeout(instance, file, this.getProcessTimeout(handler));
|
|
2163
|
-
await instance.using(data, command).catch((err) =>
|
|
2917
|
+
await instance.using(data, command).catch((err) => {
|
|
2918
|
+
errorAsset(instance, err, localUri, 2048);
|
|
2919
|
+
});
|
|
2164
2920
|
}
|
|
2165
2921
|
}
|
|
2166
2922
|
}
|
|
@@ -2175,12 +2931,16 @@ class FileManager extends core_1.Host {
|
|
|
2175
2931
|
if (this.openThread(instance, data, this.getProcessTimeout(handler))) {
|
|
2176
2932
|
instance.using(data)
|
|
2177
2933
|
.finally(() => this.closeThread(instance, data))
|
|
2178
|
-
.catch((err) =>
|
|
2934
|
+
.catch((err) => {
|
|
2935
|
+
errorAsset(instance, err, localUri);
|
|
2936
|
+
});
|
|
2179
2937
|
}
|
|
2180
2938
|
}
|
|
2181
2939
|
else if (!this.aborted) {
|
|
2182
2940
|
this.addProcessTimeout(instance, file, this.getProcessTimeout(handler));
|
|
2183
|
-
await instance.using(data).catch((err) =>
|
|
2941
|
+
await instance.using(data).catch((err) => {
|
|
2942
|
+
errorAsset(instance, err, localUri);
|
|
2943
|
+
});
|
|
2184
2944
|
}
|
|
2185
2945
|
}
|
|
2186
2946
|
}
|
|
@@ -2227,7 +2987,7 @@ class FileManager extends core_1.Host {
|
|
|
2227
2987
|
if (index !== -1) {
|
|
2228
2988
|
this.processing.splice(index, 1);
|
|
2229
2989
|
}
|
|
2230
|
-
data.queuedTasks
|
|
2990
|
+
for (const task of data.queuedTasks) {
|
|
2231
2991
|
try {
|
|
2232
2992
|
task();
|
|
2233
2993
|
}
|
|
@@ -2235,7 +2995,7 @@ class FileManager extends core_1.Host {
|
|
|
2235
2995
|
this.writeFail(["Unable to perform task", path.basename(this.getLocalUri(data))], err);
|
|
2236
2996
|
}
|
|
2237
2997
|
this.removeAsyncTask();
|
|
2238
|
-
}
|
|
2998
|
+
}
|
|
2239
2999
|
this.performFinalize();
|
|
2240
3000
|
return true;
|
|
2241
3001
|
}
|
|
@@ -2284,7 +3044,7 @@ class FileManager extends core_1.Host {
|
|
|
2284
3044
|
result = value;
|
|
2285
3045
|
}
|
|
2286
3046
|
else if (typeof value === 'string') {
|
|
2287
|
-
if ((result = (0,
|
|
3047
|
+
if ((result = (0, util_2.byteLength)(value, encoding)) === 0) {
|
|
2288
3048
|
return 0;
|
|
2289
3049
|
}
|
|
2290
3050
|
}
|
|
@@ -2347,18 +3107,21 @@ class FileManager extends core_1.Host {
|
|
|
2347
3107
|
return callback;
|
|
2348
3108
|
};
|
|
2349
3109
|
if (this.aborted) {
|
|
3110
|
+
this.clearStorage();
|
|
2350
3111
|
const pending = this._pendingResult;
|
|
2351
3112
|
if (pending) {
|
|
2352
|
-
queueMicrotask(() =>
|
|
3113
|
+
queueMicrotask(() => {
|
|
3114
|
+
abortedHost(this);
|
|
3115
|
+
});
|
|
2353
3116
|
this._pendingResult = null;
|
|
2354
3117
|
return pending;
|
|
2355
3118
|
}
|
|
2356
3119
|
return new Promise(resolve => {
|
|
2357
3120
|
this.on('end', listener(resolve));
|
|
2358
3121
|
queueMicrotask(() => {
|
|
2359
|
-
if (!abortedHost
|
|
3122
|
+
if (!abortedHost(this)) {
|
|
2360
3123
|
this.restarting = false;
|
|
2361
|
-
this.emit('end', [], collectErrors
|
|
3124
|
+
this.emit('end', [], collectErrors(this), this.collectLog());
|
|
2362
3125
|
this.done = true;
|
|
2363
3126
|
}
|
|
2364
3127
|
});
|
|
@@ -2378,7 +3141,7 @@ class FileManager extends core_1.Host {
|
|
|
2378
3141
|
}
|
|
2379
3142
|
this.finalizeState = 0;
|
|
2380
3143
|
case 2:
|
|
2381
|
-
resetAssets
|
|
3144
|
+
resetAssets(this);
|
|
2382
3145
|
break;
|
|
2383
3146
|
}
|
|
2384
3147
|
return this._pendingResult || (this._pendingResult = new Promise((resolve, reject) => {
|
|
@@ -2392,9 +3155,10 @@ class FileManager extends core_1.Host {
|
|
|
2392
3155
|
}
|
|
2393
3156
|
}));
|
|
2394
3157
|
}
|
|
2395
|
-
processAssets(emptyDir, targeted) {
|
|
3158
|
+
processAssets(emptyDir = false, targeted) {
|
|
3159
|
+
var _p;
|
|
2396
3160
|
if (this.aborted) {
|
|
2397
|
-
abortedHost
|
|
3161
|
+
abortedHost(this);
|
|
2398
3162
|
return;
|
|
2399
3163
|
}
|
|
2400
3164
|
if (this.finalizeState === 5) {
|
|
@@ -2402,561 +3166,127 @@ class FileManager extends core_1.Host {
|
|
|
2402
3166
|
}
|
|
2403
3167
|
else if (this._pendingResult) {
|
|
2404
3168
|
return;
|
|
2405
|
-
}
|
|
2406
|
-
if (!this.canWrite(this.baseDirectory, { ownPermissionOnly: true })) {
|
|
2407
|
-
this.writeFail("Unsupported access", new Error(this.baseDirectory), 8192);
|
|
2408
|
-
this.cleared = true;
|
|
2409
|
-
if (this.queued) {
|
|
2410
|
-
this.joinQueue({ reject: true });
|
|
2411
|
-
}
|
|
2412
|
-
return;
|
|
2413
|
-
}
|
|
2414
|
-
switch (this.finalizeState) {
|
|
2415
|
-
case 0:
|
|
2416
|
-
if (this.delayed === 0 && !this.cleared) {
|
|
2417
|
-
break;
|
|
2418
|
-
}
|
|
2419
|
-
case 1:
|
|
2420
|
-
case 3:
|
|
2421
|
-
case 4:
|
|
2422
|
-
return;
|
|
2423
|
-
case 2:
|
|
2424
|
-
resetAssets
|
|
2425
|
-
break;
|
|
2426
|
-
}
|
|
2427
|
-
if (this.queued) {
|
|
2428
|
-
const length = arguments.length;
|
|
2429
|
-
const args = new Array(length);
|
|
2430
|
-
for (let i = 0; i < length; ++i) {
|
|
2431
|
-
args[i] = arguments[i];
|
|
2432
|
-
}
|
|
2433
|
-
if (this.joinQueue({ args })) {
|
|
2434
|
-
this.finalizeState = 4;
|
|
2435
|
-
return;
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
if (targeted) {
|
|
2439
|
-
this.using(true, ...targeted);
|
|
2440
|
-
}
|
|
2441
|
-
this.clearProcessTimeout();
|
|
2442
|
-
this[KTimerMain] = setInterval(() => {
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
}
|
|
2447
|
-
const currentTime = Date.now();
|
|
2448
|
-
let aborted;
|
|
2449
|
-
for (let i = 0; i < processing.length; ++i) {
|
|
2450
|
-
const data = processing[i];
|
|
2451
|
-
const file = data.file;
|
|
2452
|
-
const processModule = file.processModule;
|
|
2453
|
-
let expired = processTimeout > 0 && currentTime - data.startTime >= processTimeout, moduleName;
|
|
2454
|
-
if (processModule && !expired) {
|
|
2455
|
-
for (const name in processModule) {
|
|
2456
|
-
const { startTime, timeout } = processModule[name];
|
|
2457
|
-
if (timeout > 0 && currentTime - startTime >= timeout) {
|
|
2458
|
-
moduleName = name;
|
|
2459
|
-
expired = true;
|
|
2460
|
-
break;
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
if (expired || data.aborted) {
|
|
2465
|
-
let threadCount = data.threadCount + data.queuedTasks.length;
|
|
2466
|
-
while (threadCount-- > 0) {
|
|
2467
|
-
this.removeAsyncTask();
|
|
2468
|
-
}
|
|
2469
|
-
file.invalid = true;
|
|
2470
|
-
const localUri = file.localUri;
|
|
2471
|
-
if (expired) {
|
|
2472
|
-
data.abort(new Error("Timeout was exceeded"));
|
|
2473
|
-
if (localUri) {
|
|
2474
|
-
this.deleteFile(localUri, { id: file.id, emptyDir: true, all: true });
|
|
2475
|
-
}
|
|
2476
|
-
}
|
|
2477
|
-
(moduleName && this.find(moduleName) || this).formatFail(16384, "FAIL!", ["Unable to process file", moduleName || 'main'], (0, types_1.errorValue)(expired ? "Timeout was exceeded" : "Aborted", localUri), { queue: false, startTime: data.startTime });
|
|
2478
|
-
processing.splice(i--, 1);
|
|
2479
|
-
aborted = true;
|
|
2480
|
-
}
|
|
2481
|
-
}
|
|
2482
|
-
if (this.processing.length === 0 && this.aborted) {
|
|
2483
|
-
this.performFinalize(true);
|
|
2484
|
-
}
|
|
2485
|
-
else if (aborted) {
|
|
2486
|
-
this.performFinalize();
|
|
2487
|
-
}
|
|
2488
|
-
}, types_1.THRESHOLD.FILEMANAGER_INTERVAL);
|
|
2489
|
-
const { assets, cacheToDisk, cacheToMemory, fetchedAssets, Watch: watch } = this;
|
|
2490
|
-
const downloadable = new Map();
|
|
2491
|
-
const completed = Object.create(null);
|
|
2492
|
-
const processing = Object.create(null);
|
|
2493
|
-
const downloading = Object.create(null);
|
|
2494
|
-
const appending = Object.create(null);
|
|
2495
|
-
const bundling = Object.create(null);
|
|
2496
|
-
const originCount = Object.create(null);
|
|
2497
|
-
const emptied = [this.baseDirectory];
|
|
2498
|
-
const staging = this[kIncremental] === "staging";
|
|
2499
|
-
const incremental = this.config.incremental;
|
|
2500
|
-
const isCacheable = (file) => file.initialValue?.cacheable !== false;
|
|
2501
|
-
const hasIncremental = (value) => value === "etag" || value === "exists";
|
|
2502
|
-
let cacheable = false, cacheOpen = false, cacheEtag = false;
|
|
2503
|
-
if (!staging) {
|
|
2504
|
-
cacheable = this[kRecursionLimit] === RECURSION_LIMIT;
|
|
2505
|
-
if (cacheable) {
|
|
2506
|
-
if (cacheOpen = hasIncremental(incremental)) {
|
|
2507
|
-
this[kIncremental] = incremental;
|
|
2508
|
-
}
|
|
2509
|
-
cacheEtag = incremental === "etag";
|
|
2510
|
-
}
|
|
2511
|
-
else {
|
|
2512
|
-
this[kIncremental] = "none";
|
|
2513
|
-
}
|
|
2514
|
-
}
|
|
2515
|
-
const targeting = this._usingObjects.size > 0;
|
|
2516
|
-
const hasEtag = (file) => {
|
|
2517
|
-
if (!cacheable || !(0, types_1.existsFlag)(file.flags)) {
|
|
2518
|
-
return false;
|
|
2519
|
-
}
|
|
2520
|
-
switch (file.incremental) {
|
|
2521
|
-
case false:
|
|
2522
|
-
case "none":
|
|
2523
|
-
case "exists":
|
|
2524
|
-
case "staging":
|
|
2525
|
-
return false;
|
|
2526
|
-
case "etag":
|
|
2527
|
-
return true;
|
|
2528
|
-
default:
|
|
2529
|
-
return cacheEtag;
|
|
2530
|
-
}
|
|
2531
|
-
};
|
|
2532
|
-
const applyHeaders = (file, headers, lastModified, mainEtag) => {
|
|
2533
|
-
let contentLength = headers['content-length'];
|
|
2534
|
-
if ((contentLength = parseInt(contentLength)) > 0) {
|
|
2535
|
-
file.contentLength = contentLength;
|
|
2536
|
-
}
|
|
2537
|
-
else {
|
|
2538
|
-
contentLength = 0;
|
|
2539
|
-
}
|
|
2540
|
-
const etag = headers.etag;
|
|
2541
|
-
if (etag) {
|
|
2542
|
-
if (mainEtag) {
|
|
2543
|
-
CACHE_ETAG[file.uri] = etag;
|
|
2544
|
-
}
|
|
2545
|
-
return file.etag = etag;
|
|
2546
|
-
}
|
|
2547
|
-
if (lastModified && watch) {
|
|
2548
|
-
return file.lastModified = headers['last-modified'];
|
|
2549
|
-
}
|
|
2550
|
-
};
|
|
2551
|
-
const checkQueue = (file, localUri, pathname, content) => {
|
|
2552
|
-
var _o;
|
|
2553
|
-
if (!createFolder(file, pathname)) {
|
|
2554
|
-
return true;
|
|
2555
|
-
}
|
|
2556
|
-
const { bundleId, bundleIndex = -1 } = file;
|
|
2557
|
-
if (!(0, types_1.isEmpty)(bundleId) && bundleIndex >= 0) {
|
|
2558
|
-
const items = appending[localUri] || (appending[localUri] = []);
|
|
2559
|
-
bundling[_o = file.uri] || (bundling[_o] = []);
|
|
2560
|
-
if (bundleIndex > 0) {
|
|
2561
|
-
items[bundleIndex - 1] = file;
|
|
2562
|
-
let url, parent;
|
|
2563
|
-
if (file.fetchType === 1 && (cacheToDisk.has(url = file.url) || cacheToMemory.has(url)) && (parent = assets.find(item => item.bundleIndex === 0 && item.bundleId === bundleId))) {
|
|
2564
|
-
(parent.bundleQueue || (parent.bundleQueue = [])).push(new Promise(resolve => {
|
|
2565
|
-
this.Request.open(url, { method: 'HEAD', httpVersion: 1 })
|
|
2566
|
-
.on('response', res => {
|
|
2567
|
-
if (res.statusCode < 300) {
|
|
2568
|
-
applyHeaders(file, res.headers);
|
|
2569
|
-
}
|
|
2570
|
-
resolve(file);
|
|
2571
|
-
})
|
|
2572
|
-
.on('error', () => resolve(file))
|
|
2573
|
-
.on('timeout', () => resolve(file));
|
|
2574
|
-
}));
|
|
2575
|
-
}
|
|
2576
|
-
return true;
|
|
2577
|
-
}
|
|
2578
|
-
}
|
|
2579
|
-
else if (!content && file.filename) {
|
|
2580
|
-
const previous = completed[localUri];
|
|
2581
|
-
if (previous) {
|
|
2582
|
-
if (file.uri === previous.uri) {
|
|
2583
|
-
file.etag = previous.etag;
|
|
2584
|
-
file.lastModified = previous.lastModified;
|
|
2585
|
-
}
|
|
2586
|
-
this.transformAsset(new FileThread(this, file, 1));
|
|
2587
|
-
return true;
|
|
2588
|
-
}
|
|
2589
|
-
const queue = processing[localUri];
|
|
2590
|
-
if (queue) {
|
|
2591
|
-
queue.push(file);
|
|
2592
|
-
return true;
|
|
2593
|
-
}
|
|
2594
|
-
processing[localUri] = [file];
|
|
2595
|
-
}
|
|
2596
|
-
return false;
|
|
2597
|
-
};
|
|
2598
|
-
const copyDownload = (file, queued) => {
|
|
2599
|
-
const uriMap = new Map();
|
|
2600
|
-
for (const item of queued) {
|
|
2601
|
-
const destUri = item.localUri;
|
|
2602
|
-
let items = uriMap.get(destUri);
|
|
2603
|
-
if (!items) {
|
|
2604
|
-
const pathname = path.dirname(destUri);
|
|
2605
|
-
if (!core_1.Host.createDir(pathname)) {
|
|
2606
|
-
item.invalid = true;
|
|
2607
|
-
continue;
|
|
2608
|
-
}
|
|
2609
|
-
uriMap.set(destUri, items = []);
|
|
2610
|
-
}
|
|
2611
|
-
item.etag = file.etag;
|
|
2612
|
-
item.lastModified = file.lastModified;
|
|
2613
|
-
items.push(item);
|
|
2614
|
-
}
|
|
2615
|
-
const buffer = file.sourceUTF8 || file.buffer;
|
|
2616
|
-
for (const [destUri, items] of uriMap) {
|
|
2617
|
-
try {
|
|
2618
|
-
if (buffer) {
|
|
2619
|
-
fs.writeFileSync(destUri, buffer);
|
|
2620
|
-
}
|
|
2621
|
-
else {
|
|
2622
|
-
fs.copyFileSync(file.localUri, destUri);
|
|
2623
|
-
}
|
|
2624
|
-
for (const queue of items) {
|
|
2625
|
-
this.performAsyncTask();
|
|
2626
|
-
this.transformAsset(new FileThread(this, queue, 1));
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2629
|
-
catch (err) {
|
|
2630
|
-
items.forEach(queue => queue.invalid = true);
|
|
2631
|
-
this.writeFail([buffer ? "Unable to write buffer" : "Unable to copy file", path.basename(file.localUri)], err, 32);
|
|
2632
|
-
}
|
|
2633
|
-
}
|
|
2634
|
-
};
|
|
2635
|
-
const processQueue = async (file, localUri) => {
|
|
2636
|
-
completed[localUri] = file;
|
|
2637
|
-
if (file.bundleIndex === 0 && !(0, types_1.isEmpty)(file.bundleId)) {
|
|
2638
|
-
this.setAssetContent(file, this.getUTF8String(file, localUri));
|
|
2639
|
-
const bundleQueue = file.bundleQueue;
|
|
2640
|
-
let success = true, error, checkEtag = !file.trailingContent && hasEtag(file);
|
|
2641
|
-
if (bundleQueue) {
|
|
2642
|
-
error = await Promise.all(bundleQueue).then(() => null).catch((err) => err);
|
|
2643
|
-
delete file.bundleQueue;
|
|
2644
|
-
}
|
|
2645
|
-
const items = appending[localUri];
|
|
2646
|
-
if (items) {
|
|
2647
|
-
if (error) {
|
|
2648
|
-
items.forEach(queue => queue.invalid = true);
|
|
2649
|
-
success = false;
|
|
2650
|
-
}
|
|
2651
|
-
else {
|
|
2652
|
-
const tasks = [];
|
|
2653
|
-
for (const queue of items) {
|
|
2654
|
-
const encoding = queue.encoding || (queue.encoding = 'utf-8');
|
|
2655
|
-
const { uri, fetchType: type } = queue;
|
|
2656
|
-
let tempFile;
|
|
2657
|
-
if (checkEtag && queue.trailingContent) {
|
|
2658
|
-
checkEtag = false;
|
|
2659
|
-
}
|
|
2660
|
-
const checksumValid = (buffer) => !queue.checksum || checkHash.call(this, queue.localUri || localUri, false, queue.checksum, buffer);
|
|
2661
|
-
const verifyBundle = (value, etag, checked) => {
|
|
2662
|
-
if (!queue.invalid) {
|
|
2663
|
-
if (!checked && !checksumValid(value)) {
|
|
2664
|
-
queue.invalid = true;
|
|
2665
|
-
return;
|
|
2666
|
-
}
|
|
2667
|
-
if (value instanceof Buffer) {
|
|
2668
|
-
value = value.toString(encoding);
|
|
2669
|
-
}
|
|
2670
|
-
const url = queue.url;
|
|
2671
|
-
if (etag && cacheToMemory.has(url)) {
|
|
2672
|
-
cacheToMemory.add(url, encodeURIComponent(etag), value, {
|
|
2673
|
-
encoding,
|
|
2674
|
-
contentLength: queue.contentLength,
|
|
2675
|
-
toDisk: !tempFile && isCacheable(queue) ? queue.filename || queue.localUri && path.basename(queue.localUri) : ''
|
|
2676
|
-
});
|
|
2677
|
-
}
|
|
2678
|
-
this.setAssetContent(queue, value, { localUri, bundleIndex: queue.bundleIndex, bundleReplace: queue.bundleReplace });
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
if (queue.content) {
|
|
2682
|
-
verifyBundle(queue.content);
|
|
2683
|
-
checkEtag = false;
|
|
2684
|
-
}
|
|
2685
|
-
else if (uri) {
|
|
2686
|
-
if (type === 1 || type === 2) {
|
|
2687
|
-
const url = queue.url;
|
|
2688
|
-
const options = {
|
|
2689
|
-
url,
|
|
2690
|
-
encoding,
|
|
2691
|
-
statusMessage: uri + ` (${queue.bundleIndex})`
|
|
2692
|
-
};
|
|
2693
|
-
let etag, pipeTo;
|
|
2694
|
-
if (type === 2) {
|
|
2695
|
-
options.socketPath = queue.socketPath;
|
|
2696
|
-
options.httpVersion = 1;
|
|
2697
|
-
}
|
|
2698
|
-
else if (url) {
|
|
2699
|
-
if (etag = queue.etag) {
|
|
2700
|
-
const valid = incremental !== false || file.incremental === true;
|
|
2701
|
-
const cached = valid && MEMORY.CACHE[uri];
|
|
2702
|
-
const etagDir = encodeURIComponent(etag);
|
|
2703
|
-
if (cached) {
|
|
2704
|
-
if (etagDir === cached[5]) {
|
|
2705
|
-
const source = cached[1];
|
|
2706
|
-
if (checksumValid(source)) {
|
|
2707
|
-
verifyBundle(typeof source === 'string' ? source : source.toString(encoding), '', true);
|
|
2708
|
-
this.addDownload(Buffer.byteLength(source, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
2709
|
-
continue;
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
else {
|
|
2713
|
-
cacheToMemory.clear(uri);
|
|
2714
|
-
}
|
|
2715
|
-
}
|
|
2716
|
-
if (cacheToDisk.has(url) && isCacheable(queue)) {
|
|
2717
|
-
const baseDir = path.join(this.getCacheDir(url), etagDir);
|
|
2718
|
-
pipeTo = path.join(baseDir, path.basename(localUri));
|
|
2719
|
-
try {
|
|
2720
|
-
if (valid && (0, util_1.hasSize)(pipeTo)) {
|
|
2721
|
-
const buffer = fs.readFileSync(pipeTo, { encoding });
|
|
2722
|
-
if (checksumValid(buffer)) {
|
|
2723
|
-
verifyBundle(buffer, etag, true);
|
|
2724
|
-
this.addDownload(Buffer.byteLength(buffer, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
2725
|
-
continue;
|
|
2726
|
-
}
|
|
2727
|
-
}
|
|
2728
|
-
if (!fs.existsSync(baseDir)) {
|
|
2729
|
-
fs.mkdirSync(baseDir);
|
|
2730
|
-
}
|
|
2731
|
-
tempFile = path.join(baseDir, (0, types_1.incrementUUID)());
|
|
2732
|
-
options.pipeTo = tempFile;
|
|
2733
|
-
}
|
|
2734
|
-
catch {
|
|
2735
|
-
pipeTo = undefined;
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
if ((originCount[url.origin] || 0) <= 1) {
|
|
2740
|
-
options.httpVersion = 1;
|
|
2741
|
-
}
|
|
2742
|
-
options.connected = (headers) => {
|
|
2743
|
-
etag = applyHeaders(queue, headers, true);
|
|
2744
|
-
return true;
|
|
2745
|
-
};
|
|
2746
|
-
}
|
|
2747
|
-
tasks.push(new Promise((resolve, reject) => {
|
|
2748
|
-
this.scheduleTask(url || uri, options, (data) => {
|
|
2749
|
-
if (data) {
|
|
2750
|
-
verifyBundle(data, etag);
|
|
2751
|
-
}
|
|
2752
|
-
else {
|
|
2753
|
-
queue.invalid = true;
|
|
2754
|
-
}
|
|
2755
|
-
const downloaded = bundling[uri];
|
|
2756
|
-
if ((0, types_1.isArray)(downloaded)) {
|
|
2757
|
-
if (data && !queue.invalid) {
|
|
2758
|
-
if (typeof data === 'string') {
|
|
2759
|
-
queue.sourceUTF8 = data;
|
|
2760
|
-
}
|
|
2761
|
-
else {
|
|
2762
|
-
queue.buffer = data;
|
|
2763
|
-
}
|
|
2764
|
-
copyDownload(queue, downloaded);
|
|
2765
|
-
}
|
|
2766
|
-
else {
|
|
2767
|
-
downloaded.forEach(item => item.invalid = true);
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
if (tempFile && (!pipeTo || core_1.Host.isPath(pipeTo) || !core_1.Host.renameFile(tempFile, pipeTo, false))) {
|
|
2771
|
-
queueMicrotask(() => fs.unlink(tempFile, () => { }));
|
|
2772
|
-
}
|
|
2773
|
-
resolve();
|
|
2774
|
-
}, (err) => {
|
|
2775
|
-
queue.invalid = true;
|
|
2776
|
-
if (tempFile) {
|
|
2777
|
-
queueMicrotask(() => fs.unlink(tempFile, () => { }));
|
|
2778
|
-
}
|
|
2779
|
-
reject(err);
|
|
2780
|
-
}, 1);
|
|
2781
|
-
}));
|
|
2782
|
-
}
|
|
2783
|
-
else if (type) {
|
|
2784
|
-
const mimeType = queue.mimeType || file.mimeType;
|
|
2785
|
-
const pathname = this.getTempDir({ uuidDir: true });
|
|
2786
|
-
if (!pathname || !mimeType) {
|
|
2787
|
-
queue.invalid = true;
|
|
2788
|
-
tasks.push(Promise.reject(!pathname ? new Error("Unable to create temp directory") : (0, types_1.errorValue)("MIME not found", uri)));
|
|
2789
|
-
break;
|
|
2790
|
-
}
|
|
2791
|
-
tasks.push(new Promise((resolve, reject) => {
|
|
2792
|
-
this.scheduleTask(queue.url || uri, { pathname, binOpts: queue.binOpts || file.binOpts }, (result) => {
|
|
2793
|
-
if (result.length) {
|
|
2794
|
-
verifyBundle(bundleTorrent.call(this, result, mimeType, encoding));
|
|
2795
|
-
}
|
|
2796
|
-
else {
|
|
2797
|
-
queue.invalid = true;
|
|
2798
|
-
}
|
|
2799
|
-
queueMicrotask(() => core_1.Host.removeDir(pathname));
|
|
2800
|
-
resolve();
|
|
2801
|
-
}, (err) => {
|
|
2802
|
-
queue.invalid = true;
|
|
2803
|
-
queueMicrotask(() => core_1.Host.removeDir(pathname));
|
|
2804
|
-
reject(err);
|
|
2805
|
-
}, 4);
|
|
2806
|
-
}));
|
|
2807
|
-
}
|
|
2808
|
-
else if (this.canRead(uri)) {
|
|
2809
|
-
tasks.push(fs.promises.readFile(uri, encoding)
|
|
2810
|
-
.then(data => {
|
|
2811
|
-
verifyBundle(data);
|
|
2812
|
-
this.addDownload(Buffer.byteLength(data, encoding), types_1.DOWNLOAD_TYPE.DISK);
|
|
2813
|
-
})
|
|
2814
|
-
.catch(() => {
|
|
2815
|
-
queue.invalid = true;
|
|
2816
|
-
}));
|
|
2817
|
-
}
|
|
2818
|
-
else {
|
|
2819
|
-
checkEtag = false;
|
|
2820
|
-
errorPermission(file);
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
if (tasks.length) {
|
|
2825
|
-
success = await Promise.all(tasks)
|
|
2826
|
-
.then(() => true)
|
|
2827
|
-
.catch((err) => {
|
|
2828
|
-
this.writeFail(["Unable to download file", 'bundle: ' + path.basename(localUri)], err, 1024);
|
|
2829
|
-
return false;
|
|
2830
|
-
});
|
|
2831
|
-
}
|
|
2832
|
-
else if (checkEtag && core_1.Host.isPath(localUri)) {
|
|
2833
|
-
this.completeAsyncTask();
|
|
2834
|
-
appending[localUri] = undefined;
|
|
2835
|
-
return;
|
|
3169
|
+
}
|
|
3170
|
+
if (!this.canWrite(this.baseDirectory, { ownPermissionOnly: true })) {
|
|
3171
|
+
this.writeFail("Unsupported access", new Error(this.baseDirectory), 8192);
|
|
3172
|
+
this.cleared = true;
|
|
3173
|
+
if (this.queued) {
|
|
3174
|
+
this.joinQueue({ reject: true });
|
|
3175
|
+
}
|
|
3176
|
+
return;
|
|
3177
|
+
}
|
|
3178
|
+
switch (this.finalizeState) {
|
|
3179
|
+
case 0:
|
|
3180
|
+
if (this.delayed === 0 && !this.cleared) {
|
|
3181
|
+
break;
|
|
3182
|
+
}
|
|
3183
|
+
case 1:
|
|
3184
|
+
case 3:
|
|
3185
|
+
case 4:
|
|
3186
|
+
return;
|
|
3187
|
+
case 2:
|
|
3188
|
+
resetAssets(this);
|
|
3189
|
+
break;
|
|
3190
|
+
}
|
|
3191
|
+
if (this.queued) {
|
|
3192
|
+
const length = arguments.length;
|
|
3193
|
+
const args = new Array(length);
|
|
3194
|
+
for (let i = 0; i < length; ++i) {
|
|
3195
|
+
args[i] = arguments[i];
|
|
3196
|
+
}
|
|
3197
|
+
if (this.joinQueue({ args })) {
|
|
3198
|
+
this.finalizeState = 4;
|
|
3199
|
+
return;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
if (targeted) {
|
|
3203
|
+
this.using(true, ...targeted);
|
|
3204
|
+
}
|
|
3205
|
+
this.clearProcessTimeout();
|
|
3206
|
+
this[KTimerMain] = setInterval(() => {
|
|
3207
|
+
if (this.finalizeState === 4) {
|
|
3208
|
+
return;
|
|
3209
|
+
}
|
|
3210
|
+
const { processing, processTimeout } = this;
|
|
3211
|
+
const currentTime = Date.now();
|
|
3212
|
+
let aborted;
|
|
3213
|
+
for (let i = 0; i < processing.length; ++i) {
|
|
3214
|
+
const data = processing[i];
|
|
3215
|
+
const file = data.file;
|
|
3216
|
+
const processModule = file.processModule;
|
|
3217
|
+
let expired = processTimeout > 0 && currentTime - data.startTime >= processTimeout, moduleName;
|
|
3218
|
+
if (processModule && !expired) {
|
|
3219
|
+
for (const name in processModule) {
|
|
3220
|
+
const { startTime, timeout } = processModule[name];
|
|
3221
|
+
if (timeout > 0 && currentTime - startTime >= timeout) {
|
|
3222
|
+
moduleName = name;
|
|
3223
|
+
expired = true;
|
|
3224
|
+
break;
|
|
2836
3225
|
}
|
|
2837
3226
|
}
|
|
2838
3227
|
}
|
|
2839
|
-
if (
|
|
2840
|
-
|
|
2841
|
-
|
|
3228
|
+
if (expired || data.aborted) {
|
|
3229
|
+
let threadCount = data.threadCount + data.queuedTasks.length;
|
|
3230
|
+
while (threadCount-- > 0) {
|
|
3231
|
+
this.removeAsyncTask();
|
|
2842
3232
|
}
|
|
2843
|
-
this.transformAsset(new FileThread(this, file, 1));
|
|
2844
|
-
}
|
|
2845
|
-
else {
|
|
2846
3233
|
file.invalid = true;
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
return;
|
|
2853
|
-
}
|
|
2854
|
-
const uri = file.uri;
|
|
2855
|
-
const processed = processing[localUri];
|
|
2856
|
-
const downloaded = downloading[uri];
|
|
2857
|
-
if ((0, types_1.isArray)(downloaded)) {
|
|
2858
|
-
copyDownload(file, downloaded);
|
|
2859
|
-
}
|
|
2860
|
-
if (processed) {
|
|
2861
|
-
for (const item of processed) {
|
|
2862
|
-
if (item !== file) {
|
|
2863
|
-
if (item.uri === file.uri) {
|
|
2864
|
-
item.etag = file.etag;
|
|
2865
|
-
item.lastModified = file.lastModified;
|
|
3234
|
+
const localUri = file.localUri;
|
|
3235
|
+
if (expired) {
|
|
3236
|
+
data.abort(new Error("Timeout was exceeded"));
|
|
3237
|
+
if (localUri) {
|
|
3238
|
+
this.deleteFile(localUri, { id: file.id, emptyDir: true, all: true });
|
|
2866
3239
|
}
|
|
2867
|
-
this.performAsyncTask();
|
|
2868
3240
|
}
|
|
2869
|
-
this.
|
|
3241
|
+
(moduleName && this.find(moduleName) || this).formatFail(16384, "FAIL!", ["Unable to process file", moduleName || 'main'], (0, types_1.errorValue)(expired ? "Timeout was exceeded" : "Aborted", localUri), { queue: false, startTime: data.startTime });
|
|
3242
|
+
processing.splice(i--, 1);
|
|
3243
|
+
aborted = true;
|
|
2870
3244
|
}
|
|
2871
|
-
processing[localUri] = undefined;
|
|
2872
|
-
}
|
|
2873
|
-
else {
|
|
2874
|
-
this.transformAsset(new FileThread(this, file, 1));
|
|
2875
3245
|
}
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
const clearQueue = (data, attr) => {
|
|
2879
|
-
if (attr && data[attr]) {
|
|
2880
|
-
data[attr].forEach(item => item.invalid = true);
|
|
2881
|
-
data[attr] = undefined;
|
|
3246
|
+
if (this.processing.length === 0 && this.aborted) {
|
|
3247
|
+
this.performFinalize(true);
|
|
2882
3248
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
const uri = file.uri;
|
|
2886
|
-
clearQueue(processing, localUri);
|
|
2887
|
-
clearQueue(downloading, uri);
|
|
2888
|
-
clearQueue(appending, localUri);
|
|
2889
|
-
file.invalid = true;
|
|
2890
|
-
if (!preceding) {
|
|
2891
|
-
this.completeAsyncTask();
|
|
3249
|
+
else if (aborted) {
|
|
3250
|
+
this.performFinalize();
|
|
2892
3251
|
}
|
|
2893
|
-
|
|
2894
|
-
};
|
|
2895
|
-
const
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
emptied.push(pathname);
|
|
2906
|
-
}
|
|
2907
|
-
else {
|
|
2908
|
-
file.invalid = true;
|
|
2909
|
-
this.writeFail("Unable to create directory", (0, types_1.errorValue)("Path not found", pathname));
|
|
2910
|
-
return false;
|
|
3252
|
+
}, types_1.THRESHOLD.FILEMANAGER_INTERVAL);
|
|
3253
|
+
const { assets, cacheToDisk, cacheToMemory, fetchedAssets } = this;
|
|
3254
|
+
const downloadable = new Map();
|
|
3255
|
+
const staging = this[kIncremental] === "staging";
|
|
3256
|
+
const incremental = this.config.incremental;
|
|
3257
|
+
const checkDest = (src, localUri) => staging || !(0, util_2.hasSameStat)(src, localUri);
|
|
3258
|
+
let cacheable = false, cacheOpen = false, cacheEtag = false;
|
|
3259
|
+
if (!staging) {
|
|
3260
|
+
cacheable = this[kRecursionLimit] === RECURSION_LIMIT;
|
|
3261
|
+
if (cacheable) {
|
|
3262
|
+
if (cacheOpen = hasIncremental(incremental)) {
|
|
3263
|
+
this[kIncremental] = incremental;
|
|
2911
3264
|
}
|
|
2912
|
-
|
|
2913
|
-
return true;
|
|
2914
|
-
};
|
|
2915
|
-
const fileReceived = (item, localUri, err, fetched, binary, checked) => {
|
|
2916
|
-
if (err) {
|
|
2917
|
-
item.invalid = true;
|
|
2918
|
-
this.completeAsyncTask(err, localUri);
|
|
2919
|
-
return;
|
|
2920
|
-
}
|
|
2921
|
-
if (item.checksum && !checked && !checkHash.call(this, localUri, false, item.checksum, item.buffer)) {
|
|
2922
|
-
item.invalid = true;
|
|
2923
|
-
this.filesToRemove.add(localUri);
|
|
2924
|
-
this.completeAsyncTask();
|
|
2925
|
-
this.writeFail(["Checksum did not match", path.basename(localUri)], (0, types_1.errorValue)(item.uri || localUri, "Invalid checksum"), { type: 32, queue: true });
|
|
2926
|
-
return;
|
|
2927
|
-
}
|
|
2928
|
-
if (fetched) {
|
|
2929
|
-
fetchedAssets.push(item);
|
|
2930
|
-
}
|
|
2931
|
-
else {
|
|
2932
|
-
this.copiedAssets.push(item);
|
|
2933
|
-
}
|
|
2934
|
-
if (binary) {
|
|
2935
|
-
this.transformAsset(new FileThread(this, item, 1));
|
|
3265
|
+
cacheEtag = incremental === "etag";
|
|
2936
3266
|
}
|
|
2937
3267
|
else {
|
|
2938
|
-
|
|
3268
|
+
this[kIncremental] = "none";
|
|
2939
3269
|
}
|
|
2940
|
-
}
|
|
3270
|
+
}
|
|
3271
|
+
const targeting = this._usingObjects.size > 0;
|
|
3272
|
+
const groupData = new ProcessGroup();
|
|
2941
3273
|
const imported = assets.filter(item => item.imported && (0, types_1.isArray)(item.imported));
|
|
2942
3274
|
for (let item of assets) {
|
|
2943
3275
|
if (item.invalid || (0, types_1.ignoreFlag)(item.flags)) {
|
|
2944
3276
|
continue;
|
|
2945
3277
|
}
|
|
2946
|
-
let
|
|
2947
|
-
if (!filename) {
|
|
2948
|
-
if (
|
|
3278
|
+
let download = this.setLocalUri(item), uri = item.uri;
|
|
3279
|
+
if (!item.filename) {
|
|
3280
|
+
if (item.fetchType !== 4) {
|
|
2949
3281
|
item.invalid = true;
|
|
2950
3282
|
continue;
|
|
2951
3283
|
}
|
|
2952
3284
|
item.filename = '';
|
|
2953
3285
|
}
|
|
2954
3286
|
if (targeting && !this.contains(item, (other) => (0, asset_1.isEqual)(item, other))) {
|
|
2955
|
-
this.setLocalUri(item);
|
|
2956
3287
|
item.invalid = true;
|
|
2957
3288
|
continue;
|
|
2958
3289
|
}
|
|
2959
|
-
let download = this.setLocalUri(item);
|
|
2960
3290
|
const localUri = download.localUri;
|
|
2961
3291
|
if (!localUri) {
|
|
2962
3292
|
item.invalid = true;
|
|
@@ -2977,7 +3307,7 @@ class FileManager extends core_1.Host {
|
|
|
2977
3307
|
item.incremental = undefined;
|
|
2978
3308
|
}
|
|
2979
3309
|
}
|
|
2980
|
-
if (valid && filename) {
|
|
3310
|
+
if (valid && item.filename) {
|
|
2981
3311
|
const etag = (cacheEtag && type !== "exists" || type === "etag") && !!uri;
|
|
2982
3312
|
if (etag && imported.some(file => file.imported.includes(uri))) {
|
|
2983
3313
|
item.incremental = "none";
|
|
@@ -2993,7 +3323,7 @@ class FileManager extends core_1.Host {
|
|
|
2993
3323
|
}
|
|
2994
3324
|
return false;
|
|
2995
3325
|
};
|
|
2996
|
-
if ((!etag || item.fetchType === 1 && ((0, types_1.isEmpty)(bundleId) || bundleIndex <= 0)) && (!
|
|
3326
|
+
if ((!etag || item.fetchType === 1 && ((0, types_1.isEmpty)(bundleId) || bundleIndex <= 0)) && (!this.Watch || !item.watch || setBuffer(item))) {
|
|
2997
3327
|
let childBundle, childDownload;
|
|
2998
3328
|
if (!(0, types_1.isEmpty)(bundleId) && bundleIndex > 0) {
|
|
2999
3329
|
const target = assets.find(parent => parent.bundleIndex === 0 && parent.bundleId === bundleId);
|
|
@@ -3029,7 +3359,7 @@ class FileManager extends core_1.Host {
|
|
|
3029
3359
|
setBuffer(item);
|
|
3030
3360
|
}
|
|
3031
3361
|
const checksumOutput = item.checksumOutput;
|
|
3032
|
-
if (core_1.Host.isPath(localUri) && (!checksumOutput || checkHash
|
|
3362
|
+
if (core_1.Host.isPath(localUri) && (!checksumOutput || checkHash(this, localUri, true, checksumOutput))) {
|
|
3033
3363
|
item.flags |= 128;
|
|
3034
3364
|
if (!etag || item.fetchType !== 1 || checksumOutput) {
|
|
3035
3365
|
if (bundleIndex === 0 && !(0, types_1.isEmpty)(bundleId)) {
|
|
@@ -3047,14 +3377,15 @@ class FileManager extends core_1.Host {
|
|
|
3047
3377
|
else if (cached) {
|
|
3048
3378
|
try {
|
|
3049
3379
|
const buffer = cached[1];
|
|
3050
|
-
if (!item.checksum || checkHash
|
|
3380
|
+
if (!item.checksum || checkHash(this, localUri, false, item.checksum, buffer)) {
|
|
3051
3381
|
fs.writeFileSync(localUri, buffer);
|
|
3052
3382
|
if (item.willChange && Buffer.isBuffer(buffer)) {
|
|
3053
3383
|
item.buffer = buffer;
|
|
3054
3384
|
}
|
|
3055
|
-
if (!(checksumOutput && (0, types_1.isEmpty)(bundleId) && checkHash
|
|
3385
|
+
if (!(checksumOutput && (0, types_1.isEmpty)(bundleId) && checkHash(this, localUri, true, checksumOutput, buffer))) {
|
|
3056
3386
|
this.performAsyncTask();
|
|
3057
|
-
|
|
3387
|
+
const target = new ProcessFile(this, item, localUri, groupData);
|
|
3388
|
+
target.received(null, incremental, true, false, true);
|
|
3058
3389
|
}
|
|
3059
3390
|
continue;
|
|
3060
3391
|
}
|
|
@@ -3082,6 +3413,10 @@ class FileManager extends core_1.Host {
|
|
|
3082
3413
|
}
|
|
3083
3414
|
downloadable.set(item, download);
|
|
3084
3415
|
}
|
|
3416
|
+
const { downloading, bundling, originCount } = groupData;
|
|
3417
|
+
const watching = !!this.Watch;
|
|
3418
|
+
const processTask = this[kScheduler];
|
|
3419
|
+
const diffSource = this[kDiffSource];
|
|
3085
3420
|
if (downloadable.size > 1 && this.Request.httpVersion !== 1) {
|
|
3086
3421
|
for (const { url } of downloadable.keys()) {
|
|
3087
3422
|
if (url?.protocol === 'https:') {
|
|
@@ -3095,47 +3430,61 @@ class FileManager extends core_1.Host {
|
|
|
3095
3430
|
break;
|
|
3096
3431
|
}
|
|
3097
3432
|
const { pathname, localUri } = download;
|
|
3433
|
+
const target = new ProcessFile(this, item, localUri, groupData);
|
|
3434
|
+
if (diffSource && core_1.Host.isPath(localUri, true) && diffSource[0].some(pattern => typeof pattern === 'string' ? pattern === item.mimeType || pattern === item.mimeType?.split('/')[1] : pattern(localUri))) {
|
|
3435
|
+
try {
|
|
3436
|
+
const encoding = image_1.isBinary(item.mimeType) ? 'base64' : item.encoding || 'utf-8';
|
|
3437
|
+
(_p = diffSource[1])[localUri] || (_p[localUri] = [fs.readFileSync(localUri, encoding), encoding]);
|
|
3438
|
+
}
|
|
3439
|
+
catch (err) {
|
|
3440
|
+
this.formatMessage(32, "WARN!", ["Unable to read file", path.basename(localUri)], err, { ...core_1.Host.LOG_STYLE_WARN });
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3098
3443
|
if (item.content) {
|
|
3099
|
-
if (!
|
|
3444
|
+
if (!target.queued(pathname, emptyDir, true)) {
|
|
3100
3445
|
const content = item.content;
|
|
3101
3446
|
item.sourceUTF8 = content;
|
|
3102
3447
|
this.performAsyncTask();
|
|
3103
|
-
fs.writeFile(localUri, content, item.encoding || (item.encoding = 'utf-8'), err =>
|
|
3448
|
+
fs.writeFile(localUri, content, item.encoding || (item.encoding = 'utf-8'), err => {
|
|
3449
|
+
target.received(err, incremental);
|
|
3450
|
+
});
|
|
3104
3451
|
}
|
|
3105
3452
|
continue;
|
|
3106
3453
|
}
|
|
3107
3454
|
if (item.dataView) {
|
|
3108
|
-
if (createFolder(
|
|
3455
|
+
if (target.createFolder(pathname, emptyDir)) {
|
|
3109
3456
|
this.performAsyncTask();
|
|
3110
3457
|
const dataView = item.dataView;
|
|
3111
3458
|
fs.writeFile(localUri, dataView, err => {
|
|
3112
3459
|
if (!err) {
|
|
3113
3460
|
item.buffer = Buffer.isBuffer(dataView) ? dataView : Buffer.from(dataView.buffer);
|
|
3114
3461
|
}
|
|
3115
|
-
|
|
3462
|
+
target.received(err, incremental, false, true);
|
|
3116
3463
|
});
|
|
3117
3464
|
}
|
|
3118
3465
|
continue;
|
|
3119
3466
|
}
|
|
3120
3467
|
if (item.base64) {
|
|
3121
|
-
if (createFolder(
|
|
3468
|
+
if (target.createFolder(pathname, emptyDir)) {
|
|
3122
3469
|
this.performAsyncTask();
|
|
3123
|
-
fs.writeFile(localUri, item.base64, 'base64', err =>
|
|
3470
|
+
fs.writeFile(localUri, item.base64, 'base64', err => {
|
|
3471
|
+
target.received(err, incremental, false, true);
|
|
3472
|
+
});
|
|
3124
3473
|
}
|
|
3125
3474
|
continue;
|
|
3126
3475
|
}
|
|
3127
3476
|
const uri = item.uri;
|
|
3128
3477
|
if (!uri) {
|
|
3129
3478
|
if (item.buffer) {
|
|
3130
|
-
if (createFolder(
|
|
3479
|
+
if (target.createFolder(pathname, emptyDir)) {
|
|
3131
3480
|
this.performAsyncTask();
|
|
3132
|
-
this.scheduleTask(localUri, item.buffer, () => {
|
|
3133
|
-
|
|
3481
|
+
void this.scheduleTask(localUri, item.buffer, () => {
|
|
3482
|
+
target.received(null, incremental, false, true);
|
|
3134
3483
|
}, (err) => {
|
|
3135
|
-
|
|
3484
|
+
target.received(err);
|
|
3136
3485
|
}).then(code => {
|
|
3137
3486
|
if (code === -1) {
|
|
3138
|
-
|
|
3487
|
+
target.received((0, types_1.errorValue)("Not able to read buffer", path.basename(localUri)));
|
|
3139
3488
|
}
|
|
3140
3489
|
});
|
|
3141
3490
|
}
|
|
@@ -3144,7 +3493,6 @@ class FileManager extends core_1.Host {
|
|
|
3144
3493
|
item.invalid = true;
|
|
3145
3494
|
continue;
|
|
3146
3495
|
}
|
|
3147
|
-
const checkDest = (src) => staging || !(0, util_1.hasSameStat)(src, localUri);
|
|
3148
3496
|
const type = item.fetchType || 0;
|
|
3149
3497
|
const bundleMain = item.bundleIndex === 0 && !(0, types_1.isEmpty)(item.bundleId);
|
|
3150
3498
|
if (type === 1 || type === 2) {
|
|
@@ -3152,15 +3500,15 @@ class FileManager extends core_1.Host {
|
|
|
3152
3500
|
if (bundling[uri] && (0, types_1.isEmpty)(item.bundleId)) {
|
|
3153
3501
|
bundling[uri].push(item);
|
|
3154
3502
|
}
|
|
3155
|
-
else if ((checkEtag = hasEtag(item)) || !
|
|
3156
|
-
if (type
|
|
3157
|
-
|
|
3503
|
+
else if ((checkEtag = hasEtag(item, cacheable, cacheEtag)) || !target.queued(pathname, emptyDir, false)) {
|
|
3504
|
+
if (type === 2 && !checkDest(uri, localUri)) {
|
|
3505
|
+
target.received(null, incremental);
|
|
3158
3506
|
}
|
|
3159
3507
|
else if (!checkEtag && downloading[uri]) {
|
|
3160
3508
|
downloading[uri].push(item);
|
|
3161
3509
|
}
|
|
3162
|
-
else if (type
|
|
3163
|
-
errorPermission(item);
|
|
3510
|
+
else if (type === 2 && !this.canRead(uri)) {
|
|
3511
|
+
errorPermission(this, item);
|
|
3164
3512
|
}
|
|
3165
3513
|
else {
|
|
3166
3514
|
if (!checkEtag) {
|
|
@@ -3173,12 +3521,11 @@ class FileManager extends core_1.Host {
|
|
|
3173
3521
|
cacheBuffer = cacheToMemory.has(url);
|
|
3174
3522
|
mainEtag = (0, types_1.mainFlag)(item.flags) && (cacheEtag || item.incremental === "etag");
|
|
3175
3523
|
}
|
|
3176
|
-
const closeResponse = () => client?.destroy();
|
|
3177
3524
|
const downloadUri = (request, etagDir) => {
|
|
3178
3525
|
if (checkEtag) {
|
|
3179
3526
|
item.flags &= ~128;
|
|
3180
3527
|
}
|
|
3181
|
-
closeResponse();
|
|
3528
|
+
closeResponse(client);
|
|
3182
3529
|
const location = request.url.toString();
|
|
3183
3530
|
request.encoding = encoding;
|
|
3184
3531
|
request.pipeTo = localUri;
|
|
@@ -3187,7 +3534,7 @@ class FileManager extends core_1.Host {
|
|
|
3187
3534
|
request.method = 'GET';
|
|
3188
3535
|
request.httpVersion = (originCount[request.url.origin] || 0) <= 1 ? 1 : undefined;
|
|
3189
3536
|
request.connected = headers => {
|
|
3190
|
-
|
|
3537
|
+
processHeaders(item, headers, watching, mainEtag);
|
|
3191
3538
|
return item.willChange || !!etagDir && (cacheDir || !item.contentLength || cacheToMemory.within(item.contentLength)) || this.hasLog('progress');
|
|
3192
3539
|
};
|
|
3193
3540
|
}
|
|
@@ -3196,14 +3543,14 @@ class FileManager extends core_1.Host {
|
|
|
3196
3543
|
request.method = undefined;
|
|
3197
3544
|
request.httpVersion = 1;
|
|
3198
3545
|
}
|
|
3199
|
-
this.scheduleTask(request.url, request, (data) => {
|
|
3546
|
+
void this.scheduleTask(request.url, request, (data) => {
|
|
3200
3547
|
if (typeof data === 'string') {
|
|
3201
3548
|
item.sourceUTF8 = data;
|
|
3202
3549
|
}
|
|
3203
3550
|
else if (data) {
|
|
3204
3551
|
item.buffer = data;
|
|
3205
3552
|
}
|
|
3206
|
-
|
|
3553
|
+
target.received(null, incremental, type === 1);
|
|
3207
3554
|
if (etagDir) {
|
|
3208
3555
|
queueMicrotask(() => {
|
|
3209
3556
|
if (cacheBuffer && data) {
|
|
@@ -3215,7 +3562,7 @@ class FileManager extends core_1.Host {
|
|
|
3215
3562
|
});
|
|
3216
3563
|
}
|
|
3217
3564
|
}, (err) => {
|
|
3218
|
-
|
|
3565
|
+
target.abort(err);
|
|
3219
3566
|
}, 1);
|
|
3220
3567
|
};
|
|
3221
3568
|
this.performAsyncTask();
|
|
@@ -3224,13 +3571,15 @@ class FileManager extends core_1.Host {
|
|
|
3224
3571
|
(function checkHeaders(href) {
|
|
3225
3572
|
const request = this.Request;
|
|
3226
3573
|
try {
|
|
3227
|
-
|
|
3228
|
-
|
|
3574
|
+
++processTask.pending;
|
|
3575
|
+
const opts = request.opts(href, { method: 'HEAD', httpVersion: 1 });
|
|
3576
|
+
(client = request.open(href, opts))
|
|
3229
3577
|
.on('response', res => {
|
|
3578
|
+
--processTask.pending;
|
|
3230
3579
|
const statusCode = res.statusCode;
|
|
3231
3580
|
if (statusCode < 300) {
|
|
3232
|
-
const etag =
|
|
3233
|
-
let etagDir =
|
|
3581
|
+
const etag = processHeaders(item, res.headers, false, mainEtag);
|
|
3582
|
+
let etagDir = null, tempDir;
|
|
3234
3583
|
if (etag) {
|
|
3235
3584
|
if (cacheDir || mainEtag) {
|
|
3236
3585
|
tempDir = this.getCacheDir(href);
|
|
@@ -3242,13 +3591,13 @@ class FileManager extends core_1.Host {
|
|
|
3242
3591
|
let buffer;
|
|
3243
3592
|
if (cached) {
|
|
3244
3593
|
if (etagDir === cached[5] && (!encoding || encoding === cached[2])) {
|
|
3245
|
-
if (item.checksum && !checkHash
|
|
3594
|
+
if (item.checksum && !checkHash(this, localUri, false, item.checksum, cached[1])) {
|
|
3246
3595
|
tempDir = undefined;
|
|
3247
3596
|
}
|
|
3248
3597
|
else {
|
|
3249
3598
|
if (checkEtag) {
|
|
3250
3599
|
this.completeAsyncTask(null, localUri);
|
|
3251
|
-
closeResponse();
|
|
3600
|
+
closeResponse(client);
|
|
3252
3601
|
return;
|
|
3253
3602
|
}
|
|
3254
3603
|
buffer = cached[1];
|
|
@@ -3262,68 +3611,56 @@ class FileManager extends core_1.Host {
|
|
|
3262
3611
|
}
|
|
3263
3612
|
}
|
|
3264
3613
|
try {
|
|
3265
|
-
const setBuffer = () => {
|
|
3266
|
-
if (typeof buffer === 'string') {
|
|
3267
|
-
item.sourceUTF8 = buffer;
|
|
3268
|
-
}
|
|
3269
|
-
else if (buffer) {
|
|
3270
|
-
item.buffer = buffer;
|
|
3271
|
-
}
|
|
3272
|
-
};
|
|
3273
3614
|
let pipeAs;
|
|
3274
|
-
if (tempDir && (0,
|
|
3615
|
+
if (tempDir && (0, util_2.hasSize)(pipeAs = path.join(tempDir, etagDir, path.basename(localUri)))) {
|
|
3275
3616
|
if (!checkEtag) {
|
|
3276
3617
|
if (cacheBuffer && !buffer) {
|
|
3277
3618
|
buffer = fs.readFileSync(pipeAs, encoding);
|
|
3278
|
-
if (item.checksum && !checkHash
|
|
3279
|
-
downloadUri(
|
|
3619
|
+
if (item.checksum && !checkHash(this, localUri, false, item.checksum, buffer)) {
|
|
3620
|
+
downloadUri(opts, etagDir);
|
|
3280
3621
|
return;
|
|
3281
3622
|
}
|
|
3282
3623
|
if (cacheToMemory.within(item.contentLength = Buffer.byteLength(buffer, encoding))) {
|
|
3283
3624
|
cacheToMemory.add(location, etagDir, buffer, { encoding, contentLength: item.contentLength, tempFile: pipeAs });
|
|
3284
3625
|
}
|
|
3285
3626
|
}
|
|
3286
|
-
if (checkDest(pipeAs)) {
|
|
3287
|
-
const writeBuffer = () => {
|
|
3288
|
-
fs.writeFileSync(localUri, buffer);
|
|
3289
|
-
this.addDownload(Buffer.byteLength(buffer, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
3290
|
-
};
|
|
3627
|
+
if (checkDest(pipeAs, localUri)) {
|
|
3291
3628
|
if (buffer) {
|
|
3292
|
-
|
|
3629
|
+
writeBufferCache(this, localUri, buffer, encoding);
|
|
3293
3630
|
}
|
|
3294
3631
|
else if (item.checksum) {
|
|
3295
3632
|
buffer = fs.readFileSync(pipeAs, encoding);
|
|
3296
|
-
if (!checkHash
|
|
3297
|
-
downloadUri(
|
|
3633
|
+
if (!checkHash(this, localUri, false, item.checksum, buffer)) {
|
|
3634
|
+
downloadUri(opts, etagDir);
|
|
3298
3635
|
return;
|
|
3299
3636
|
}
|
|
3300
|
-
|
|
3637
|
+
writeBufferCache(this, localUri, buffer, encoding);
|
|
3301
3638
|
}
|
|
3302
3639
|
else {
|
|
3303
3640
|
fs.copyFileSync(pipeAs, localUri);
|
|
3304
3641
|
this.addDownload(pipeAs, types_1.DOWNLOAD_TYPE.CACHE);
|
|
3305
3642
|
}
|
|
3306
3643
|
}
|
|
3307
|
-
if (item.willChange) {
|
|
3308
|
-
|
|
3644
|
+
if (item.willChange && buffer) {
|
|
3645
|
+
setBufferTarget(item, buffer);
|
|
3309
3646
|
}
|
|
3310
|
-
|
|
3647
|
+
target.received(null, incremental, true, false, true);
|
|
3311
3648
|
}
|
|
3312
3649
|
else {
|
|
3313
3650
|
this.completeAsyncTask(null, localUri);
|
|
3314
3651
|
}
|
|
3315
|
-
closeResponse();
|
|
3652
|
+
closeResponse(client);
|
|
3316
3653
|
return;
|
|
3317
3654
|
}
|
|
3318
3655
|
if (buffer) {
|
|
3319
|
-
|
|
3656
|
+
setBufferTarget(item, buffer);
|
|
3320
3657
|
fs.writeFileSync(localUri, buffer);
|
|
3321
3658
|
this.addDownload(Buffer.byteLength(buffer, encoding), types_1.DOWNLOAD_TYPE.CACHE);
|
|
3322
3659
|
if (checkEtag) {
|
|
3323
3660
|
item.flags &= ~128;
|
|
3324
3661
|
}
|
|
3325
|
-
|
|
3326
|
-
closeResponse();
|
|
3662
|
+
target.received(null, incremental, true, false, true);
|
|
3663
|
+
closeResponse(client);
|
|
3327
3664
|
if (pipeAs) {
|
|
3328
3665
|
fs.writeFile(pipeAs, buffer, () => { });
|
|
3329
3666
|
}
|
|
@@ -3334,10 +3671,10 @@ class FileManager extends core_1.Host {
|
|
|
3334
3671
|
}
|
|
3335
3672
|
}
|
|
3336
3673
|
}
|
|
3337
|
-
downloadUri(
|
|
3674
|
+
downloadUri(opts, etagDir);
|
|
3338
3675
|
}
|
|
3339
3676
|
else if (statusCode < 400) {
|
|
3340
|
-
closeResponse();
|
|
3677
|
+
closeResponse(client);
|
|
3341
3678
|
const location = res.headers.location;
|
|
3342
3679
|
if (location && ++redirects <= HTTP_CLIENT.redirectLimit) {
|
|
3343
3680
|
try {
|
|
@@ -3347,29 +3684,32 @@ class FileManager extends core_1.Host {
|
|
|
3347
3684
|
catch {
|
|
3348
3685
|
}
|
|
3349
3686
|
}
|
|
3350
|
-
|
|
3687
|
+
target.abort((0, types_1.errorMessage)(statusCode, "Exceeded redirect limit", url.toString()));
|
|
3351
3688
|
}
|
|
3352
3689
|
else {
|
|
3353
|
-
downloadUri(
|
|
3690
|
+
downloadUri(opts, null);
|
|
3354
3691
|
}
|
|
3355
3692
|
})
|
|
3356
3693
|
.on('error', err => {
|
|
3694
|
+
--processTask.pending;
|
|
3357
3695
|
if (!client.destroyed) {
|
|
3358
|
-
if ((0,
|
|
3359
|
-
downloadUri(
|
|
3696
|
+
if ((0, util_2.checkRetryable)(err)) {
|
|
3697
|
+
downloadUri(opts, null);
|
|
3360
3698
|
}
|
|
3361
3699
|
else {
|
|
3362
|
-
|
|
3700
|
+
target.abort(err);
|
|
3363
3701
|
}
|
|
3364
3702
|
}
|
|
3365
3703
|
})
|
|
3366
3704
|
.on('timeout', () => {
|
|
3705
|
+
--processTask.pending;
|
|
3367
3706
|
if (!client.destroyed) {
|
|
3368
|
-
downloadUri(
|
|
3707
|
+
downloadUri(opts, null);
|
|
3369
3708
|
}
|
|
3370
3709
|
});
|
|
3371
3710
|
}
|
|
3372
3711
|
catch {
|
|
3712
|
+
--processTask.pending;
|
|
3373
3713
|
downloadUri(request.opts(href), null);
|
|
3374
3714
|
}
|
|
3375
3715
|
}).bind(this)(url);
|
|
@@ -3380,30 +3720,30 @@ class FileManager extends core_1.Host {
|
|
|
3380
3720
|
}
|
|
3381
3721
|
}
|
|
3382
3722
|
}
|
|
3383
|
-
else if (type) {
|
|
3723
|
+
else if (type === 3 || type === 4) {
|
|
3384
3724
|
if (bundleMain && !item.mimeType) {
|
|
3385
|
-
|
|
3725
|
+
target.abort((0, types_1.errorValue)("MIME not found", uri), true);
|
|
3386
3726
|
}
|
|
3387
|
-
else if (!
|
|
3727
|
+
else if (!target.queued(pathname, emptyDir, false)) {
|
|
3388
3728
|
if (downloading[uri]) {
|
|
3389
3729
|
downloading[uri].push(item);
|
|
3390
3730
|
continue;
|
|
3391
3731
|
}
|
|
3392
3732
|
downloading[uri] = [];
|
|
3393
3733
|
this.performAsyncTask();
|
|
3394
|
-
this.scheduleTask(item.url || uri, { pathname, binOpts: item.binOpts }, (result) => {
|
|
3734
|
+
void this.scheduleTask(item.url || uri, { pathname, binOpts: item.binOpts }, (result) => {
|
|
3395
3735
|
if (result.length === 0) {
|
|
3396
|
-
|
|
3736
|
+
target.abort((0, types_1.errorValue)("No files were successfully downloaded", uri));
|
|
3397
3737
|
}
|
|
3398
3738
|
else if (bundleMain) {
|
|
3399
3739
|
const encoding = item.encoding || (item.encoding = 'utf-8');
|
|
3400
|
-
fs.writeFile(localUri, bundleTorrent
|
|
3740
|
+
fs.writeFile(localUri, bundleTorrent(this, result, item.mimeType, encoding), encoding, err => {
|
|
3401
3741
|
if (!err) {
|
|
3402
3742
|
fetchedAssets.push(item);
|
|
3403
|
-
|
|
3743
|
+
void target.finalize(incremental);
|
|
3404
3744
|
}
|
|
3405
3745
|
else {
|
|
3406
|
-
|
|
3746
|
+
target.abort(err);
|
|
3407
3747
|
}
|
|
3408
3748
|
});
|
|
3409
3749
|
}
|
|
@@ -3428,44 +3768,44 @@ class FileManager extends core_1.Host {
|
|
|
3428
3768
|
}
|
|
3429
3769
|
if (found) {
|
|
3430
3770
|
fetchedAssets.push(item);
|
|
3431
|
-
|
|
3771
|
+
void target.finalize(incremental);
|
|
3432
3772
|
}
|
|
3433
3773
|
else {
|
|
3434
3774
|
item.filename = '';
|
|
3435
3775
|
item.localUri = '';
|
|
3436
3776
|
item.mimeType = '';
|
|
3437
|
-
clearQueue(processing, localUri);
|
|
3777
|
+
clearQueue(groupData.processing, localUri);
|
|
3438
3778
|
clearQueue(downloading, uri);
|
|
3439
3779
|
this.completeAsyncTask();
|
|
3440
3780
|
}
|
|
3441
3781
|
}
|
|
3442
3782
|
}, (err) => {
|
|
3443
|
-
|
|
3783
|
+
target.abort(err);
|
|
3444
3784
|
}, 4);
|
|
3445
3785
|
}
|
|
3446
3786
|
}
|
|
3447
3787
|
else if (!this.canRead(uri)) {
|
|
3448
|
-
errorPermission(item);
|
|
3788
|
+
errorPermission(this, item);
|
|
3449
3789
|
}
|
|
3450
|
-
else if (!
|
|
3790
|
+
else if (!target.queued(pathname, emptyDir, false)) {
|
|
3451
3791
|
this.performAsyncTask();
|
|
3452
|
-
if (checkDest(uri)) {
|
|
3792
|
+
if (checkDest(uri, localUri)) {
|
|
3453
3793
|
fs.copyFile(uri, localUri, err => {
|
|
3454
3794
|
if (!err) {
|
|
3455
3795
|
this.addDownload(localUri, types_1.DOWNLOAD_TYPE.DISK);
|
|
3456
3796
|
}
|
|
3457
|
-
|
|
3797
|
+
target.received(err);
|
|
3458
3798
|
});
|
|
3459
3799
|
}
|
|
3460
3800
|
else {
|
|
3461
|
-
|
|
3801
|
+
target.received(null, incremental);
|
|
3462
3802
|
}
|
|
3463
3803
|
}
|
|
3464
3804
|
}
|
|
3465
3805
|
this.cleared = true;
|
|
3466
3806
|
}
|
|
3467
3807
|
updateProgress(name, ...args) {
|
|
3468
|
-
if (name === 'request' && STDOUT_CURSOR) {
|
|
3808
|
+
if (name === 'request' && this.hasLog('progress') && STDOUT_CURSOR) {
|
|
3469
3809
|
const processTask = this[kScheduler];
|
|
3470
3810
|
const status = processTask.status;
|
|
3471
3811
|
const id = args[0];
|
|
@@ -3491,39 +3831,76 @@ class FileManager extends core_1.Host {
|
|
|
3491
3831
|
else if (processTask.updated + 100 > currentTime) {
|
|
3492
3832
|
return;
|
|
3493
3833
|
}
|
|
3494
|
-
const length = status.length;
|
|
3495
3834
|
const logCurrent = (0, types_1.getLogCurrent)();
|
|
3496
|
-
const
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3835
|
+
const statusHeight = status.length;
|
|
3836
|
+
const barLength = processTask.barLength;
|
|
3837
|
+
const barIncrement = 100 / barLength;
|
|
3838
|
+
const initial = processTask.logCurrent !== logCurrent;
|
|
3839
|
+
let redraw = false, scrollHeight = 0, logDelayed;
|
|
3840
|
+
if ((logDelayed = core_1.Host.getLogDelayed()) && logDelayed.length > 0) {
|
|
3841
|
+
logDelayed = logDelayed.filter(item => typeof item[4].progressBar !== 'boolean');
|
|
3842
|
+
scrollHeight = Math.min(logDelayed.length, LOGGER.PROGRESS_SCROLLBUFFER);
|
|
3843
|
+
}
|
|
3844
|
+
else {
|
|
3845
|
+
logDelayed = null;
|
|
3846
|
+
}
|
|
3847
|
+
if (initial || statusHeight > processTask.statusHeight || scrollHeight > processTask.scrollHeight) {
|
|
3848
|
+
if (this.logState !== 0) {
|
|
3849
|
+
this.pauseLog('progress');
|
|
3850
|
+
}
|
|
3851
|
+
if (!initial) {
|
|
3852
|
+
PROCESS_STDOUT.write('\n'.repeat(statusHeight + scrollHeight - processTask.statusHeight - processTask.scrollHeight));
|
|
3853
|
+
}
|
|
3854
|
+
processTask.statusHeight = statusHeight;
|
|
3855
|
+
processTask.scrollHeight = scrollHeight;
|
|
3500
3856
|
processTask.logCurrent = logCurrent;
|
|
3501
|
-
PROCESS_STDOUT.write('\n'.repeat(redraw ? length : length - processTask.length));
|
|
3502
|
-
processTask.length = length;
|
|
3503
3857
|
redraw = true;
|
|
3504
3858
|
}
|
|
3505
|
-
|
|
3859
|
+
if (initial) {
|
|
3860
|
+
processTask.section(true);
|
|
3861
|
+
}
|
|
3862
|
+
else {
|
|
3863
|
+
PROCESS_STDOUT.moveCursor(0, -(statusHeight + 1 + 1 + (scrollHeight > 0 ? 1 + scrollHeight : 0)));
|
|
3864
|
+
}
|
|
3506
3865
|
processTask.updated = currentTime;
|
|
3507
|
-
const
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
const
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3866
|
+
const summary = new TaskStatus(-1, chalk.bold(`${statusHeight} requests`.padEnd(LOGGER.VALUE_WIDTH)));
|
|
3867
|
+
const spacer = LOGGER.PROGRESS_SPACER;
|
|
3868
|
+
let finished = processTask.pending === 0;
|
|
3869
|
+
for (let i = 0; i <= statusHeight; ++i) {
|
|
3870
|
+
const item = i === statusHeight ? summary : status[i];
|
|
3871
|
+
let { receivedBytes, endTime } = item;
|
|
3872
|
+
if (i === statusHeight) {
|
|
3873
|
+
processTask.section(redraw);
|
|
3874
|
+
if (finished) {
|
|
3875
|
+
endTime = 1;
|
|
3876
|
+
}
|
|
3518
3877
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3878
|
+
else {
|
|
3879
|
+
if (!endTime) {
|
|
3880
|
+
finished = false;
|
|
3881
|
+
}
|
|
3882
|
+
if (i === 0) {
|
|
3883
|
+
summary.dataTime = item.dataTime;
|
|
3884
|
+
summary.startTime = item.startTime;
|
|
3885
|
+
}
|
|
3886
|
+
summary.receivedBytes += receivedBytes;
|
|
3887
|
+
summary.totalBytes += item.totalBytes;
|
|
3888
|
+
if (item.previousBytes === receivedBytes) {
|
|
3889
|
+
if (!redraw) {
|
|
3890
|
+
PROCESS_STDOUT.moveCursor(0, 1);
|
|
3891
|
+
continue;
|
|
3892
|
+
}
|
|
3893
|
+
const value = item.finished || item.current;
|
|
3894
|
+
if (value) {
|
|
3895
|
+
PROCESS_STDOUT.clearLine(0);
|
|
3896
|
+
PROCESS_STDOUT.write(value);
|
|
3897
|
+
continue;
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
item.previousBytes = receivedBytes;
|
|
3523
3901
|
}
|
|
3524
3902
|
let percent = 0, bars = 0;
|
|
3525
|
-
|
|
3526
|
-
if (endTime) {
|
|
3903
|
+
if (endTime > 0) {
|
|
3527
3904
|
if (receivedBytes === item.totalBytes) {
|
|
3528
3905
|
bars = -1;
|
|
3529
3906
|
}
|
|
@@ -3531,34 +3908,126 @@ class FileManager extends core_1.Host {
|
|
|
3531
3908
|
else if (receivedBytes > item.totalBytes) {
|
|
3532
3909
|
item.totalBytes = receivedBytes;
|
|
3533
3910
|
percent = 99;
|
|
3534
|
-
bars =
|
|
3911
|
+
bars = barIncrement > 0 ? barLength - 1 : NaN;
|
|
3535
3912
|
}
|
|
3536
3913
|
else {
|
|
3537
3914
|
percent = (receivedBytes / item.totalBytes) * 100;
|
|
3538
|
-
bars = Math.
|
|
3915
|
+
bars = barIncrement > 0 ? Math.round(percent / barIncrement) : NaN;
|
|
3539
3916
|
}
|
|
3540
3917
|
const diffTime = currentTime - item.startTime;
|
|
3541
|
-
const
|
|
3542
|
-
const size = formatSegment(endTime, (0, types_1.formatSize)(receivedBytes, { unit:
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3918
|
+
const unit = receivedBytes < 1048576 ? 'KB' : receivedBytes < 1073741824 ? 'MB' : 'GB';
|
|
3919
|
+
const [time, size, speed] = formatSegment(endTime > 0 ? bars === 0 ? -1 : endTime : 0, formatMinutes(diffTime).padStart(LOGGER.TITLE_WIDTH), (0, types_1.formatSize)(receivedBytes, { unit, unitSeparator: ' ', fixedDecimals: true, decimalPlaces: unit === 'KB' ? 0 : unit === 'MB' ? 1 : 2 }).padStart(8), (0, util_2.getTransferRate)(receivedBytes, item.dataTime ? (0, types_1.convertTime)(process.hrtime(item.dataTime), false) * 1000 : diffTime, ' ').padStart(10));
|
|
3920
|
+
let output = time + ` ${chalk.blackBright(LOGGER.TITLE_SEP)} ` + (endTime > 0 && bars === 0 ? chalk.grey(item.url) : item.url) + spacer;
|
|
3921
|
+
if (barLength === 1) {
|
|
3922
|
+
output += ` ${endTime > 0 ? bars === 0 ? chalk.red('ERR!') : LOGGER.PROGRESS_COMPLETE : formatPercent(percent)} ` + spacer;
|
|
3923
|
+
}
|
|
3924
|
+
else if (!isNaN(barLength)) {
|
|
3925
|
+
output += ` ${size} ` + spacer;
|
|
3926
|
+
if (endTime > 0) {
|
|
3927
|
+
output += ` ${speed} ${spacer} ${bars === 0 ? chalk.red('ERR!') : LOGGER.PROGRESS_COMPLETE} ` + spacer;
|
|
3928
|
+
}
|
|
3929
|
+
else if (!isNaN(percent)) {
|
|
3930
|
+
output += ` ${speed} ${spacer} ${formatPercent(percent)} ` + spacer;
|
|
3931
|
+
if (bars >= 0) {
|
|
3932
|
+
output += writeProgressBar(bars, barLength);
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3547
3935
|
}
|
|
3548
3936
|
output += '\n';
|
|
3937
|
+
if (!LOGGER.PROGRESS_USECOLOR) {
|
|
3938
|
+
output = stripansi(output);
|
|
3939
|
+
}
|
|
3549
3940
|
PROCESS_STDOUT.clearLine(0);
|
|
3550
3941
|
PROCESS_STDOUT.write(output);
|
|
3551
|
-
if (endTime) {
|
|
3552
|
-
item.
|
|
3942
|
+
if (endTime > 0) {
|
|
3943
|
+
item.finished = output;
|
|
3944
|
+
}
|
|
3945
|
+
else {
|
|
3946
|
+
item.current = output;
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
const cleared = finished && this.cleared;
|
|
3950
|
+
if (logDelayed) {
|
|
3951
|
+
processTask.section(redraw);
|
|
3952
|
+
const { PROGRESS_COLOR: color, PROGRESS_BGCOLOR: bgColor, PROGRESS_USECOLOR: useColor, PROGRESS_TEXTWRAP: messageTextWrap } = LOGGER;
|
|
3953
|
+
const scroll = processTask.scroll;
|
|
3954
|
+
let start = 0, end = 0, output, last;
|
|
3955
|
+
if (cleared) {
|
|
3956
|
+
logDelayed = this._logDelayed;
|
|
3957
|
+
end = Math.min(logDelayed.length, scrollHeight);
|
|
3958
|
+
}
|
|
3959
|
+
else {
|
|
3960
|
+
[start, end] = [Math.max(0, logDelayed.length - scrollHeight), logDelayed.length];
|
|
3961
|
+
}
|
|
3962
|
+
for (let i = 0; start < end; ++i, ++start) {
|
|
3963
|
+
let item = logDelayed[start];
|
|
3964
|
+
if (cleared) {
|
|
3965
|
+
last = item;
|
|
3966
|
+
}
|
|
3967
|
+
else {
|
|
3968
|
+
if (!redraw && scroll[i] === item) {
|
|
3969
|
+
PROCESS_STDOUT.moveCursor(0, 1);
|
|
3970
|
+
continue;
|
|
3971
|
+
}
|
|
3972
|
+
const options = { ...item[4], messageTextWrap, broadcastId: '' };
|
|
3973
|
+
if (!useColor) {
|
|
3974
|
+
options.useColor = false;
|
|
3975
|
+
}
|
|
3976
|
+
else if (color || bgColor) {
|
|
3977
|
+
options.useColor = true;
|
|
3978
|
+
if (color) {
|
|
3979
|
+
options.titleColor = color;
|
|
3980
|
+
options.valueColor = color;
|
|
3981
|
+
options.hintColor = color;
|
|
3982
|
+
options.messageColor = color;
|
|
3983
|
+
}
|
|
3984
|
+
if (bgColor) {
|
|
3985
|
+
options.titleBgColor = bgColor;
|
|
3986
|
+
options.valueBgColor = bgColor;
|
|
3987
|
+
options.hintBgColor = bgColor;
|
|
3988
|
+
options.messageBgColor = bgColor;
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
scroll[i] = item;
|
|
3992
|
+
item = item.slice(0);
|
|
3993
|
+
item[4] = options;
|
|
3994
|
+
}
|
|
3995
|
+
PROCESS_STDOUT.clearLine(0);
|
|
3996
|
+
core_1.Host.formatMessage(...item);
|
|
3997
|
+
output = true;
|
|
3998
|
+
}
|
|
3999
|
+
if (last) {
|
|
4000
|
+
if (end < scrollHeight) {
|
|
4001
|
+
for (let i = end; i < scrollHeight; ++i) {
|
|
4002
|
+
PROCESS_STDOUT.clearLine(0);
|
|
4003
|
+
PROCESS_STDOUT.moveCursor(0, 1);
|
|
4004
|
+
}
|
|
4005
|
+
PROCESS_STDOUT.moveCursor(0, end - scrollHeight);
|
|
4006
|
+
}
|
|
4007
|
+
const index = logDelayed.findIndex(item => item === last);
|
|
4008
|
+
if (index !== -1) {
|
|
4009
|
+
logDelayed.splice(0, index + 1);
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
else if (output) {
|
|
4013
|
+
processTask.logCurrent = (0, types_1.getLogCurrent)();
|
|
3553
4014
|
}
|
|
3554
4015
|
}
|
|
3555
|
-
if (
|
|
3556
|
-
this.resumeLog();
|
|
4016
|
+
if (cleared) {
|
|
4017
|
+
this.resumeLog('progress');
|
|
3557
4018
|
processTask.reset();
|
|
3558
4019
|
}
|
|
4020
|
+
else if (initial) {
|
|
4021
|
+
if (processTask.screenReset) {
|
|
4022
|
+
processTask.screenReset = false;
|
|
4023
|
+
}
|
|
4024
|
+
else {
|
|
4025
|
+
PROCESS_STDOUT.write('\n');
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
3559
4028
|
}
|
|
3560
4029
|
}
|
|
3561
|
-
scheduleTask(url, data, thenCallback, catchCallback, priority = 0) {
|
|
4030
|
+
async scheduleTask(url, data, thenCallback, catchCallback, priority = 0) {
|
|
3562
4031
|
if (typeof thenCallback === 'number') {
|
|
3563
4032
|
priority = thenCallback;
|
|
3564
4033
|
thenCallback = undefined;
|
|
@@ -3569,25 +4038,6 @@ class FileManager extends core_1.Host {
|
|
|
3569
4038
|
scheduler.queue.sort((a, b) => b[4] - a[4]);
|
|
3570
4039
|
return Promise.resolve(0);
|
|
3571
4040
|
}
|
|
3572
|
-
const nextTask = (pid) => {
|
|
3573
|
-
if (pid > 0) {
|
|
3574
|
-
const found = scheduler.status.find(item => item.id === pid);
|
|
3575
|
-
if (found) {
|
|
3576
|
-
found.endTime || (found.endTime = Date.now());
|
|
3577
|
-
}
|
|
3578
|
-
}
|
|
3579
|
-
--scheduler.count;
|
|
3580
|
-
if (scheduler.queue.length) {
|
|
3581
|
-
const params = scheduler.queue.pop();
|
|
3582
|
-
this.scheduleTask(...params);
|
|
3583
|
-
}
|
|
3584
|
-
else if (scheduler.transform.length) {
|
|
3585
|
-
do {
|
|
3586
|
-
const args = scheduler.transform.shift();
|
|
3587
|
-
this.transformAsset(args[0], args[1], true);
|
|
3588
|
-
} while (scheduler.transform.length && scheduler.queue.length === 0);
|
|
3589
|
-
}
|
|
3590
|
-
};
|
|
3591
4041
|
let id = 0, target;
|
|
3592
4042
|
if ((0, types_1.isPlainObject)(data)) {
|
|
3593
4043
|
++scheduler.count;
|
|
@@ -3595,7 +4045,7 @@ class FileManager extends core_1.Host {
|
|
|
3595
4045
|
target = this.fetchFiles(url, data);
|
|
3596
4046
|
}
|
|
3597
4047
|
else {
|
|
3598
|
-
if (this.hasLog('progress')
|
|
4048
|
+
if (STDOUT_CURSOR && this.hasLog('progress')) {
|
|
3599
4049
|
id = ++scheduler.id;
|
|
3600
4050
|
data.progressId = id;
|
|
3601
4051
|
}
|
|
@@ -3608,7 +4058,7 @@ class FileManager extends core_1.Host {
|
|
|
3608
4058
|
}
|
|
3609
4059
|
else {
|
|
3610
4060
|
if (data instanceof URL && data.protocol === 'file:') {
|
|
3611
|
-
data =
|
|
4061
|
+
data = (0, url_1.fileURLToPath)(data);
|
|
3612
4062
|
}
|
|
3613
4063
|
if ((0, types_1.isString)(data) && core_1.Host.isPath(data, true) && this.canRead(data)) {
|
|
3614
4064
|
data = fs.createReadStream(data);
|
|
@@ -3617,19 +4067,19 @@ class FileManager extends core_1.Host {
|
|
|
3617
4067
|
if (data instanceof stream.Readable) {
|
|
3618
4068
|
++scheduler.count;
|
|
3619
4069
|
target = new Promise((resolve, reject) => {
|
|
3620
|
-
const
|
|
3621
|
-
|
|
4070
|
+
const writable = fs.createWriteStream(url);
|
|
4071
|
+
writable.on('finish', () => {
|
|
3622
4072
|
resolve(1);
|
|
3623
4073
|
});
|
|
3624
|
-
|
|
4074
|
+
writable.on('error', reject);
|
|
3625
4075
|
data.on('error', reject);
|
|
3626
|
-
data.pipe(
|
|
4076
|
+
data.pipe(writable);
|
|
3627
4077
|
});
|
|
3628
4078
|
}
|
|
3629
4079
|
}
|
|
3630
4080
|
if (target) {
|
|
3631
4081
|
if (thenCallback) {
|
|
3632
|
-
target.then(thenCallback);
|
|
4082
|
+
void target.then(thenCallback);
|
|
3633
4083
|
}
|
|
3634
4084
|
if (catchCallback) {
|
|
3635
4085
|
target.catch(catchCallback);
|
|
@@ -3637,7 +4087,7 @@ class FileManager extends core_1.Host {
|
|
|
3637
4087
|
if (id > 0) {
|
|
3638
4088
|
scheduler.add(id, url.toString());
|
|
3639
4089
|
}
|
|
3640
|
-
return target.finally(
|
|
4090
|
+
return target.finally(nextScheduled.bind(this, scheduler, id));
|
|
3641
4091
|
}
|
|
3642
4092
|
return Promise.resolve(-1);
|
|
3643
4093
|
}
|
|
@@ -3648,53 +4098,57 @@ class FileManager extends core_1.Host {
|
|
|
3648
4098
|
}
|
|
3649
4099
|
async finalizeCompress(assets) {
|
|
3650
4100
|
const compress = this.Compress;
|
|
3651
|
-
if (!(assets.length && compress)) {
|
|
4101
|
+
if (!(assets.length > 0 && compress)) {
|
|
3652
4102
|
return;
|
|
3653
4103
|
}
|
|
3654
4104
|
const tasks = [];
|
|
3655
4105
|
for (const item of assets) {
|
|
3656
|
-
|
|
3657
|
-
if (!(localUri && image_1.isBinary(item.mimeType))) {
|
|
4106
|
+
if (!image_1.isBinary(item.mimeType)) {
|
|
3658
4107
|
continue;
|
|
3659
4108
|
}
|
|
3660
|
-
const files = [localUri];
|
|
4109
|
+
const files = [[item.localUri, item.mimeType || '']];
|
|
3661
4110
|
if (item.transforms) {
|
|
3662
|
-
files.push(...item.transforms);
|
|
3663
|
-
}
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
4111
|
+
files.push(...item.transforms.map(img => [img, core_1.Host.lookupMime(img)]));
|
|
4112
|
+
}
|
|
4113
|
+
tasks.push(new Promise(async (resolve) => {
|
|
4114
|
+
for (const [file, mimeType] of files) {
|
|
4115
|
+
const ext = mimeType.split('/')[1];
|
|
4116
|
+
const output = item.compress.filter(({ format, condition }) => (!format || format === ext) && (!condition || withinSizeRange(file, condition)));
|
|
4117
|
+
if (output.length > 0 && this.has(file)) {
|
|
4118
|
+
for (let i = 0, length = output.length, buffer = null; i < length; ++i) {
|
|
4119
|
+
const options = output[i];
|
|
4120
|
+
options.mimeType = mimeType;
|
|
4121
|
+
options.timeout ?? (options.timeout = this[kProcessTimeout].compress ?? PROCESS_TIMEOUT.compress);
|
|
4122
|
+
await compress.tryImage(buffer || files.length === 1 && item.buffer || file, file, options)
|
|
4123
|
+
.then(result => {
|
|
4124
|
+
if (result) {
|
|
4125
|
+
if (file === item.localUri) {
|
|
4126
|
+
item.buffer = result instanceof Uint8Array ? Buffer.from(result) : result;
|
|
4127
|
+
}
|
|
4128
|
+
if (i < length - 1) {
|
|
4129
|
+
buffer = Buffer.from(result);
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
})
|
|
4133
|
+
.catch((err) => {
|
|
4134
|
+
this.writeFail(["Unable to compress file", path.basename(file)], err, 8);
|
|
4135
|
+
});
|
|
3684
4136
|
}
|
|
3685
|
-
}
|
|
3686
|
-
.catch((err) => this.writeFail(["Unable to compress file", path.basename(file)], err, { type: 8, startTime: options.startTime })));
|
|
4137
|
+
}
|
|
3687
4138
|
}
|
|
3688
|
-
|
|
4139
|
+
resolve();
|
|
4140
|
+
}));
|
|
3689
4141
|
}
|
|
3690
|
-
if (tasks.length) {
|
|
3691
|
-
|
|
4142
|
+
if (tasks.length > 0) {
|
|
4143
|
+
await Promise.all(tasks);
|
|
3692
4144
|
}
|
|
3693
4145
|
}
|
|
3694
4146
|
async finalizeDocument() {
|
|
3695
4147
|
for (const { instance, constructor } of this.Document) {
|
|
3696
|
-
if (constructor.finalize && instance.assets.length) {
|
|
3697
|
-
await constructor.finalize.call(this, instance).catch((err) =>
|
|
4148
|
+
if (constructor.finalize && instance.assets.length > 0) {
|
|
4149
|
+
await constructor.finalize.call(this, instance).catch((err) => {
|
|
4150
|
+
rejectModule(instance, err, 4);
|
|
4151
|
+
});
|
|
3698
4152
|
if (this.aborted) {
|
|
3699
4153
|
return;
|
|
3700
4154
|
}
|
|
@@ -3702,11 +4156,13 @@ class FileManager extends core_1.Host {
|
|
|
3702
4156
|
}
|
|
3703
4157
|
}
|
|
3704
4158
|
async finalizeTask(assets) {
|
|
3705
|
-
if (assets.length) {
|
|
4159
|
+
if (assets.length > 0) {
|
|
3706
4160
|
for (const { instance, constructor } of this.Task) {
|
|
3707
4161
|
const items = assets.filter(item => item.tasks.find(data => data.handler === instance.moduleName));
|
|
3708
|
-
if (items.length) {
|
|
3709
|
-
await constructor.finalize.call(this, instance, items).catch((err) =>
|
|
4162
|
+
if (items.length > 0) {
|
|
4163
|
+
await constructor.finalize.call(this, instance, items).catch((err) => {
|
|
4164
|
+
rejectModule(instance, err, 4);
|
|
4165
|
+
});
|
|
3710
4166
|
if (this.aborted) {
|
|
3711
4167
|
return;
|
|
3712
4168
|
}
|
|
@@ -3717,11 +4173,36 @@ class FileManager extends core_1.Host {
|
|
|
3717
4173
|
async finalizeCloud() {
|
|
3718
4174
|
const cloud = this.Cloud;
|
|
3719
4175
|
if (cloud) {
|
|
3720
|
-
|
|
4176
|
+
await cloud_1.finalize.call(this, cloud).catch((err) => {
|
|
4177
|
+
rejectModule(cloud, err, 64);
|
|
4178
|
+
});
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
async finalizeChecksum() {
|
|
4182
|
+
let checksum = this.config.checksum;
|
|
4183
|
+
if (!checksum) {
|
|
4184
|
+
return;
|
|
4185
|
+
}
|
|
4186
|
+
if (typeof checksum === 'boolean' || checksum === 1) {
|
|
4187
|
+
checksum = { recursive: checksum };
|
|
4188
|
+
}
|
|
4189
|
+
else if ((0, types_1.isString)(checksum)) {
|
|
4190
|
+
const items = checksum.split('.');
|
|
4191
|
+
checksum = items.length > 1 ? { algorithm: items[items.length - 1], filename: checksum } : { algorithm: checksum };
|
|
4192
|
+
}
|
|
4193
|
+
if ((0, types_1.isPlainObject)(checksum)) {
|
|
4194
|
+
const baseDirectory = this.baseDirectory;
|
|
4195
|
+
checksum.joinRoot = true;
|
|
4196
|
+
checksum.throwsEmpty = true;
|
|
4197
|
+
const sumTime = LOG_TIMEELAPSED ? process.hrtime() : 0;
|
|
4198
|
+
const files = (await FileManager.writeChecksum(baseDirectory, checksum.filename, checksum));
|
|
4199
|
+
if (sumTime) {
|
|
4200
|
+
this.writeTimeElapsed(checksum.algorithm || "sha256", [baseDirectory, files.length + (files.length === 1 ? ' file' : ' files')], sumTime, { ...core_1.Host.LOG_STYLE_WARN });
|
|
4201
|
+
}
|
|
3721
4202
|
}
|
|
3722
4203
|
}
|
|
3723
4204
|
async finalizeCleanup() {
|
|
3724
|
-
if (this.emptyDir.size) {
|
|
4205
|
+
if (this.emptyDir.size > 0) {
|
|
3725
4206
|
for (const value of Array.from(this.emptyDir).reverse()) {
|
|
3726
4207
|
try {
|
|
3727
4208
|
fs.rmdirSync(value);
|
|
@@ -3731,8 +4212,10 @@ class FileManager extends core_1.Host {
|
|
|
3731
4212
|
}
|
|
3732
4213
|
}
|
|
3733
4214
|
for (const { instance, constructor } of this.Document) {
|
|
3734
|
-
if (constructor.cleanup && instance.assets.length) {
|
|
3735
|
-
await constructor.cleanup.call(this, instance).catch((err) =>
|
|
4215
|
+
if (constructor.cleanup && instance.assets.length > 0) {
|
|
4216
|
+
await constructor.cleanup.call(this, instance).catch((err) => {
|
|
4217
|
+
rejectModule(instance, err, 4);
|
|
4218
|
+
});
|
|
3736
4219
|
}
|
|
3737
4220
|
}
|
|
3738
4221
|
}
|
|
@@ -3745,17 +4228,11 @@ class FileManager extends core_1.Host {
|
|
|
3745
4228
|
}
|
|
3746
4229
|
const startTime = process.hrtime();
|
|
3747
4230
|
const filesToRemove = this.filesToRemove;
|
|
3748
|
-
const removeFiles = () => {
|
|
3749
|
-
if (filesToRemove.size) {
|
|
3750
|
-
filesToRemove.forEach(value => this.deleteFile(value, { emptyDir: true }));
|
|
3751
|
-
filesToRemove.clear();
|
|
3752
|
-
}
|
|
3753
|
-
};
|
|
3754
4231
|
for (const [file, output] of this.filesToCompare) {
|
|
3755
4232
|
const localUri = file.localUri;
|
|
3756
|
-
let minFile = localUri, minSize = (0,
|
|
4233
|
+
let minFile = localUri, minSize = (0, util_2.getSize)(minFile);
|
|
3757
4234
|
for (const other of output) {
|
|
3758
|
-
const size = (0,
|
|
4235
|
+
const size = (0, util_2.getSize)(other);
|
|
3759
4236
|
if (minSize === 0 || size > 0 && size < minSize) {
|
|
3760
4237
|
filesToRemove.add(minFile);
|
|
3761
4238
|
minFile = other;
|
|
@@ -3769,12 +4246,16 @@ class FileManager extends core_1.Host {
|
|
|
3769
4246
|
this.replace(file, minFile);
|
|
3770
4247
|
}
|
|
3771
4248
|
}
|
|
3772
|
-
removeFiles();
|
|
3773
|
-
await this.finalizeCompress(this.assets.filter(item => item.compress && !ignoreAsset(item))).catch((err) =>
|
|
4249
|
+
removeFiles(this, filesToRemove);
|
|
4250
|
+
await this.finalizeCompress(this.assets.filter(item => item.compress && !ignoreAsset(item))).catch((err) => {
|
|
4251
|
+
rejectModule(this, err, 8);
|
|
4252
|
+
});
|
|
3774
4253
|
if (this.aborted) {
|
|
3775
4254
|
return (0, types_1.createAbortError)(true);
|
|
3776
4255
|
}
|
|
3777
|
-
await this.finalizeDocument().catch((err) =>
|
|
4256
|
+
await this.finalizeDocument().catch((err) => {
|
|
4257
|
+
rejectModule(this, err, 4);
|
|
4258
|
+
});
|
|
3778
4259
|
if (this.aborted) {
|
|
3779
4260
|
return (0, types_1.createAbortError)(true);
|
|
3780
4261
|
}
|
|
@@ -3788,62 +4269,62 @@ class FileManager extends core_1.Host {
|
|
|
3788
4269
|
}
|
|
3789
4270
|
}
|
|
3790
4271
|
}
|
|
3791
|
-
removeFiles();
|
|
3792
|
-
await this.finalizeTask(this.taskAssets.filter(item => item.tasks?.find(data => !data.preceding) && item.localUri && this.has(item.localUri) && !ignoreAsset(item))).catch((err) =>
|
|
4272
|
+
removeFiles(this, filesToRemove);
|
|
4273
|
+
await this.finalizeTask(this.taskAssets.filter(item => item.tasks?.find(data => !data.preceding) && item.localUri && this.has(item.localUri) && !ignoreAsset(item))).catch((err) => {
|
|
4274
|
+
rejectModule(this, err, 4);
|
|
4275
|
+
});
|
|
3793
4276
|
if (this.aborted) {
|
|
3794
4277
|
return (0, types_1.createAbortError)(true);
|
|
3795
4278
|
}
|
|
3796
|
-
removeFiles();
|
|
4279
|
+
removeFiles(this, filesToRemove);
|
|
3797
4280
|
for (const item of this.assets) {
|
|
3798
4281
|
if (item.checksumOutput && !ignoreAsset(item)) {
|
|
3799
4282
|
const localUri = item.localUri;
|
|
3800
|
-
if (!filesToRemove.has(localUri) && !checkHash
|
|
4283
|
+
if (!filesToRemove.has(localUri) && !checkHash(this, localUri, true, item.checksumOutput)) {
|
|
3801
4284
|
item.invalid = true;
|
|
3802
4285
|
filesToRemove.add(localUri);
|
|
3803
4286
|
this.writeFail(["Checksum did not match", path.basename(localUri)], (0, types_1.errorValue)(localUri, "Invalid checksum"), { type: 32, startTime, queue: true });
|
|
3804
4287
|
}
|
|
3805
4288
|
}
|
|
3806
4289
|
}
|
|
3807
|
-
removeFiles();
|
|
3808
|
-
await this.finalizeCloud().catch((err) =>
|
|
4290
|
+
removeFiles(this, filesToRemove);
|
|
4291
|
+
await this.finalizeCloud().catch((err) => {
|
|
4292
|
+
rejectModule(this, err, 64);
|
|
4293
|
+
});
|
|
3809
4294
|
if (this.aborted) {
|
|
3810
4295
|
return (0, types_1.createAbortError)(true);
|
|
3811
4296
|
}
|
|
3812
|
-
removeFiles();
|
|
4297
|
+
removeFiles(this, filesToRemove);
|
|
3813
4298
|
if (this.Compress) {
|
|
3814
4299
|
const tasks = [];
|
|
3815
|
-
|
|
3816
|
-
|
|
4300
|
+
for (const item of this.assets) {
|
|
4301
|
+
if (item.compress && !ignoreAsset(item, true)) {
|
|
4302
|
+
tasks.push(this.compressFile(item, false));
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
if (tasks.length > 0) {
|
|
3817
4306
|
await Promise.allSettled(tasks);
|
|
3818
4307
|
}
|
|
3819
4308
|
}
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
if (sumTime) {
|
|
3837
|
-
this.writeTimeElapsed(checksum.algorithm || "sha256", [baseDirectory, files.length + (files.length === 1 ? ' file' : ' files')], sumTime, { ...core_1.Host.LOG_STYLE_WARN });
|
|
3838
|
-
}
|
|
3839
|
-
}
|
|
3840
|
-
catch (err) {
|
|
3841
|
-
this.writeFail(["Unable to read directory", path.basename(baseDirectory)], err, { type: 32, startTime });
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
4309
|
+
await this.finalizeChecksum().catch((err) => {
|
|
4310
|
+
rejectModule(this, err, 32);
|
|
4311
|
+
});
|
|
4312
|
+
await this.finalizeCleanup().catch((err) => {
|
|
4313
|
+
rejectModule(this, err, 1);
|
|
4314
|
+
});
|
|
4315
|
+
removeFiles(this, filesToRemove);
|
|
4316
|
+
this.closeMessage(startTime);
|
|
4317
|
+
this.Watch?.start(this.assets);
|
|
4318
|
+
}
|
|
4319
|
+
close() {
|
|
4320
|
+
this.Request.close();
|
|
4321
|
+
}
|
|
4322
|
+
startMessage() {
|
|
4323
|
+
if (!this.silent) {
|
|
4324
|
+
this.formatMessage(128, 'START', [new Date().toLocaleString(), this.assets.length + ' assets'], this.baseDirectory, { ...core_1.Host.LOG_STYLE_SUCCESS });
|
|
3844
4325
|
}
|
|
3845
|
-
|
|
3846
|
-
|
|
4326
|
+
}
|
|
4327
|
+
closeMessage(startTime) {
|
|
3847
4328
|
if (LOG_TIMEELAPSED) {
|
|
3848
4329
|
const [http, disk, cache] = this[kDownloadStats];
|
|
3849
4330
|
const errorCount = this.errorCount;
|
|
@@ -3867,16 +4348,81 @@ class FileManager extends core_1.Host {
|
|
|
3867
4348
|
const bufferCount = Object.keys(MEMORY.CACHE).length;
|
|
3868
4349
|
message.push('BUFFER ' + (bufferCount > 1 ? bufferCount + ' / ' : '') + (0, types_1.formatSize)(MEMORY.SIZE));
|
|
3869
4350
|
}
|
|
3870
|
-
this.writeTimeElapsed('CLOSE', ['No further modifications', message.length ?
|
|
4351
|
+
this.writeTimeElapsed('CLOSE', ['No further modifications', message.length > 0 ? message.join(chalk.blackBright(LOGGER.MESSAGE_SEP)) : ''], startTime, { ...core_1.Host.LOG_STYLE_WARN });
|
|
3871
4352
|
}
|
|
3872
|
-
this.Watch?.start(this.assets);
|
|
3873
4353
|
}
|
|
3874
|
-
|
|
3875
|
-
this
|
|
4354
|
+
diffMessage() {
|
|
4355
|
+
const diffSource = this[kDiffSource]?.[1];
|
|
4356
|
+
if (!diffSource) {
|
|
4357
|
+
return;
|
|
4358
|
+
}
|
|
4359
|
+
const output = [];
|
|
4360
|
+
const addHeader = (pathname, summary) => {
|
|
4361
|
+
output.push(chalk.blackBright('-'.repeat(LOGGER.MESSAGE_WIDTH)), ' ' + (summary === 'deleted' ? chalk.yellow(pathname) : pathname), chalk.blackBright('-'.repeat(LOGGER.MESSAGE_WIDTH - summary.length - 1)) + ' ' + chalk.bold(summary));
|
|
4362
|
+
};
|
|
4363
|
+
let divider = false;
|
|
4364
|
+
for (const pathname in diffSource) {
|
|
4365
|
+
if (core_1.Host.isPath(pathname, true)) {
|
|
4366
|
+
const [content, encoding] = diffSource[pathname];
|
|
4367
|
+
const hunks = diff.structuredPatch('', '', checkEOF(content), checkEOF(fs.readFileSync(pathname, encoding)), '', '', { context: 0 }).hunks;
|
|
4368
|
+
const length = hunks.length;
|
|
4369
|
+
if (length === 0) {
|
|
4370
|
+
continue;
|
|
4371
|
+
}
|
|
4372
|
+
const lastHunk = hunks[length - 1];
|
|
4373
|
+
const oldMax = lastHunk.oldStart + lastHunk.oldLines;
|
|
4374
|
+
const newMax = lastHunk.newStart + lastHunk.newLines;
|
|
4375
|
+
const posLength = Math.max(Math.max(oldMax, newMax).toString().length, Math.min(oldMax, newMax).toString().length);
|
|
4376
|
+
addHeader(pathname, length + ` hunk${length > 1 ? 's' : ''}`);
|
|
4377
|
+
for (const { lines, oldLines, oldStart, newStart, newLines } of hunks) {
|
|
4378
|
+
for (let i = 0, j = oldStart, k = oldLines, l = 0, q = lines.length, added = false; i < q && k > 0; ++i) {
|
|
4379
|
+
const line = lines[i].substring(1);
|
|
4380
|
+
output.push(` ${chalk[!line && k === 1 ? 'grey' : added ? 'green' : 'red']((j + l++).toString().padStart(posLength))} ${chalk[added ? 'green' : 'red'](line)}`);
|
|
4381
|
+
if (--k === 0 && !added) {
|
|
4382
|
+
j = newStart;
|
|
4383
|
+
k = newLines;
|
|
4384
|
+
l = 0;
|
|
4385
|
+
added = true;
|
|
4386
|
+
}
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
divider = true;
|
|
4390
|
+
}
|
|
4391
|
+
else {
|
|
4392
|
+
addHeader(pathname, 'deleted');
|
|
4393
|
+
divider = false;
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
if (output.length > 0) {
|
|
4397
|
+
if (divider) {
|
|
4398
|
+
output.push(chalk.blackBright('-'.repeat(LOGGER.MESSAGE_WIDTH)));
|
|
4399
|
+
}
|
|
4400
|
+
output.push('');
|
|
4401
|
+
if (this.broadcastId && core_1.Host.hasLogType(2)) {
|
|
4402
|
+
core_1.Host.formatMessage(2, '', '', output.join('\n'), { broadcastId: this.broadcastId, rawOutput: true });
|
|
4403
|
+
}
|
|
4404
|
+
else {
|
|
4405
|
+
process.stdout.write(output.join('\n'));
|
|
4406
|
+
(0, types_1.setLogCurrent)(null);
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
endMessage(errors) {
|
|
4411
|
+
if (LOG_TIMEELAPSED) {
|
|
4412
|
+
this.writeTimeElapsed('END', this.baseDirectory, this.startTime, errors.length > 0 ? { failed: true, ...core_1.Host.LOG_STYLE_FAIL } : { ...core_1.Host.LOG_STYLE_SUCCESS });
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4415
|
+
clearStorage() {
|
|
4416
|
+
if (this[kDiffSource]) {
|
|
4417
|
+
this[kDiffSource][1] = {};
|
|
4418
|
+
}
|
|
4419
|
+
this.contentToAppend.clear();
|
|
4420
|
+
this.contentToReplace.clear();
|
|
3876
4421
|
}
|
|
3877
4422
|
resetState() {
|
|
3878
4423
|
this.finalizeState = 2;
|
|
3879
4424
|
this._pendingResult = null;
|
|
4425
|
+
this.clearStorage();
|
|
3880
4426
|
}
|
|
3881
4427
|
abortFinalize(err) {
|
|
3882
4428
|
if (!this.restarting) {
|
|
@@ -3886,7 +4432,7 @@ class FileManager extends core_1.Host {
|
|
|
3886
4432
|
else {
|
|
3887
4433
|
this.finalizeState = 4;
|
|
3888
4434
|
}
|
|
3889
|
-
this.emit('end', [], collectErrors
|
|
4435
|
+
this.emit('end', [], collectErrors(this), this.collectLog());
|
|
3890
4436
|
if (!this.restarting) {
|
|
3891
4437
|
this.done = true;
|
|
3892
4438
|
}
|
|
@@ -3928,9 +4474,9 @@ class FileManager extends core_1.Host {
|
|
|
3928
4474
|
const start = Math.max(queue.length - available, 0);
|
|
3929
4475
|
const items = queue.slice(start);
|
|
3930
4476
|
queue.splice(queue.length - items.length);
|
|
3931
|
-
|
|
3932
|
-
this.scheduleTask(...params);
|
|
3933
|
-
}
|
|
4477
|
+
for (const params of items) {
|
|
4478
|
+
void this.scheduleTask(...params);
|
|
4479
|
+
}
|
|
3934
4480
|
}
|
|
3935
4481
|
}
|
|
3936
4482
|
}
|
|
@@ -3942,5 +4488,5 @@ class FileManager extends core_1.Host {
|
|
|
3942
4488
|
return Array.from(this.modules).reduce((a, b) => a + b.errors.length, this.errors.length);
|
|
3943
4489
|
}
|
|
3944
4490
|
}
|
|
3945
|
-
|
|
4491
|
+
setLogMinWidth();
|
|
3946
4492
|
module.exports = FileManager;
|