@pi-r/chrome 0.6.3 → 0.6.5
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/LICENSE +1 -1
- package/README.md +6 -3
- package/index.js +120 -86
- package/package.json +5 -5
- package/types/index.d.ts +8 -7
- package/types/squared.d.ts +16 -2
package/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright
|
|
1
|
+
Copyright 2024 An Pham
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
package/README.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# @pi-r/chrome
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Documentation
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- [E-mc](https://e-mc.readthedocs.io/en/latest/document/index.html)
|
|
6
|
+
- [squared](https://squared.readthedocs.io)
|
|
7
|
+
|
|
8
|
+
## LICENSE
|
|
6
9
|
|
|
7
10
|
MIT
|
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const path = require("path");
|
|
4
3
|
const fs = require("fs");
|
|
5
4
|
const asset_1 = require("@e-mc/document/asset");
|
|
@@ -166,7 +165,7 @@ function addCacheItem(map, key, data, timeout) {
|
|
|
166
165
|
map.set(key, [
|
|
167
166
|
Date.now(),
|
|
168
167
|
data,
|
|
169
|
-
setTimeout(() => deleteCacheItem(map, key), timeout * 1000
|
|
168
|
+
setTimeout(() => deleteCacheItem(map, key), timeout * 1000)
|
|
170
169
|
]);
|
|
171
170
|
}
|
|
172
171
|
function deleteCacheItem(map, key) {
|
|
@@ -224,10 +223,10 @@ function hasCondition(data, condition) {
|
|
|
224
223
|
if (arg2) {
|
|
225
224
|
switch (item[0]) {
|
|
226
225
|
case 'eq':
|
|
227
|
-
valid = parseArg(arg1) == parseArg(arg2);
|
|
226
|
+
valid = parseArg(arg1) == parseArg(arg2);
|
|
228
227
|
break;
|
|
229
228
|
case 'ne':
|
|
230
|
-
valid = parseArg(arg1) != parseArg(arg2);
|
|
229
|
+
valid = parseArg(arg1) != parseArg(arg2);
|
|
231
230
|
break;
|
|
232
231
|
case 'lt':
|
|
233
232
|
valid = parseArg(arg1) < parseArg(arg2);
|
|
@@ -351,7 +350,7 @@ function createHash(host, file, hash, bufferMap) {
|
|
|
351
350
|
throw (0, types_1.errorMessage)('hash', 'Source not found', filename);
|
|
352
351
|
}
|
|
353
352
|
catch (err) {
|
|
354
|
-
host.writeFail(["Unable to read file"
|
|
353
|
+
host.writeFail(["Unable to read file", filename], err, 32);
|
|
355
354
|
}
|
|
356
355
|
}
|
|
357
356
|
function getSrcURL(parent, file) {
|
|
@@ -513,7 +512,7 @@ function transformURL(host, parent, type, source, importFile) {
|
|
|
513
512
|
}
|
|
514
513
|
}
|
|
515
514
|
if (asset.initialValue && !asset.initialValue.cacheable) {
|
|
516
|
-
parent.flags |= 16
|
|
515
|
+
parent.flags |= 16;
|
|
517
516
|
}
|
|
518
517
|
related.push(asset);
|
|
519
518
|
}
|
|
@@ -609,7 +608,7 @@ function transformURL(host, parent, type, source, importFile) {
|
|
|
609
608
|
else {
|
|
610
609
|
related.push(asset);
|
|
611
610
|
if (!(0, types_1.existsFlag)(asset.flags)) {
|
|
612
|
-
asset.flags |= 8
|
|
611
|
+
asset.flags |= 8;
|
|
613
612
|
}
|
|
614
613
|
}
|
|
615
614
|
modified = true;
|
|
@@ -769,12 +768,12 @@ function transformJs(host, file, output) {
|
|
|
769
768
|
});
|
|
770
769
|
}
|
|
771
770
|
else {
|
|
772
|
-
this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4
|
|
771
|
+
this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
|
|
773
772
|
}
|
|
774
773
|
}
|
|
775
774
|
}
|
|
776
775
|
catch (err) {
|
|
777
|
-
this.writeFail(["Unable to write file"
|
|
776
|
+
this.writeFail(["Unable to write file", path.basename(chunkUri)], err, 32);
|
|
778
777
|
}
|
|
779
778
|
}
|
|
780
779
|
appending?.forEach(item => item.order += order);
|
|
@@ -862,19 +861,18 @@ async function checkData(item, name, result, validate) {
|
|
|
862
861
|
if (typeof callback === 'function') {
|
|
863
862
|
try {
|
|
864
863
|
let output;
|
|
865
|
-
|
|
866
|
-
if (callback["__cjs__" /* INTERNAL.CJS */]) {
|
|
864
|
+
if (callback["__cjs__"]) {
|
|
867
865
|
output = await callback(result, item);
|
|
868
866
|
}
|
|
869
867
|
else {
|
|
870
|
-
output = await callback.apply(Document.enabled("node.process.inline"
|
|
868
|
+
output = await callback.apply(Document.enabled("node.process.inline") ? process : null, Document.enabled("node.require.inline") ? [result, item, require] : [result, item]);
|
|
871
869
|
}
|
|
872
870
|
if (validate(output)) {
|
|
873
871
|
return output;
|
|
874
872
|
}
|
|
875
873
|
}
|
|
876
874
|
catch (err) {
|
|
877
|
-
this.writeFail(["Unable to parse inline method"
|
|
875
|
+
this.writeFail(["Unable to parse inline method", name], err);
|
|
878
876
|
}
|
|
879
877
|
}
|
|
880
878
|
}
|
|
@@ -902,7 +900,6 @@ const getEndIndex = (match) => match.index + match[0].length;
|
|
|
902
900
|
const getRelativeURL = (file) => joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
|
|
903
901
|
const errorHtml = ({ tagName, tagIndex = -1 }) => (0, types_1.errorMessage)('html', 'Location did not resolve', tagName.toLowerCase() + (tagIndex >= 0 ? ': ' + tagIndex : ''));
|
|
904
902
|
const errorDataSource = (value, hint) => (0, types_1.errorMessage)('data-source', value, hint);
|
|
905
|
-
// @ts-ignore
|
|
906
903
|
class ChromeDocument extends Document {
|
|
907
904
|
constructor() {
|
|
908
905
|
super(...arguments);
|
|
@@ -986,7 +983,7 @@ class ChromeDocument extends Document {
|
|
|
986
983
|
const { Db: db, htmlFile, assets } = instance;
|
|
987
984
|
const outHtml = htmlFile && !isIgnored(htmlFile, true);
|
|
988
985
|
if (db && await db.commit()) {
|
|
989
|
-
db.writeTimeElapsed('DB', ["Transactions were committed"
|
|
986
|
+
db.writeTimeElapsed('DB', ["Transactions were committed", db.moduleName], processing.startTime, { ...Document.LOG_STYLE_SUCCESS, type: 65536 });
|
|
990
987
|
}
|
|
991
988
|
if (instance.dataSource.length === 0 && outHtml) {
|
|
992
989
|
const incremental = htmlFile.incremental ?? this.incremental;
|
|
@@ -1029,7 +1026,7 @@ class ChromeDocument extends Document {
|
|
|
1029
1026
|
}
|
|
1030
1027
|
case 'exists':
|
|
1031
1028
|
if (hint || isHtmlOnly()) {
|
|
1032
|
-
this.formatMessage(4
|
|
1029
|
+
this.formatMessage(4, 'HTML', ['No changes detected', 'incremental: ' + incremental], hint, { ...Document.LOG_STYLE_NOTICE, messageBgColor: 'bgWhite', messageColor: 'black' });
|
|
1033
1030
|
return super.finalize.call(this, instance);
|
|
1034
1031
|
}
|
|
1035
1032
|
break;
|
|
@@ -1069,7 +1066,7 @@ class ChromeDocument extends Document {
|
|
|
1069
1066
|
for (const item of children) {
|
|
1070
1067
|
if (!items.has(item)) {
|
|
1071
1068
|
if (isWatched.call(instance, item)) {
|
|
1072
|
-
item.flags |= 8
|
|
1069
|
+
item.flags |= 8;
|
|
1073
1070
|
}
|
|
1074
1071
|
items.add(item);
|
|
1075
1072
|
const next = related.get(item);
|
|
@@ -1100,18 +1097,18 @@ class ChromeDocument extends Document {
|
|
|
1100
1097
|
this.delete(value);
|
|
1101
1098
|
}
|
|
1102
1099
|
else {
|
|
1103
|
-
instance.writeFail(["Unable to move file"
|
|
1100
|
+
instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
|
|
1104
1101
|
}
|
|
1105
1102
|
}
|
|
1106
1103
|
}
|
|
1107
1104
|
}
|
|
1108
1105
|
}
|
|
1109
1106
|
else {
|
|
1110
|
-
instance.writeFail(["Unable to write directory"
|
|
1107
|
+
instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Access denied', productionRelease));
|
|
1111
1108
|
}
|
|
1112
1109
|
}
|
|
1113
1110
|
else {
|
|
1114
|
-
instance.writeFail(["Unable to read directory"
|
|
1111
|
+
instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', productionRelease), 32);
|
|
1115
1112
|
}
|
|
1116
1113
|
}
|
|
1117
1114
|
static sanitizeAssets(assets, exclusions = []) {
|
|
@@ -1302,6 +1299,7 @@ class ChromeDocument extends Document {
|
|
|
1302
1299
|
forDb(item) {
|
|
1303
1300
|
switch (item.source) {
|
|
1304
1301
|
case 'cloud':
|
|
1302
|
+
case 'json':
|
|
1305
1303
|
case 'uri':
|
|
1306
1304
|
case 'local':
|
|
1307
1305
|
case 'export':
|
|
@@ -1431,7 +1429,7 @@ class ChromeDocument extends Document {
|
|
|
1431
1429
|
await instance.tryFile(buffer, { format: to, filename: file.filename, etag: file.etag }, (err, result, ext) => {
|
|
1432
1430
|
if (err) {
|
|
1433
1431
|
setFormat();
|
|
1434
|
-
this.writeFail("Unable to compress file"
|
|
1432
|
+
this.writeFail("Unable to compress file", err, 8);
|
|
1435
1433
|
}
|
|
1436
1434
|
else if (result) {
|
|
1437
1435
|
if (ext) {
|
|
@@ -1445,7 +1443,7 @@ class ChromeDocument extends Document {
|
|
|
1445
1443
|
host.replace(file, output);
|
|
1446
1444
|
}
|
|
1447
1445
|
else {
|
|
1448
|
-
this.writeFail("Unable to write file"
|
|
1446
|
+
this.writeFail("Unable to write file", error, 32);
|
|
1449
1447
|
}
|
|
1450
1448
|
});
|
|
1451
1449
|
}
|
|
@@ -1757,7 +1755,7 @@ class ChromeDocument extends Document {
|
|
|
1757
1755
|
item.sourceUTF8 = output;
|
|
1758
1756
|
}
|
|
1759
1757
|
catch (err) {
|
|
1760
|
-
host.writeFail(["Unable to write file"
|
|
1758
|
+
host.writeFail(["Unable to write file", path.basename(item.localUri)], err, 32);
|
|
1761
1759
|
}
|
|
1762
1760
|
}
|
|
1763
1761
|
}
|
|
@@ -1959,7 +1957,7 @@ class ChromeDocument extends Document {
|
|
|
1959
1957
|
host.removeAsset(item);
|
|
1960
1958
|
}
|
|
1961
1959
|
catch (err) {
|
|
1962
|
-
this.writeFail(["Unable to read file"
|
|
1960
|
+
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime });
|
|
1963
1961
|
return false;
|
|
1964
1962
|
}
|
|
1965
1963
|
}
|
|
@@ -2142,7 +2140,7 @@ class ChromeDocument extends Document {
|
|
|
2142
2140
|
const { moduleName, config } = this;
|
|
2143
2141
|
const htmlFile = this.htmlFile;
|
|
2144
2142
|
const localUri = htmlFile.localUri;
|
|
2145
|
-
this.formatMessage(4
|
|
2143
|
+
this.formatMessage(4, 'HTML', ['Rewriting content...', path.dirname(localUri)]);
|
|
2146
2144
|
let source = host.getUTF8String(htmlFile, localUri), output;
|
|
2147
2145
|
const domBase = new dom_1.DomWriter(moduleName, source, this.elements, { normalize: config.normalizeHtmlOutput, stripComments: config.stripCommentsAndCDATA, ignoreTagGroup: config.ignoreServerCodeBlocks, escapeEntities: config.escapeReservedCharacters });
|
|
2148
2146
|
if (config.useUnsafeHtmlReplace) {
|
|
@@ -2168,7 +2166,7 @@ class ChromeDocument extends Document {
|
|
|
2168
2166
|
const domElement = new dom_1.HtmlElement(moduleName, element, item.attributes);
|
|
2169
2167
|
domElement.remove = true;
|
|
2170
2168
|
if (!domBase.write(domElement)) {
|
|
2171
|
-
this.writeFail('Unable to exclude HTML element', errorHtml(element), 4
|
|
2169
|
+
this.writeFail('Unable to exclude HTML element', errorHtml(element), 4);
|
|
2172
2170
|
}
|
|
2173
2171
|
}
|
|
2174
2172
|
}
|
|
@@ -2208,7 +2206,7 @@ class ChromeDocument extends Document {
|
|
|
2208
2206
|
domBase.errors.forEach(err => this.addLog(types_1.STATUS_TYPE.WARN, 'dom-writer -> ' + err.message, timeStamp));
|
|
2209
2207
|
}
|
|
2210
2208
|
if (domBase.failCount > 0) {
|
|
2211
|
-
this.writeFail(['Unable to update document', moduleName], (0, types_1.errorMessage)('html', 'DOM rewrite failed', domBase.failCount + ' errors'), { type: 4
|
|
2209
|
+
this.writeFail(['Unable to update document', moduleName], (0, types_1.errorMessage)('html', 'DOM rewrite failed', domBase.failCount + ' errors'), { type: 4, startTime });
|
|
2212
2210
|
}
|
|
2213
2211
|
else {
|
|
2214
2212
|
this.writeTimeProcess('html', `dom-writer (${domBase.modifyCount} modified) -> ` + path.basename(localUri), startTime);
|
|
@@ -2219,7 +2217,7 @@ class ChromeDocument extends Document {
|
|
|
2219
2217
|
for (const name in data) {
|
|
2220
2218
|
message.push(name + `(${data[name]})`);
|
|
2221
2219
|
}
|
|
2222
|
-
this.formatMessage(65536
|
|
2220
|
+
this.formatMessage(65536, 'DB', ['Cache statistics', cacheMiss.length + ' missed'], message.join(' - '), { ...Document.LOG_STYLE_NOTICE, hintBold: true });
|
|
2223
2221
|
}
|
|
2224
2222
|
}
|
|
2225
2223
|
htmlFile.modified = true;
|
|
@@ -2293,49 +2291,52 @@ class ChromeDocument extends Document {
|
|
|
2293
2291
|
const detectWidth = domElement.getAttribute('width') === 'detect';
|
|
2294
2292
|
const detectHeight = domElement.getAttribute('height') === 'detect';
|
|
2295
2293
|
if (detectWidth || detectHeight) {
|
|
2296
|
-
let width = 0, height = 0, buffer = null;
|
|
2294
|
+
let width = 0, height = 0, buffer = null, packageName;
|
|
2295
|
+
const addLog = (dimension) => this.addLog(types_1.STATUS_TYPE.WARN, 'Could not detect image ' + dimension, packageName || this.moduleName, item.localUri ? path.basename(item.localUri) : item.filename);
|
|
2297
2296
|
if (isImage(item.mimeType) && (buffer = host.getBuffer(item))) {
|
|
2298
|
-
let dimensions;
|
|
2299
2297
|
try {
|
|
2300
|
-
|
|
2298
|
+
({ width, height } = require(packageName = 'image-size').imageSize(buffer));
|
|
2301
2299
|
}
|
|
2302
2300
|
catch {
|
|
2303
|
-
}
|
|
2304
|
-
if (dimensions) {
|
|
2305
|
-
({ width, height } = dimensions);
|
|
2306
|
-
}
|
|
2307
|
-
else {
|
|
2308
2301
|
try {
|
|
2309
|
-
|
|
2302
|
+
const dimension = require(packageName = 'probe-image-size').sync(buffer);
|
|
2303
|
+
if (!dimension) {
|
|
2304
|
+
throw new Error("MIME not found");
|
|
2305
|
+
}
|
|
2306
|
+
({ width, height } = dimension);
|
|
2310
2307
|
}
|
|
2311
2308
|
catch {
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2309
|
+
try {
|
|
2310
|
+
({ width, height } = (await require('jimp').read(buffer)).bitmap);
|
|
2311
|
+
}
|
|
2312
|
+
catch {
|
|
2315
2313
|
}
|
|
2314
|
+
packageName = '';
|
|
2316
2315
|
}
|
|
2317
2316
|
}
|
|
2318
2317
|
}
|
|
2319
2318
|
if (detectWidth) {
|
|
2320
|
-
if (width
|
|
2319
|
+
if (width) {
|
|
2321
2320
|
domElement.setAttribute('width', width.toString());
|
|
2322
2321
|
}
|
|
2323
2322
|
else {
|
|
2324
2323
|
domElement.removeAttribute('width');
|
|
2324
|
+
addLog('width');
|
|
2325
2325
|
}
|
|
2326
2326
|
}
|
|
2327
2327
|
if (detectHeight) {
|
|
2328
|
-
if (height
|
|
2328
|
+
if (height) {
|
|
2329
2329
|
domElement.setAttribute('height', height.toString());
|
|
2330
2330
|
}
|
|
2331
2331
|
else {
|
|
2332
2332
|
domElement.removeAttribute('height');
|
|
2333
|
+
addLog('height');
|
|
2333
2334
|
}
|
|
2334
2335
|
}
|
|
2335
2336
|
}
|
|
2336
2337
|
}
|
|
2337
2338
|
if (!domBase.write(domElement)) {
|
|
2338
|
-
this.writeFail(inlineContent ? 'Inline tag replacement' : 'Element attribute replacement', errorHtml(element), { type: 4
|
|
2339
|
+
this.writeFail(inlineContent ? 'Inline tag replacement' : 'Element attribute replacement', errorHtml(element), { type: 4, startTime });
|
|
2339
2340
|
delete item.inlineUrlCloud;
|
|
2340
2341
|
}
|
|
2341
2342
|
else if (inlineContent) {
|
|
@@ -2359,7 +2360,7 @@ class ChromeDocument extends Document {
|
|
|
2359
2360
|
if (item.removeEmpty || item.type === 'display') {
|
|
2360
2361
|
(element || (element = new dom_1.HtmlElement(moduleName, item.element))).remove = true;
|
|
2361
2362
|
if (!domBase.write(element)) {
|
|
2362
|
-
this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4
|
|
2363
|
+
this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4, startTime });
|
|
2363
2364
|
}
|
|
2364
2365
|
}
|
|
2365
2366
|
};
|
|
@@ -2367,7 +2368,7 @@ class ChromeDocument extends Document {
|
|
|
2367
2368
|
removeElement(item);
|
|
2368
2369
|
const pkg = getPackageName(err);
|
|
2369
2370
|
if (!(pkg && this.checkPackage(err, pkg))) {
|
|
2370
|
-
this.writeFail(["Invalid credentials"
|
|
2371
|
+
this.writeFail(["Invalid credentials", item.source], err);
|
|
2371
2372
|
}
|
|
2372
2373
|
};
|
|
2373
2374
|
const checkObject = (item, data) => {
|
|
@@ -2397,7 +2398,7 @@ class ChromeDocument extends Document {
|
|
|
2397
2398
|
}
|
|
2398
2399
|
catch (err) {
|
|
2399
2400
|
this.abort(item.source);
|
|
2400
|
-
this.checkPackage(err, pkg, ["Unable to filter results"
|
|
2401
|
+
this.checkPackage(err, pkg, ["Unable to filter results", item.source]);
|
|
2401
2402
|
}
|
|
2402
2403
|
}
|
|
2403
2404
|
}
|
|
@@ -2420,10 +2421,11 @@ class ChromeDocument extends Document {
|
|
|
2420
2421
|
(batchMap[key] || (batchMap[key] = [])).push(item);
|
|
2421
2422
|
}
|
|
2422
2423
|
else {
|
|
2423
|
-
errorCredential(item, (0, types_1.errorValue)("Cloud module not installed"
|
|
2424
|
+
errorCredential(item, (0, types_1.errorValue)("Cloud module not installed", service));
|
|
2424
2425
|
}
|
|
2425
2426
|
break;
|
|
2426
2427
|
}
|
|
2428
|
+
case 'json':
|
|
2427
2429
|
case 'uri':
|
|
2428
2430
|
case 'local':
|
|
2429
2431
|
case 'export':
|
|
@@ -2453,7 +2455,7 @@ class ChromeDocument extends Document {
|
|
|
2453
2455
|
}
|
|
2454
2456
|
}
|
|
2455
2457
|
else {
|
|
2456
|
-
errorCredential(item, (0, types_1.errorValue)(db ? "Database provider not found"
|
|
2458
|
+
errorCredential(item, (0, types_1.errorValue)(db ? "Database provider not found" : "Db module not installed", type));
|
|
2457
2459
|
}
|
|
2458
2460
|
break;
|
|
2459
2461
|
}
|
|
@@ -2470,7 +2472,7 @@ class ChromeDocument extends Document {
|
|
|
2470
2472
|
const errorClient = (item, reason) => {
|
|
2471
2473
|
removeElement(item);
|
|
2472
2474
|
if (reason) {
|
|
2473
|
-
this.writeFail(["Unable to configure client"
|
|
2475
|
+
this.writeFail(["Unable to configure client", item.source], reason);
|
|
2474
2476
|
}
|
|
2475
2477
|
reject();
|
|
2476
2478
|
};
|
|
@@ -2488,11 +2490,20 @@ class ChromeDocument extends Document {
|
|
|
2488
2490
|
return [];
|
|
2489
2491
|
});
|
|
2490
2492
|
break;
|
|
2493
|
+
case 'json':
|
|
2494
|
+
if ((result[0] = checkObject(current, current.items)) === null) {
|
|
2495
|
+
this.abort(type);
|
|
2496
|
+
errorRemove(current, errorDataSource("Invalid parameters" + ' (items)', type));
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
if (this.settingsOf(type, 'coerce') === true) {
|
|
2500
|
+
(0, types_1.coerceObject)(result[0]);
|
|
2501
|
+
}
|
|
2502
|
+
break;
|
|
2491
2503
|
case 'uri':
|
|
2492
2504
|
case 'local': {
|
|
2493
2505
|
const { ignoreCache, encoding = 'utf-8', options } = current;
|
|
2494
2506
|
let content, target, data, cacheKey;
|
|
2495
|
-
const addDownload = () => typeof content === 'string' && host.addDownload(Buffer.byteLength(content, encoding));
|
|
2496
2507
|
if (type === 'local') {
|
|
2497
2508
|
let location;
|
|
2498
2509
|
({ pathname: target } = current);
|
|
@@ -2508,11 +2519,10 @@ class ChromeDocument extends Document {
|
|
|
2508
2519
|
try {
|
|
2509
2520
|
content = fs.readFileSync(location, encoding);
|
|
2510
2521
|
cacheKey = location;
|
|
2511
|
-
addDownload();
|
|
2512
2522
|
}
|
|
2513
2523
|
catch (err) {
|
|
2514
2524
|
this.abort(type);
|
|
2515
|
-
this.writeFail(["Unable to read file"
|
|
2525
|
+
this.writeFail(["Unable to read file", path.basename(location)], err, { type: 32, startTime });
|
|
2516
2526
|
errorRemove(current);
|
|
2517
2527
|
return;
|
|
2518
2528
|
}
|
|
@@ -2531,7 +2541,22 @@ class ChromeDocument extends Document {
|
|
|
2531
2541
|
return;
|
|
2532
2542
|
}
|
|
2533
2543
|
else if (Document.isURL(target, 'file')) {
|
|
2534
|
-
|
|
2544
|
+
let { format, contentType, body } = current;
|
|
2545
|
+
if (body) {
|
|
2546
|
+
if (!format && !contentType && (0, types_1.isPlainObject)(body)) {
|
|
2547
|
+
format = 'json';
|
|
2548
|
+
}
|
|
2549
|
+
try {
|
|
2550
|
+
content = await host.Request.post(target, body, { format, encoding, contentType });
|
|
2551
|
+
}
|
|
2552
|
+
catch (err) {
|
|
2553
|
+
this.abort(type);
|
|
2554
|
+
this.writeFail(["Unable to download file", target], err, { type: 1024, startTime });
|
|
2555
|
+
errorRemove(current);
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
else if (!ignoreCache && CACHE_DBRESULT.has(target)) {
|
|
2535
2560
|
data = getCacheItem(CACHE_DBRESULT, target);
|
|
2536
2561
|
}
|
|
2537
2562
|
else {
|
|
@@ -2540,15 +2565,12 @@ class ChromeDocument extends Document {
|
|
|
2540
2565
|
}
|
|
2541
2566
|
if (!(data = cacheData[target])) {
|
|
2542
2567
|
try {
|
|
2543
|
-
content = await host.
|
|
2544
|
-
if (Buffer.isBuffer(content)) {
|
|
2545
|
-
content = content.toString('utf-8');
|
|
2546
|
-
}
|
|
2568
|
+
content = await host.Request.get(target, { format, encoding });
|
|
2547
2569
|
cacheKey = target;
|
|
2548
2570
|
}
|
|
2549
2571
|
catch (err) {
|
|
2550
2572
|
this.abort(type);
|
|
2551
|
-
this.writeFail(["Unable to download file"
|
|
2573
|
+
this.writeFail(["Unable to download file", target], err, { type: 1024, startTime });
|
|
2552
2574
|
errorRemove(current);
|
|
2553
2575
|
return;
|
|
2554
2576
|
}
|
|
@@ -2573,17 +2595,19 @@ class ChromeDocument extends Document {
|
|
|
2573
2595
|
try {
|
|
2574
2596
|
content = fs.readFileSync(pathname, encoding);
|
|
2575
2597
|
cacheKey = pathname;
|
|
2576
|
-
addDownload();
|
|
2577
2598
|
}
|
|
2578
2599
|
catch (err) {
|
|
2579
2600
|
this.abort(type);
|
|
2580
|
-
this.writeFail(["Unable to read file"
|
|
2601
|
+
this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
|
|
2581
2602
|
errorRemove(current);
|
|
2582
2603
|
return;
|
|
2583
2604
|
}
|
|
2584
2605
|
}
|
|
2585
2606
|
}
|
|
2586
2607
|
}
|
|
2608
|
+
if (Buffer.isBuffer(content)) {
|
|
2609
|
+
content = content.toString('utf-8');
|
|
2610
|
+
}
|
|
2587
2611
|
if ((0, types_1.isString)(content)) {
|
|
2588
2612
|
const { format = path.extname(target).substring(1) } = current;
|
|
2589
2613
|
try {
|
|
@@ -2591,19 +2615,23 @@ class ChromeDocument extends Document {
|
|
|
2591
2615
|
}
|
|
2592
2616
|
catch (err) {
|
|
2593
2617
|
this.abort(type);
|
|
2594
|
-
this.writeFail(['Unable to parse data source', format], err, { type: 4
|
|
2618
|
+
this.writeFail(['Unable to parse data source', format], err, { type: 4, startTime });
|
|
2595
2619
|
errorRemove(current);
|
|
2596
2620
|
return;
|
|
2597
2621
|
}
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2622
|
+
host.addDownload(Buffer.byteLength(content, encoding));
|
|
2623
|
+
}
|
|
2624
|
+
else if (content) {
|
|
2625
|
+
data = content;
|
|
2601
2626
|
}
|
|
2602
2627
|
if (!data) {
|
|
2603
2628
|
this.abort(type);
|
|
2604
2629
|
errorRemove(current, errorDataSource(content !== null ? 'Invalid response' : 'Empty response', target));
|
|
2605
2630
|
return;
|
|
2606
2631
|
}
|
|
2632
|
+
if (cacheKey) {
|
|
2633
|
+
setCacheData.call(this, current, data, cacheKey, cacheData);
|
|
2634
|
+
}
|
|
2607
2635
|
if ((result[0] = checkObject(current, data)) === null) {
|
|
2608
2636
|
this.abort(type);
|
|
2609
2637
|
errorRemove(current, errorDataSource('Invalid ' + (current.query ? 'query' : 'URI'), target));
|
|
@@ -2667,13 +2695,12 @@ class ChromeDocument extends Document {
|
|
|
2667
2695
|
if (params && this.settingsOf(type, 'coerce') === true) {
|
|
2668
2696
|
(0, types_1.coerceObject)(params);
|
|
2669
2697
|
}
|
|
2670
|
-
|
|
2671
|
-
if (getData["__cjs__" /* INTERNAL.CJS */]) {
|
|
2698
|
+
if (getData["__cjs__"]) {
|
|
2672
2699
|
data = await getData(params);
|
|
2673
2700
|
}
|
|
2674
2701
|
else {
|
|
2675
|
-
const thisArg = Document.enabled("node.process.inline"
|
|
2676
|
-
const inline = Document.enabled("node.require.inline"
|
|
2702
|
+
const thisArg = Document.enabled("node.process.inline") ? process : null;
|
|
2703
|
+
const inline = Document.enabled("node.require.inline");
|
|
2677
2704
|
const args = [params];
|
|
2678
2705
|
if (getData.toString().startsWith('async')) {
|
|
2679
2706
|
if (inline) {
|
|
@@ -2695,7 +2722,7 @@ class ChromeDocument extends Document {
|
|
|
2695
2722
|
}
|
|
2696
2723
|
catch (err) {
|
|
2697
2724
|
this.abort(type);
|
|
2698
|
-
this.writeFail(['Unable to retrieve data source', hint], err, { type: 4
|
|
2725
|
+
this.writeFail(['Unable to retrieve data source', hint], err, { type: 4, startTime });
|
|
2699
2726
|
errorRemove(current);
|
|
2700
2727
|
return;
|
|
2701
2728
|
}
|
|
@@ -2781,12 +2808,12 @@ class ChromeDocument extends Document {
|
|
|
2781
2808
|
}
|
|
2782
2809
|
}
|
|
2783
2810
|
else {
|
|
2784
|
-
throw (0, types_1.errorMessage)(type, "File not found"
|
|
2811
|
+
throw (0, types_1.errorMessage)(type, "File not found", query);
|
|
2785
2812
|
}
|
|
2786
2813
|
}
|
|
2787
2814
|
catch (err) {
|
|
2788
2815
|
this.abort(type);
|
|
2789
|
-
this.writeFail(["Unable to read file"
|
|
2816
|
+
this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, { startTime });
|
|
2790
2817
|
errorRemove(current);
|
|
2791
2818
|
return;
|
|
2792
2819
|
}
|
|
@@ -2823,7 +2850,7 @@ class ChromeDocument extends Document {
|
|
|
2823
2850
|
this.abort(type, err);
|
|
2824
2851
|
}
|
|
2825
2852
|
if (err) {
|
|
2826
|
-
this.writeFail(["Unable to execute query"
|
|
2853
|
+
this.writeFail(["Unable to execute query", message || "Unknown"], err instanceof Error ? errors = err : err, { type: 65536, startTime });
|
|
2827
2854
|
}
|
|
2828
2855
|
return this.aborted;
|
|
2829
2856
|
};
|
|
@@ -2837,7 +2864,7 @@ class ChromeDocument extends Document {
|
|
|
2837
2864
|
}
|
|
2838
2865
|
break;
|
|
2839
2866
|
}
|
|
2840
|
-
errorRemove(current, errorDataSource('Not found', type || "Unknown"
|
|
2867
|
+
errorRemove(current, errorDataSource('Not found', type || "Unknown"));
|
|
2841
2868
|
return;
|
|
2842
2869
|
}
|
|
2843
2870
|
if (this.aborted) {
|
|
@@ -2901,7 +2928,7 @@ class ChromeDocument extends Document {
|
|
|
2901
2928
|
setCacheData.call(this, item, item.value, pathname, cacheData, true);
|
|
2902
2929
|
}
|
|
2903
2930
|
catch (err) {
|
|
2904
|
-
this.writeFail(["Unable to read file"
|
|
2931
|
+
this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
|
|
2905
2932
|
errors = true;
|
|
2906
2933
|
}
|
|
2907
2934
|
}
|
|
@@ -2944,7 +2971,7 @@ class ChromeDocument extends Document {
|
|
|
2944
2971
|
const literal = segment.trim();
|
|
2945
2972
|
if (literal.startsWith('`') && literal.endsWith('`')) {
|
|
2946
2973
|
if (!this.hasEval('function')) {
|
|
2947
|
-
errors = (0, types_1.errorMessage)('eval', "Unsupported access"
|
|
2974
|
+
errors = (0, types_1.errorMessage)('eval', "Unsupported access", 'function');
|
|
2948
2975
|
continue;
|
|
2949
2976
|
}
|
|
2950
2977
|
try {
|
|
@@ -2965,7 +2992,7 @@ class ChromeDocument extends Document {
|
|
|
2965
2992
|
else {
|
|
2966
2993
|
const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
|
|
2967
2994
|
while (match = pattern.exec(segment)) {
|
|
2968
|
-
segment = replaceMatch(match, segment, match[1] === "__index__"
|
|
2995
|
+
segment = replaceMatch(match, segment, match[1] === "__index__" && !(0, types_1.isObject)(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
|
|
2969
2996
|
}
|
|
2970
2997
|
}
|
|
2971
2998
|
value += trimTemplate(segment);
|
|
@@ -2974,6 +3001,13 @@ class ChromeDocument extends Document {
|
|
|
2974
3001
|
if (preRender) {
|
|
2975
3002
|
await checkValue(preRender);
|
|
2976
3003
|
}
|
|
3004
|
+
const { leadingText, trailingText } = item;
|
|
3005
|
+
if (leadingText) {
|
|
3006
|
+
value = leadingText + value;
|
|
3007
|
+
}
|
|
3008
|
+
if (trailingText) {
|
|
3009
|
+
value += trailingText;
|
|
3010
|
+
}
|
|
2977
3011
|
domElement.innerXml = domBase.initOpts.normalize ? dom_1.DomWriter.normalize(value, { newline: domBase.newline, escapeEntities: domBase.initOpts.escapeEntities }) : value;
|
|
2978
3012
|
}
|
|
2979
3013
|
else {
|
|
@@ -3160,37 +3194,37 @@ class ChromeDocument extends Document {
|
|
|
3160
3194
|
default:
|
|
3161
3195
|
removeElement(item, domElement);
|
|
3162
3196
|
if (length === 1) {
|
|
3163
|
-
reject(errorDataSource('Invalid action', item.type || "Unknown"
|
|
3197
|
+
reject(errorDataSource('Invalid action', item.type || "Unknown"));
|
|
3164
3198
|
return;
|
|
3165
3199
|
}
|
|
3166
3200
|
break invalid;
|
|
3167
3201
|
}
|
|
3168
3202
|
if (!domBase.write(domElement) || errors) {
|
|
3169
|
-
this.writeFail(item.type === 'display' ? domElement.remove ? errors ? 'Element was removed with errors' : 'Unable to remove element' : 'Unable to determine display conditional' : 'Unable to replace ' + item.type, errors instanceof Error ? errors : errorHtml(element), { type: 4
|
|
3203
|
+
this.writeFail(item.type === 'display' ? domElement.remove ? errors ? 'Element was removed with errors' : 'Unable to remove element' : 'Unable to determine display conditional' : 'Unable to replace ' + item.type, errors instanceof Error ? errors : errorHtml(element), { type: 4, startTime });
|
|
3170
3204
|
}
|
|
3171
3205
|
}
|
|
3172
3206
|
}
|
|
3173
3207
|
else {
|
|
3174
3208
|
if (!empty && item.type !== 'display' || item.transactionFail) {
|
|
3175
3209
|
const emptyResponse = (value, service = item.source) => {
|
|
3176
|
-
value || (value = "Unknown"
|
|
3210
|
+
value || (value = "Unknown");
|
|
3177
3211
|
return errors instanceof Error ? (0, types_1.errorMessage)(service, value, errors.message) : errorDataSource(service + ' -> Empty', value);
|
|
3178
3212
|
};
|
|
3179
3213
|
switch (item.source) {
|
|
3180
3214
|
case 'cloud': {
|
|
3181
3215
|
const { service, table, id, query } = item;
|
|
3182
3216
|
const queryString = (table ? 'table=' + table : '') + (id || query ? (table ? ';' : '') + (id ? 'id=' + id : 'query=' + asString(query)) : '');
|
|
3183
|
-
(cloud || this).formatFail(64
|
|
3217
|
+
(cloud || this).formatFail(64, service, ["Unable to execute query", queryString], emptyResponse(queryString, service), { ...Cloud.LOG_CLOUD_FAIL, startTime });
|
|
3184
3218
|
break;
|
|
3185
3219
|
}
|
|
3186
3220
|
case 'uri': {
|
|
3187
3221
|
const { uri, format = uri && path.extname(uri).substring(1) } = item;
|
|
3188
|
-
this.formatFail(4
|
|
3222
|
+
this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri), { startTime });
|
|
3189
3223
|
break;
|
|
3190
3224
|
}
|
|
3191
3225
|
case 'local': {
|
|
3192
3226
|
const { pathname, format = pathname && path.extname(pathname).substring(1) } = item;
|
|
3193
|
-
this.formatFail(4
|
|
3227
|
+
this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname), { startTime });
|
|
3194
3228
|
break;
|
|
3195
3229
|
}
|
|
3196
3230
|
case 'export': {
|
|
@@ -3199,7 +3233,7 @@ class ChromeDocument extends Document {
|
|
|
3199
3233
|
if (typeof target === 'function') {
|
|
3200
3234
|
target = target.name;
|
|
3201
3235
|
}
|
|
3202
|
-
this.formatFail(4
|
|
3236
|
+
this.formatFail(4, 'EXPORT', ['No records were retrieved', target], emptyResponse(target), { startTime });
|
|
3203
3237
|
break;
|
|
3204
3238
|
}
|
|
3205
3239
|
}
|
|
@@ -3251,7 +3285,7 @@ class ChromeDocument extends Document {
|
|
|
3251
3285
|
throw (0, types_1.errorMessage)('hash', 'Source not found', item.filename);
|
|
3252
3286
|
}
|
|
3253
3287
|
catch (err) {
|
|
3254
|
-
this.writeFail(["Unable to read file"
|
|
3288
|
+
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime });
|
|
3255
3289
|
}
|
|
3256
3290
|
default:
|
|
3257
3291
|
if (algorithm) {
|
|
@@ -3690,7 +3724,7 @@ class ChromeDocument extends Document {
|
|
|
3690
3724
|
return (_a = this.module).settings || (_a.settings = {});
|
|
3691
3725
|
}
|
|
3692
3726
|
}
|
|
3693
|
-
ChromeDocument.INTERNAL_ASSIGNUUID = "__assign__"
|
|
3694
|
-
ChromeDocument.INTERNAL_SERVERROOT = "__serverroot__"
|
|
3727
|
+
ChromeDocument.INTERNAL_ASSIGNUUID = "__assign__";
|
|
3728
|
+
ChromeDocument.INTERNAL_SERVERROOT = "__serverroot__";
|
|
3695
3729
|
|
|
3696
3730
|
module.exports = ChromeDocument;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/chrome",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Chrome document constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/cloud": "^0.8.
|
|
24
|
-
"@e-mc/core": "^0.8.
|
|
25
|
-
"@e-mc/document": "^0.8.
|
|
26
|
-
"@e-mc/types": "^0.8.
|
|
23
|
+
"@e-mc/cloud": "^0.8.6",
|
|
24
|
+
"@e-mc/core": "^0.8.6",
|
|
25
|
+
"@e-mc/document": "^0.8.6",
|
|
26
|
+
"@e-mc/types": "^0.8.6"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ interface DocumentDirectory extends IDocumentDirectory {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
interface DocumentComponentExtended<T> extends DbSourceDataType<T> {
|
|
29
|
+
json?: T;
|
|
29
30
|
uri?: T;
|
|
30
31
|
local?: T;
|
|
31
32
|
export?: T;
|
|
@@ -98,12 +99,12 @@ export interface IChromeDocument<T extends IFileManager<U>, U extends DocumentAs
|
|
|
98
99
|
formatMap?: ObjectMap<FormatUri>;
|
|
99
100
|
setElementSrc(asset: U, element: IXmlElement, value: string): void;
|
|
100
101
|
findDataValue(name: string): Undef<string>;
|
|
101
|
-
setInlinedAttributes(processing: FinalizeProcessing<T>): void;
|
|
102
|
-
applyTransforms(processing: FinalizeProcessing<T>): Promise<void>;
|
|
103
|
-
rewriteHtml(processing: FinalizeProcessing<T>): Promise<void>;
|
|
104
|
-
setElementAttributes(processing: FinalizeProcessing<T>, domBase: IDomWriter): Promise<void>;
|
|
105
|
-
applyDataSource(processing: FinalizeProcessing<T>, domBase: IDomWriter): Promise<void>;
|
|
106
|
-
setProductionAttributes(processing: FinalizeProcessing<T>): void;
|
|
102
|
+
setInlinedAttributes(processing: FinalizeProcessing<T, U>): void;
|
|
103
|
+
applyTransforms(processing: FinalizeProcessing<T, U>): Promise<void>;
|
|
104
|
+
rewriteHtml(processing: FinalizeProcessing<T, U>): Promise<void>;
|
|
105
|
+
setElementAttributes(processing: FinalizeProcessing<T, U>, domBase: IDomWriter): Promise<void>;
|
|
106
|
+
applyDataSource(processing: FinalizeProcessing<T, U>, domBase: IDomWriter): Promise<void>;
|
|
107
|
+
setProductionAttributes(processing: FinalizeProcessing<T, U>): void;
|
|
107
108
|
removeUnusedStyles(source: string, options?: UserConfig): Undef<string>;
|
|
108
109
|
removeServerRoot(value: string): string;
|
|
109
110
|
replaceContent(source: string, match: RegExpExecArray | string, mimeType?: string): Undef<string>;
|
|
@@ -123,4 +124,4 @@ export interface ChromeDocumentConstructor<T extends IFileManager<U>, U extends
|
|
|
123
124
|
INTERNAL_SERVERROOT: string;
|
|
124
125
|
readonly prototype: IChromeDocument<T, U>;
|
|
125
126
|
new(module?: DocumentModule, ...args: unknown[]): IChromeDocument<T, U>;
|
|
126
|
-
}
|
|
127
|
+
}
|
package/types/squared.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { AttributeAction, ConditionProperty, CssConditionData, ElementActio
|
|
|
3
3
|
import type { UploadAction } from '@e-mc/types/lib/cloud';
|
|
4
4
|
import type { CascadeAction, DbSource } from '@e-mc/types/lib/db';
|
|
5
5
|
import type { RequestData as IRequestData } from '@e-mc/types/lib/node';
|
|
6
|
+
import type { BufferFormat } from '@e-mc/types/lib/request';
|
|
6
7
|
|
|
7
8
|
interface ImportFrom {
|
|
8
9
|
placeholder: string;
|
|
@@ -13,7 +14,7 @@ interface ImportFrom {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
interface DataObject extends CascadeAction {
|
|
16
|
-
format?:
|
|
17
|
+
format?: BufferFormat;
|
|
17
18
|
options?: PlainObject;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -86,7 +87,7 @@ export interface UnusedAtRule {
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
export interface DataSource<T = string> extends IDataSource<T>, ElementAction {
|
|
89
|
-
source: "cloud" | "uri" | "local" | "export" | DbSource;
|
|
90
|
+
source: "cloud" | "json" | "uri" | "local" | "export" | DbSource;
|
|
90
91
|
element?: XmlTagNode;
|
|
91
92
|
type?: "text" | "attribute" | "display";
|
|
92
93
|
dynamic?: boolean;
|
|
@@ -96,8 +97,16 @@ export interface DataSource<T = string> extends IDataSource<T>, ElementAction {
|
|
|
96
97
|
ignoreEmpty?: boolean;
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
export interface TextDataSource extends DataSource {
|
|
101
|
+
type: "text";
|
|
102
|
+
leadingText?: string;
|
|
103
|
+
trailingText?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
99
106
|
export interface UriDataSource extends DataSource, DataObject {
|
|
100
107
|
source: "uri";
|
|
108
|
+
body?: unknown;
|
|
109
|
+
contentType?: string;
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
export interface LocalDataSource extends DataSource, DataObject {
|
|
@@ -105,6 +114,11 @@ export interface LocalDataSource extends DataSource, DataObject {
|
|
|
105
114
|
pathname?: string;
|
|
106
115
|
}
|
|
107
116
|
|
|
117
|
+
export interface JSONDataSource extends DataSource, CascadeAction {
|
|
118
|
+
source: "json";
|
|
119
|
+
items?: unknown;
|
|
120
|
+
}
|
|
121
|
+
|
|
108
122
|
export interface ExportDataSource extends DataSource, CascadeAction {
|
|
109
123
|
source: "export";
|
|
110
124
|
execute?: FunctionType;
|