@jsenv/core 34.3.0 → 35.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +1 -1
  2. package/dist/{jsenv.js → jsenv_core.js} +1054 -3850
  3. package/package.json +6 -21
  4. package/src/build/build.js +2 -2
  5. package/src/dev/file_service.js +8 -8
  6. package/src/dev/start_dev_server.js +3 -3
  7. package/src/dev/user_agent.js +1 -1
  8. package/src/main.js +0 -23
  9. package/src/plugins/supervisor/jsenv_plugin_supervisor.js +1 -1
  10. package/src/plugins/transpilation/babel/require_babel_plugin.js +1 -1
  11. package/src/plugins/transpilation/js_module_fallback/convert_js_module_to_js_classic.js +1 -1
  12. package/dist/controllable_child_process.mjs +0 -129
  13. package/dist/controllable_worker_thread.mjs +0 -91
  14. package/dist/importmap_node_loader.mjs +0 -49
  15. package/dist/js/execute_using_dynamic_import.js +0 -850
  16. package/dist/js/resolveImport.js +0 -504
  17. package/dist/js/v8_coverage.js +0 -508
  18. package/dist/no_experimental_warnings.cjs +0 -8
  19. package/src/execute/execute.js +0 -111
  20. package/src/execute/run.js +0 -161
  21. package/src/execute/runtimes/browsers/chromium.js +0 -10
  22. package/src/execute/runtimes/browsers/firefox.js +0 -9
  23. package/src/execute/runtimes/browsers/from_playwright.js +0 -574
  24. package/src/execute/runtimes/browsers/middleware_istanbul.js +0 -65
  25. package/src/execute/runtimes/browsers/middleware_js_supervisor.js +0 -100
  26. package/src/execute/runtimes/browsers/webkit.js +0 -26
  27. package/src/execute/runtimes/node/child_exec_options.js +0 -166
  28. package/src/execute/runtimes/node/controllable_child_process.mjs +0 -135
  29. package/src/execute/runtimes/node/controllable_worker_thread.mjs +0 -103
  30. package/src/execute/runtimes/node/exec_options.js +0 -57
  31. package/src/execute/runtimes/node/execute_using_dynamic_import.js +0 -55
  32. package/src/execute/runtimes/node/exit_codes.js +0 -9
  33. package/src/execute/runtimes/node/importmap_node_loader.mjs +0 -51
  34. package/src/execute/runtimes/node/importmap_node_loader_file_url.js +0 -4
  35. package/src/execute/runtimes/node/kill_process_tree.js +0 -76
  36. package/src/execute/runtimes/node/no_experimental_warnings.cjs +0 -12
  37. package/src/execute/runtimes/node/no_experimental_warnings_file_url.js +0 -4
  38. package/src/execute/runtimes/node/node_child_process.js +0 -363
  39. package/src/execute/runtimes/node/node_execution_performance.js +0 -67
  40. package/src/execute/runtimes/node/node_worker_thread.js +0 -295
  41. package/src/execute/runtimes/node/profiler_v8_coverage.js +0 -56
  42. package/src/execute/runtimes/readme.md +0 -13
  43. package/src/execute/web_server_param.js +0 -74
  44. package/src/test/coverage/babel_plugin_instrument.js +0 -48
  45. package/src/test/coverage/coverage_reporter_html_directory.js +0 -32
  46. package/src/test/coverage/coverage_reporter_json_file.js +0 -17
  47. package/src/test/coverage/coverage_reporter_text_log.js +0 -19
  48. package/src/test/coverage/empty_coverage_factory.js +0 -52
  49. package/src/test/coverage/file_by_file_coverage.js +0 -25
  50. package/src/test/coverage/istanbul_coverage_composition.js +0 -28
  51. package/src/test/coverage/istanbul_coverage_map_from_coverage.js +0 -16
  52. package/src/test/coverage/list_files_not_covered.js +0 -15
  53. package/src/test/coverage/missing_coverage.js +0 -41
  54. package/src/test/coverage/report_to_coverage.js +0 -198
  55. package/src/test/coverage/v8_and_istanbul.js +0 -37
  56. package/src/test/coverage/v8_coverage.js +0 -26
  57. package/src/test/coverage/v8_coverage_composition.js +0 -24
  58. package/src/test/coverage/v8_coverage_node_directory.js +0 -85
  59. package/src/test/coverage/v8_coverage_to_istanbul.js +0 -99
  60. package/src/test/execute_steps.js +0 -425
  61. package/src/test/execute_test_plan.js +0 -372
  62. package/src/test/execution_colors.js +0 -10
  63. package/src/test/execution_steps.js +0 -65
  64. package/src/test/gc.js +0 -9
  65. package/src/test/logs_file_execution.js +0 -427
  66. package/src/test/logs_file_execution.test.mjs +0 -41
  67. package/src/test/readme.md +0 -3
  68. /package/src/{basic_fetch.js → helpers/basic_fetch.js} +0 -0
  69. /package/src/{lookup_package_directory.js → helpers/lookup_package_directory.js} +0 -0
  70. /package/src/{ping_server.js → helpers/ping_server.js} +0 -0
  71. /package/src/{require_from_jsenv.js → helpers/require_from_jsenv.js} +0 -0
  72. /package/src/{watch_source_files.js → helpers/watch_source_files.js} +0 -0
  73. /package/src/{web_url_converter.js → helpers/web_url_converter.js} +0 -0
@@ -1,508 +0,0 @@
1
- const assertUrlLike = (value, name = "url") => {
2
- if (typeof value !== "string") {
3
- throw new TypeError(`${name} must be a url string, got ${value}`);
4
- }
5
- if (isWindowsPathnameSpecifier(value)) {
6
- throw new TypeError(`${name} must be a url but looks like a windows pathname, got ${value}`);
7
- }
8
- if (!hasScheme(value)) {
9
- throw new TypeError(`${name} must be a url and no scheme found, got ${value}`);
10
- }
11
- };
12
- const isPlainObject = value => {
13
- if (value === null) {
14
- return false;
15
- }
16
- if (typeof value === "object") {
17
- if (Array.isArray(value)) {
18
- return false;
19
- }
20
- return true;
21
- }
22
- return false;
23
- };
24
- const isWindowsPathnameSpecifier = specifier => {
25
- const firstChar = specifier[0];
26
- if (!/[a-zA-Z]/.test(firstChar)) return false;
27
- const secondChar = specifier[1];
28
- if (secondChar !== ":") return false;
29
- const thirdChar = specifier[2];
30
- return thirdChar === "/" || thirdChar === "\\";
31
- };
32
- const hasScheme = specifier => /^[a-zA-Z]+:/.test(specifier);
33
-
34
- const resolveAssociations = (associations, baseUrl) => {
35
- assertUrlLike(baseUrl, "baseUrl");
36
- const associationsResolved = {};
37
- Object.keys(associations).forEach(key => {
38
- const value = associations[key];
39
- if (typeof value === "object" && value !== null) {
40
- const valueMapResolved = {};
41
- Object.keys(value).forEach(pattern => {
42
- const valueAssociated = value[pattern];
43
- const patternResolved = normalizeUrlPattern(pattern, baseUrl);
44
- valueMapResolved[patternResolved] = valueAssociated;
45
- });
46
- associationsResolved[key] = valueMapResolved;
47
- } else {
48
- associationsResolved[key] = value;
49
- }
50
- });
51
- return associationsResolved;
52
- };
53
- const normalizeUrlPattern = (urlPattern, baseUrl) => {
54
- try {
55
- return String(new URL(urlPattern, baseUrl));
56
- } catch (e) {
57
- // it's not really an url, no need to perform url resolution nor encoding
58
- return urlPattern;
59
- }
60
- };
61
-
62
- const asFlatAssociations = associations => {
63
- if (!isPlainObject(associations)) {
64
- throw new TypeError(`associations must be a plain object, got ${associations}`);
65
- }
66
- const flatAssociations = {};
67
- Object.keys(associations).forEach(associationName => {
68
- const associationValue = associations[associationName];
69
- if (isPlainObject(associationValue)) {
70
- Object.keys(associationValue).forEach(pattern => {
71
- const patternValue = associationValue[pattern];
72
- const previousValue = flatAssociations[pattern];
73
- if (isPlainObject(previousValue)) {
74
- flatAssociations[pattern] = {
75
- ...previousValue,
76
- [associationName]: patternValue
77
- };
78
- } else {
79
- flatAssociations[pattern] = {
80
- [associationName]: patternValue
81
- };
82
- }
83
- });
84
- }
85
- });
86
- return flatAssociations;
87
- };
88
-
89
- /*
90
- * Link to things doing pattern matching:
91
- * https://git-scm.com/docs/gitignore
92
- * https://github.com/kaelzhang/node-ignore
93
- */
94
-
95
- /** @module jsenv_url_meta **/
96
- /**
97
- * An object representing the result of applying a pattern to an url
98
- * @typedef {Object} MatchResult
99
- * @property {boolean} matched Indicates if url matched pattern
100
- * @property {number} patternIndex Index where pattern stopped matching url, otherwise pattern.length
101
- * @property {number} urlIndex Index where url stopped matching pattern, otherwise url.length
102
- * @property {Array} matchGroups Array of strings captured during pattern matching
103
- */
104
-
105
- /**
106
- * Apply a pattern to an url
107
- * @param {Object} applyPatternMatchingParams
108
- * @param {string} applyPatternMatchingParams.pattern "*", "**" and trailing slash have special meaning
109
- * @param {string} applyPatternMatchingParams.url a string representing an url
110
- * @return {MatchResult}
111
- */
112
- const applyPatternMatching = ({
113
- url,
114
- pattern
115
- }) => {
116
- assertUrlLike(pattern, "pattern");
117
- assertUrlLike(url, "url");
118
- const {
119
- matched,
120
- patternIndex,
121
- index,
122
- groups
123
- } = applyMatching(pattern, url);
124
- const matchGroups = [];
125
- let groupIndex = 0;
126
- groups.forEach(group => {
127
- if (group.name) {
128
- matchGroups[group.name] = group.string;
129
- } else {
130
- matchGroups[groupIndex] = group.string;
131
- groupIndex++;
132
- }
133
- });
134
- return {
135
- matched,
136
- patternIndex,
137
- urlIndex: index,
138
- matchGroups
139
- };
140
- };
141
- const applyMatching = (pattern, string) => {
142
- const groups = [];
143
- let patternIndex = 0;
144
- let index = 0;
145
- let remainingPattern = pattern;
146
- let remainingString = string;
147
- let restoreIndexes = true;
148
- const consumePattern = count => {
149
- const subpattern = remainingPattern.slice(0, count);
150
- remainingPattern = remainingPattern.slice(count);
151
- patternIndex += count;
152
- return subpattern;
153
- };
154
- const consumeString = count => {
155
- const substring = remainingString.slice(0, count);
156
- remainingString = remainingString.slice(count);
157
- index += count;
158
- return substring;
159
- };
160
- const consumeRemainingString = () => {
161
- return consumeString(remainingString.length);
162
- };
163
- let matched;
164
- const iterate = () => {
165
- const patternIndexBefore = patternIndex;
166
- const indexBefore = index;
167
- matched = matchOne();
168
- if (matched === undefined) {
169
- consumePattern(1);
170
- consumeString(1);
171
- iterate();
172
- return;
173
- }
174
- if (matched === false && restoreIndexes) {
175
- patternIndex = patternIndexBefore;
176
- index = indexBefore;
177
- }
178
- };
179
- const matchOne = () => {
180
- // pattern consumed and string consumed
181
- if (remainingPattern === "" && remainingString === "") {
182
- return true; // string fully matched pattern
183
- }
184
- // pattern consumed, string not consumed
185
- if (remainingPattern === "" && remainingString !== "") {
186
- return false; // fails because string longer than expected
187
- }
188
- // -- from this point pattern is not consumed --
189
- // string consumed, pattern not consumed
190
- if (remainingString === "") {
191
- if (remainingPattern === "**") {
192
- // trailing "**" is optional
193
- consumePattern(2);
194
- return true;
195
- }
196
- if (remainingPattern === "*") {
197
- groups.push({
198
- string: ""
199
- });
200
- }
201
- return false; // fail because string shorter than expected
202
- }
203
- // -- from this point pattern and string are not consumed --
204
- // fast path trailing slash
205
- if (remainingPattern === "/") {
206
- if (remainingString[0] === "/") {
207
- // trailing slash match remaining
208
- consumePattern(1);
209
- groups.push({
210
- string: consumeRemainingString()
211
- });
212
- return true;
213
- }
214
- return false;
215
- }
216
- // fast path trailing '**'
217
- if (remainingPattern === "**") {
218
- consumePattern(2);
219
- consumeRemainingString();
220
- return true;
221
- }
222
- // pattern leading **
223
- if (remainingPattern.slice(0, 2) === "**") {
224
- consumePattern(2); // consumes "**"
225
- let skipAllowed = true;
226
- if (remainingPattern[0] === "/") {
227
- consumePattern(1); // consumes "/"
228
- // when remainingPattern was preceeded by "**/"
229
- // and remainingString have no "/"
230
- // then skip is not allowed, a regular match will be performed
231
- if (!remainingString.includes("/")) {
232
- skipAllowed = false;
233
- }
234
- }
235
- // pattern ending with "**" or "**/" match remaining string
236
- if (remainingPattern === "") {
237
- consumeRemainingString();
238
- return true;
239
- }
240
- if (skipAllowed) {
241
- const skipResult = skipUntilMatch({
242
- pattern: remainingPattern,
243
- string: remainingString,
244
- canSkipSlash: true
245
- });
246
- groups.push(...skipResult.groups);
247
- consumePattern(skipResult.patternIndex);
248
- consumeRemainingString();
249
- restoreIndexes = false;
250
- return skipResult.matched;
251
- }
252
- }
253
- if (remainingPattern[0] === "*") {
254
- consumePattern(1); // consumes "*"
255
- if (remainingPattern === "") {
256
- // matches everything except "/"
257
- const slashIndex = remainingString.indexOf("/");
258
- if (slashIndex === -1) {
259
- groups.push({
260
- string: consumeRemainingString()
261
- });
262
- return true;
263
- }
264
- groups.push({
265
- string: consumeString(slashIndex)
266
- });
267
- return false;
268
- }
269
- // the next char must not the one expected by remainingPattern[0]
270
- // because * is greedy and expect to skip at least one char
271
- if (remainingPattern[0] === remainingString[0]) {
272
- groups.push({
273
- string: ""
274
- });
275
- patternIndex = patternIndex - 1;
276
- return false;
277
- }
278
- const skipResult = skipUntilMatch({
279
- pattern: remainingPattern,
280
- string: remainingString,
281
- canSkipSlash: false
282
- });
283
- groups.push(skipResult.group, ...skipResult.groups);
284
- consumePattern(skipResult.patternIndex);
285
- consumeString(skipResult.index);
286
- restoreIndexes = false;
287
- return skipResult.matched;
288
- }
289
- if (remainingPattern[0] !== remainingString[0]) {
290
- return false;
291
- }
292
- return undefined;
293
- };
294
- iterate();
295
- return {
296
- matched,
297
- patternIndex,
298
- index,
299
- groups
300
- };
301
- };
302
- const skipUntilMatch = ({
303
- pattern,
304
- string,
305
- canSkipSlash
306
- }) => {
307
- let index = 0;
308
- let remainingString = string;
309
- let longestAttemptRange = null;
310
- let isLastAttempt = false;
311
- const failure = () => {
312
- return {
313
- matched: false,
314
- patternIndex: longestAttemptRange.patternIndex,
315
- index: longestAttemptRange.index + longestAttemptRange.length,
316
- groups: longestAttemptRange.groups,
317
- group: {
318
- string: string.slice(0, longestAttemptRange.index)
319
- }
320
- };
321
- };
322
- const tryToMatch = () => {
323
- const matchAttempt = applyMatching(pattern, remainingString);
324
- if (matchAttempt.matched) {
325
- return {
326
- matched: true,
327
- patternIndex: matchAttempt.patternIndex,
328
- index: index + matchAttempt.index,
329
- groups: matchAttempt.groups,
330
- group: {
331
- string: remainingString === "" ? string : string.slice(0, -remainingString.length)
332
- }
333
- };
334
- }
335
- const attemptIndex = matchAttempt.index;
336
- const attemptRange = {
337
- patternIndex: matchAttempt.patternIndex,
338
- index,
339
- length: attemptIndex,
340
- groups: matchAttempt.groups
341
- };
342
- if (!longestAttemptRange || longestAttemptRange.length < attemptRange.length) {
343
- longestAttemptRange = attemptRange;
344
- }
345
- if (isLastAttempt) {
346
- return failure();
347
- }
348
- const nextIndex = attemptIndex + 1;
349
- if (nextIndex >= remainingString.length) {
350
- return failure();
351
- }
352
- if (remainingString[0] === "/") {
353
- if (!canSkipSlash) {
354
- return failure();
355
- }
356
- // when it's the last slash, the next attempt is the last
357
- if (remainingString.indexOf("/", 1) === -1) {
358
- isLastAttempt = true;
359
- }
360
- }
361
- // search against the next unattempted string
362
- index += nextIndex;
363
- remainingString = remainingString.slice(nextIndex);
364
- return tryToMatch();
365
- };
366
- return tryToMatch();
367
- };
368
-
369
- const applyAssociations = ({
370
- url,
371
- associations
372
- }) => {
373
- assertUrlLike(url);
374
- const flatAssociations = asFlatAssociations(associations);
375
- return Object.keys(flatAssociations).reduce((previousValue, pattern) => {
376
- const {
377
- matched
378
- } = applyPatternMatching({
379
- pattern,
380
- url
381
- });
382
- if (matched) {
383
- const value = flatAssociations[pattern];
384
- if (isPlainObject(previousValue) && isPlainObject(value)) {
385
- return {
386
- ...previousValue,
387
- ...value
388
- };
389
- }
390
- return value;
391
- }
392
- return previousValue;
393
- }, {});
394
- };
395
-
396
- const applyAliases = ({
397
- url,
398
- aliases
399
- }) => {
400
- let aliasFullMatchResult;
401
- const aliasMatchingKey = Object.keys(aliases).find(key => {
402
- const aliasMatchResult = applyPatternMatching({
403
- pattern: key,
404
- url
405
- });
406
- if (aliasMatchResult.matched) {
407
- aliasFullMatchResult = aliasMatchResult;
408
- return true;
409
- }
410
- return false;
411
- });
412
- if (!aliasMatchingKey) {
413
- return url;
414
- }
415
- const {
416
- matchGroups
417
- } = aliasFullMatchResult;
418
- const alias = aliases[aliasMatchingKey];
419
- const parts = alias.split("*");
420
- const newUrl = parts.reduce((previous, value, index) => {
421
- return `${previous}${value}${index === parts.length - 1 ? "" : matchGroups[index]}`;
422
- }, "");
423
- return newUrl;
424
- };
425
-
426
- const urlChildMayMatch = ({
427
- url,
428
- associations,
429
- predicate
430
- }) => {
431
- assertUrlLike(url, "url");
432
- // the function was meants to be used on url ending with '/'
433
- if (!url.endsWith("/")) {
434
- throw new Error(`url should end with /, got ${url}`);
435
- }
436
- if (typeof predicate !== "function") {
437
- throw new TypeError(`predicate must be a function, got ${predicate}`);
438
- }
439
- const flatAssociations = asFlatAssociations(associations);
440
- // for full match we must create an object to allow pattern to override previous ones
441
- let fullMatchMeta = {};
442
- let someFullMatch = false;
443
- // for partial match, any meta satisfying predicate will be valid because
444
- // we don't know for sure if pattern will still match for a file inside pathname
445
- const partialMatchMetaArray = [];
446
- Object.keys(flatAssociations).forEach(pattern => {
447
- const value = flatAssociations[pattern];
448
- const matchResult = applyPatternMatching({
449
- pattern,
450
- url
451
- });
452
- if (matchResult.matched) {
453
- someFullMatch = true;
454
- if (isPlainObject(fullMatchMeta) && isPlainObject(value)) {
455
- fullMatchMeta = {
456
- ...fullMatchMeta,
457
- ...value
458
- };
459
- } else {
460
- fullMatchMeta = value;
461
- }
462
- } else if (someFullMatch === false && matchResult.urlIndex >= url.length) {
463
- partialMatchMetaArray.push(value);
464
- }
465
- });
466
- if (someFullMatch) {
467
- return Boolean(predicate(fullMatchMeta));
468
- }
469
- return partialMatchMetaArray.some(partialMatchMeta => predicate(partialMatchMeta));
470
- };
471
-
472
- const URL_META = {
473
- resolveAssociations,
474
- applyAssociations,
475
- urlChildMayMatch,
476
- applyPatternMatching,
477
- applyAliases
478
- };
479
-
480
- const filterV8Coverage = async (v8Coverage, {
481
- rootDirectoryUrl,
482
- coverageConfig
483
- }) => {
484
- const associations = URL_META.resolveAssociations({
485
- cover: coverageConfig
486
- }, rootDirectoryUrl);
487
- const urlShouldBeCovered = url => {
488
- const {
489
- cover
490
- } = URL_META.applyAssociations({
491
- url: new URL(url, rootDirectoryUrl).href,
492
- associations
493
- });
494
- return cover;
495
- };
496
- const v8CoverageFiltered = {
497
- ...v8Coverage,
498
- result: v8Coverage.result.filter(fileReport => urlShouldBeCovered(fileReport.url))
499
- };
500
- return v8CoverageFiltered;
501
- };
502
-
503
- const v8_coverage = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
504
- __proto__: null,
505
- filterV8Coverage
506
- }, Symbol.toStringTag, { value: 'Module' }));
507
-
508
- export { URL_META, filterV8Coverage, v8_coverage };
@@ -1,8 +0,0 @@
1
- // see https://github.com/nodejs/node/issues/47478
2
- const originalEmit = process.emit;
3
- process.emit = (event, error) => {
4
- if (event === "warning" && error.name === "ExperimentalWarning" && error.message.includes("--experimental-loader")) {
5
- return false;
6
- }
7
- return originalEmit.call(process, event, error);
8
- };
@@ -1,111 +0,0 @@
1
- /*
2
- * Export a function capable to execute a file on a runtime (browser or node) and return how it goes.
3
- *
4
- * - can be useful to execute a file in a browser/node.js programmatically
5
- * - not documented
6
- * - the most importants parts:
7
- * - fileRelativeUrl: the file to execute inside rootDirectoryUrl
8
- * - runtime: an object with a "run" method.
9
- * The run method will start a browser/node process and execute file in it
10
- * - Most of the logic lives in "./run.js" used by executeTestPlan to run tests
11
- */
12
-
13
- import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
14
- import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
15
- import { createLogger } from "@jsenv/log"
16
-
17
- import { assertAndNormalizeWebServer } from "./web_server_param.js"
18
- import { run } from "./run.js"
19
-
20
- export const execute = async ({
21
- signal = new AbortController().signal,
22
- handleSIGINT = true,
23
- logLevel,
24
- rootDirectoryUrl,
25
- webServer,
26
- importMap,
27
-
28
- fileRelativeUrl,
29
- allocatedMs,
30
- mirrorConsole = true,
31
- keepRunning = false,
32
-
33
- collectConsole,
34
- collectCoverage,
35
- coverageTempDirectoryUrl,
36
- collectPerformance = false,
37
- runtime,
38
- runtimeParams,
39
-
40
- ignoreError = false,
41
- }) => {
42
- const logger = createLogger({ logLevel })
43
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(
44
- rootDirectoryUrl,
45
- "rootDirectoryUrl",
46
- )
47
- const executeOperation = Abort.startOperation()
48
- executeOperation.addAbortSignal(signal)
49
- if (handleSIGINT) {
50
- executeOperation.addAbortSource((abort) => {
51
- return raceProcessTeardownEvents(
52
- {
53
- SIGINT: true,
54
- },
55
- abort,
56
- )
57
- })
58
- }
59
-
60
- if (runtime.type === "browser") {
61
- await assertAndNormalizeWebServer(webServer)
62
- }
63
-
64
- let resultTransformer = (result) => result
65
- runtimeParams = {
66
- rootDirectoryUrl,
67
- webServer,
68
- fileRelativeUrl,
69
- importMap,
70
- ...runtimeParams,
71
- }
72
-
73
- let result = await run({
74
- signal: executeOperation.signal,
75
- logger,
76
- allocatedMs,
77
- keepRunning,
78
- mirrorConsole,
79
- collectConsole,
80
- collectCoverage,
81
- coverageTempDirectoryUrl,
82
- collectPerformance,
83
- runtime,
84
- runtimeParams,
85
- })
86
- result = resultTransformer(result)
87
-
88
- try {
89
- if (result.status === "failed") {
90
- if (ignoreError) {
91
- return result
92
- }
93
- /*
94
- Warning: when node launched with --unhandled-rejections=strict, despites
95
- this promise being rejected by throw result.error node will completely ignore it.
96
-
97
- The error can be logged by doing
98
- ```js
99
- process.setUncaughtExceptionCaptureCallback((error) => {
100
- console.error(error.stack)
101
- })
102
- ```
103
- But it feels like a hack.
104
- */
105
- throw result.errors[result.errors.length - 1]
106
- }
107
- return result
108
- } finally {
109
- await executeOperation.end()
110
- }
111
- }