@jsenv/core 34.3.0 → 35.0.1
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 +2 -9
- package/dist/js/ws.js +1 -145
- package/dist/{jsenv.js → jsenv_core.js} +1056 -3850
- package/package.json +8 -23
- package/src/build/build.js +2 -2
- package/src/dev/file_service.js +8 -8
- package/src/dev/start_dev_server.js +3 -3
- package/src/dev/user_agent.js +1 -1
- package/src/main.js +0 -23
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +1 -1
- package/src/plugins/transpilation/babel/require_babel_plugin.js +1 -1
- package/src/plugins/transpilation/js_module_fallback/convert_js_module_to_js_classic.js +1 -1
- package/dist/controllable_child_process.mjs +0 -129
- package/dist/controllable_worker_thread.mjs +0 -91
- package/dist/importmap_node_loader.mjs +0 -49
- package/dist/js/execute_using_dynamic_import.js +0 -850
- package/dist/js/resolveImport.js +0 -504
- package/dist/js/v8_coverage.js +0 -508
- package/dist/no_experimental_warnings.cjs +0 -8
- package/src/execute/execute.js +0 -111
- package/src/execute/run.js +0 -161
- package/src/execute/runtimes/browsers/chromium.js +0 -10
- package/src/execute/runtimes/browsers/firefox.js +0 -9
- package/src/execute/runtimes/browsers/from_playwright.js +0 -574
- package/src/execute/runtimes/browsers/middleware_istanbul.js +0 -65
- package/src/execute/runtimes/browsers/middleware_js_supervisor.js +0 -100
- package/src/execute/runtimes/browsers/webkit.js +0 -26
- package/src/execute/runtimes/node/child_exec_options.js +0 -166
- package/src/execute/runtimes/node/controllable_child_process.mjs +0 -135
- package/src/execute/runtimes/node/controllable_worker_thread.mjs +0 -103
- package/src/execute/runtimes/node/exec_options.js +0 -57
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +0 -55
- package/src/execute/runtimes/node/exit_codes.js +0 -9
- package/src/execute/runtimes/node/importmap_node_loader.mjs +0 -51
- package/src/execute/runtimes/node/importmap_node_loader_file_url.js +0 -4
- package/src/execute/runtimes/node/kill_process_tree.js +0 -76
- package/src/execute/runtimes/node/no_experimental_warnings.cjs +0 -12
- package/src/execute/runtimes/node/no_experimental_warnings_file_url.js +0 -4
- package/src/execute/runtimes/node/node_child_process.js +0 -363
- package/src/execute/runtimes/node/node_execution_performance.js +0 -67
- package/src/execute/runtimes/node/node_worker_thread.js +0 -295
- package/src/execute/runtimes/node/profiler_v8_coverage.js +0 -56
- package/src/execute/runtimes/readme.md +0 -13
- package/src/execute/web_server_param.js +0 -74
- package/src/test/coverage/babel_plugin_instrument.js +0 -48
- package/src/test/coverage/coverage_reporter_html_directory.js +0 -32
- package/src/test/coverage/coverage_reporter_json_file.js +0 -17
- package/src/test/coverage/coverage_reporter_text_log.js +0 -19
- package/src/test/coverage/empty_coverage_factory.js +0 -52
- package/src/test/coverage/file_by_file_coverage.js +0 -25
- package/src/test/coverage/istanbul_coverage_composition.js +0 -28
- package/src/test/coverage/istanbul_coverage_map_from_coverage.js +0 -16
- package/src/test/coverage/list_files_not_covered.js +0 -15
- package/src/test/coverage/missing_coverage.js +0 -41
- package/src/test/coverage/report_to_coverage.js +0 -198
- package/src/test/coverage/v8_and_istanbul.js +0 -37
- package/src/test/coverage/v8_coverage.js +0 -26
- package/src/test/coverage/v8_coverage_composition.js +0 -24
- package/src/test/coverage/v8_coverage_node_directory.js +0 -85
- package/src/test/coverage/v8_coverage_to_istanbul.js +0 -99
- package/src/test/execute_steps.js +0 -425
- package/src/test/execute_test_plan.js +0 -372
- package/src/test/execution_colors.js +0 -10
- package/src/test/execution_steps.js +0 -65
- package/src/test/gc.js +0 -9
- package/src/test/logs_file_execution.js +0 -427
- package/src/test/logs_file_execution.test.mjs +0 -41
- package/src/test/readme.md +0 -3
- /package/src/{basic_fetch.js → helpers/basic_fetch.js} +0 -0
- /package/src/{lookup_package_directory.js → helpers/lookup_package_directory.js} +0 -0
- /package/src/{ping_server.js → helpers/ping_server.js} +0 -0
- /package/src/{require_from_jsenv.js → helpers/require_from_jsenv.js} +0 -0
- /package/src/{watch_source_files.js → helpers/watch_source_files.js} +0 -0
- /package/src/{web_url_converter.js → helpers/web_url_converter.js} +0 -0
|
@@ -1,850 +0,0 @@
|
|
|
1
|
-
import { writeFileSync } from "node:fs";
|
|
2
|
-
import { Session } from "node:inspector";
|
|
3
|
-
import { PerformanceObserver, performance } from "node:perf_hooks";
|
|
4
|
-
|
|
5
|
-
// https://developer.mozilla.org/en-US/docs/Glossary/Primitive
|
|
6
|
-
|
|
7
|
-
const isComposite = value => {
|
|
8
|
-
if (value === null) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
const type = typeof value;
|
|
12
|
-
if (type === "object") {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
if (type === "function") {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
return false;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
|
|
22
|
-
const compositeWellKnownMap = new WeakMap();
|
|
23
|
-
const primitiveWellKnownMap = new Map();
|
|
24
|
-
const getCompositeGlobalPath = value => compositeWellKnownMap.get(value);
|
|
25
|
-
const getPrimitiveGlobalPath = value => primitiveWellKnownMap.get(value);
|
|
26
|
-
const visitGlobalObject = value => {
|
|
27
|
-
const visitValue = (value, path) => {
|
|
28
|
-
if (isComposite(value)) {
|
|
29
|
-
// prevent infinite recursion
|
|
30
|
-
if (compositeWellKnownMap.has(value)) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
compositeWellKnownMap.set(value, path);
|
|
34
|
-
const visitProperty = property => {
|
|
35
|
-
let descriptor;
|
|
36
|
-
try {
|
|
37
|
-
descriptor = Object.getOwnPropertyDescriptor(value, property);
|
|
38
|
-
} catch (e) {
|
|
39
|
-
if (e.name === "SecurityError") {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
throw e;
|
|
43
|
-
}
|
|
44
|
-
if (!descriptor) {
|
|
45
|
-
// it's apparently possible to have getOwnPropertyNames returning
|
|
46
|
-
// a property that later returns a null descriptor
|
|
47
|
-
// for instance window.showModalDialog in webkit 13.0
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// do not trigger getter/setter
|
|
52
|
-
if ("value" in descriptor) {
|
|
53
|
-
const propertyValue = descriptor.value;
|
|
54
|
-
visitValue(propertyValue, [...path, property]);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
Object.getOwnPropertyNames(value).forEach(name => visitProperty(name));
|
|
58
|
-
Object.getOwnPropertySymbols(value).forEach(symbol => visitProperty(symbol));
|
|
59
|
-
}
|
|
60
|
-
primitiveWellKnownMap.set(value, path);
|
|
61
|
-
return;
|
|
62
|
-
};
|
|
63
|
-
visitValue(value, []);
|
|
64
|
-
};
|
|
65
|
-
if (typeof window === "object") visitGlobalObject(window);
|
|
66
|
-
if (typeof global === "object") visitGlobalObject(global);
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* transforms a javascript value into an object describing it.
|
|
70
|
-
*
|
|
71
|
-
*/
|
|
72
|
-
const decompose = (mainValue, {
|
|
73
|
-
functionAllowed,
|
|
74
|
-
prototypeStrict,
|
|
75
|
-
ignoreSymbols
|
|
76
|
-
}) => {
|
|
77
|
-
const valueMap = {};
|
|
78
|
-
const recipeArray = [];
|
|
79
|
-
const valueToIdentifier = (value, path = []) => {
|
|
80
|
-
if (!isComposite(value)) {
|
|
81
|
-
const existingIdentifier = identifierForPrimitive(value);
|
|
82
|
-
if (existingIdentifier !== undefined) {
|
|
83
|
-
return existingIdentifier;
|
|
84
|
-
}
|
|
85
|
-
const identifier = identifierForNewValue(value);
|
|
86
|
-
recipeArray[identifier] = primitiveToRecipe(value);
|
|
87
|
-
return identifier;
|
|
88
|
-
}
|
|
89
|
-
if (typeof Promise === "function" && value instanceof Promise) {
|
|
90
|
-
throw new Error(createPromiseAreNotSupportedMessage({
|
|
91
|
-
path
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
if (typeof WeakSet === "function" && value instanceof WeakSet) {
|
|
95
|
-
throw new Error(createWeakSetAreNotSupportedMessage({
|
|
96
|
-
path
|
|
97
|
-
}));
|
|
98
|
-
}
|
|
99
|
-
if (typeof WeakMap === "function" && value instanceof WeakMap) {
|
|
100
|
-
throw new Error(createWeakMapAreNotSupportedMessage({
|
|
101
|
-
path
|
|
102
|
-
}));
|
|
103
|
-
}
|
|
104
|
-
if (typeof value === "function" && !functionAllowed) {
|
|
105
|
-
throw new Error(createForbiddenFunctionMessage({
|
|
106
|
-
path
|
|
107
|
-
}));
|
|
108
|
-
}
|
|
109
|
-
const existingIdentifier = identifierForComposite(value);
|
|
110
|
-
if (existingIdentifier !== undefined) {
|
|
111
|
-
return existingIdentifier;
|
|
112
|
-
}
|
|
113
|
-
const identifier = identifierForNewValue(value);
|
|
114
|
-
const compositeGlobalPath = getCompositeGlobalPath(value);
|
|
115
|
-
if (compositeGlobalPath) {
|
|
116
|
-
recipeArray[identifier] = createGlobalReferenceRecipe(compositeGlobalPath);
|
|
117
|
-
return identifier;
|
|
118
|
-
}
|
|
119
|
-
const propertyDescriptionArray = [];
|
|
120
|
-
Object.getOwnPropertyNames(value).forEach(propertyName => {
|
|
121
|
-
const propertyDescriptor = Object.getOwnPropertyDescriptor(value, propertyName);
|
|
122
|
-
const propertyNameIdentifier = valueToIdentifier(propertyName, [...path, propertyName]);
|
|
123
|
-
const propertyDescription = computePropertyDescription(propertyDescriptor, propertyName, path);
|
|
124
|
-
propertyDescriptionArray.push({
|
|
125
|
-
propertyNameIdentifier,
|
|
126
|
-
propertyDescription
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
const symbolDescriptionArray = [];
|
|
130
|
-
if (!ignoreSymbols) {
|
|
131
|
-
Object.getOwnPropertySymbols(value).forEach(symbol => {
|
|
132
|
-
const propertyDescriptor = Object.getOwnPropertyDescriptor(value, symbol);
|
|
133
|
-
const symbolIdentifier = valueToIdentifier(symbol, [...path, `[${symbol.toString()}]`]);
|
|
134
|
-
const propertyDescription = computePropertyDescription(propertyDescriptor, symbol, path);
|
|
135
|
-
symbolDescriptionArray.push({
|
|
136
|
-
symbolIdentifier,
|
|
137
|
-
propertyDescription
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
const methodDescriptionArray = computeMethodDescriptionArray(value, path);
|
|
142
|
-
const extensible = Object.isExtensible(value);
|
|
143
|
-
recipeArray[identifier] = createCompositeRecipe({
|
|
144
|
-
propertyDescriptionArray,
|
|
145
|
-
symbolDescriptionArray,
|
|
146
|
-
methodDescriptionArray,
|
|
147
|
-
extensible
|
|
148
|
-
});
|
|
149
|
-
return identifier;
|
|
150
|
-
};
|
|
151
|
-
const computePropertyDescription = (propertyDescriptor, propertyNameOrSymbol, path) => {
|
|
152
|
-
if (propertyDescriptor.set && !functionAllowed) {
|
|
153
|
-
throw new Error(createForbiddenPropertySetterMessage({
|
|
154
|
-
path,
|
|
155
|
-
propertyNameOrSymbol
|
|
156
|
-
}));
|
|
157
|
-
}
|
|
158
|
-
if (propertyDescriptor.get && !functionAllowed) {
|
|
159
|
-
throw new Error(createForbiddenPropertyGetterMessage({
|
|
160
|
-
path,
|
|
161
|
-
propertyNameOrSymbol
|
|
162
|
-
}));
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
configurable: propertyDescriptor.configurable,
|
|
166
|
-
writable: propertyDescriptor.writable,
|
|
167
|
-
enumerable: propertyDescriptor.enumerable,
|
|
168
|
-
getIdentifier: "get" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.get, [...path, String(propertyNameOrSymbol), "[[descriptor:get]]"]) : undefined,
|
|
169
|
-
setIdentifier: "set" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.set, [...path, String(propertyNameOrSymbol), "[[descriptor:set]]"]) : undefined,
|
|
170
|
-
valueIdentifier: "value" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.value, [...path, String(propertyNameOrSymbol), "[[descriptor:value]]"]) : undefined
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
const computeMethodDescriptionArray = (value, path) => {
|
|
174
|
-
const methodDescriptionArray = [];
|
|
175
|
-
if (typeof Set === "function" && value instanceof Set) {
|
|
176
|
-
const callArray = [];
|
|
177
|
-
value.forEach((entryValue, index) => {
|
|
178
|
-
const entryValueIdentifier = valueToIdentifier(entryValue, [...path, `[[SetEntryValue]]`, index]);
|
|
179
|
-
callArray.push([entryValueIdentifier]);
|
|
180
|
-
});
|
|
181
|
-
methodDescriptionArray.push({
|
|
182
|
-
methodNameIdentifier: valueToIdentifier("add"),
|
|
183
|
-
callArray
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
if (typeof Map === "function" && value instanceof Map) {
|
|
187
|
-
const callArray = [];
|
|
188
|
-
value.forEach((entryValue, entryKey) => {
|
|
189
|
-
const entryKeyIdentifier = valueToIdentifier(entryKey, [...path, "[[MapEntryKey]]", entryKey]);
|
|
190
|
-
const entryValueIdentifier = valueToIdentifier(entryValue, [...path, "[[MapEntryValue]]", entryValue]);
|
|
191
|
-
callArray.push([entryKeyIdentifier, entryValueIdentifier]);
|
|
192
|
-
});
|
|
193
|
-
methodDescriptionArray.push({
|
|
194
|
-
methodNameIdentifier: valueToIdentifier("set"),
|
|
195
|
-
callArray
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
return methodDescriptionArray;
|
|
199
|
-
};
|
|
200
|
-
const identifierForPrimitive = value => {
|
|
201
|
-
return Object.keys(valueMap).find(existingIdentifier => {
|
|
202
|
-
const existingValue = valueMap[existingIdentifier];
|
|
203
|
-
if (Object.is(value, existingValue)) return true;
|
|
204
|
-
return value === existingValue;
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
const identifierForComposite = value => {
|
|
208
|
-
return Object.keys(valueMap).find(existingIdentifier => {
|
|
209
|
-
const existingValue = valueMap[existingIdentifier];
|
|
210
|
-
return value === existingValue;
|
|
211
|
-
});
|
|
212
|
-
};
|
|
213
|
-
const identifierForNewValue = value => {
|
|
214
|
-
const identifier = nextIdentifier();
|
|
215
|
-
valueMap[identifier] = value;
|
|
216
|
-
return identifier;
|
|
217
|
-
};
|
|
218
|
-
let currentIdentifier = -1;
|
|
219
|
-
const nextIdentifier = () => {
|
|
220
|
-
const identifier = String(parseInt(currentIdentifier) + 1);
|
|
221
|
-
currentIdentifier = identifier;
|
|
222
|
-
return identifier;
|
|
223
|
-
};
|
|
224
|
-
const mainIdentifier = valueToIdentifier(mainValue);
|
|
225
|
-
|
|
226
|
-
// prototype, important to keep after the whole structure was visited
|
|
227
|
-
// so that we discover if any prototype is part of the value
|
|
228
|
-
const prototypeValueToIdentifier = prototypeValue => {
|
|
229
|
-
// prototype is null
|
|
230
|
-
if (prototypeValue === null) {
|
|
231
|
-
return valueToIdentifier(prototypeValue);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// prototype found somewhere already
|
|
235
|
-
const prototypeExistingIdentifier = identifierForComposite(prototypeValue);
|
|
236
|
-
if (prototypeExistingIdentifier !== undefined) {
|
|
237
|
-
return prototypeExistingIdentifier;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// mark prototype as visited
|
|
241
|
-
const prototypeIdentifier = identifierForNewValue(prototypeValue);
|
|
242
|
-
|
|
243
|
-
// prototype is a global reference ?
|
|
244
|
-
const prototypeGlobalPath = getCompositeGlobalPath(prototypeValue);
|
|
245
|
-
if (prototypeGlobalPath) {
|
|
246
|
-
recipeArray[prototypeIdentifier] = createGlobalReferenceRecipe(prototypeGlobalPath);
|
|
247
|
-
return prototypeIdentifier;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// otherwise prototype is unknown
|
|
251
|
-
if (prototypeStrict) {
|
|
252
|
-
throw new Error(createUnknownPrototypeMessage({
|
|
253
|
-
prototypeValue
|
|
254
|
-
}));
|
|
255
|
-
}
|
|
256
|
-
return prototypeValueToIdentifier(Object.getPrototypeOf(prototypeValue));
|
|
257
|
-
};
|
|
258
|
-
const identifierForValueOf = (value, path = []) => {
|
|
259
|
-
if (value instanceof Array) {
|
|
260
|
-
return valueToIdentifier(value.length, [...path, "length"]);
|
|
261
|
-
}
|
|
262
|
-
if ("valueOf" in value === false) {
|
|
263
|
-
return undefined;
|
|
264
|
-
}
|
|
265
|
-
if (typeof value.valueOf !== "function") {
|
|
266
|
-
return undefined;
|
|
267
|
-
}
|
|
268
|
-
const valueOfReturnValue = value.valueOf();
|
|
269
|
-
if (!isComposite(valueOfReturnValue)) {
|
|
270
|
-
return valueToIdentifier(valueOfReturnValue, [...path, "valueOf()"]);
|
|
271
|
-
}
|
|
272
|
-
if (valueOfReturnValue === value) {
|
|
273
|
-
return undefined;
|
|
274
|
-
}
|
|
275
|
-
throw new Error(createUnexpectedValueOfReturnValueMessage());
|
|
276
|
-
};
|
|
277
|
-
recipeArray.slice().forEach((recipe, index) => {
|
|
278
|
-
if (recipe.type === "composite") {
|
|
279
|
-
const value = valueMap[index];
|
|
280
|
-
if (typeof value === "function") {
|
|
281
|
-
const valueOfIdentifier = nextIdentifier();
|
|
282
|
-
recipeArray[valueOfIdentifier] = {
|
|
283
|
-
type: "primitive",
|
|
284
|
-
value
|
|
285
|
-
};
|
|
286
|
-
recipe.valueOfIdentifier = valueOfIdentifier;
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
if (value instanceof RegExp) {
|
|
290
|
-
const valueOfIdentifier = nextIdentifier();
|
|
291
|
-
recipeArray[valueOfIdentifier] = {
|
|
292
|
-
type: "primitive",
|
|
293
|
-
value
|
|
294
|
-
};
|
|
295
|
-
recipe.valueOfIdentifier = valueOfIdentifier;
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// valueOf, mandatory to uneval new Date(10) for instance.
|
|
300
|
-
recipe.valueOfIdentifier = identifierForValueOf(value);
|
|
301
|
-
const prototypeValue = Object.getPrototypeOf(value);
|
|
302
|
-
recipe.prototypeIdentifier = prototypeValueToIdentifier(prototypeValue);
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
return {
|
|
306
|
-
recipeArray,
|
|
307
|
-
mainIdentifier,
|
|
308
|
-
valueMap
|
|
309
|
-
};
|
|
310
|
-
};
|
|
311
|
-
const primitiveToRecipe = value => {
|
|
312
|
-
if (typeof value === "symbol") {
|
|
313
|
-
return symbolToRecipe(value);
|
|
314
|
-
}
|
|
315
|
-
return createPimitiveRecipe(value);
|
|
316
|
-
};
|
|
317
|
-
const symbolToRecipe = symbol => {
|
|
318
|
-
const globalSymbolKey = Symbol.keyFor(symbol);
|
|
319
|
-
if (globalSymbolKey !== undefined) {
|
|
320
|
-
return createGlobalSymbolRecipe(globalSymbolKey);
|
|
321
|
-
}
|
|
322
|
-
const symbolGlobalPath = getPrimitiveGlobalPath(symbol);
|
|
323
|
-
if (!symbolGlobalPath) {
|
|
324
|
-
throw new Error(createUnknownSymbolMessage({
|
|
325
|
-
symbol
|
|
326
|
-
}));
|
|
327
|
-
}
|
|
328
|
-
return createGlobalReferenceRecipe(symbolGlobalPath);
|
|
329
|
-
};
|
|
330
|
-
const createPimitiveRecipe = value => {
|
|
331
|
-
return {
|
|
332
|
-
type: "primitive",
|
|
333
|
-
value
|
|
334
|
-
};
|
|
335
|
-
};
|
|
336
|
-
const createGlobalReferenceRecipe = path => {
|
|
337
|
-
const recipe = {
|
|
338
|
-
type: "global-reference",
|
|
339
|
-
path
|
|
340
|
-
};
|
|
341
|
-
return recipe;
|
|
342
|
-
};
|
|
343
|
-
const createGlobalSymbolRecipe = key => {
|
|
344
|
-
return {
|
|
345
|
-
type: "global-symbol",
|
|
346
|
-
key
|
|
347
|
-
};
|
|
348
|
-
};
|
|
349
|
-
const createCompositeRecipe = ({
|
|
350
|
-
prototypeIdentifier,
|
|
351
|
-
valueOfIdentifier,
|
|
352
|
-
propertyDescriptionArray,
|
|
353
|
-
symbolDescriptionArray,
|
|
354
|
-
methodDescriptionArray,
|
|
355
|
-
extensible
|
|
356
|
-
}) => {
|
|
357
|
-
return {
|
|
358
|
-
type: "composite",
|
|
359
|
-
prototypeIdentifier,
|
|
360
|
-
valueOfIdentifier,
|
|
361
|
-
propertyDescriptionArray,
|
|
362
|
-
symbolDescriptionArray,
|
|
363
|
-
methodDescriptionArray,
|
|
364
|
-
extensible
|
|
365
|
-
};
|
|
366
|
-
};
|
|
367
|
-
const createPromiseAreNotSupportedMessage = ({
|
|
368
|
-
path
|
|
369
|
-
}) => {
|
|
370
|
-
if (path.length === 0) {
|
|
371
|
-
return `promise are not supported.`;
|
|
372
|
-
}
|
|
373
|
-
return `promise are not supported.
|
|
374
|
-
promise found at: ${path.join("")}`;
|
|
375
|
-
};
|
|
376
|
-
const createWeakSetAreNotSupportedMessage = ({
|
|
377
|
-
path
|
|
378
|
-
}) => {
|
|
379
|
-
if (path.length === 0) {
|
|
380
|
-
return `weakSet are not supported.`;
|
|
381
|
-
}
|
|
382
|
-
return `weakSet are not supported.
|
|
383
|
-
weakSet found at: ${path.join("")}`;
|
|
384
|
-
};
|
|
385
|
-
const createWeakMapAreNotSupportedMessage = ({
|
|
386
|
-
path
|
|
387
|
-
}) => {
|
|
388
|
-
if (path.length === 0) {
|
|
389
|
-
return `weakMap are not supported.`;
|
|
390
|
-
}
|
|
391
|
-
return `weakMap are not supported.
|
|
392
|
-
weakMap found at: ${path.join("")}`;
|
|
393
|
-
};
|
|
394
|
-
const createForbiddenFunctionMessage = ({
|
|
395
|
-
path
|
|
396
|
-
}) => {
|
|
397
|
-
if (path.length === 0) {
|
|
398
|
-
return `function are not allowed.`;
|
|
399
|
-
}
|
|
400
|
-
return `function are not allowed.
|
|
401
|
-
function found at: ${path.join("")}`;
|
|
402
|
-
};
|
|
403
|
-
const createForbiddenPropertyGetterMessage = ({
|
|
404
|
-
path,
|
|
405
|
-
propertyNameOrSymbol
|
|
406
|
-
}) => `property getter are not allowed.
|
|
407
|
-
getter found on property: ${String(propertyNameOrSymbol)}
|
|
408
|
-
at: ${path.join("")}`;
|
|
409
|
-
const createForbiddenPropertySetterMessage = ({
|
|
410
|
-
path,
|
|
411
|
-
propertyNameOrSymbol
|
|
412
|
-
}) => `property setter are not allowed.
|
|
413
|
-
setter found on property: ${String(propertyNameOrSymbol)}
|
|
414
|
-
at: ${path.join("")}`;
|
|
415
|
-
const createUnexpectedValueOfReturnValueMessage = () => `valueOf() must return a primitive of the object itself.`;
|
|
416
|
-
const createUnknownSymbolMessage = ({
|
|
417
|
-
symbol
|
|
418
|
-
}) => `symbol must be global, like Symbol.iterator, or created using Symbol.for().
|
|
419
|
-
symbol: ${symbol.toString()}`;
|
|
420
|
-
const createUnknownPrototypeMessage = ({
|
|
421
|
-
prototypeValue
|
|
422
|
-
}) => `prototype must be global, like Object.prototype, or somewhere in the value.
|
|
423
|
-
prototype constructor name: ${prototypeValue.constructor.name}`;
|
|
424
|
-
|
|
425
|
-
// be carefull because this function is mutating recipe objects inside the recipeArray.
|
|
426
|
-
// this is not an issue because each recipe object is not accessible from the outside
|
|
427
|
-
// when used internally by uneval
|
|
428
|
-
const sortRecipe = recipeArray => {
|
|
429
|
-
const findInRecipePrototypeChain = (recipe, callback) => {
|
|
430
|
-
let currentRecipe = recipe;
|
|
431
|
-
// eslint-disable-next-line no-constant-condition
|
|
432
|
-
while (true) {
|
|
433
|
-
if (currentRecipe.type !== "composite") {
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
436
|
-
const prototypeIdentifier = currentRecipe.prototypeIdentifier;
|
|
437
|
-
if (prototypeIdentifier === undefined) {
|
|
438
|
-
break;
|
|
439
|
-
}
|
|
440
|
-
currentRecipe = recipeArray[prototypeIdentifier];
|
|
441
|
-
if (callback(currentRecipe, prototypeIdentifier)) {
|
|
442
|
-
return prototypeIdentifier;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
return undefined;
|
|
446
|
-
};
|
|
447
|
-
const recipeArrayOrdered = recipeArray.slice();
|
|
448
|
-
recipeArrayOrdered.sort((leftRecipe, rightRecipe) => {
|
|
449
|
-
const leftType = leftRecipe.type;
|
|
450
|
-
const rightType = rightRecipe.type;
|
|
451
|
-
if (leftType === "composite" && rightType === "composite") {
|
|
452
|
-
const rightRecipeIsInLeftRecipePrototypeChain = findInRecipePrototypeChain(leftRecipe, recipeCandidate => recipeCandidate === rightRecipe);
|
|
453
|
-
// if left recipe requires right recipe, left must be after right
|
|
454
|
-
if (rightRecipeIsInLeftRecipePrototypeChain) {
|
|
455
|
-
return 1;
|
|
456
|
-
}
|
|
457
|
-
const leftRecipeIsInRightRecipePrototypeChain = findInRecipePrototypeChain(rightRecipe, recipeCandidate => recipeCandidate === leftRecipe);
|
|
458
|
-
// if right recipe requires left recipe, right must be after left
|
|
459
|
-
if (leftRecipeIsInRightRecipePrototypeChain) {
|
|
460
|
-
return -1;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
if (leftType !== rightType) {
|
|
464
|
-
// if left is a composite, left must be after right
|
|
465
|
-
if (leftType === "composite") {
|
|
466
|
-
return 1;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// if right is a composite, right must be after left
|
|
470
|
-
if (rightType === "composite") {
|
|
471
|
-
return -1;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
const leftIndex = recipeArray.indexOf(leftRecipe);
|
|
475
|
-
const rightIndex = recipeArray.indexOf(rightRecipe);
|
|
476
|
-
// left was before right, don't change that
|
|
477
|
-
if (leftIndex < rightIndex) {
|
|
478
|
-
return -1;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// right was after left, don't change that
|
|
482
|
-
return 1;
|
|
483
|
-
});
|
|
484
|
-
return recipeArrayOrdered;
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
// https://github.com/joliss/js-string-escape/blob/master/index.js
|
|
488
|
-
// http://javascript.crockford.com/remedial.html
|
|
489
|
-
const escapeString = value => {
|
|
490
|
-
const string = String(value);
|
|
491
|
-
let i = 0;
|
|
492
|
-
const j = string.length;
|
|
493
|
-
var escapedString = "";
|
|
494
|
-
while (i < j) {
|
|
495
|
-
const char = string[i];
|
|
496
|
-
let escapedChar;
|
|
497
|
-
if (char === '"' || char === "'" || char === "\\") {
|
|
498
|
-
escapedChar = `\\${char}`;
|
|
499
|
-
} else if (char === "\n") {
|
|
500
|
-
escapedChar = "\\n";
|
|
501
|
-
} else if (char === "\r") {
|
|
502
|
-
escapedChar = "\\r";
|
|
503
|
-
} else if (char === "\u2028") {
|
|
504
|
-
escapedChar = "\\u2028";
|
|
505
|
-
} else if (char === "\u2029") {
|
|
506
|
-
escapedChar = "\\u2029";
|
|
507
|
-
} else {
|
|
508
|
-
escapedChar = char;
|
|
509
|
-
}
|
|
510
|
-
escapedString += escapedChar;
|
|
511
|
-
i++;
|
|
512
|
-
}
|
|
513
|
-
return escapedString;
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
const uneval = (value, {
|
|
517
|
-
functionAllowed = false,
|
|
518
|
-
prototypeStrict = false,
|
|
519
|
-
ignoreSymbols = false
|
|
520
|
-
} = {}) => {
|
|
521
|
-
const {
|
|
522
|
-
recipeArray,
|
|
523
|
-
mainIdentifier,
|
|
524
|
-
valueMap
|
|
525
|
-
} = decompose(value, {
|
|
526
|
-
functionAllowed,
|
|
527
|
-
prototypeStrict,
|
|
528
|
-
ignoreSymbols
|
|
529
|
-
});
|
|
530
|
-
const recipeArraySorted = sortRecipe(recipeArray);
|
|
531
|
-
let source = `(function () {
|
|
532
|
-
var globalObject
|
|
533
|
-
try {
|
|
534
|
-
globalObject = Function('return this')() || (42, eval)('this');
|
|
535
|
-
} catch(e) {
|
|
536
|
-
globalObject = window;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
function safeDefineProperty(object, propertyNameOrSymbol, descriptor) {
|
|
540
|
-
var currentDescriptor = Object.getOwnPropertyDescriptor(object, propertyNameOrSymbol);
|
|
541
|
-
if (currentDescriptor && !currentDescriptor.configurable) return
|
|
542
|
-
Object.defineProperty(object, propertyNameOrSymbol, descriptor)
|
|
543
|
-
};
|
|
544
|
-
`;
|
|
545
|
-
const variableNameMap = {};
|
|
546
|
-
recipeArray.forEach((recipe, index) => {
|
|
547
|
-
const indexSorted = recipeArraySorted.indexOf(recipe);
|
|
548
|
-
variableNameMap[index] = `_${indexSorted}`;
|
|
549
|
-
});
|
|
550
|
-
const identifierToVariableName = identifier => variableNameMap[identifier];
|
|
551
|
-
const recipeToSetupSource = recipe => {
|
|
552
|
-
if (recipe.type === "primitive") return primitiveRecipeToSetupSource(recipe);
|
|
553
|
-
if (recipe.type === "global-symbol") return globalSymbolRecipeToSetupSource(recipe);
|
|
554
|
-
if (recipe.type === "global-reference") return globalReferenceRecipeToSetupSource(recipe);
|
|
555
|
-
return compositeRecipeToSetupSource(recipe);
|
|
556
|
-
};
|
|
557
|
-
const primitiveRecipeToSetupSource = ({
|
|
558
|
-
value
|
|
559
|
-
}) => {
|
|
560
|
-
const type = typeof value;
|
|
561
|
-
if (type === "string") {
|
|
562
|
-
return `"${escapeString(value)}";`;
|
|
563
|
-
}
|
|
564
|
-
if (type === "bigint") {
|
|
565
|
-
return `${value.toString()}n`;
|
|
566
|
-
}
|
|
567
|
-
if (Object.is(value, -0)) {
|
|
568
|
-
return "-0;";
|
|
569
|
-
}
|
|
570
|
-
return `${String(value)};`;
|
|
571
|
-
};
|
|
572
|
-
const globalSymbolRecipeToSetupSource = recipe => {
|
|
573
|
-
return `Symbol.for("${escapeString(recipe.key)}");`;
|
|
574
|
-
};
|
|
575
|
-
const globalReferenceRecipeToSetupSource = recipe => {
|
|
576
|
-
const pathSource = recipe.path.map(part => `["${escapeString(part)}"]`).join("");
|
|
577
|
-
return `globalObject${pathSource};`;
|
|
578
|
-
};
|
|
579
|
-
const compositeRecipeToSetupSource = ({
|
|
580
|
-
prototypeIdentifier,
|
|
581
|
-
valueOfIdentifier
|
|
582
|
-
}) => {
|
|
583
|
-
if (prototypeIdentifier === undefined) {
|
|
584
|
-
return identifierToVariableName(valueOfIdentifier);
|
|
585
|
-
}
|
|
586
|
-
const prototypeValue = valueMap[prototypeIdentifier];
|
|
587
|
-
if (prototypeValue === null) {
|
|
588
|
-
return `Object.create(null);`;
|
|
589
|
-
}
|
|
590
|
-
const prototypeConstructor = prototypeValue.constructor;
|
|
591
|
-
if (prototypeConstructor === Object) {
|
|
592
|
-
return `Object.create(${identifierToVariableName(prototypeIdentifier)});`;
|
|
593
|
-
}
|
|
594
|
-
if (valueOfIdentifier === undefined) {
|
|
595
|
-
return `new ${prototypeConstructor.name}();`;
|
|
596
|
-
}
|
|
597
|
-
if (prototypeConstructor.name === "BigInt") {
|
|
598
|
-
return `Object(${identifierToVariableName(valueOfIdentifier)})`;
|
|
599
|
-
}
|
|
600
|
-
return `new ${prototypeConstructor.name}(${identifierToVariableName(valueOfIdentifier)});`;
|
|
601
|
-
};
|
|
602
|
-
recipeArraySorted.forEach(recipe => {
|
|
603
|
-
const recipeVariableName = identifierToVariableName(recipeArray.indexOf(recipe));
|
|
604
|
-
source += `var ${recipeVariableName} = ${recipeToSetupSource(recipe)}
|
|
605
|
-
`;
|
|
606
|
-
});
|
|
607
|
-
const recipeToMutateSource = (recipe, recipeVariableName) => {
|
|
608
|
-
if (recipe.type === "composite") {
|
|
609
|
-
return compositeRecipeToMutateSource(recipe, recipeVariableName);
|
|
610
|
-
}
|
|
611
|
-
return ``;
|
|
612
|
-
};
|
|
613
|
-
const compositeRecipeToMutateSource = ({
|
|
614
|
-
propertyDescriptionArray,
|
|
615
|
-
symbolDescriptionArray,
|
|
616
|
-
methodDescriptionArray,
|
|
617
|
-
extensible
|
|
618
|
-
}, recipeVariableName) => {
|
|
619
|
-
let mutateSource = ``;
|
|
620
|
-
propertyDescriptionArray.forEach(({
|
|
621
|
-
propertyNameIdentifier,
|
|
622
|
-
propertyDescription
|
|
623
|
-
}) => {
|
|
624
|
-
mutateSource += generateDefinePropertySource(recipeVariableName, propertyNameIdentifier, propertyDescription);
|
|
625
|
-
});
|
|
626
|
-
symbolDescriptionArray.forEach(({
|
|
627
|
-
symbolIdentifier,
|
|
628
|
-
propertyDescription
|
|
629
|
-
}) => {
|
|
630
|
-
mutateSource += generateDefinePropertySource(recipeVariableName, symbolIdentifier, propertyDescription);
|
|
631
|
-
});
|
|
632
|
-
methodDescriptionArray.forEach(({
|
|
633
|
-
methodNameIdentifier,
|
|
634
|
-
callArray
|
|
635
|
-
}) => {
|
|
636
|
-
mutateSource += generateMethodCallSource(recipeVariableName, methodNameIdentifier, callArray);
|
|
637
|
-
});
|
|
638
|
-
if (!extensible) {
|
|
639
|
-
mutateSource += generatePreventExtensionSource(recipeVariableName);
|
|
640
|
-
}
|
|
641
|
-
return mutateSource;
|
|
642
|
-
};
|
|
643
|
-
const generateDefinePropertySource = (recipeVariableName, propertyNameOrSymbolIdentifier, propertyDescription) => {
|
|
644
|
-
const propertyOrSymbolVariableName = identifierToVariableName(propertyNameOrSymbolIdentifier);
|
|
645
|
-
const propertyDescriptorSource = generatePropertyDescriptorSource(propertyDescription);
|
|
646
|
-
return `safeDefineProperty(${recipeVariableName}, ${propertyOrSymbolVariableName}, ${propertyDescriptorSource});`;
|
|
647
|
-
};
|
|
648
|
-
const generatePropertyDescriptorSource = ({
|
|
649
|
-
configurable,
|
|
650
|
-
writable,
|
|
651
|
-
enumerable,
|
|
652
|
-
getIdentifier,
|
|
653
|
-
setIdentifier,
|
|
654
|
-
valueIdentifier
|
|
655
|
-
}) => {
|
|
656
|
-
if (valueIdentifier === undefined) {
|
|
657
|
-
return `{
|
|
658
|
-
configurable: ${configurable},
|
|
659
|
-
enumerable: ${enumerable},
|
|
660
|
-
get: ${getIdentifier === undefined ? undefined : identifierToVariableName(getIdentifier)},
|
|
661
|
-
set: ${setIdentifier === undefined ? undefined : identifierToVariableName(setIdentifier)},
|
|
662
|
-
}`;
|
|
663
|
-
}
|
|
664
|
-
return `{
|
|
665
|
-
configurable: ${configurable},
|
|
666
|
-
writable: ${writable},
|
|
667
|
-
enumerable: ${enumerable},
|
|
668
|
-
value: ${valueIdentifier === undefined ? undefined : identifierToVariableName(valueIdentifier)}
|
|
669
|
-
}`;
|
|
670
|
-
};
|
|
671
|
-
const generateMethodCallSource = (recipeVariableName, methodNameIdentifier, callArray) => {
|
|
672
|
-
let methodCallSource = ``;
|
|
673
|
-
const methodVariableName = identifierToVariableName(methodNameIdentifier);
|
|
674
|
-
callArray.forEach(argumentIdentifiers => {
|
|
675
|
-
const argumentVariableNames = argumentIdentifiers.map(argumentIdentifier => identifierToVariableName(argumentIdentifier));
|
|
676
|
-
methodCallSource += `${recipeVariableName}[${methodVariableName}](${argumentVariableNames.join(",")});`;
|
|
677
|
-
});
|
|
678
|
-
return methodCallSource;
|
|
679
|
-
};
|
|
680
|
-
const generatePreventExtensionSource = recipeVariableName => {
|
|
681
|
-
return `Object.preventExtensions(${recipeVariableName});`;
|
|
682
|
-
};
|
|
683
|
-
recipeArraySorted.forEach(recipe => {
|
|
684
|
-
const recipeVariableName = identifierToVariableName(recipeArray.indexOf(recipe));
|
|
685
|
-
source += `${recipeToMutateSource(recipe, recipeVariableName)}`;
|
|
686
|
-
});
|
|
687
|
-
source += `return ${identifierToVariableName(mainIdentifier)}; })()`;
|
|
688
|
-
return source;
|
|
689
|
-
};
|
|
690
|
-
|
|
691
|
-
/*
|
|
692
|
-
* Calling Profiler.startPreciseCoverage DO NOT propagate to
|
|
693
|
-
* subprocesses (new Worker or child_process.fork())
|
|
694
|
-
* So the best solution remains NODE_V8_COVERAGE
|
|
695
|
-
* This profiler strategy remains useful when:
|
|
696
|
-
* - As fallback when NODE_V8_COVERAGE is not configured
|
|
697
|
-
* - If explicitely enabled with coverageMethodForNodeJs: 'Profiler'
|
|
698
|
-
* - Used by jsenv during automated tests about coverage
|
|
699
|
-
* - Anyone prefering this approach over NODE_V8_COVERAGE and assuming
|
|
700
|
-
* it will not fork subprocess or don't care if coverage is missed for this code
|
|
701
|
-
* - https://v8.dev/blog/javascript-code-coverage#for-embedders
|
|
702
|
-
* - https://github.com/nodejs/node/issues/28283
|
|
703
|
-
* - https://vanilla.aslushnikov.com/?Profiler.startPreciseCoverage
|
|
704
|
-
*/
|
|
705
|
-
const startJsCoverage = async ({
|
|
706
|
-
callCount = true,
|
|
707
|
-
detailed = true
|
|
708
|
-
} = {}) => {
|
|
709
|
-
const session = new Session();
|
|
710
|
-
session.connect();
|
|
711
|
-
const postSession = (action, options) => {
|
|
712
|
-
const promise = new Promise((resolve, reject) => {
|
|
713
|
-
session.post(action, options, (error, data) => {
|
|
714
|
-
if (error) {
|
|
715
|
-
reject(error);
|
|
716
|
-
} else {
|
|
717
|
-
resolve(data);
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
});
|
|
721
|
-
return promise;
|
|
722
|
-
};
|
|
723
|
-
await postSession("Profiler.enable");
|
|
724
|
-
await postSession("Profiler.startPreciseCoverage", {
|
|
725
|
-
callCount,
|
|
726
|
-
detailed
|
|
727
|
-
});
|
|
728
|
-
const takeJsCoverage = async () => {
|
|
729
|
-
const coverage = await postSession("Profiler.takePreciseCoverage");
|
|
730
|
-
return coverage;
|
|
731
|
-
};
|
|
732
|
-
const stopJsCoverage = async () => {
|
|
733
|
-
const coverage = await takeJsCoverage();
|
|
734
|
-
await postSession("Profiler.stopPreciseCoverage");
|
|
735
|
-
await postSession("Profiler.disable");
|
|
736
|
-
return coverage;
|
|
737
|
-
};
|
|
738
|
-
return {
|
|
739
|
-
takeJsCoverage,
|
|
740
|
-
stopJsCoverage
|
|
741
|
-
};
|
|
742
|
-
};
|
|
743
|
-
|
|
744
|
-
const startObservingPerformances = () => {
|
|
745
|
-
const measureEntries = [];
|
|
746
|
-
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html
|
|
747
|
-
const perfObserver = new PerformanceObserver((
|
|
748
|
-
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceobserverentrylist
|
|
749
|
-
list) => {
|
|
750
|
-
const perfMeasureEntries = list.getEntriesByType("measure");
|
|
751
|
-
measureEntries.push(...perfMeasureEntries);
|
|
752
|
-
});
|
|
753
|
-
perfObserver.observe({
|
|
754
|
-
entryTypes: ["measure"]
|
|
755
|
-
});
|
|
756
|
-
return async () => {
|
|
757
|
-
// wait for node to call the performance observer
|
|
758
|
-
await new Promise(resolve => {
|
|
759
|
-
setTimeout(resolve);
|
|
760
|
-
});
|
|
761
|
-
performance.clearMarks();
|
|
762
|
-
perfObserver.disconnect();
|
|
763
|
-
return {
|
|
764
|
-
...readNodePerformance(),
|
|
765
|
-
measures: measuresFromMeasureEntries(measureEntries)
|
|
766
|
-
};
|
|
767
|
-
};
|
|
768
|
-
};
|
|
769
|
-
const readNodePerformance = () => {
|
|
770
|
-
const nodePerformance = {
|
|
771
|
-
nodeTiming: asPlainObject(performance.nodeTiming),
|
|
772
|
-
timeOrigin: performance.timeOrigin,
|
|
773
|
-
eventLoopUtilization: performance.eventLoopUtilization()
|
|
774
|
-
};
|
|
775
|
-
return nodePerformance;
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
// remove getters that cannot be stringified
|
|
779
|
-
const asPlainObject = objectWithGetters => {
|
|
780
|
-
const objectWithoutGetters = {};
|
|
781
|
-
Object.keys(objectWithGetters).forEach(key => {
|
|
782
|
-
objectWithoutGetters[key] = objectWithGetters[key];
|
|
783
|
-
});
|
|
784
|
-
return objectWithoutGetters;
|
|
785
|
-
};
|
|
786
|
-
const measuresFromMeasureEntries = measureEntries => {
|
|
787
|
-
const measures = {};
|
|
788
|
-
// Sort to ensure measures order is predictable
|
|
789
|
-
// It seems to be already predictable on Node 16+ but
|
|
790
|
-
// it's not the case on Node 14.
|
|
791
|
-
measureEntries.sort((a, b) => {
|
|
792
|
-
return a.startTime - b.startTime;
|
|
793
|
-
});
|
|
794
|
-
measureEntries.forEach((
|
|
795
|
-
// https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceentry
|
|
796
|
-
perfMeasureEntry) => {
|
|
797
|
-
measures[perfMeasureEntry.name] = perfMeasureEntry.duration;
|
|
798
|
-
});
|
|
799
|
-
return measures;
|
|
800
|
-
};
|
|
801
|
-
|
|
802
|
-
const executeUsingDynamicImport = async ({
|
|
803
|
-
rootDirectoryUrl,
|
|
804
|
-
fileUrl,
|
|
805
|
-
collectPerformance,
|
|
806
|
-
coverageEnabled,
|
|
807
|
-
coverageConfig,
|
|
808
|
-
coverageMethodForNodeJs,
|
|
809
|
-
coverageFileUrl
|
|
810
|
-
}) => {
|
|
811
|
-
const result = {};
|
|
812
|
-
const afterImportCallbacks = [];
|
|
813
|
-
if (coverageEnabled && coverageMethodForNodeJs === "Profiler") {
|
|
814
|
-
const {
|
|
815
|
-
filterV8Coverage
|
|
816
|
-
} = await import("./v8_coverage.js").then(n => n.v8_coverage);
|
|
817
|
-
const {
|
|
818
|
-
stopJsCoverage
|
|
819
|
-
} = await startJsCoverage();
|
|
820
|
-
afterImportCallbacks.push(async () => {
|
|
821
|
-
const coverage = await stopJsCoverage();
|
|
822
|
-
const coverageLight = await filterV8Coverage(coverage, {
|
|
823
|
-
rootDirectoryUrl,
|
|
824
|
-
coverageConfig
|
|
825
|
-
});
|
|
826
|
-
writeFileSync(new URL(coverageFileUrl), JSON.stringify(coverageLight, null, " "));
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
if (collectPerformance) {
|
|
830
|
-
const getPerformance = startObservingPerformances();
|
|
831
|
-
afterImportCallbacks.push(async () => {
|
|
832
|
-
const performance = await getPerformance();
|
|
833
|
-
result.performance = performance;
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
const namespace = await import(fileUrl);
|
|
837
|
-
const namespaceResolved = {};
|
|
838
|
-
await Promise.all(Object.keys(namespace).map(async key => {
|
|
839
|
-
const value = await namespace[key];
|
|
840
|
-
namespaceResolved[key] = value;
|
|
841
|
-
}));
|
|
842
|
-
result.namespace = namespaceResolved;
|
|
843
|
-
await afterImportCallbacks.reduce(async (previous, afterImportCallback) => {
|
|
844
|
-
await previous;
|
|
845
|
-
await afterImportCallback();
|
|
846
|
-
}, Promise.resolve());
|
|
847
|
-
return result;
|
|
848
|
-
};
|
|
849
|
-
|
|
850
|
-
export { executeUsingDynamicImport, uneval };
|