@e-mc/document 0.9.6 → 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 +10 -10
- package/asset.js +3 -4
- package/index.d.ts +4 -4
- package/index.js +474 -345
- package/package.json +4 -4
- package/parse/dom.js +15 -10
- package/parse/index.js +71 -52
- package/parse/types/index.d.ts +2 -2
- package/transform/index.d.ts +7 -7
- package/transform/index.js +39 -13
- package/util.d.ts +4 -0
- package/util.js +27 -31
package/index.js
CHANGED
|
@@ -7,10 +7,9 @@ const chalk = require("chalk");
|
|
|
7
7
|
const types_1 = require("@e-mc/types");
|
|
8
8
|
const core_1 = require("@e-mc/core");
|
|
9
9
|
const db_1 = require("@e-mc/db");
|
|
10
|
-
const util_1 = require("@e-mc/document/util");
|
|
11
10
|
const transform_1 = require("@e-mc/document/transform");
|
|
12
11
|
const parse_1 = require("@e-mc/document/parse");
|
|
13
|
-
const
|
|
12
|
+
const util_1 = require("@e-mc/document/util");
|
|
14
13
|
const CACHE_PACKAGE = {};
|
|
15
14
|
const CACHE_REQUIRE = {};
|
|
16
15
|
const CACHE_ETAG = {};
|
|
@@ -20,12 +19,6 @@ const CACHE_TEMPLATE = {};
|
|
|
20
19
|
const CACHE_EXTERNAL = {};
|
|
21
20
|
const CACHE_PICOMATCH = new Map();
|
|
22
21
|
let CACHE_TOTAL = 0;
|
|
23
|
-
function renewTransform(map, key, expires) {
|
|
24
|
-
if (expires > 0) {
|
|
25
|
-
return setTimeout(() => deleteTransform(map, key), expires);
|
|
26
|
-
}
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
22
|
function deleteTransform(map, key, timeout) {
|
|
30
23
|
if (timeout) {
|
|
31
24
|
clearTimeout(timeout);
|
|
@@ -33,57 +26,309 @@ function deleteTransform(map, key, timeout) {
|
|
|
33
26
|
delete map[key];
|
|
34
27
|
--CACHE_TOTAL;
|
|
35
28
|
}
|
|
36
|
-
function
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
clearTimeout(stored.timeout);
|
|
40
|
-
}
|
|
41
|
-
stored.timeout = renewTransform(map, key, config.expires);
|
|
29
|
+
function getSourceMappingURL(value, css) {
|
|
30
|
+
if (value.includes(' ')) {
|
|
31
|
+
value = encodeURIComponent(value);
|
|
42
32
|
}
|
|
43
|
-
|
|
33
|
+
return css ? `\n/*# sourceMappingURL=${value} */\n` : `\n//# sourceMappingURL=${value}\n`;
|
|
44
34
|
}
|
|
45
|
-
function
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
function normalizeDir(value, check) {
|
|
36
|
+
const sep = !check && value.includes('\\') && !value.includes('/') ? '\\' : '/';
|
|
37
|
+
if (check) {
|
|
38
|
+
value = toPosix(value).toLowerCase();
|
|
39
|
+
}
|
|
40
|
+
return value.endsWith(sep) ? value : value + sep;
|
|
41
|
+
}
|
|
42
|
+
function getConfigObject(instance, data, name, target, cache) {
|
|
43
|
+
if (instance.settingsOf('transform', 'coerce') === true) {
|
|
44
|
+
(0, types_1.coerceObject)(target, cache);
|
|
45
|
+
}
|
|
46
|
+
return (0, types_1.cloneObject)(data[name] = target, true);
|
|
47
|
+
}
|
|
48
|
+
function errorConfig(instance, ...message) {
|
|
49
|
+
instance.addLog(types_1.STATUS_TYPE.ERROR, joinString('config', ...message));
|
|
50
|
+
}
|
|
51
|
+
const isExcluded = (type, name, config, cacheData) => !(config?.hasType(type, name) || cacheData?.override === true);
|
|
52
|
+
const wrapCount = (value) => chalk.grey('(') + value + chalk.grey(')');
|
|
53
|
+
const fixHint = (warningCount, errorCount, value) => warningCount > 0 || errorCount > 0 ? ':' + value : '';
|
|
54
|
+
const compareValue = (value) => value.replace(/["'()]/g, '').trim();
|
|
55
|
+
const toPath = (uri, hostname) => path.resolve(hostname[1], uri.substring(normalizeDir(hostname[0]).length).split('?')[0]);
|
|
56
|
+
const toBase64 = (value) => 'data:application/json;base64,' + Buffer.from(value).toString('base64');
|
|
57
|
+
const toPosix = (value) => value.replace(/(?:^\\|\\+)/g, '/');
|
|
58
|
+
const joinString = (name, ...values) => (name ? name + ': ' : '') + values.reduce((a, b) => b ? a + (a ? ' -> ' : '') + b : a, '');
|
|
59
|
+
const truncateString = (value, width) => value.length > width ? value.substring(0, width - 3) + '...' : value.padStart(width);
|
|
60
|
+
const spliceSource = (source, startIndex, endIndex, content) => source.substring(0, startIndex) + content + source.substring(endIndex);
|
|
61
|
+
const isFunction = (value) => typeof value === 'function';
|
|
62
|
+
class TransformCache {
|
|
63
|
+
constructor(config, cacheData, cacheDir, encoding, formatKey) {
|
|
64
|
+
this.config = config;
|
|
65
|
+
this.cacheData = cacheData;
|
|
66
|
+
this.cacheDir = cacheDir;
|
|
67
|
+
this.encoding = encoding;
|
|
68
|
+
this.formatKey = formatKey;
|
|
69
|
+
this.formatType = 0;
|
|
70
|
+
this.hashKey = '';
|
|
71
|
+
}
|
|
72
|
+
set(type, data) {
|
|
73
|
+
let pathname;
|
|
74
|
+
if (typeof this.cacheDir === 'string' && core_1.Client.createDir(pathname = path.join(this.cacheDir, 'transform', type))) {
|
|
75
|
+
try {
|
|
76
|
+
fs.writeFileSync(pathname = path.join(pathname, (0, types_1.incrementUUID)()), JSON.stringify(data));
|
|
77
|
+
return pathname;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
}
|
|
50
81
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
return data;
|
|
83
|
+
}
|
|
84
|
+
get(stored) {
|
|
85
|
+
const location = stored.format[this.formatKey];
|
|
86
|
+
if (typeof location === 'string') {
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(fs.readFileSync(location, this.encoding));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
delete stored.format[this.formatKey];
|
|
92
|
+
fs.unlink(location, () => { });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
54
95
|
}
|
|
96
|
+
return location;
|
|
55
97
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
98
|
+
save(type, code, formatData) {
|
|
99
|
+
const lastAccessed = Date.now();
|
|
100
|
+
const config = this.config;
|
|
101
|
+
if (this.formatType === 1) {
|
|
102
|
+
const { uri, etag } = this.cacheData;
|
|
103
|
+
const etagMap = CACHE_ETAG[config.moduleName];
|
|
104
|
+
const stored = etagMap[uri];
|
|
105
|
+
if (stored) {
|
|
106
|
+
if (stored.etag === etag) {
|
|
107
|
+
stored.format[this.formatKey] = this.set(type, formatData);
|
|
108
|
+
stored.lastAccessed = lastAccessed;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
deleteTransform(etagMap, uri, stored.timeout);
|
|
112
|
+
}
|
|
113
|
+
etagMap[uri] = { lastAccessed, etag, timeout: config.renewSession(etagMap, uri), format: { [this.formatKey]: this.set(type, formatData) } };
|
|
114
|
+
++CACHE_TOTAL;
|
|
64
115
|
}
|
|
65
|
-
|
|
116
|
+
else if (this.formatType === 2) {
|
|
117
|
+
const hashMap = CACHE_HASH[config.moduleName];
|
|
118
|
+
const key = this.hashKey;
|
|
119
|
+
const stored = hashMap[key];
|
|
120
|
+
if (stored) {
|
|
121
|
+
stored.format[this.formatKey] = this.set(type, formatData);
|
|
122
|
+
stored.lastAccessed = lastAccessed;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
hashMap[key] = { lastAccessed, timeout: config.renewSession(hashMap, key), format: { [this.formatKey]: this.set(type, formatData) } };
|
|
126
|
+
++CACHE_TOTAL;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const uri = this.cacheData.uri;
|
|
130
|
+
const codeMap = CACHE_CODE[config.moduleName];
|
|
131
|
+
const stored = codeMap[uri];
|
|
132
|
+
if (stored) {
|
|
133
|
+
if (stored.code === code) {
|
|
134
|
+
stored.format[this.formatKey] = this.set(type, formatData);
|
|
135
|
+
stored.lastAccessed = lastAccessed;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
deleteTransform(codeMap, uri, stored.timeout);
|
|
139
|
+
}
|
|
140
|
+
codeMap[uri] = { lastAccessed, code, timeout: config.renewSession(codeMap, uri), format: { [this.formatKey]: this.set(type, formatData) } };
|
|
141
|
+
++CACHE_TOTAL;
|
|
66
142
|
}
|
|
67
143
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
144
|
+
finalize(type, code, formatData) {
|
|
145
|
+
if (typeof this.cacheDir === 'string') {
|
|
146
|
+
return new Promise(resolve => {
|
|
147
|
+
this.save(type, code, formatData);
|
|
148
|
+
resolve();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
this.save(type, code, formatData);
|
|
75
152
|
}
|
|
76
|
-
return data?.override === true;
|
|
77
153
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
154
|
+
class TransformConfig {
|
|
155
|
+
constructor(moduleName) {
|
|
156
|
+
this.moduleName = moduleName;
|
|
157
|
+
this.algorithm = undefined;
|
|
158
|
+
this.etag = false;
|
|
159
|
+
this.expires = 0;
|
|
160
|
+
this.renew = false;
|
|
161
|
+
this.limit = Infinity;
|
|
162
|
+
this.exclude = {};
|
|
163
|
+
this.include = {};
|
|
164
|
+
}
|
|
165
|
+
init(options) {
|
|
166
|
+
let enabled, algorithm, etag, expires, renew, limit, exclude, include;
|
|
167
|
+
if (options === true || options === 'etag') {
|
|
168
|
+
etag = true;
|
|
169
|
+
enabled = true;
|
|
170
|
+
}
|
|
171
|
+
else if (typeof options === 'string') {
|
|
172
|
+
algorithm = options;
|
|
173
|
+
enabled = true;
|
|
174
|
+
}
|
|
175
|
+
else if ((0, types_1.isPlainObject)(options)) {
|
|
176
|
+
({ enabled = true, algorithm, etag, expires, renew, limit, exclude, include } = options);
|
|
177
|
+
}
|
|
178
|
+
if (!enabled) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
switch (algorithm = algorithm?.toLowerCase()) {
|
|
182
|
+
case 'md5':
|
|
183
|
+
case 'sha1':
|
|
184
|
+
case 'sha224':
|
|
185
|
+
case 'sha256':
|
|
186
|
+
case 'sha384':
|
|
187
|
+
case 'sha512':
|
|
188
|
+
case 'ripemd':
|
|
189
|
+
case 'ripemd-160':
|
|
190
|
+
this.algorithm = algorithm;
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
this.algorithm = undefined;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (typeof etag === 'boolean') {
|
|
197
|
+
this.etag = etag;
|
|
198
|
+
}
|
|
199
|
+
if (expires && (expires = (0, types_1.parseExpires)(expires)) >= 0) {
|
|
200
|
+
this.expires = Math.min(expires, core_1.Client.MAX_TIMEOUT);
|
|
201
|
+
}
|
|
202
|
+
if (renew) {
|
|
203
|
+
this.renew = true;
|
|
204
|
+
}
|
|
205
|
+
if ((0, types_1.isPlainObject)(exclude)) {
|
|
206
|
+
for (const type in exclude) {
|
|
207
|
+
const item = exclude[type];
|
|
208
|
+
if (item === '*') {
|
|
209
|
+
this.exclude[type] = true;
|
|
210
|
+
}
|
|
211
|
+
else if ((0, types_1.isArray)(item)) {
|
|
212
|
+
this.exclude[type] = item;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if ((0, types_1.isPlainObject)(include)) {
|
|
217
|
+
for (const type in include) {
|
|
218
|
+
const item = include[type];
|
|
219
|
+
if (item === '*') {
|
|
220
|
+
this.include[type] = true;
|
|
221
|
+
}
|
|
222
|
+
else if ((0, types_1.isArray)(item)) {
|
|
223
|
+
this.include[type] = item;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (limit !== undefined) {
|
|
228
|
+
let value;
|
|
229
|
+
if (typeof limit === 'string') {
|
|
230
|
+
if (parseFloat(limit) === 0) {
|
|
231
|
+
value = 0;
|
|
232
|
+
}
|
|
233
|
+
else if ((value = (0, types_1.formatSize)(limit)) === 0) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
value = limit;
|
|
239
|
+
}
|
|
240
|
+
if (value >= 0) {
|
|
241
|
+
this.limit = value;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
valid(type, format) {
|
|
247
|
+
const { exclude, include } = this;
|
|
248
|
+
return !exclude[type] || Array.isArray(exclude[type]) && !format.some(value => exclude[type].includes(value)) || Array.isArray(include[type]) && format.every(value => include[type].includes(value));
|
|
249
|
+
}
|
|
250
|
+
hasType(type, name) {
|
|
251
|
+
const include = this.include[type];
|
|
252
|
+
if (include === true || include?.includes(name)) {
|
|
253
|
+
const exclude = this.exclude[type];
|
|
254
|
+
return !exclude || exclude === true && include !== true || Array.isArray(exclude) && !exclude.includes(name);
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
resetSession(map, key, stored) {
|
|
259
|
+
if (this.renew) {
|
|
260
|
+
if (stored.timeout) {
|
|
261
|
+
clearTimeout(stored.timeout);
|
|
262
|
+
}
|
|
263
|
+
stored.timeout = this.renewSession(map, key);
|
|
264
|
+
}
|
|
265
|
+
stored.lastAccessed = Date.now();
|
|
266
|
+
}
|
|
267
|
+
renewSession(map, key) {
|
|
268
|
+
if (this.expires > 0) {
|
|
269
|
+
return setTimeout(() => {
|
|
270
|
+
deleteTransform(map, key);
|
|
271
|
+
}, this.expires);
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
useETag(cache, etag, uri) {
|
|
276
|
+
var _a;
|
|
277
|
+
const etagMap = CACHE_ETAG[_a = this.moduleName] || (CACHE_ETAG[_a] = {});
|
|
278
|
+
const stored = etagMap[uri];
|
|
279
|
+
cache.formatType = 1;
|
|
280
|
+
if (stored) {
|
|
281
|
+
let result;
|
|
282
|
+
if (stored.etag !== etag) {
|
|
283
|
+
deleteTransform(etagMap, uri, stored.timeout);
|
|
284
|
+
}
|
|
285
|
+
else if (result = cache.get(stored)) {
|
|
286
|
+
this.resetSession(etagMap, uri, stored);
|
|
287
|
+
return [result, 'etag'];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
useHash(cache, code) {
|
|
293
|
+
var _a;
|
|
294
|
+
let key;
|
|
295
|
+
if (this.withinLimit(code, cache.encoding) && (key = core_1.Client.asHash(code, this.algorithm, { encoding: cache.encoding }))) {
|
|
296
|
+
const hashMap = CACHE_HASH[_a = this.moduleName] || (CACHE_HASH[_a] = {});
|
|
297
|
+
const stored = hashMap[key];
|
|
298
|
+
let result;
|
|
299
|
+
cache.formatType || (cache.formatType = 2);
|
|
300
|
+
cache.hashKey = key;
|
|
301
|
+
if (stored && (result = cache.get(stored))) {
|
|
302
|
+
this.resetSession(hashMap, key, stored);
|
|
303
|
+
return [result, this.algorithm || (this.algorithm = 'sha256')];
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return [];
|
|
307
|
+
}
|
|
308
|
+
useUri(cache, code, uri) {
|
|
309
|
+
var _a;
|
|
310
|
+
if (this.withinLimit(code, cache.encoding)) {
|
|
311
|
+
const codeMap = CACHE_CODE[_a = this.moduleName] || (CACHE_CODE[_a] = {});
|
|
312
|
+
const stored = codeMap[uri];
|
|
313
|
+
cache.formatType || (cache.formatType = 3);
|
|
314
|
+
if (stored) {
|
|
315
|
+
let result;
|
|
316
|
+
if (stored.code !== code) {
|
|
317
|
+
deleteTransform(codeMap, uri, stored.timeout);
|
|
318
|
+
}
|
|
319
|
+
else if (result = cache.get(stored)) {
|
|
320
|
+
this.resetSession(codeMap, uri, stored);
|
|
321
|
+
return [result, 'uri'];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
withinLimit(code, encoding) {
|
|
328
|
+
const limit = this.limit;
|
|
329
|
+
return limit === Infinity || limit > 0 && Buffer.byteLength(code, encoding) <= limit;
|
|
81
330
|
}
|
|
82
|
-
return css ? `\n/*# sourceMappingURL=${value} */\n` : `\n//# sourceMappingURL=${value}\n`;
|
|
83
331
|
}
|
|
84
|
-
const joinString = (...values) => values.reduce((a, b) => b ? a + (a ? ' -> ' : '') + b : a, '');
|
|
85
|
-
const spliceSource = (source, startIndex, endIndex, content) => source.substring(0, startIndex) + content + source.substring(endIndex);
|
|
86
|
-
const isFunction = (value) => typeof value === 'function';
|
|
87
332
|
class Document extends core_1.Client {
|
|
88
333
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
89
334
|
if (limit > 0 && CACHE_TOTAL < limit) {
|
|
@@ -169,7 +414,6 @@ class Document extends core_1.Client {
|
|
|
169
414
|
try {
|
|
170
415
|
let css = mimeType === 'text/css', flags = 0;
|
|
171
416
|
const output = JSON.stringify(map);
|
|
172
|
-
const toBase64 = () => 'data:application/json;base64,' + Buffer.from(output).toString('base64');
|
|
173
417
|
if (!inlineMap) {
|
|
174
418
|
if (!sourceMappingURL) {
|
|
175
419
|
sourceMappingURL = data.sourceMappingURL || file;
|
|
@@ -194,13 +438,13 @@ class Document extends core_1.Client {
|
|
|
194
438
|
}
|
|
195
439
|
if (inlineMap || capture[3]) {
|
|
196
440
|
flags |= 2;
|
|
197
|
-
return getSourceMappingURL(toBase64(), css);
|
|
441
|
+
return getSourceMappingURL(toBase64(output), css);
|
|
198
442
|
}
|
|
199
443
|
return capture[1] || css ? getSourceMappingURL(sourceMappingURL, css) : capture[0];
|
|
200
444
|
});
|
|
201
445
|
if (inlineMap || flags & 2) {
|
|
202
446
|
if (flags === 0) {
|
|
203
|
-
code += getSourceMappingURL(toBase64(), css);
|
|
447
|
+
code += getSourceMappingURL(toBase64(output), css);
|
|
204
448
|
}
|
|
205
449
|
data.code = code;
|
|
206
450
|
}
|
|
@@ -221,7 +465,7 @@ class Document extends core_1.Client {
|
|
|
221
465
|
return new transform_1.SourceMap(code, uri, remove);
|
|
222
466
|
}
|
|
223
467
|
static updateGradle(source, namespaces, value, options) {
|
|
224
|
-
const local = /^(\w+)\s*(=)?\s*(".+"|'.+'|\(
|
|
468
|
+
const local = /^([\w.]+)(?:\((.+)\)|\s*(=)?\s*(".+"|'.+'|\(.+\)||\[.+\]|\S+))$/s.exec(value = value.trim());
|
|
225
469
|
if (!local) {
|
|
226
470
|
return source;
|
|
227
471
|
}
|
|
@@ -232,9 +476,7 @@ class Document extends core_1.Client {
|
|
|
232
476
|
else if (options) {
|
|
233
477
|
({ upgrade, multiple, addendum, updateOnly } = options);
|
|
234
478
|
}
|
|
235
|
-
|
|
236
|
-
value += ' ' + addendum;
|
|
237
|
-
}
|
|
479
|
+
const replacement = addendum ? value + ' ' + addendum : value;
|
|
238
480
|
const length = namespaces.length;
|
|
239
481
|
let ident, lastIndex = 0, i = 0;
|
|
240
482
|
while (i < length) {
|
|
@@ -253,8 +495,7 @@ class Document extends core_1.Client {
|
|
|
253
495
|
const newline = (0, util_1.getNewline)(source);
|
|
254
496
|
ident || (ident = (0, util_1.getIndent)(source));
|
|
255
497
|
if (i === length) {
|
|
256
|
-
const
|
|
257
|
-
const pattern = new RegExp(`\\b${(0, types_1.escapePattern)(local[1])}\\b` + (local[2] ? '\\s*=\\s*' : '\\s*') + `("[^"]+"|'[^']+'|\\([^)]+\\)|[^\\s]+)?` + (addendum ? '[^\\r\\n]*' : '[^\\w\\r\\n]*'), 'g');
|
|
498
|
+
const pattern = new RegExp(`\\b(${(0, types_1.escapePattern)(local[1])}` + (local[2] ? `\\(${util_1.PATTERN_PARENTHESIS}\\)` : '\\b' + (local[3] ? '\\s*=\\s*' : '\\s*') + `("[^"]+"|'[^']+'|\\(${util_1.PATTERN_PARENTHESIS}\\)|\\S+)?`) + ')' + (addendum ? '[^\\r\\n]*' : '[^\\w\\r\\n]*'), 'g');
|
|
258
499
|
pattern.lastIndex = lastIndex;
|
|
259
500
|
let match;
|
|
260
501
|
while (match = pattern.exec(source)) {
|
|
@@ -271,13 +512,13 @@ class Document extends core_1.Client {
|
|
|
271
512
|
}
|
|
272
513
|
}
|
|
273
514
|
if (opening === closing) {
|
|
274
|
-
if (!multiple ||
|
|
275
|
-
return upgrade ? parse_1.XmlWriter.replaceMatch(match, source,
|
|
515
|
+
if (!multiple || local[2] && local[1].includes('.') || match[2] && local[4] && compareValue(match[2]) === compareValue(local[4])) {
|
|
516
|
+
return upgrade && match[1] !== value ? parse_1.XmlWriter.replaceMatch(match, source, replacement, pattern) : source;
|
|
276
517
|
}
|
|
277
518
|
lastIndex = match.index + match[0].length;
|
|
278
519
|
}
|
|
279
520
|
}
|
|
280
|
-
return spliceSource(source, lastIndex, lastIndex, ident.repeat(length) +
|
|
521
|
+
return spliceSource(source, lastIndex, lastIndex, ident.repeat(length) + replacement + newline);
|
|
281
522
|
}
|
|
282
523
|
if (updateOnly) {
|
|
283
524
|
return source;
|
|
@@ -291,15 +532,14 @@ class Document extends core_1.Client {
|
|
|
291
532
|
for (i = length - 1; i >= j; --i) {
|
|
292
533
|
trailing += ident.repeat(i) + '}' + newline;
|
|
293
534
|
}
|
|
294
|
-
const content = leading + ident.repeat(length) +
|
|
295
|
-
return lastIndex > 0 ? spliceSource(source, lastIndex, lastIndex, content) : source + newline + content;
|
|
535
|
+
const content = leading + ident.repeat(length) + replacement + newline + trailing;
|
|
536
|
+
return lastIndex > 0 ? spliceSource(source, lastIndex, lastIndex, content) : source.trimEnd() + newline + newline + content;
|
|
296
537
|
}
|
|
297
538
|
static generateLintTable(messages, options) {
|
|
298
539
|
const { leadingText, trailingText, pathname, filename, ruleWidth = 30, messageWidth = 60 } = options;
|
|
299
540
|
const result = [];
|
|
300
|
-
const truncate = (value, width) => value.length > width ? value.substring(0, width - 3) + '...' : value.padStart(width);
|
|
301
541
|
const currentTime = Date.now();
|
|
302
|
-
let timeStamp = options.timeStamp, maxWidth = 0, maxLine = 0, maxColumn = 0, errorCount = 0, warningCount = 0, fatalErrorCount = 0;
|
|
542
|
+
let timeStamp = options.timeStamp, maxWidth = 0, maxLine = 0, maxColumn = 0, errorCount = 0, warningCount = 0, fatalErrorCount = 0, fixableErrorCount = 0, fixableWarningCount = 0;
|
|
303
543
|
messages.sort((a, b) => {
|
|
304
544
|
const offset = a.line - b.line;
|
|
305
545
|
return offset === 0 ? a.column - b.column : offset;
|
|
@@ -333,22 +573,32 @@ class Document extends core_1.Client {
|
|
|
333
573
|
maxWidth = Math.max(1 + 0 + 1 + 0 + 1 + 2 + Math.min(Math.max(ruleId.length, ruleWidth), ruleWidth) + 2 + Math.min(Math.max(message.length, messageWidth), messageWidth), maxWidth);
|
|
334
574
|
result.push({
|
|
335
575
|
type,
|
|
336
|
-
value: chalk[errorColor]('
|
|
576
|
+
value: chalk[errorColor]('|') + chalk.bold(line.toString().padStart(maxLine)) + chalk.grey(':' + column.toString().padEnd(maxColumn)) + chalk[errorColor]('|') + ' ' + chalk.bold(chalk.white(truncateString(ruleId, ruleWidth))) + ' ' + chalk.grey(truncateString(message, messageWidth)),
|
|
337
577
|
timeStamp
|
|
338
578
|
});
|
|
339
579
|
}
|
|
340
580
|
maxWidth += maxLine + maxColumn;
|
|
341
581
|
const title = (leadingText || '') + (pathname || filename ? (leadingText ? ': ' : '') + (pathname && filename ? path.join(pathname, filename) : pathname || filename) : '');
|
|
342
582
|
const divider = { type: types_1.STATUS_TYPE.INFO, value: '-'.repeat(maxWidth), timeStamp };
|
|
343
|
-
errorCount = (options.errorCount ?? errorCount).toString();
|
|
344
|
-
warningCount = (options.warningCount ?? warningCount).toString();
|
|
583
|
+
errorCount = ((Array.isArray(options.errorCount) ? (fixableErrorCount = options.errorCount[1], options.errorCount[0]) : options.errorCount) ?? errorCount).toString();
|
|
584
|
+
warningCount = ((Array.isArray(options.warningCount) ? (fixableWarningCount = options.warningCount[1], options.warningCount[0]) : options.warningCount) ?? warningCount).toString();
|
|
345
585
|
fatalErrorCount = (options.fatalErrorCount ?? fatalErrorCount).toString();
|
|
346
586
|
const hasFatal = fatalErrorCount !== '0';
|
|
347
|
-
result.unshift(divider, {
|
|
587
|
+
result.unshift(divider, {
|
|
588
|
+
type: types_1.STATUS_TYPE.INFO,
|
|
589
|
+
value: title + ' '.repeat(maxWidth - title.length - (hasFatal ? fatalErrorCount.length + 9 : 0)) + (hasFatal ? `fatal(${chalk.bold.bgRed.white(` ${fatalErrorCount} `)})` : ''),
|
|
590
|
+
timeStamp,
|
|
591
|
+
duration: currentTime - timeStamp
|
|
592
|
+
}, divider);
|
|
348
593
|
result.push(divider);
|
|
349
594
|
if (trailingText) {
|
|
350
|
-
const
|
|
351
|
-
|
|
595
|
+
const errorHint = fixHint(fixableWarningCount, fixableErrorCount, fixableErrorCount);
|
|
596
|
+
const warningHint = fixHint(fixableWarningCount, fixableErrorCount, fixableWarningCount);
|
|
597
|
+
result.push({
|
|
598
|
+
type: types_1.STATUS_TYPE.INFO,
|
|
599
|
+
value: chalk.bold.red('error') + wrapCount(errorCount + errorHint) + ' / ' + chalk.bold.yellow('warning') + wrapCount(warningCount + warningHint) + ' '.repeat(maxWidth - trailingText.length - (7 + errorCount.length + errorHint.length + 3 + warningCount.length + warningHint.length + 9)) + trailingText,
|
|
600
|
+
timeStamp
|
|
601
|
+
});
|
|
352
602
|
}
|
|
353
603
|
return result;
|
|
354
604
|
}
|
|
@@ -373,12 +623,12 @@ class Document extends core_1.Client {
|
|
|
373
623
|
let baseUrl;
|
|
374
624
|
({ baseUrl, ignoreModules, ignoreExtensions } = config);
|
|
375
625
|
const users = this.getUserSettings();
|
|
376
|
-
if (
|
|
626
|
+
if (Array.isArray(users?.extensions)) {
|
|
377
627
|
this._extensions = users.extensions.slice(0);
|
|
378
628
|
}
|
|
379
629
|
if (baseUrl) {
|
|
380
630
|
let pages = this.settings.pages;
|
|
381
|
-
if (
|
|
631
|
+
if ((0, types_1.isPlainObject)(users?.pages)) {
|
|
382
632
|
pages = (0, types_1.isPlainObject)(pages) ? { ...pages, ...users.pages } : users.pages;
|
|
383
633
|
}
|
|
384
634
|
if ((0, types_1.isPlainObject)(pages)) {
|
|
@@ -409,7 +659,7 @@ class Document extends core_1.Client {
|
|
|
409
659
|
items.sort((a, b) => typeof a.ordinal === 'number' && typeof b.ordinal === 'number' ? a.ordinal - b.ordinal : 0);
|
|
410
660
|
mimeMap = items.reduce((a, b) => Object.assign(a, b), {});
|
|
411
661
|
}
|
|
412
|
-
else if (items.length) {
|
|
662
|
+
else if (items.length > 0) {
|
|
413
663
|
mimeMap = { ...items[0] };
|
|
414
664
|
}
|
|
415
665
|
}
|
|
@@ -426,7 +676,7 @@ class Document extends core_1.Client {
|
|
|
426
676
|
}
|
|
427
677
|
}
|
|
428
678
|
}
|
|
429
|
-
if (this.dataSource.length && !ignoreModules?.includes('db')) {
|
|
679
|
+
if (this.dataSource.length > 0 && !ignoreModules?.includes('db')) {
|
|
430
680
|
const db = (_a = this.module).db || (_a.db = {});
|
|
431
681
|
const handler = db.handler;
|
|
432
682
|
const database = this.dataSource.filter(this.forDb.bind(this));
|
|
@@ -492,83 +742,9 @@ class Document extends core_1.Client {
|
|
|
492
742
|
customize(options) {
|
|
493
743
|
const transform = options.transform;
|
|
494
744
|
if (transform) {
|
|
495
|
-
const config = this._transformConfig || (this._transformConfig =
|
|
496
|
-
|
|
497
|
-
if (transform === true || transform === 'etag') {
|
|
498
|
-
etag = true;
|
|
499
|
-
enabled = true;
|
|
500
|
-
}
|
|
501
|
-
else if (typeof transform === 'string') {
|
|
502
|
-
algorithm = transform;
|
|
503
|
-
enabled = true;
|
|
504
|
-
}
|
|
505
|
-
else if ((0, types_1.isPlainObject)(transform)) {
|
|
506
|
-
({ enabled = true, algorithm, etag, expires, renew, limit, exclude, include } = transform);
|
|
507
|
-
}
|
|
508
|
-
if (!enabled) {
|
|
745
|
+
const config = this._transformConfig || (this._transformConfig = new TransformConfig(this.moduleName));
|
|
746
|
+
if (!config.init(transform)) {
|
|
509
747
|
this._transformConfig = null;
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
512
|
-
switch (algorithm = algorithm?.toLowerCase()) {
|
|
513
|
-
case 'md5':
|
|
514
|
-
case 'sha1':
|
|
515
|
-
case 'sha224':
|
|
516
|
-
case 'sha256':
|
|
517
|
-
case 'sha384':
|
|
518
|
-
case 'sha512':
|
|
519
|
-
config.algorithm = algorithm;
|
|
520
|
-
break;
|
|
521
|
-
default:
|
|
522
|
-
config.algorithm = undefined;
|
|
523
|
-
break;
|
|
524
|
-
}
|
|
525
|
-
if (typeof etag === 'boolean') {
|
|
526
|
-
config.etag = etag;
|
|
527
|
-
}
|
|
528
|
-
if (expires && (expires = (0, types_1.parseExpires)(expires)) >= 0) {
|
|
529
|
-
config.expires = Math.min(expires, core_1.Client.MAX_TIMEOUT);
|
|
530
|
-
}
|
|
531
|
-
if (renew) {
|
|
532
|
-
config.renew = true;
|
|
533
|
-
}
|
|
534
|
-
if ((0, types_1.isPlainObject)(exclude)) {
|
|
535
|
-
for (const type in exclude) {
|
|
536
|
-
const item = exclude[type];
|
|
537
|
-
if (item === '*') {
|
|
538
|
-
config.exclude[type] = true;
|
|
539
|
-
}
|
|
540
|
-
else if ((0, types_1.isArray)(item)) {
|
|
541
|
-
config.exclude[type] = item;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
if ((0, types_1.isPlainObject)(include)) {
|
|
546
|
-
for (const type in include) {
|
|
547
|
-
const item = include[type];
|
|
548
|
-
if (item === '*') {
|
|
549
|
-
config.include[type] = true;
|
|
550
|
-
}
|
|
551
|
-
else if ((0, types_1.isArray)(item)) {
|
|
552
|
-
config.include[type] = item;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (limit !== undefined) {
|
|
557
|
-
let value;
|
|
558
|
-
if (typeof limit === 'string') {
|
|
559
|
-
if (parseFloat(limit) === 0) {
|
|
560
|
-
value = 0;
|
|
561
|
-
}
|
|
562
|
-
else if ((value = (0, types_1.formatSize)(limit)) === 0) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
value = limit;
|
|
568
|
-
}
|
|
569
|
-
if (value >= 0) {
|
|
570
|
-
config.limit = value;
|
|
571
|
-
}
|
|
572
748
|
}
|
|
573
749
|
}
|
|
574
750
|
else if (transform === false || transform === null) {
|
|
@@ -592,34 +768,30 @@ class Document extends core_1.Client {
|
|
|
592
768
|
}
|
|
593
769
|
loadConfig(data, name) {
|
|
594
770
|
const value = data[name];
|
|
595
|
-
const getObject = (target, cache) => {
|
|
596
|
-
if (this.settingsOf('transform', 'coerce') === true) {
|
|
597
|
-
(0, types_1.coerceObject)(target, cache);
|
|
598
|
-
}
|
|
599
|
-
return (0, types_1.cloneObject)(data[name] = target, true);
|
|
600
|
-
};
|
|
601
771
|
switch (typeof value) {
|
|
602
772
|
case 'function':
|
|
603
773
|
return value;
|
|
604
774
|
case 'object':
|
|
605
775
|
if (value) {
|
|
606
|
-
return
|
|
776
|
+
return getConfigObject(this, data, name, value, true);
|
|
607
777
|
}
|
|
608
778
|
break;
|
|
609
779
|
case 'string': {
|
|
610
|
-
const warning = (message) => this.addLog(types_1.STATUS_TYPE.ERROR, joinString(this.moduleName, 'transform@' + name, message));
|
|
611
780
|
const result = this.asSourceFile(value);
|
|
612
781
|
if (typeof result === 'function') {
|
|
613
782
|
if (!name.endsWith('-output')) {
|
|
614
783
|
return data[name] = result;
|
|
615
784
|
}
|
|
616
|
-
|
|
785
|
+
errorConfig(this, "\"output\" can only be a plain object");
|
|
617
786
|
}
|
|
618
787
|
else if ((0, types_1.isPlainObject)(result)) {
|
|
619
|
-
return
|
|
788
|
+
return getConfigObject(this, data, name, result, false);
|
|
789
|
+
}
|
|
790
|
+
else if (path.isAbsolute(value)) {
|
|
791
|
+
errorConfig(this, name, "Unsupported access", value);
|
|
620
792
|
}
|
|
621
793
|
else {
|
|
622
|
-
|
|
794
|
+
errorConfig(this, name, "Unknown");
|
|
623
795
|
}
|
|
624
796
|
break;
|
|
625
797
|
}
|
|
@@ -628,24 +800,25 @@ class Document extends core_1.Client {
|
|
|
628
800
|
}
|
|
629
801
|
resolveDir(name, ...paths) {
|
|
630
802
|
let baseDir = this.settings.directory?.[name];
|
|
631
|
-
if (baseDir) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
if (fs.existsSync(result = path.join(baseDir, ...paths)) && result.startsWith(baseDir)) {
|
|
803
|
+
if (!baseDir) {
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
try {
|
|
807
|
+
baseDir = path.resolve(baseDir);
|
|
808
|
+
const username = this.host?.username;
|
|
809
|
+
let result;
|
|
810
|
+
if (username) {
|
|
811
|
+
const leading = path.join(baseDir, 'users', username);
|
|
812
|
+
if (fs.existsSync(result = path.join(leading, ...paths))) {
|
|
643
813
|
return result;
|
|
644
814
|
}
|
|
645
815
|
}
|
|
646
|
-
|
|
816
|
+
if (fs.existsSync(result = path.join(baseDir, ...paths))) {
|
|
817
|
+
return result;
|
|
647
818
|
}
|
|
648
819
|
}
|
|
820
|
+
catch {
|
|
821
|
+
}
|
|
649
822
|
}
|
|
650
823
|
asSourceFile(value, options) {
|
|
651
824
|
let encoding, persist, cache;
|
|
@@ -738,14 +911,6 @@ class Document extends core_1.Client {
|
|
|
738
911
|
if (!(0, types_1.isPlainObject)(imports)) {
|
|
739
912
|
return;
|
|
740
913
|
}
|
|
741
|
-
const toPosix = (value) => value.replace(/(?:^\\|\\+)/g, '/');
|
|
742
|
-
const normalizeDir = (value, check) => {
|
|
743
|
-
const sep = !check && value.includes('\\') && !value.includes('/') ? '\\' : '/';
|
|
744
|
-
if (check) {
|
|
745
|
-
value = toPosix(value).toLowerCase();
|
|
746
|
-
}
|
|
747
|
-
return value.endsWith(sep) ? value : value + sep;
|
|
748
|
-
};
|
|
749
914
|
const importsStrict = this.getUserSettings()?.imports_strict ?? this.settings.imports_strict;
|
|
750
915
|
const scopes = (importsStrict ? this.findSourceScope(uri, imports) : []).concat([imports]);
|
|
751
916
|
const isDir = /[\\/]$/;
|
|
@@ -775,7 +940,7 @@ class Document extends core_1.Client {
|
|
|
775
940
|
found.push([url, result]);
|
|
776
941
|
}
|
|
777
942
|
else if (core_1.Client.isPath(result = path.join(result, remote.substring(local.length)))) {
|
|
778
|
-
return PLATFORM_WIN32 ? toPosix(result) : result;
|
|
943
|
+
return core_1.Client.PLATFORM_WIN32 ? toPosix(result) : result;
|
|
779
944
|
}
|
|
780
945
|
}
|
|
781
946
|
}
|
|
@@ -785,7 +950,7 @@ class Document extends core_1.Client {
|
|
|
785
950
|
for (const scope of scopes) {
|
|
786
951
|
for (const url in scope) {
|
|
787
952
|
const local = normalizeDir(url);
|
|
788
|
-
if ((normalizeDir(uri) === local || PLATFORM_WIN32 && normalizeDir(uri, true) === local.toLowerCase()) && (0, types_1.isString)(result = scope[url])) {
|
|
953
|
+
if ((normalizeDir(uri) === local || core_1.Client.PLATFORM_WIN32 && normalizeDir(uri, true) === local.toLowerCase()) && (0, types_1.isString)(result = scope[url])) {
|
|
789
954
|
return result;
|
|
790
955
|
}
|
|
791
956
|
}
|
|
@@ -796,22 +961,21 @@ class Document extends core_1.Client {
|
|
|
796
961
|
}
|
|
797
962
|
}
|
|
798
963
|
}
|
|
799
|
-
if (found.length) {
|
|
964
|
+
if (found.length > 0) {
|
|
800
965
|
found.sort((a, b) => b[0].length - a[0].length);
|
|
801
|
-
const toPath = (hostname) => path.resolve(hostname[1], uri.substring(normalizeDir(hostname[0]).length).split('?')[0]);
|
|
802
966
|
if (importsStrict) {
|
|
803
967
|
for (const url of found) {
|
|
804
|
-
if (core_1.Client.isPath(result = toPath(url))) {
|
|
968
|
+
if (core_1.Client.isPath(result = toPath(uri, url))) {
|
|
805
969
|
break;
|
|
806
970
|
}
|
|
807
971
|
result = '';
|
|
808
972
|
}
|
|
809
973
|
}
|
|
810
974
|
else {
|
|
811
|
-
result = toPath(found[0]);
|
|
975
|
+
result = toPath(uri, found[0]);
|
|
812
976
|
}
|
|
813
977
|
if (result) {
|
|
814
|
-
return PLATFORM_WIN32 ? toPosix(result) : result;
|
|
978
|
+
return core_1.Client.PLATFORM_WIN32 ? toPosix(result) : result;
|
|
815
979
|
}
|
|
816
980
|
}
|
|
817
981
|
}
|
|
@@ -823,7 +987,7 @@ class Document extends core_1.Client {
|
|
|
823
987
|
if (Document.isFile(href, 'unc') || path.isAbsolute(href)) {
|
|
824
988
|
sourceFile.push([href]);
|
|
825
989
|
}
|
|
826
|
-
else if (Object.keys(imports).length) {
|
|
990
|
+
else if (Object.keys(imports).length > 0) {
|
|
827
991
|
const bundleId = file.bundleId;
|
|
828
992
|
const assets = !(0, types_1.isEmpty)(bundleId) ? this.assets.filter(item => item.bundleId === bundleId).sort((a, b) => a.bundleIndex - b.bundleIndex) : [file];
|
|
829
993
|
if (!Array.isArray(bundleContent) || bundleContent.length !== assets.length - 1) {
|
|
@@ -863,7 +1027,7 @@ class Document extends core_1.Client {
|
|
|
863
1027
|
}
|
|
864
1028
|
}
|
|
865
1029
|
}
|
|
866
|
-
if (sourceFile.length && (sourceFile[0] && (mainFile = sourceFile[0][0]) || !invalid) && (!this.hasOwnPermission() || !sourceFile.some(item => item[0] && !this.canRead(item[0])))) {
|
|
1030
|
+
if (sourceFile.length > 0 && (sourceFile[0] && (mainFile = sourceFile[0][0]) || !invalid) && (!this.hasOwnPermission() || !sourceFile.some(item => item[0] && !this.canRead(item[0])))) {
|
|
867
1031
|
return { code, sourceFile: !invalid ? sourceFile : undefined, sourcesRelativeTo: mainFile && path.dirname(mainFile) };
|
|
868
1032
|
}
|
|
869
1033
|
};
|
|
@@ -872,7 +1036,7 @@ class Document extends core_1.Client {
|
|
|
872
1036
|
return (code, imports = this.imports) => {
|
|
873
1037
|
const uri = file.uri;
|
|
874
1038
|
let source, sourceFile;
|
|
875
|
-
if (code && Object.keys(imports).length) {
|
|
1039
|
+
if (code && Object.keys(imports).length > 0) {
|
|
876
1040
|
const output = this.resolveImports?.(file, code, uri && this.findSourceRoot(uri, imports));
|
|
877
1041
|
if (output) {
|
|
878
1042
|
source = output;
|
|
@@ -950,9 +1114,9 @@ class Document extends core_1.Client {
|
|
|
950
1114
|
if (length === 0 && !target.outputEmpty) {
|
|
951
1115
|
return '';
|
|
952
1116
|
}
|
|
953
|
-
let name;
|
|
954
1117
|
try {
|
|
955
|
-
const
|
|
1118
|
+
const name = target.name;
|
|
1119
|
+
const context = require(name);
|
|
956
1120
|
const { singleRow, options = {} } = target;
|
|
957
1121
|
let { compile, output } = options;
|
|
958
1122
|
if (!(0, types_1.isPlainObject)(output)) {
|
|
@@ -968,44 +1132,50 @@ class Document extends core_1.Client {
|
|
|
968
1132
|
}
|
|
969
1133
|
const username = this.host?.username || '';
|
|
970
1134
|
const cache = CACHE_TEMPLATE[name] || (CACHE_TEMPLATE[name] = {});
|
|
971
|
-
const cacheKey = username +
|
|
972
|
-
let result = '', render, valid;
|
|
973
|
-
if (!
|
|
1135
|
+
const cacheKey = (username ? username + ':' : '') + (0, types_1.hashKey)(template + (compile ? core_1.Client.asString(compile) : ''));
|
|
1136
|
+
let result = '', render = cache[cacheKey], valid;
|
|
1137
|
+
if (!render) {
|
|
974
1138
|
render = await context.compile(template, compile);
|
|
975
1139
|
cache[cacheKey] = render;
|
|
976
1140
|
if (!core_1.Client.enabled("memory.settings.users", username)) {
|
|
977
1141
|
setTimeout(() => delete cache[cacheKey], 60000);
|
|
978
1142
|
}
|
|
979
1143
|
}
|
|
980
|
-
|
|
981
|
-
|
|
1144
|
+
const writeRow = async (row) => {
|
|
1145
|
+
const content = await render.call(context, row);
|
|
1146
|
+
if (content !== undefined && content !== null) {
|
|
1147
|
+
result += content;
|
|
1148
|
+
valid = true;
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
for (let i = 0, j = 0; i < length; ++i) {
|
|
1152
|
+
let row = data[i];
|
|
1153
|
+
if ((0, types_1.isPlainObject)(row)) {
|
|
982
1154
|
row.__index__ ?? (row.__index__ = ++j);
|
|
983
1155
|
if (output) {
|
|
984
1156
|
row = { ...output, ...row };
|
|
985
1157
|
}
|
|
986
1158
|
}
|
|
987
1159
|
else if (!(0, types_1.isObject)(row)) {
|
|
988
|
-
this.addLog(types_1.STATUS_TYPE.WARN, joinString(
|
|
1160
|
+
this.addLog(types_1.STATUS_TYPE.WARN, joinString('view engine', name, `row #${i + 1}`, core_1.Client.asString(row) || "Unknown"));
|
|
989
1161
|
continue;
|
|
990
1162
|
}
|
|
991
1163
|
if (!singleRow) {
|
|
992
|
-
|
|
993
|
-
if (content !== undefined && content !== null) {
|
|
994
|
-
result += content;
|
|
995
|
-
valid = true;
|
|
996
|
-
}
|
|
1164
|
+
await writeRow(row);
|
|
997
1165
|
}
|
|
998
1166
|
}
|
|
999
|
-
|
|
1167
|
+
if (singleRow) {
|
|
1168
|
+
await writeRow(data);
|
|
1169
|
+
}
|
|
1170
|
+
return valid ? result : null;
|
|
1000
1171
|
}
|
|
1001
1172
|
catch (err) {
|
|
1002
1173
|
this.abort('view_engine');
|
|
1003
|
-
this.checkPackage(err, name, "Unknown", 4);
|
|
1174
|
+
this.checkPackage(err, target.name, "Unknown", 4);
|
|
1004
1175
|
}
|
|
1005
1176
|
return null;
|
|
1006
1177
|
}
|
|
1007
1178
|
async transform(type, code, format, options = {}) {
|
|
1008
|
-
var _a, _b, _c;
|
|
1009
1179
|
let transform = this.settings.transform, data;
|
|
1010
1180
|
if (!(transform && (0, types_1.isObject)(data = transform[type]))) {
|
|
1011
1181
|
return;
|
|
@@ -1014,88 +1184,61 @@ class Document extends core_1.Client {
|
|
|
1014
1184
|
const username = this.host?.username || '';
|
|
1015
1185
|
const config = this._transformConfig;
|
|
1016
1186
|
const cacheData = config && options.cacheData;
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (stored) {
|
|
1029
|
-
if (stored.etag !== etag) {
|
|
1030
|
-
deleteTransform(etagMap, uri, stored.timeout);
|
|
1031
|
-
}
|
|
1032
|
-
else if (result = getTransformData(stored, formatKey, encoding)) {
|
|
1033
|
-
resetTransform(config, etagMap, uri, stored);
|
|
1034
|
-
cacheName = 'etag';
|
|
1035
|
-
}
|
|
1187
|
+
let cache = null, cacheDir = false, excludeKey;
|
|
1188
|
+
if (cacheData) {
|
|
1189
|
+
cacheDir = username && core_1.Client.enabled("memory.settings.users", username) ? true : this.cacheDir || core_1.Client.enabled("memory.settings.users");
|
|
1190
|
+
if (cacheDir && !CACHE_EXTERNAL[excludeKey = this.moduleName + '_' + type + '_' + format] && config.valid(type, format)) {
|
|
1191
|
+
const { uri, etag } = cacheData;
|
|
1192
|
+
const encoding = (0, types_1.getEncoding)(cacheData.encoding);
|
|
1193
|
+
const hashOpts = core_1.Client.asString(options.external) + core_1.Client.asString(options.metadata);
|
|
1194
|
+
cache = new TransformCache(config, cacheData, cacheDir, encoding, (username ? username + ':' : '') + type + '_' + format + '_' + encoding + (hashOpts ? '_' + (0, types_1.hashKey)(hashOpts) : ''));
|
|
1195
|
+
let result, cacheName;
|
|
1196
|
+
if (config.etag && etag && uri) {
|
|
1197
|
+
[result, cacheName] = config.useETag(cache, etag, uri);
|
|
1036
1198
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
const limit = config.limit;
|
|
1041
|
-
if ((limit === Infinity || limit > 0 && Buffer.byteLength(code, encoding) <= limit) && (hashKey = core_1.Client.asHash(code, { algorithm, encoding }))) {
|
|
1042
|
-
const hashMap = CACHE_HASH[_b = this.moduleName] || (CACHE_HASH[_b] = {});
|
|
1043
|
-
const stored = hashMap[hashKey];
|
|
1044
|
-
if (stored && (result = getTransformData(stored, formatKey, encoding))) {
|
|
1045
|
-
resetTransform(config, hashMap, hashKey, stored);
|
|
1046
|
-
cacheName = algorithm;
|
|
1047
|
-
}
|
|
1199
|
+
if (!result) {
|
|
1200
|
+
if (config.algorithm) {
|
|
1201
|
+
[result, cacheName] = config.useHash(cache, code);
|
|
1048
1202
|
}
|
|
1049
|
-
else {
|
|
1050
|
-
|
|
1203
|
+
else if (uri) {
|
|
1204
|
+
[result, cacheName] = config.useUri(cache, code, uri);
|
|
1051
1205
|
}
|
|
1052
1206
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
}
|
|
1060
|
-
else if (result = getTransformData(stored, formatKey, encoding)) {
|
|
1061
|
-
resetTransform(config, codeMap, uri, stored);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
else {
|
|
1066
|
-
formatKey = '';
|
|
1207
|
+
if (result) {
|
|
1208
|
+
result.log?.forEach(log => {
|
|
1209
|
+
this.addLog(log);
|
|
1210
|
+
});
|
|
1211
|
+
this.formatMessage(4, type, [joinString(cacheName, format.filter(value => value).join(' | '), options.filename), 'cache'], uri, { ...core_1.Client.LOG_STYLE_NOTICE, hintBold: true });
|
|
1212
|
+
return result;
|
|
1067
1213
|
}
|
|
1068
1214
|
}
|
|
1069
|
-
if (result) {
|
|
1070
|
-
result.storedLog?.forEach(log => this.addLog(log));
|
|
1071
|
-
this.formatMessage(4, type, [joinString(cacheName, format.filter(value => value).join(' | '), options.filename), 'cache'], uri, { ...core_1.Client.LOG_STYLE_NOTICE, hintBold: true });
|
|
1072
|
-
return result;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
if (cacheData) {
|
|
1076
1215
|
delete options.cacheData;
|
|
1077
1216
|
}
|
|
1078
1217
|
const imports = transform.imports || (transform.imports = {});
|
|
1079
1218
|
const series = new transform_1.TransformSeries(type, code, options);
|
|
1080
1219
|
series.init(this, __dirname);
|
|
1081
1220
|
let valid, excluded, userData, userImports, ignoreCache, storedLog, sourceFiles;
|
|
1082
|
-
if (username && (transform = this.
|
|
1221
|
+
if (username && (0, types_1.isObject)(transform = this.getUserSettings()?.transform)) {
|
|
1083
1222
|
userData = transform[type];
|
|
1223
|
+
if (!(0, types_1.isObject)(userData)) {
|
|
1224
|
+
userData = undefined;
|
|
1225
|
+
}
|
|
1084
1226
|
userImports = transform.imports;
|
|
1085
1227
|
}
|
|
1086
1228
|
const abortTransform = () => {
|
|
1087
1229
|
ignoreCache = true;
|
|
1088
1230
|
this.abort('transform');
|
|
1089
1231
|
};
|
|
1090
|
-
for (let i = 0, length = format.length
|
|
1232
|
+
for (let i = 0, length = format.length; i < length; ++i) {
|
|
1091
1233
|
if (this.aborted) {
|
|
1092
1234
|
break;
|
|
1093
1235
|
}
|
|
1094
|
-
|
|
1236
|
+
const name = format[i];
|
|
1237
|
+
if (!name) {
|
|
1095
1238
|
continue;
|
|
1096
1239
|
}
|
|
1097
1240
|
let [plugin, baseConfig, outputConfig, baseSettings] = this.findConfig(data, name, type);
|
|
1098
|
-
if (
|
|
1241
|
+
if (userData) {
|
|
1099
1242
|
const [a, b, c, d] = this.findConfig(userData, name, type);
|
|
1100
1243
|
if (!plugin || a === plugin) {
|
|
1101
1244
|
if (b) {
|
|
@@ -1120,14 +1263,14 @@ class Document extends core_1.Client {
|
|
|
1120
1263
|
}
|
|
1121
1264
|
}
|
|
1122
1265
|
if (!baseSettings) {
|
|
1123
|
-
excluded =
|
|
1266
|
+
excluded = isExcluded(type, name, config, cacheData);
|
|
1124
1267
|
}
|
|
1125
1268
|
outputConfig || (outputConfig = {});
|
|
1126
1269
|
if (plugin && baseConfig) {
|
|
1127
1270
|
series.outputConfig = outputConfig;
|
|
1128
1271
|
const source = series.code;
|
|
1129
1272
|
const startTime = process.hrtime();
|
|
1130
|
-
const hint = plugin + '
|
|
1273
|
+
const hint = plugin + ':' + name;
|
|
1131
1274
|
const next = (value) => {
|
|
1132
1275
|
if (this.aborted) {
|
|
1133
1276
|
valid = false;
|
|
@@ -1138,12 +1281,12 @@ class Document extends core_1.Client {
|
|
|
1138
1281
|
if (typeof value !== 'string' || (0, types_1.isArray)(out.sourceFiles) && this.hasOwnPermission() && out.sourceFiles.some(item => !this.canRead(item, { ownPermissionOnly: true }))) {
|
|
1139
1282
|
failed = true;
|
|
1140
1283
|
ignoreCache = true;
|
|
1141
|
-
this.writeFail(["Unable to transform document", plugin], (0, types_1.errorMessage)(plugin, name, typeof value === 'string' ? "Unsupported access" :
|
|
1284
|
+
this.writeFail(["Unable to transform document", plugin], (0, types_1.errorMessage)(plugin, name, typeof value === 'string' ? "Unsupported access" : "Empty"), { type: 4, startTime });
|
|
1142
1285
|
}
|
|
1143
1286
|
else if (source !== value) {
|
|
1144
1287
|
series.code = value;
|
|
1145
1288
|
valid = true;
|
|
1146
|
-
if (out.ignoreCache &&
|
|
1289
|
+
if (out.ignoreCache && isExcluded(type, name, config, cacheData)) {
|
|
1147
1290
|
ignoreCache = true;
|
|
1148
1291
|
}
|
|
1149
1292
|
if ((0, types_1.isArray)(out.sourceFiles)) {
|
|
@@ -1151,28 +1294,42 @@ class Document extends core_1.Client {
|
|
|
1151
1294
|
sourceFiles = out.sourceFiles.slice(0);
|
|
1152
1295
|
}
|
|
1153
1296
|
else {
|
|
1154
|
-
out.sourceFiles.forEach(item =>
|
|
1297
|
+
out.sourceFiles.forEach(item => {
|
|
1298
|
+
if (!sourceFiles.includes(item)) {
|
|
1299
|
+
sourceFiles.push(item);
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1155
1302
|
}
|
|
1156
1303
|
}
|
|
1157
1304
|
}
|
|
1158
1305
|
if ((0, types_1.isArray)(out.logAppend)) {
|
|
1159
|
-
out.logAppend.forEach(log =>
|
|
1306
|
+
out.logAppend.forEach(log => {
|
|
1307
|
+
this.addLog(log);
|
|
1308
|
+
});
|
|
1160
1309
|
(storedLog || (storedLog = [])).push(...out.logAppend);
|
|
1161
1310
|
bypassLog = true;
|
|
1162
1311
|
}
|
|
1163
1312
|
if ((0, types_1.isArray)(out.logQueued)) {
|
|
1164
|
-
out.logQueued.forEach(log =>
|
|
1313
|
+
out.logQueued.forEach(log => {
|
|
1314
|
+
this.writeLog(log, true);
|
|
1315
|
+
});
|
|
1165
1316
|
(storedLog || (storedLog = [])).push(...out.logQueued);
|
|
1166
1317
|
bypassLog = true;
|
|
1167
1318
|
}
|
|
1168
1319
|
if (i < length - 1) {
|
|
1169
1320
|
series.reset();
|
|
1170
1321
|
}
|
|
1171
|
-
this.writeTimeProcess(failed ? 'CHECK' : type, joinString(
|
|
1322
|
+
this.writeTimeProcess(failed ? 'CHECK' : type, joinString(plugin, name, options.filename) + (series.out.messageAppend || ''), startTime, { failed, bypassLog });
|
|
1172
1323
|
};
|
|
1173
|
-
this.formatMessage(4, type, [
|
|
1324
|
+
this.formatMessage(4, type, ["Transforming source...", hint], options.filename, { hintColor: 'cyan' });
|
|
1174
1325
|
try {
|
|
1175
|
-
let context
|
|
1326
|
+
let context;
|
|
1327
|
+
try {
|
|
1328
|
+
context = require(plugin);
|
|
1329
|
+
}
|
|
1330
|
+
catch {
|
|
1331
|
+
context = await (0, types_1.importESM)(plugin);
|
|
1332
|
+
}
|
|
1176
1333
|
series.packageName = plugin;
|
|
1177
1334
|
if (typeof baseConfig === 'function') {
|
|
1178
1335
|
series.baseConfig = outputConfig;
|
|
@@ -1181,10 +1338,10 @@ class Document extends core_1.Client {
|
|
|
1181
1338
|
}
|
|
1182
1339
|
else {
|
|
1183
1340
|
const thisArg = core_1.Client.enabled("node.process.inline") ? process : null;
|
|
1184
|
-
const
|
|
1341
|
+
const inlineArg = core_1.Client.enabled("node.require.inline");
|
|
1185
1342
|
const args = [context, source, series];
|
|
1186
1343
|
if (baseConfig.toString().startsWith('async')) {
|
|
1187
|
-
if (
|
|
1344
|
+
if (inlineArg) {
|
|
1188
1345
|
args.push(require);
|
|
1189
1346
|
}
|
|
1190
1347
|
next(await baseConfig.apply(thisArg, args));
|
|
@@ -1192,10 +1349,10 @@ class Document extends core_1.Client {
|
|
|
1192
1349
|
else {
|
|
1193
1350
|
next(await new Promise(resolve => {
|
|
1194
1351
|
args.push(resolve);
|
|
1195
|
-
if (
|
|
1352
|
+
if (inlineArg) {
|
|
1196
1353
|
args.push(require);
|
|
1197
1354
|
}
|
|
1198
|
-
baseConfig.apply(thisArg, args);
|
|
1355
|
+
void baseConfig.apply(thisArg, args);
|
|
1199
1356
|
}));
|
|
1200
1357
|
}
|
|
1201
1358
|
}
|
|
@@ -1204,24 +1361,38 @@ class Document extends core_1.Client {
|
|
|
1204
1361
|
let transformer = CACHE_PACKAGE[plugin + username];
|
|
1205
1362
|
if (!transformer) {
|
|
1206
1363
|
try {
|
|
1207
|
-
let pkg = this.resolveDir('package', plugin + '.js') || userImports?.[plugin] || imports[plugin] ||
|
|
1364
|
+
let pkg = this.resolveDir('package', plugin + '.js') || this.resolveDir('package', plugin + '.cjs') || this.resolveDir('package', plugin + '.mjs') || userImports?.[plugin] || imports[plugin] || types_1.IMPORT_MAP[plugin];
|
|
1208
1365
|
if (pkg) {
|
|
1209
|
-
const match = /^(@?\S+)
|
|
1366
|
+
const match = /^(@?\S+)[@:](\d+(?:\.\d+(?:[.-]\S+)?)?|[a-z]+)$/.exec(pkg);
|
|
1210
1367
|
if (match) {
|
|
1211
1368
|
pkg = match[1];
|
|
1212
1369
|
series.version = match[2];
|
|
1213
1370
|
}
|
|
1214
|
-
|
|
1371
|
+
const ext = path.extname(pkg);
|
|
1372
|
+
if (ext === '.mjs') {
|
|
1373
|
+
transformer = await (0, types_1.importESM)(pkg, true, true);
|
|
1374
|
+
}
|
|
1375
|
+
else if (ext === '.cjs') {
|
|
1376
|
+
transformer = require(pkg);
|
|
1377
|
+
}
|
|
1378
|
+
else {
|
|
1379
|
+
try {
|
|
1380
|
+
transformer = require(pkg);
|
|
1381
|
+
}
|
|
1382
|
+
catch {
|
|
1383
|
+
transformer = await (0, types_1.importESM)(pkg, true, true);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1215
1386
|
}
|
|
1216
1387
|
else {
|
|
1217
1388
|
transformer = context;
|
|
1218
1389
|
context = this;
|
|
1219
1390
|
}
|
|
1391
|
+
if ((0, types_1.isObject)(transformer) && 'default' in transformer) {
|
|
1392
|
+
transformer = transformer.default;
|
|
1393
|
+
}
|
|
1220
1394
|
if (typeof transformer !== 'function') {
|
|
1221
|
-
|
|
1222
|
-
if (typeof transformer !== 'function') {
|
|
1223
|
-
throw (0, types_1.errorMessage)(plugin, pkg || name, 'Invalid function');
|
|
1224
|
-
}
|
|
1395
|
+
throw (0, types_1.errorMessage)(plugin, pkg || name, "Invalid function");
|
|
1225
1396
|
}
|
|
1226
1397
|
if (pkg) {
|
|
1227
1398
|
CACHE_PACKAGE[plugin + username] = transformer;
|
|
@@ -1248,10 +1419,10 @@ class Document extends core_1.Client {
|
|
|
1248
1419
|
else {
|
|
1249
1420
|
abortTransform();
|
|
1250
1421
|
if (plugin) {
|
|
1251
|
-
this.writeFail("Unable to load configuration", (0, types_1.errorMessage)(plugin, name,
|
|
1422
|
+
this.writeFail("Unable to load configuration", (0, types_1.errorMessage)(plugin, name, "Invalid config"), 4);
|
|
1252
1423
|
}
|
|
1253
1424
|
else {
|
|
1254
|
-
this.writeFail(
|
|
1425
|
+
this.writeFail("Format method was not found", (0, types_1.errorValue)(name, "Unknown"), 4);
|
|
1255
1426
|
}
|
|
1256
1427
|
}
|
|
1257
1428
|
}
|
|
@@ -1277,49 +1448,8 @@ class Document extends core_1.Client {
|
|
|
1277
1448
|
if (sourceFiles) {
|
|
1278
1449
|
output.sourceFiles = sourceFiles;
|
|
1279
1450
|
}
|
|
1280
|
-
if (
|
|
1281
|
-
|
|
1282
|
-
const formatData = { ...output, storedLog };
|
|
1283
|
-
const lastAccessed = Date.now();
|
|
1284
|
-
if (config.etag && etag && uri) {
|
|
1285
|
-
const etagMap = CACHE_ETAG[this.moduleName];
|
|
1286
|
-
const stored = etagMap[uri];
|
|
1287
|
-
if (stored) {
|
|
1288
|
-
if (stored.etag === etag) {
|
|
1289
|
-
stored.format[formatKey] = setTransformData(type, cacheDir, formatData);
|
|
1290
|
-
stored.lastAccessed = lastAccessed;
|
|
1291
|
-
return output;
|
|
1292
|
-
}
|
|
1293
|
-
deleteTransform(etagMap, uri, stored.timeout);
|
|
1294
|
-
}
|
|
1295
|
-
etagMap[uri] = { lastAccessed, etag, timeout: renewTransform(etagMap, uri, config.expires), format: { [formatKey]: setTransformData(type, cacheDir, formatData) } };
|
|
1296
|
-
++CACHE_TOTAL;
|
|
1297
|
-
}
|
|
1298
|
-
else if (hashKey) {
|
|
1299
|
-
const hashMap = CACHE_HASH[this.moduleName];
|
|
1300
|
-
const stored = hashMap[hashKey];
|
|
1301
|
-
if (stored) {
|
|
1302
|
-
stored.format[formatKey] = setTransformData(type, cacheDir, formatData);
|
|
1303
|
-
stored.lastAccessed = lastAccessed;
|
|
1304
|
-
return output;
|
|
1305
|
-
}
|
|
1306
|
-
hashMap[hashKey] = { lastAccessed, timeout: renewTransform(hashMap, hashKey, config.expires), format: { [formatKey]: setTransformData(type, cacheDir, formatData) } };
|
|
1307
|
-
++CACHE_TOTAL;
|
|
1308
|
-
}
|
|
1309
|
-
else if (uri) {
|
|
1310
|
-
const codeMap = CACHE_CODE[this.moduleName];
|
|
1311
|
-
const stored = codeMap[uri];
|
|
1312
|
-
if (stored) {
|
|
1313
|
-
if (stored.code === code) {
|
|
1314
|
-
stored.format[formatKey] = setTransformData(type, cacheDir, formatData);
|
|
1315
|
-
stored.lastAccessed = lastAccessed;
|
|
1316
|
-
return output;
|
|
1317
|
-
}
|
|
1318
|
-
deleteTransform(codeMap, uri, stored.timeout);
|
|
1319
|
-
}
|
|
1320
|
-
codeMap[uri] = { lastAccessed, code, timeout: renewTransform(codeMap, uri, config.expires), format: { [formatKey]: setTransformData(type, cacheDir, formatData) } };
|
|
1321
|
-
++CACHE_TOTAL;
|
|
1322
|
-
}
|
|
1451
|
+
if (!excluded && !ignoreCache && cache?.formatType) {
|
|
1452
|
+
void cache.finalize(type, code, { ...output, log: storedLog });
|
|
1323
1453
|
}
|
|
1324
1454
|
return output;
|
|
1325
1455
|
}
|
|
@@ -1327,27 +1457,27 @@ class Document extends core_1.Client {
|
|
|
1327
1457
|
this._assets = value;
|
|
1328
1458
|
}
|
|
1329
1459
|
get assets() {
|
|
1330
|
-
if (this.
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1460
|
+
if (this._assets) {
|
|
1461
|
+
return this._assets;
|
|
1462
|
+
}
|
|
1463
|
+
const host = this.host;
|
|
1464
|
+
if (host && 'getDocumentAssets' in host) {
|
|
1465
|
+
return this._assets = host.getDocumentAssets(this);
|
|
1336
1466
|
}
|
|
1337
|
-
return
|
|
1467
|
+
return [];
|
|
1338
1468
|
}
|
|
1339
1469
|
set dataSource(value) {
|
|
1340
1470
|
this._dataSource = value;
|
|
1341
1471
|
}
|
|
1342
1472
|
get dataSource() {
|
|
1343
|
-
if (this.
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1473
|
+
if (this._dataSource) {
|
|
1474
|
+
return this._dataSource;
|
|
1475
|
+
}
|
|
1476
|
+
const host = this.host;
|
|
1477
|
+
if (host && 'getDataSourceItems' in host) {
|
|
1478
|
+
return this._dataSource = host.getDataSourceItems(this);
|
|
1349
1479
|
}
|
|
1350
|
-
return
|
|
1480
|
+
return [];
|
|
1351
1481
|
}
|
|
1352
1482
|
set imports(value) {
|
|
1353
1483
|
if (!(0, types_1.isPlainObject)(value)) {
|
|
@@ -1373,5 +1503,4 @@ class Document extends core_1.Client {
|
|
|
1373
1503
|
return this.assets.some(item => item.watch);
|
|
1374
1504
|
}
|
|
1375
1505
|
}
|
|
1376
|
-
|
|
1377
1506
|
module.exports = Document;
|