@jsenv/core 27.0.2 → 27.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllable_child_process.mjs +139 -0
- package/dist/controllable_worker_thread.mjs +103 -0
- package/dist/js/execute_using_dynamic_import.js +169 -0
- package/dist/js/v8_coverage.js +539 -0
- package/dist/main.js +703 -827
- package/package.json +13 -12
- package/src/build/build.js +9 -12
- package/src/build/build_urls_generator.js +1 -1
- package/src/build/inject_global_version_mappings.js +3 -2
- package/src/build/inject_service_worker_urls.js +1 -2
- package/src/execute/run.js +50 -68
- package/src/execute/runtimes/browsers/from_playwright.js +13 -8
- package/src/execute/runtimes/node/{controllable_file.mjs → controllable_child_process.mjs} +18 -50
- package/src/execute/runtimes/node/controllable_worker_thread.mjs +103 -0
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +49 -0
- package/src/execute/runtimes/node/exit_codes.js +9 -0
- package/src/execute/runtimes/node/{node_process.js → node_child_process.js} +56 -50
- package/src/execute/runtimes/node/node_worker_thread.js +268 -25
- package/src/execute/runtimes/node/profiler_v8_coverage.js +56 -0
- package/src/main.js +3 -1
- package/src/omega/kitchen.js +19 -6
- package/src/omega/server/file_service.js +2 -2
- package/src/omega/url_graph/url_graph_load.js +0 -1
- package/src/omega/url_graph/url_info_transformations.js +27 -14
- package/src/omega/url_graph.js +2 -0
- package/src/plugins/bundling/js_module/bundle_js_module.js +2 -5
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +18 -15
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +2 -1
- package/src/test/coverage/report_to_coverage.js +16 -19
- package/src/test/coverage/v8_coverage.js +26 -0
- package/src/test/coverage/{v8_coverage_from_directory.js → v8_coverage_node_directory.js} +22 -26
- package/src/test/execute_plan.js +98 -91
- package/src/test/execute_test_plan.js +19 -13
- package/src/test/logs_file_execution.js +90 -13
- package/dist/js/controllable_file.mjs +0 -227
package/dist/main.js
CHANGED
|
@@ -13,17 +13,17 @@ import { performance } from "node:perf_hooks";
|
|
|
13
13
|
import { extname, dirname, basename } from "node:path";
|
|
14
14
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
15
15
|
import crypto, { createHash } from "node:crypto";
|
|
16
|
+
import { U as URL_META, f as filterV8Coverage } from "./js/v8_coverage.js";
|
|
16
17
|
import { parseHtmlString, stringifyHtmlAst, visitHtmlNodes, getHtmlNodeAttribute, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, findHtmlNode, getHtmlNodeText, removeHtmlNode, setHtmlNodeText, analyzeScriptNode, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode } from "@jsenv/ast";
|
|
17
18
|
import { createMagicSource, composeTwoSourcemaps, sourcemapConverter, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
18
19
|
import { createRequire } from "node:module";
|
|
19
20
|
import babelParser from "@babel/parser";
|
|
21
|
+
import v8, { takeCoverage } from "node:v8";
|
|
20
22
|
import wrapAnsi from "wrap-ansi";
|
|
21
23
|
import stripAnsi from "strip-ansi";
|
|
22
24
|
import cuid from "cuid";
|
|
23
|
-
import v8 from "node:v8";
|
|
24
25
|
import { runInNewContext, Script } from "node:vm";
|
|
25
26
|
import { fork } from "node:child_process";
|
|
26
|
-
import { u as uneval } from "./js/uneval.js";
|
|
27
27
|
|
|
28
28
|
const LOG_LEVEL_OFF = "off";
|
|
29
29
|
const LOG_LEVEL_DEBUG = "debug";
|
|
@@ -332,23 +332,27 @@ const canUseUnicode = isUnicodeSupported();
|
|
|
332
332
|
const COMMAND_RAW = canUseUnicode ? `❯` : `>`;
|
|
333
333
|
const OK_RAW = canUseUnicode ? `✔` : `√`;
|
|
334
334
|
const FAILURE_RAW = canUseUnicode ? `✖` : `×`;
|
|
335
|
+
const DEBUG_RAW = canUseUnicode ? `◆` : `♦`;
|
|
335
336
|
const INFO_RAW = canUseUnicode ? `ℹ` : `i`;
|
|
336
337
|
const WARNING_RAW = canUseUnicode ? `⚠` : `‼`;
|
|
337
338
|
const COMMAND = ANSI.color(COMMAND_RAW, ANSI.GREY); // ANSI_MAGENTA)
|
|
338
339
|
|
|
339
340
|
const OK = ANSI.color(OK_RAW, ANSI.GREEN);
|
|
340
341
|
const FAILURE = ANSI.color(FAILURE_RAW, ANSI.RED);
|
|
342
|
+
const DEBUG = ANSI.color(DEBUG_RAW, ANSI.GREY);
|
|
341
343
|
const INFO = ANSI.color(INFO_RAW, ANSI.BLUE);
|
|
342
344
|
const WARNING = ANSI.color(WARNING_RAW, ANSI.YELLOW);
|
|
343
345
|
const UNICODE = {
|
|
344
346
|
COMMAND,
|
|
345
347
|
OK,
|
|
346
348
|
FAILURE,
|
|
349
|
+
DEBUG,
|
|
347
350
|
INFO,
|
|
348
351
|
WARNING,
|
|
349
352
|
COMMAND_RAW,
|
|
350
353
|
OK_RAW,
|
|
351
354
|
FAILURE_RAW,
|
|
355
|
+
DEBUG_RAW,
|
|
352
356
|
INFO_RAW,
|
|
353
357
|
WARNING_RAW,
|
|
354
358
|
supported: canUseUnicode
|
|
@@ -5738,515 +5742,6 @@ const createEventHistory = limit => {
|
|
|
5738
5742
|
};
|
|
5739
5743
|
};
|
|
5740
5744
|
|
|
5741
|
-
const assertUrlLike = (value, name = "url") => {
|
|
5742
|
-
if (typeof value !== "string") {
|
|
5743
|
-
throw new TypeError(`${name} must be a url string, got ${value}`);
|
|
5744
|
-
}
|
|
5745
|
-
|
|
5746
|
-
if (isWindowsPathnameSpecifier(value)) {
|
|
5747
|
-
throw new TypeError(`${name} must be a url but looks like a windows pathname, got ${value}`);
|
|
5748
|
-
}
|
|
5749
|
-
|
|
5750
|
-
if (!hasScheme$1(value)) {
|
|
5751
|
-
throw new TypeError(`${name} must be a url and no scheme found, got ${value}`);
|
|
5752
|
-
}
|
|
5753
|
-
};
|
|
5754
|
-
const isPlainObject = value => {
|
|
5755
|
-
if (value === null) {
|
|
5756
|
-
return false;
|
|
5757
|
-
}
|
|
5758
|
-
|
|
5759
|
-
if (typeof value === "object") {
|
|
5760
|
-
if (Array.isArray(value)) {
|
|
5761
|
-
return false;
|
|
5762
|
-
}
|
|
5763
|
-
|
|
5764
|
-
return true;
|
|
5765
|
-
}
|
|
5766
|
-
|
|
5767
|
-
return false;
|
|
5768
|
-
};
|
|
5769
|
-
|
|
5770
|
-
const isWindowsPathnameSpecifier = specifier => {
|
|
5771
|
-
const firstChar = specifier[0];
|
|
5772
|
-
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
5773
|
-
const secondChar = specifier[1];
|
|
5774
|
-
if (secondChar !== ":") return false;
|
|
5775
|
-
const thirdChar = specifier[2];
|
|
5776
|
-
return thirdChar === "/" || thirdChar === "\\";
|
|
5777
|
-
};
|
|
5778
|
-
|
|
5779
|
-
const hasScheme$1 = specifier => /^[a-zA-Z]+:/.test(specifier);
|
|
5780
|
-
|
|
5781
|
-
const resolveAssociations = (associations, baseUrl) => {
|
|
5782
|
-
assertUrlLike(baseUrl, "baseUrl");
|
|
5783
|
-
const associationsResolved = {};
|
|
5784
|
-
Object.keys(associations).forEach(key => {
|
|
5785
|
-
const valueMap = associations[key];
|
|
5786
|
-
const valueMapResolved = {};
|
|
5787
|
-
Object.keys(valueMap).forEach(pattern => {
|
|
5788
|
-
const value = valueMap[pattern];
|
|
5789
|
-
const patternResolved = normalizeUrlPattern(pattern, baseUrl);
|
|
5790
|
-
valueMapResolved[patternResolved] = value;
|
|
5791
|
-
});
|
|
5792
|
-
associationsResolved[key] = valueMapResolved;
|
|
5793
|
-
});
|
|
5794
|
-
return associationsResolved;
|
|
5795
|
-
};
|
|
5796
|
-
|
|
5797
|
-
const normalizeUrlPattern = (urlPattern, baseUrl) => {
|
|
5798
|
-
// starts with a scheme
|
|
5799
|
-
if (/^[a-zA-Z]{2,}:/.test(urlPattern)) {
|
|
5800
|
-
return urlPattern;
|
|
5801
|
-
}
|
|
5802
|
-
|
|
5803
|
-
return String(new URL(urlPattern, baseUrl));
|
|
5804
|
-
};
|
|
5805
|
-
|
|
5806
|
-
const asFlatAssociations = associations => {
|
|
5807
|
-
if (!isPlainObject(associations)) {
|
|
5808
|
-
throw new TypeError(`associations must be a plain object, got ${associations}`);
|
|
5809
|
-
}
|
|
5810
|
-
|
|
5811
|
-
const flatAssociations = {};
|
|
5812
|
-
Object.keys(associations).forEach(key => {
|
|
5813
|
-
const valueMap = associations[key];
|
|
5814
|
-
|
|
5815
|
-
if (!isPlainObject(valueMap)) {
|
|
5816
|
-
throw new TypeError(`all associations value must be objects, found "${key}": ${valueMap}`);
|
|
5817
|
-
}
|
|
5818
|
-
|
|
5819
|
-
Object.keys(valueMap).forEach(pattern => {
|
|
5820
|
-
const value = valueMap[pattern];
|
|
5821
|
-
const previousValue = flatAssociations[pattern];
|
|
5822
|
-
flatAssociations[pattern] = previousValue ? { ...previousValue,
|
|
5823
|
-
[key]: value
|
|
5824
|
-
} : {
|
|
5825
|
-
[key]: value
|
|
5826
|
-
};
|
|
5827
|
-
});
|
|
5828
|
-
});
|
|
5829
|
-
return flatAssociations;
|
|
5830
|
-
};
|
|
5831
|
-
|
|
5832
|
-
/*
|
|
5833
|
-
* Link to things doing pattern matching:
|
|
5834
|
-
* https://git-scm.com/docs/gitignore
|
|
5835
|
-
* https://github.com/kaelzhang/node-ignore
|
|
5836
|
-
*/
|
|
5837
|
-
/** @module jsenv_url_meta **/
|
|
5838
|
-
|
|
5839
|
-
/**
|
|
5840
|
-
* An object representing the result of applying a pattern to an url
|
|
5841
|
-
* @typedef {Object} MatchResult
|
|
5842
|
-
* @property {boolean} matched Indicates if url matched pattern
|
|
5843
|
-
* @property {number} patternIndex Index where pattern stopped matching url, otherwise pattern.length
|
|
5844
|
-
* @property {number} urlIndex Index where url stopped matching pattern, otherwise url.length
|
|
5845
|
-
* @property {Array} matchGroups Array of strings captured during pattern matching
|
|
5846
|
-
*/
|
|
5847
|
-
|
|
5848
|
-
/**
|
|
5849
|
-
* Apply a pattern to an url
|
|
5850
|
-
* @param {Object} applyPatternMatchingParams
|
|
5851
|
-
* @param {string} applyPatternMatchingParams.pattern "*", "**" and trailing slash have special meaning
|
|
5852
|
-
* @param {string} applyPatternMatchingParams.url a string representing an url
|
|
5853
|
-
* @return {MatchResult}
|
|
5854
|
-
*/
|
|
5855
|
-
|
|
5856
|
-
const applyPatternMatching = ({
|
|
5857
|
-
url,
|
|
5858
|
-
pattern
|
|
5859
|
-
}) => {
|
|
5860
|
-
assertUrlLike(pattern, "pattern");
|
|
5861
|
-
assertUrlLike(url, "url");
|
|
5862
|
-
const {
|
|
5863
|
-
matched,
|
|
5864
|
-
patternIndex,
|
|
5865
|
-
index,
|
|
5866
|
-
groups
|
|
5867
|
-
} = applyMatching(pattern, url);
|
|
5868
|
-
const matchGroups = [];
|
|
5869
|
-
let groupIndex = 0;
|
|
5870
|
-
groups.forEach(group => {
|
|
5871
|
-
if (group.name) {
|
|
5872
|
-
matchGroups[group.name] = group.string;
|
|
5873
|
-
} else {
|
|
5874
|
-
matchGroups[groupIndex] = group.string;
|
|
5875
|
-
groupIndex++;
|
|
5876
|
-
}
|
|
5877
|
-
});
|
|
5878
|
-
return {
|
|
5879
|
-
matched,
|
|
5880
|
-
patternIndex,
|
|
5881
|
-
urlIndex: index,
|
|
5882
|
-
matchGroups
|
|
5883
|
-
};
|
|
5884
|
-
};
|
|
5885
|
-
|
|
5886
|
-
const applyMatching = (pattern, string) => {
|
|
5887
|
-
const groups = [];
|
|
5888
|
-
let patternIndex = 0;
|
|
5889
|
-
let index = 0;
|
|
5890
|
-
let remainingPattern = pattern;
|
|
5891
|
-
let remainingString = string;
|
|
5892
|
-
let restoreIndexes = true;
|
|
5893
|
-
|
|
5894
|
-
const consumePattern = count => {
|
|
5895
|
-
const subpattern = remainingPattern.slice(0, count);
|
|
5896
|
-
remainingPattern = remainingPattern.slice(count);
|
|
5897
|
-
patternIndex += count;
|
|
5898
|
-
return subpattern;
|
|
5899
|
-
};
|
|
5900
|
-
|
|
5901
|
-
const consumeString = count => {
|
|
5902
|
-
const substring = remainingString.slice(0, count);
|
|
5903
|
-
remainingString = remainingString.slice(count);
|
|
5904
|
-
index += count;
|
|
5905
|
-
return substring;
|
|
5906
|
-
};
|
|
5907
|
-
|
|
5908
|
-
const consumeRemainingString = () => {
|
|
5909
|
-
return consumeString(remainingString.length);
|
|
5910
|
-
};
|
|
5911
|
-
|
|
5912
|
-
let matched;
|
|
5913
|
-
|
|
5914
|
-
const iterate = () => {
|
|
5915
|
-
const patternIndexBefore = patternIndex;
|
|
5916
|
-
const indexBefore = index;
|
|
5917
|
-
matched = matchOne();
|
|
5918
|
-
|
|
5919
|
-
if (matched === undefined) {
|
|
5920
|
-
consumePattern(1);
|
|
5921
|
-
consumeString(1);
|
|
5922
|
-
iterate();
|
|
5923
|
-
return;
|
|
5924
|
-
}
|
|
5925
|
-
|
|
5926
|
-
if (matched === false && restoreIndexes) {
|
|
5927
|
-
patternIndex = patternIndexBefore;
|
|
5928
|
-
index = indexBefore;
|
|
5929
|
-
}
|
|
5930
|
-
};
|
|
5931
|
-
|
|
5932
|
-
const matchOne = () => {
|
|
5933
|
-
// pattern consumed and string consumed
|
|
5934
|
-
if (remainingPattern === "" && remainingString === "") {
|
|
5935
|
-
return true; // string fully matched pattern
|
|
5936
|
-
} // pattern consumed, string not consumed
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
if (remainingPattern === "" && remainingString !== "") {
|
|
5940
|
-
return false; // fails because string longer than expected
|
|
5941
|
-
} // -- from this point pattern is not consumed --
|
|
5942
|
-
// string consumed, pattern not consumed
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
if (remainingString === "") {
|
|
5946
|
-
if (remainingPattern === "**") {
|
|
5947
|
-
// trailing "**" is optional
|
|
5948
|
-
consumePattern(2);
|
|
5949
|
-
return true;
|
|
5950
|
-
}
|
|
5951
|
-
|
|
5952
|
-
if (remainingPattern === "*") {
|
|
5953
|
-
groups.push({
|
|
5954
|
-
string: ""
|
|
5955
|
-
});
|
|
5956
|
-
}
|
|
5957
|
-
|
|
5958
|
-
return false; // fail because string shorter than expected
|
|
5959
|
-
} // -- from this point pattern and string are not consumed --
|
|
5960
|
-
// fast path trailing slash
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
if (remainingPattern === "/") {
|
|
5964
|
-
if (remainingString[0] === "/") {
|
|
5965
|
-
// trailing slash match remaining
|
|
5966
|
-
consumePattern(1);
|
|
5967
|
-
groups.push({
|
|
5968
|
-
string: consumeRemainingString()
|
|
5969
|
-
});
|
|
5970
|
-
return true;
|
|
5971
|
-
}
|
|
5972
|
-
|
|
5973
|
-
return false;
|
|
5974
|
-
} // fast path trailing '**'
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
if (remainingPattern === "**") {
|
|
5978
|
-
consumePattern(2);
|
|
5979
|
-
consumeRemainingString();
|
|
5980
|
-
return true;
|
|
5981
|
-
} // pattern leading **
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
if (remainingPattern.slice(0, 2) === "**") {
|
|
5985
|
-
consumePattern(2); // consumes "**"
|
|
5986
|
-
|
|
5987
|
-
if (remainingPattern[0] === "/") {
|
|
5988
|
-
consumePattern(1); // consumes "/"
|
|
5989
|
-
} // pattern ending with ** always match remaining string
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
if (remainingPattern === "") {
|
|
5993
|
-
consumeRemainingString();
|
|
5994
|
-
return true;
|
|
5995
|
-
}
|
|
5996
|
-
|
|
5997
|
-
const skipResult = skipUntilMatch({
|
|
5998
|
-
pattern: remainingPattern,
|
|
5999
|
-
string: remainingString,
|
|
6000
|
-
canSkipSlash: true
|
|
6001
|
-
});
|
|
6002
|
-
groups.push(...skipResult.groups);
|
|
6003
|
-
consumePattern(skipResult.patternIndex);
|
|
6004
|
-
consumeRemainingString();
|
|
6005
|
-
restoreIndexes = false;
|
|
6006
|
-
return skipResult.matched;
|
|
6007
|
-
}
|
|
6008
|
-
|
|
6009
|
-
if (remainingPattern[0] === "*") {
|
|
6010
|
-
consumePattern(1); // consumes "*"
|
|
6011
|
-
|
|
6012
|
-
if (remainingPattern === "") {
|
|
6013
|
-
// matches everything except '/'
|
|
6014
|
-
const slashIndex = remainingString.indexOf("/");
|
|
6015
|
-
|
|
6016
|
-
if (slashIndex === -1) {
|
|
6017
|
-
groups.push({
|
|
6018
|
-
string: consumeRemainingString()
|
|
6019
|
-
});
|
|
6020
|
-
return true;
|
|
6021
|
-
}
|
|
6022
|
-
|
|
6023
|
-
groups.push({
|
|
6024
|
-
string: consumeString(slashIndex)
|
|
6025
|
-
});
|
|
6026
|
-
return false;
|
|
6027
|
-
} // the next char must not the one expected by remainingPattern[0]
|
|
6028
|
-
// because * is greedy and expect to skip at least one char
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
if (remainingPattern[0] === remainingString[0]) {
|
|
6032
|
-
groups.push({
|
|
6033
|
-
string: ""
|
|
6034
|
-
});
|
|
6035
|
-
patternIndex = patternIndex - 1;
|
|
6036
|
-
return false;
|
|
6037
|
-
}
|
|
6038
|
-
|
|
6039
|
-
const skipResult = skipUntilMatch({
|
|
6040
|
-
pattern: remainingPattern,
|
|
6041
|
-
string: remainingString,
|
|
6042
|
-
canSkipSlash: false
|
|
6043
|
-
});
|
|
6044
|
-
groups.push(skipResult.group, ...skipResult.groups);
|
|
6045
|
-
consumePattern(skipResult.patternIndex);
|
|
6046
|
-
consumeString(skipResult.index);
|
|
6047
|
-
restoreIndexes = false;
|
|
6048
|
-
return skipResult.matched;
|
|
6049
|
-
}
|
|
6050
|
-
|
|
6051
|
-
if (remainingPattern[0] !== remainingString[0]) {
|
|
6052
|
-
return false;
|
|
6053
|
-
}
|
|
6054
|
-
|
|
6055
|
-
return undefined;
|
|
6056
|
-
};
|
|
6057
|
-
|
|
6058
|
-
iterate();
|
|
6059
|
-
return {
|
|
6060
|
-
matched,
|
|
6061
|
-
patternIndex,
|
|
6062
|
-
index,
|
|
6063
|
-
groups
|
|
6064
|
-
};
|
|
6065
|
-
};
|
|
6066
|
-
|
|
6067
|
-
const skipUntilMatch = ({
|
|
6068
|
-
pattern,
|
|
6069
|
-
string,
|
|
6070
|
-
canSkipSlash
|
|
6071
|
-
}) => {
|
|
6072
|
-
let index = 0;
|
|
6073
|
-
let remainingString = string;
|
|
6074
|
-
let longestMatchRange = null;
|
|
6075
|
-
|
|
6076
|
-
const tryToMatch = () => {
|
|
6077
|
-
const matchAttempt = applyMatching(pattern, remainingString);
|
|
6078
|
-
|
|
6079
|
-
if (matchAttempt.matched) {
|
|
6080
|
-
return {
|
|
6081
|
-
matched: true,
|
|
6082
|
-
patternIndex: matchAttempt.patternIndex,
|
|
6083
|
-
index: index + matchAttempt.index,
|
|
6084
|
-
groups: matchAttempt.groups,
|
|
6085
|
-
group: {
|
|
6086
|
-
string: remainingString === "" ? string : string.slice(0, -remainingString.length)
|
|
6087
|
-
}
|
|
6088
|
-
};
|
|
6089
|
-
}
|
|
6090
|
-
|
|
6091
|
-
const matchAttemptIndex = matchAttempt.index;
|
|
6092
|
-
const matchRange = {
|
|
6093
|
-
patternIndex: matchAttempt.patternIndex,
|
|
6094
|
-
index,
|
|
6095
|
-
length: matchAttemptIndex,
|
|
6096
|
-
groups: matchAttempt.groups
|
|
6097
|
-
};
|
|
6098
|
-
|
|
6099
|
-
if (!longestMatchRange || longestMatchRange.length < matchRange.length) {
|
|
6100
|
-
longestMatchRange = matchRange;
|
|
6101
|
-
}
|
|
6102
|
-
|
|
6103
|
-
const nextIndex = matchAttemptIndex + 1;
|
|
6104
|
-
const canSkip = nextIndex < remainingString.length && (canSkipSlash || remainingString[0] !== "/");
|
|
6105
|
-
|
|
6106
|
-
if (canSkip) {
|
|
6107
|
-
// search against the next unattempted string
|
|
6108
|
-
index += nextIndex;
|
|
6109
|
-
remainingString = remainingString.slice(nextIndex);
|
|
6110
|
-
return tryToMatch();
|
|
6111
|
-
}
|
|
6112
|
-
|
|
6113
|
-
return {
|
|
6114
|
-
matched: false,
|
|
6115
|
-
patternIndex: longestMatchRange.patternIndex,
|
|
6116
|
-
index: longestMatchRange.index + longestMatchRange.length,
|
|
6117
|
-
groups: longestMatchRange.groups,
|
|
6118
|
-
group: {
|
|
6119
|
-
string: string.slice(0, longestMatchRange.index)
|
|
6120
|
-
}
|
|
6121
|
-
};
|
|
6122
|
-
};
|
|
6123
|
-
|
|
6124
|
-
return tryToMatch();
|
|
6125
|
-
};
|
|
6126
|
-
|
|
6127
|
-
const applyAssociations = ({
|
|
6128
|
-
url,
|
|
6129
|
-
associations
|
|
6130
|
-
}) => {
|
|
6131
|
-
assertUrlLike(url);
|
|
6132
|
-
const flatAssociations = asFlatAssociations(associations);
|
|
6133
|
-
return Object.keys(flatAssociations).reduce((previousValue, pattern) => {
|
|
6134
|
-
const {
|
|
6135
|
-
matched
|
|
6136
|
-
} = applyPatternMatching({
|
|
6137
|
-
pattern,
|
|
6138
|
-
url
|
|
6139
|
-
});
|
|
6140
|
-
|
|
6141
|
-
if (matched) {
|
|
6142
|
-
const value = flatAssociations[pattern];
|
|
6143
|
-
|
|
6144
|
-
if (isPlainObject(previousValue) && isPlainObject(value)) {
|
|
6145
|
-
return { ...previousValue,
|
|
6146
|
-
...value
|
|
6147
|
-
};
|
|
6148
|
-
}
|
|
6149
|
-
|
|
6150
|
-
return value;
|
|
6151
|
-
}
|
|
6152
|
-
|
|
6153
|
-
return previousValue;
|
|
6154
|
-
}, {});
|
|
6155
|
-
};
|
|
6156
|
-
|
|
6157
|
-
const applyAliases = ({
|
|
6158
|
-
url,
|
|
6159
|
-
aliases
|
|
6160
|
-
}) => {
|
|
6161
|
-
let aliasFullMatchResult;
|
|
6162
|
-
const aliasMatchingKey = Object.keys(aliases).find(key => {
|
|
6163
|
-
const aliasMatchResult = applyPatternMatching({
|
|
6164
|
-
pattern: key,
|
|
6165
|
-
url
|
|
6166
|
-
});
|
|
6167
|
-
|
|
6168
|
-
if (aliasMatchResult.matched) {
|
|
6169
|
-
aliasFullMatchResult = aliasMatchResult;
|
|
6170
|
-
return true;
|
|
6171
|
-
}
|
|
6172
|
-
|
|
6173
|
-
return false;
|
|
6174
|
-
});
|
|
6175
|
-
|
|
6176
|
-
if (!aliasMatchingKey) {
|
|
6177
|
-
return url;
|
|
6178
|
-
}
|
|
6179
|
-
|
|
6180
|
-
const {
|
|
6181
|
-
matchGroups
|
|
6182
|
-
} = aliasFullMatchResult;
|
|
6183
|
-
const alias = aliases[aliasMatchingKey];
|
|
6184
|
-
const parts = alias.split("*");
|
|
6185
|
-
const newUrl = parts.reduce((previous, value, index) => {
|
|
6186
|
-
return `${previous}${value}${index === parts.length - 1 ? "" : matchGroups[index]}`;
|
|
6187
|
-
}, "");
|
|
6188
|
-
return newUrl;
|
|
6189
|
-
};
|
|
6190
|
-
|
|
6191
|
-
const urlChildMayMatch = ({
|
|
6192
|
-
url,
|
|
6193
|
-
associations,
|
|
6194
|
-
predicate
|
|
6195
|
-
}) => {
|
|
6196
|
-
assertUrlLike(url, "url"); // the function was meants to be used on url ending with '/'
|
|
6197
|
-
|
|
6198
|
-
if (!url.endsWith("/")) {
|
|
6199
|
-
throw new Error(`url should end with /, got ${url}`);
|
|
6200
|
-
}
|
|
6201
|
-
|
|
6202
|
-
if (typeof predicate !== "function") {
|
|
6203
|
-
throw new TypeError(`predicate must be a function, got ${predicate}`);
|
|
6204
|
-
}
|
|
6205
|
-
|
|
6206
|
-
const flatAssociations = asFlatAssociations(associations); // for full match we must create an object to allow pattern to override previous ones
|
|
6207
|
-
|
|
6208
|
-
let fullMatchMeta = {};
|
|
6209
|
-
let someFullMatch = false; // for partial match, any meta satisfying predicate will be valid because
|
|
6210
|
-
// we don't know for sure if pattern will still match for a file inside pathname
|
|
6211
|
-
|
|
6212
|
-
const partialMatchMetaArray = [];
|
|
6213
|
-
Object.keys(flatAssociations).forEach(pattern => {
|
|
6214
|
-
const value = flatAssociations[pattern];
|
|
6215
|
-
const matchResult = applyPatternMatching({
|
|
6216
|
-
pattern,
|
|
6217
|
-
url
|
|
6218
|
-
});
|
|
6219
|
-
|
|
6220
|
-
if (matchResult.matched) {
|
|
6221
|
-
someFullMatch = true;
|
|
6222
|
-
|
|
6223
|
-
if (isPlainObject(fullMatchMeta) && isPlainObject(value)) {
|
|
6224
|
-
fullMatchMeta = { ...fullMatchMeta,
|
|
6225
|
-
...value
|
|
6226
|
-
};
|
|
6227
|
-
} else {
|
|
6228
|
-
fullMatchMeta = value;
|
|
6229
|
-
}
|
|
6230
|
-
} else if (someFullMatch === false && matchResult.urlIndex >= url.length) {
|
|
6231
|
-
partialMatchMetaArray.push(value);
|
|
6232
|
-
}
|
|
6233
|
-
});
|
|
6234
|
-
|
|
6235
|
-
if (someFullMatch) {
|
|
6236
|
-
return Boolean(predicate(fullMatchMeta));
|
|
6237
|
-
}
|
|
6238
|
-
|
|
6239
|
-
return partialMatchMetaArray.some(partialMatchMeta => predicate(partialMatchMeta));
|
|
6240
|
-
};
|
|
6241
|
-
|
|
6242
|
-
const URL_META = {
|
|
6243
|
-
resolveAssociations,
|
|
6244
|
-
applyAssociations,
|
|
6245
|
-
urlChildMayMatch,
|
|
6246
|
-
applyPatternMatching,
|
|
6247
|
-
applyAliases
|
|
6248
|
-
};
|
|
6249
|
-
|
|
6250
5745
|
const pluginRequestWaitingCheck = ({
|
|
6251
5746
|
requestWaitingMs = 20000,
|
|
6252
5747
|
requestWaitingCallback = ({
|
|
@@ -10067,7 +9562,10 @@ const jsenvPluginUrlResolution = () => {
|
|
|
10067
9562
|
name: "jsenv:url_resolution",
|
|
10068
9563
|
appliesDuring: "*",
|
|
10069
9564
|
resolveUrl: {
|
|
9565
|
+
"http_request": urlResolver,
|
|
9566
|
+
// during dev
|
|
10070
9567
|
"entry_point": urlResolver,
|
|
9568
|
+
// during build
|
|
10071
9569
|
"link_href": urlResolver,
|
|
10072
9570
|
"script_src": urlResolver,
|
|
10073
9571
|
"a_href": urlResolver,
|
|
@@ -18022,16 +17520,16 @@ const jsenvPluginAsJsClassicConversion = ({
|
|
|
18022
17520
|
return null;
|
|
18023
17521
|
}
|
|
18024
17522
|
|
|
18025
|
-
const
|
|
18026
|
-
//
|
|
18027
|
-
//
|
|
18028
|
-
//
|
|
18029
|
-
|
|
18030
|
-
|
|
17523
|
+
const jsClassicFormat = // in general html file are entry points, but js can be entry point when:
|
|
17524
|
+
// - passed in entryPoints to build
|
|
17525
|
+
// - is used by web worker
|
|
17526
|
+
// - the reference contains ?entry_point
|
|
17527
|
+
// When js is entry point there can be no HTML to inject systemjs
|
|
17528
|
+
// and systemjs must be injected into the js file
|
|
17529
|
+
originalUrlInfo.isEntryPoint && // if it's an entry point without dependency (it does not use import)
|
|
18031
17530
|
// then we can use UMD, otherwise we have to use systemjs
|
|
18032
17531
|
// because it is imported by systemjs
|
|
18033
|
-
|
|
18034
|
-
const jsClassicFormat = isJsEntryPoint && !originalUrlInfo.data.usesImport ? "umd" : "system";
|
|
17532
|
+
!originalUrlInfo.data.usesImport ? "umd" : "system";
|
|
18035
17533
|
const {
|
|
18036
17534
|
content,
|
|
18037
17535
|
sourcemap
|
|
@@ -18039,7 +17537,6 @@ const jsenvPluginAsJsClassicConversion = ({
|
|
|
18039
17537
|
systemJsInjection,
|
|
18040
17538
|
systemJsClientFileUrl,
|
|
18041
17539
|
urlInfo: originalUrlInfo,
|
|
18042
|
-
isJsEntryPoint,
|
|
18043
17540
|
jsClassicFormat
|
|
18044
17541
|
});
|
|
18045
17542
|
urlInfo.data.jsClassicFormat = jsClassicFormat;
|
|
@@ -18083,7 +17580,6 @@ const convertJsModuleToJsClassic = async ({
|
|
|
18083
17580
|
systemJsInjection,
|
|
18084
17581
|
systemJsClientFileUrl,
|
|
18085
17582
|
urlInfo,
|
|
18086
|
-
isJsEntryPoint,
|
|
18087
17583
|
jsClassicFormat
|
|
18088
17584
|
}) => {
|
|
18089
17585
|
const {
|
|
@@ -18102,7 +17598,7 @@ const convertJsModuleToJsClassic = async ({
|
|
|
18102
17598
|
let sourcemap = urlInfo.sourcemap;
|
|
18103
17599
|
sourcemap = await composeTwoSourcemaps(sourcemap, map);
|
|
18104
17600
|
|
|
18105
|
-
if (systemJsInjection && jsClassicFormat === "system" &&
|
|
17601
|
+
if (systemJsInjection && jsClassicFormat === "system" && urlInfo.isEntryPoint) {
|
|
18106
17602
|
const magicSource = createMagicSource(code);
|
|
18107
17603
|
const systemjsCode = readFileSync(systemJsClientFileUrl, {
|
|
18108
17604
|
as: "string"
|
|
@@ -19796,7 +19292,7 @@ const rollupPluginJsenv = ({
|
|
|
19796
19292
|
jsModuleUrlInfos.forEach(jsModuleUrlInfo => {
|
|
19797
19293
|
const id = jsModuleUrlInfo.url;
|
|
19798
19294
|
|
|
19799
|
-
if (jsModuleUrlInfo.
|
|
19295
|
+
if (jsModuleUrlInfo.isEntryPoint) {
|
|
19800
19296
|
emitChunk({
|
|
19801
19297
|
id
|
|
19802
19298
|
});
|
|
@@ -20079,7 +19575,7 @@ const willBeInsideJsDirectory = ({
|
|
|
20079
19575
|
return true;
|
|
20080
19576
|
}
|
|
20081
19577
|
|
|
20082
|
-
if (!jsModuleUrlInfo.
|
|
19578
|
+
if (!jsModuleUrlInfo.isEntryPoint) {
|
|
20083
19579
|
// not an entry point, jsenv will put it inside js/ directory
|
|
20084
19580
|
return true;
|
|
20085
19581
|
}
|
|
@@ -21439,6 +20935,7 @@ const createUrlInfo = url => {
|
|
|
21439
20935
|
originalUrl: undefined,
|
|
21440
20936
|
generatedUrl: null,
|
|
21441
20937
|
filename: "",
|
|
20938
|
+
isEntryPoint: false,
|
|
21442
20939
|
isInline: false,
|
|
21443
20940
|
inlineUrlSite: null,
|
|
21444
20941
|
shouldHandle: undefined,
|
|
@@ -21446,6 +20943,7 @@ const createUrlInfo = url => {
|
|
|
21446
20943
|
content: undefined,
|
|
21447
20944
|
sourcemap: null,
|
|
21448
20945
|
sourcemapReference: null,
|
|
20946
|
+
sourcemapIsWrong: false,
|
|
21449
20947
|
timing: {},
|
|
21450
20948
|
headers: {}
|
|
21451
20949
|
};
|
|
@@ -21891,7 +21389,8 @@ const createUrlInfoTransformer = ({
|
|
|
21891
21389
|
type,
|
|
21892
21390
|
contentType,
|
|
21893
21391
|
content,
|
|
21894
|
-
sourcemap
|
|
21392
|
+
sourcemap,
|
|
21393
|
+
sourcemapIsWrong
|
|
21895
21394
|
} = transformations;
|
|
21896
21395
|
|
|
21897
21396
|
if (type) {
|
|
@@ -21910,7 +21409,17 @@ const createUrlInfoTransformer = ({
|
|
|
21910
21409
|
const sourcemapNormalized = normalizeSourcemap(urlInfo, sourcemap);
|
|
21911
21410
|
const finalSourcemap = await composeTwoSourcemaps(urlInfo.sourcemap, sourcemapNormalized);
|
|
21912
21411
|
const finalSourcemapNormalized = normalizeSourcemap(urlInfo, finalSourcemap);
|
|
21913
|
-
urlInfo.sourcemap = finalSourcemapNormalized;
|
|
21412
|
+
urlInfo.sourcemap = finalSourcemapNormalized; // A plugin is allowed to modify url content
|
|
21413
|
+
// without returning a sourcemap
|
|
21414
|
+
// This is the case for preact and react plugins.
|
|
21415
|
+
// They are currently generating wrong source mappings
|
|
21416
|
+
// when used.
|
|
21417
|
+
// Generating the correct sourcemap in this situation
|
|
21418
|
+
// is a nightmare no-one could solve in years so
|
|
21419
|
+
// jsenv won't emit a warning and use the following strategy:
|
|
21420
|
+
// "no sourcemap is better than wrong sourcemap"
|
|
21421
|
+
|
|
21422
|
+
urlInfo.sourcemapIsWrong = sourcemapIsWrong;
|
|
21914
21423
|
}
|
|
21915
21424
|
};
|
|
21916
21425
|
|
|
@@ -21939,16 +21448,18 @@ const createUrlInfoTransformer = ({
|
|
|
21939
21448
|
|
|
21940
21449
|
sourcemapUrlInfo.content = JSON.stringify(sourcemap, null, " ");
|
|
21941
21450
|
|
|
21942
|
-
if (
|
|
21943
|
-
|
|
21944
|
-
|
|
21451
|
+
if (!urlInfo.sourcemapIsWrong) {
|
|
21452
|
+
if (sourcemaps === "inline") {
|
|
21453
|
+
sourcemapReference.generatedSpecifier = generateSourcemapDataUrl(sourcemap);
|
|
21454
|
+
}
|
|
21945
21455
|
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21951
|
-
|
|
21456
|
+
if (sourcemaps === "file" || sourcemaps === "inline") {
|
|
21457
|
+
urlInfo.content = SOURCEMAP.writeComment({
|
|
21458
|
+
contentType: urlInfo.contentType,
|
|
21459
|
+
content: urlInfo.content,
|
|
21460
|
+
specifier: sourcemaps === "file" && sourcemapsRelativeSources ? urlToRelativeUrl(sourcemapReference.url, urlInfo.url) : sourcemapReference.generatedSpecifier
|
|
21461
|
+
});
|
|
21462
|
+
}
|
|
21952
21463
|
}
|
|
21953
21464
|
} else if (urlInfo.sourcemapReference) {
|
|
21954
21465
|
// in the end we don't use the sourcemap placeholder
|
|
@@ -22356,6 +21867,7 @@ const createKitchen = ({
|
|
|
22356
21867
|
baseUrl,
|
|
22357
21868
|
isOriginalPosition,
|
|
22358
21869
|
shouldHandle,
|
|
21870
|
+
isEntryPoint = false,
|
|
22359
21871
|
isInline = false,
|
|
22360
21872
|
injected = false,
|
|
22361
21873
|
isRessourceHint = false,
|
|
@@ -22393,6 +21905,7 @@ const createKitchen = ({
|
|
|
22393
21905
|
baseUrl,
|
|
22394
21906
|
isOriginalPosition,
|
|
22395
21907
|
shouldHandle,
|
|
21908
|
+
isEntryPoint,
|
|
22396
21909
|
isInline,
|
|
22397
21910
|
injected,
|
|
22398
21911
|
isRessourceHint,
|
|
@@ -22409,7 +21922,7 @@ const createKitchen = ({
|
|
|
22409
21922
|
const mutateReference = (reference, newReference) => {
|
|
22410
21923
|
reference.next = newReference;
|
|
22411
21924
|
newReference.prev = reference;
|
|
22412
|
-
newReference.original = reference.original || reference;
|
|
21925
|
+
newReference.original = reference.original || reference; // newReference.isEntryPoint = reference.isEntryPoint
|
|
22413
21926
|
};
|
|
22414
21927
|
|
|
22415
21928
|
const resolveReference = reference => {
|
|
@@ -22434,11 +21947,16 @@ const createKitchen = ({
|
|
|
22434
21947
|
reference.url = normalizedReturnValue;
|
|
22435
21948
|
mutateReference(previousReference, reference);
|
|
22436
21949
|
});
|
|
22437
|
-
const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
|
|
22438
|
-
applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext);
|
|
22439
21950
|
const referenceUrlObject = new URL(reference.url);
|
|
22440
21951
|
reference.searchParams = referenceUrlObject.searchParams;
|
|
22441
|
-
reference.generatedUrl = reference.url;
|
|
21952
|
+
reference.generatedUrl = reference.url;
|
|
21953
|
+
|
|
21954
|
+
if (reference.searchParams.has("entry_point")) {
|
|
21955
|
+
reference.isEntryPoint = true;
|
|
21956
|
+
}
|
|
21957
|
+
|
|
21958
|
+
const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
|
|
21959
|
+
applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext); // This hook must touch reference.generatedUrl, NOT reference.url
|
|
22442
21960
|
// And this is because this hook inject query params used to:
|
|
22443
21961
|
// - bypass browser cache (?v)
|
|
22444
21962
|
// - convey information (?hmr)
|
|
@@ -22539,7 +22057,8 @@ const createKitchen = ({
|
|
|
22539
22057
|
filename,
|
|
22540
22058
|
status = 200,
|
|
22541
22059
|
headers = {},
|
|
22542
|
-
body
|
|
22060
|
+
body,
|
|
22061
|
+
isEntryPoint
|
|
22543
22062
|
} = fetchUrlContentReturnValue;
|
|
22544
22063
|
|
|
22545
22064
|
if (status !== 200) {
|
|
@@ -22575,6 +22094,10 @@ const createKitchen = ({
|
|
|
22575
22094
|
Object.assign(urlInfo.data, data);
|
|
22576
22095
|
}
|
|
22577
22096
|
|
|
22097
|
+
if (typeof isEntryPoint === "boolean") {
|
|
22098
|
+
urlInfo.isEntryPoint = isEntryPoint;
|
|
22099
|
+
}
|
|
22100
|
+
|
|
22578
22101
|
if (filename) {
|
|
22579
22102
|
urlInfo.filename = filename;
|
|
22580
22103
|
}
|
|
@@ -22877,6 +22400,7 @@ const createKitchen = ({
|
|
|
22877
22400
|
|
|
22878
22401
|
const prepareEntryPoint = params => {
|
|
22879
22402
|
const entryReference = createReference(params);
|
|
22403
|
+
entryReference.isEntryPoint = true;
|
|
22880
22404
|
const entryUrlInfo = resolveReference(entryReference);
|
|
22881
22405
|
return [entryReference, entryUrlInfo];
|
|
22882
22406
|
};
|
|
@@ -22984,6 +22508,11 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
|
22984
22508
|
}
|
|
22985
22509
|
|
|
22986
22510
|
urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
|
|
22511
|
+
|
|
22512
|
+
if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
|
|
22513
|
+
urlInfo.isEntryPoint = true;
|
|
22514
|
+
}
|
|
22515
|
+
|
|
22987
22516
|
Object.assign(urlInfo.data, reference.data);
|
|
22988
22517
|
Object.assign(urlInfo.timing, reference.timing);
|
|
22989
22518
|
|
|
@@ -23008,10 +22537,6 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
|
23008
22537
|
urlInfo.originalContent = context === "build" ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
|
|
23009
22538
|
urlInfo.content = reference.content;
|
|
23010
22539
|
}
|
|
23011
|
-
|
|
23012
|
-
if (isWebWorkerEntryPointReference(reference)) {
|
|
23013
|
-
urlInfo.data.isWebWorkerEntryPoint = true;
|
|
23014
|
-
}
|
|
23015
22540
|
};
|
|
23016
22541
|
|
|
23017
22542
|
const adjustUrlSite = (urlInfo, {
|
|
@@ -23294,10 +22819,10 @@ const createFileService = ({
|
|
|
23294
22819
|
}
|
|
23295
22820
|
|
|
23296
22821
|
if (!reference) {
|
|
23297
|
-
const entryPoint = kitchen.
|
|
22822
|
+
const entryPoint = kitchen.injectReference({
|
|
23298
22823
|
trace: parentUrl || rootDirectoryUrl,
|
|
23299
22824
|
parentUrl: parentUrl || rootDirectoryUrl,
|
|
23300
|
-
type: "
|
|
22825
|
+
type: "http_request",
|
|
23301
22826
|
specifier: request.ressource
|
|
23302
22827
|
});
|
|
23303
22828
|
reference = entryPoint[0];
|
|
@@ -24050,23 +23575,31 @@ const babelPluginInstrument = (api, {
|
|
|
24050
23575
|
};
|
|
24051
23576
|
};
|
|
24052
23577
|
|
|
24053
|
-
const
|
|
23578
|
+
const readNodeV8CoverageDirectory = async ({
|
|
24054
23579
|
logger,
|
|
24055
23580
|
signal,
|
|
24056
|
-
NODE_V8_COVERAGE,
|
|
24057
23581
|
onV8Coverage,
|
|
24058
23582
|
maxMsWaitingForNodeToWriteCoverageFile = 2000
|
|
24059
23583
|
}) => {
|
|
23584
|
+
const NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE;
|
|
24060
23585
|
const operation = Abort.startOperation();
|
|
24061
23586
|
operation.addAbortSignal(signal);
|
|
23587
|
+
let timeSpentTrying = 0;
|
|
24062
23588
|
|
|
24063
23589
|
const tryReadDirectory = async () => {
|
|
24064
|
-
const dirContent =
|
|
23590
|
+
const dirContent = readdirSync(NODE_V8_COVERAGE);
|
|
24065
23591
|
|
|
24066
23592
|
if (dirContent.length > 0) {
|
|
24067
23593
|
return dirContent;
|
|
24068
23594
|
}
|
|
24069
23595
|
|
|
23596
|
+
if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
|
|
23597
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
23598
|
+
timeSpentTrying += 200;
|
|
23599
|
+
logger.debug("retry to read coverage directory");
|
|
23600
|
+
return tryReadDirectory();
|
|
23601
|
+
}
|
|
23602
|
+
|
|
24070
23603
|
logger.warn(`v8 coverage directory is empty at ${NODE_V8_COVERAGE}`);
|
|
24071
23604
|
return dirContent;
|
|
24072
23605
|
};
|
|
@@ -24078,17 +23611,16 @@ const visitNodeV8Directory = async ({
|
|
|
24078
23611
|
await dirContent.reduce(async (previous, dirEntry) => {
|
|
24079
23612
|
operation.throwIfAborted();
|
|
24080
23613
|
await previous;
|
|
24081
|
-
const dirEntryUrl =
|
|
23614
|
+
const dirEntryUrl = new URL(dirEntry, coverageDirectoryUrl);
|
|
24082
23615
|
|
|
24083
|
-
const tryReadJsonFile = async (
|
|
24084
|
-
const fileContent =
|
|
24085
|
-
as: "string"
|
|
24086
|
-
});
|
|
23616
|
+
const tryReadJsonFile = async () => {
|
|
23617
|
+
const fileContent = String(readFileSync$1(dirEntryUrl));
|
|
24087
23618
|
|
|
24088
23619
|
if (fileContent === "") {
|
|
24089
|
-
if (timeSpentTrying <
|
|
23620
|
+
if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
|
|
24090
23621
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
24091
|
-
|
|
23622
|
+
timeSpentTrying += 200;
|
|
23623
|
+
return tryReadJsonFile();
|
|
24092
23624
|
}
|
|
24093
23625
|
|
|
24094
23626
|
console.warn(`Coverage JSON file is empty at ${dirEntryUrl}`);
|
|
@@ -24101,7 +23633,8 @@ const visitNodeV8Directory = async ({
|
|
|
24101
23633
|
} catch (e) {
|
|
24102
23634
|
if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
|
|
24103
23635
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
24104
|
-
|
|
23636
|
+
timeSpentTrying += 200;
|
|
23637
|
+
return tryReadJsonFile();
|
|
24105
23638
|
}
|
|
24106
23639
|
|
|
24107
23640
|
console.warn(createDetailedMessage$1(`Error while reading coverage file`, {
|
|
@@ -24115,21 +23648,13 @@ const visitNodeV8Directory = async ({
|
|
|
24115
23648
|
const fileContent = await tryReadJsonFile();
|
|
24116
23649
|
|
|
24117
23650
|
if (fileContent) {
|
|
24118
|
-
onV8Coverage(fileContent);
|
|
23651
|
+
await onV8Coverage(fileContent);
|
|
24119
23652
|
}
|
|
24120
23653
|
}, Promise.resolve());
|
|
24121
23654
|
} finally {
|
|
24122
23655
|
await operation.end();
|
|
24123
23656
|
}
|
|
24124
23657
|
};
|
|
24125
|
-
const filterV8Coverage = (v8Coverage, {
|
|
24126
|
-
urlShouldBeCovered
|
|
24127
|
-
}) => {
|
|
24128
|
-
const v8CoverageFiltered = { ...v8Coverage,
|
|
24129
|
-
result: v8Coverage.result.filter(fileReport => urlShouldBeCovered(fileReport.url))
|
|
24130
|
-
};
|
|
24131
|
-
return v8CoverageFiltered;
|
|
24132
|
-
};
|
|
24133
23658
|
|
|
24134
23659
|
const composeTwoV8Coverages = (firstV8Coverage, secondV8Coverage) => {
|
|
24135
23660
|
if (secondV8Coverage.result.length === 0) {
|
|
@@ -24430,8 +23955,7 @@ const reportToCoverage = async (report, {
|
|
|
24430
23955
|
rootDirectoryUrl,
|
|
24431
23956
|
coverageConfig,
|
|
24432
23957
|
coverageIncludeMissing,
|
|
24433
|
-
|
|
24434
|
-
coverageForceIstanbul,
|
|
23958
|
+
coverageMethodForNodeJs,
|
|
24435
23959
|
coverageV8ConflictWarning
|
|
24436
23960
|
}) => {
|
|
24437
23961
|
// collect v8 and istanbul coverage from executions
|
|
@@ -24460,20 +23984,20 @@ const reportToCoverage = async (report, {
|
|
|
24460
23984
|
// in any scenario we are fine because
|
|
24461
23985
|
// coverDescription will generate empty coverage for files
|
|
24462
23986
|
// that were suppose to be coverage but were not.
|
|
24463
|
-
if (executionResult.status === "completed" && executionResult.
|
|
24464
|
-
logger.warn(`No
|
|
23987
|
+
if (executionResult.status === "completed" && executionResult.type === "node" && coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
|
|
23988
|
+
logger.warn(`No "coverageFileUrl" from execution named "${executionName}" of ${file}`);
|
|
24465
23989
|
}
|
|
24466
23990
|
}
|
|
24467
23991
|
});
|
|
24468
23992
|
|
|
24469
|
-
if (
|
|
24470
|
-
await
|
|
23993
|
+
if (coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
|
|
23994
|
+
await readNodeV8CoverageDirectory({
|
|
24471
23995
|
logger,
|
|
24472
23996
|
signal,
|
|
24473
|
-
|
|
24474
|
-
|
|
24475
|
-
|
|
24476
|
-
|
|
23997
|
+
onV8Coverage: async nodeV8Coverage => {
|
|
23998
|
+
const nodeV8CoverageLight = await filterV8Coverage(nodeV8Coverage, {
|
|
23999
|
+
rootDirectoryUrl,
|
|
24000
|
+
coverageConfig
|
|
24477
24001
|
});
|
|
24478
24002
|
v8Coverage = v8Coverage ? composeTwoV8Coverages(v8Coverage, nodeV8CoverageLight) : nodeV8CoverageLight;
|
|
24479
24003
|
}
|
|
@@ -24552,9 +24076,7 @@ const getCoverageFromReport = async ({
|
|
|
24552
24076
|
return;
|
|
24553
24077
|
}
|
|
24554
24078
|
|
|
24555
|
-
const executionCoverage =
|
|
24556
|
-
as: "json"
|
|
24557
|
-
});
|
|
24079
|
+
const executionCoverage = JSON.parse(String(readFileSync$1(new URL(coverageFileUrl))));
|
|
24558
24080
|
|
|
24559
24081
|
if (isV8Coverage(executionCoverage)) {
|
|
24560
24082
|
v8Coverage = v8Coverage ? composeTwoV8Coverages(v8Coverage, executionCoverage) : executionCoverage;
|
|
@@ -24581,21 +24103,20 @@ const run = async ({
|
|
|
24581
24103
|
keepRunning = false,
|
|
24582
24104
|
mirrorConsole = false,
|
|
24583
24105
|
collectConsole = false,
|
|
24584
|
-
|
|
24106
|
+
coverageEnabled = false,
|
|
24585
24107
|
coverageTempDirectoryUrl,
|
|
24586
24108
|
collectPerformance = false,
|
|
24587
24109
|
runtime,
|
|
24588
24110
|
runtimeParams
|
|
24589
24111
|
}) => {
|
|
24112
|
+
let result = {};
|
|
24113
|
+
const callbacks = [];
|
|
24590
24114
|
const onConsoleRef = {
|
|
24591
24115
|
current: () => {}
|
|
24592
24116
|
};
|
|
24593
24117
|
const stopSignal = {
|
|
24594
24118
|
notify: () => {}
|
|
24595
24119
|
};
|
|
24596
|
-
|
|
24597
|
-
let resultTransformer = result => result;
|
|
24598
|
-
|
|
24599
24120
|
const runtimeLabel = `${runtime.name}/${runtime.version}`;
|
|
24600
24121
|
const runOperation = Abort.startOperation();
|
|
24601
24122
|
runOperation.addAbortSignal(signal);
|
|
@@ -24604,21 +24125,21 @@ const run = async ({
|
|
|
24604
24125
|
// when keepRunning is true
|
|
24605
24126
|
!keepRunning && typeof allocatedMs === "number" && allocatedMs !== Infinity) {
|
|
24606
24127
|
const timeoutAbortSource = runOperation.timeout(allocatedMs);
|
|
24607
|
-
|
|
24128
|
+
callbacks.push(() => {
|
|
24608
24129
|
if (result.status === "errored" && Abort.isAbortError(result.error) && timeoutAbortSource.signal.aborted) {
|
|
24609
|
-
|
|
24130
|
+
result = {
|
|
24131
|
+
status: "timedout"
|
|
24132
|
+
};
|
|
24610
24133
|
}
|
|
24611
|
-
|
|
24612
|
-
return result;
|
|
24613
24134
|
});
|
|
24614
24135
|
}
|
|
24615
24136
|
|
|
24616
|
-
|
|
24137
|
+
callbacks.push(() => {
|
|
24617
24138
|
if (result.status === "errored" && Abort.isAbortError(result.error)) {
|
|
24618
|
-
|
|
24139
|
+
result = {
|
|
24140
|
+
status: "aborted"
|
|
24141
|
+
};
|
|
24619
24142
|
}
|
|
24620
|
-
|
|
24621
|
-
return result;
|
|
24622
24143
|
});
|
|
24623
24144
|
const consoleCalls = [];
|
|
24624
24145
|
|
|
@@ -24643,44 +24164,14 @@ const run = async ({
|
|
|
24643
24164
|
};
|
|
24644
24165
|
|
|
24645
24166
|
if (collectConsole) {
|
|
24646
|
-
|
|
24167
|
+
callbacks.push(() => {
|
|
24647
24168
|
result.consoleCalls = consoleCalls;
|
|
24648
|
-
return result;
|
|
24649
|
-
});
|
|
24650
|
-
}
|
|
24651
|
-
|
|
24652
|
-
if (collectCoverage) {
|
|
24653
|
-
resultTransformer = composeTransformer$1(resultTransformer, async result => {
|
|
24654
|
-
// we do not keep coverage in memory, it can grow very big
|
|
24655
|
-
// instead we store it on the filesystem
|
|
24656
|
-
// and they can be read later at "coverageFileUrl"
|
|
24657
|
-
const {
|
|
24658
|
-
coverage
|
|
24659
|
-
} = result;
|
|
24660
|
-
|
|
24661
|
-
if (coverage) {
|
|
24662
|
-
const coverageFileUrl = resolveUrl$1(`./${runtime.name}/${cuid()}`, coverageTempDirectoryUrl);
|
|
24663
|
-
await writeFile(coverageFileUrl, JSON.stringify(coverage, null, " "));
|
|
24664
|
-
result.coverageFileUrl = coverageFileUrl;
|
|
24665
|
-
delete result.coverage;
|
|
24666
|
-
}
|
|
24667
|
-
|
|
24668
|
-
return result;
|
|
24669
|
-
});
|
|
24670
|
-
} else {
|
|
24671
|
-
resultTransformer = composeTransformer$1(resultTransformer, result => {
|
|
24672
|
-
// as collectCoverage is disabled
|
|
24673
|
-
// executionResult.coverage is undefined or {}
|
|
24674
|
-
// we delete it just to have a cleaner object
|
|
24675
|
-
delete result.coverage;
|
|
24676
|
-
return result;
|
|
24677
24169
|
});
|
|
24678
24170
|
}
|
|
24679
24171
|
|
|
24680
24172
|
const startMs = Date.now();
|
|
24681
|
-
|
|
24173
|
+
callbacks.push(() => {
|
|
24682
24174
|
result.duration = Date.now() - startMs;
|
|
24683
|
-
return result;
|
|
24684
24175
|
});
|
|
24685
24176
|
|
|
24686
24177
|
try {
|
|
@@ -24696,7 +24187,7 @@ const run = async ({
|
|
|
24696
24187
|
},
|
|
24697
24188
|
runned: async cb => {
|
|
24698
24189
|
try {
|
|
24699
|
-
const
|
|
24190
|
+
const runResult = await runtime.run({
|
|
24700
24191
|
signal: runOperation.signal,
|
|
24701
24192
|
logger,
|
|
24702
24193
|
...runtimeParams,
|
|
@@ -24705,7 +24196,7 @@ const run = async ({
|
|
|
24705
24196
|
stopSignal,
|
|
24706
24197
|
onConsole: log => onConsoleRef.current(log)
|
|
24707
24198
|
});
|
|
24708
|
-
cb(
|
|
24199
|
+
cb(runResult);
|
|
24709
24200
|
} catch (e) {
|
|
24710
24201
|
cb({
|
|
24711
24202
|
status: "errored",
|
|
@@ -24721,40 +24212,55 @@ const run = async ({
|
|
|
24721
24212
|
runOperation.throwIfAborted();
|
|
24722
24213
|
}
|
|
24723
24214
|
|
|
24724
|
-
|
|
24725
|
-
|
|
24215
|
+
const {
|
|
24216
|
+
status,
|
|
24217
|
+
namespace,
|
|
24218
|
+
error,
|
|
24219
|
+
performance,
|
|
24220
|
+
coverage
|
|
24221
|
+
} = winner.data;
|
|
24222
|
+
result.status = status;
|
|
24223
|
+
|
|
24224
|
+
if (status === "errored") {
|
|
24225
|
+
result.error = error;
|
|
24226
|
+
} else {
|
|
24227
|
+
result.namespace = namespace;
|
|
24228
|
+
}
|
|
24229
|
+
|
|
24230
|
+
if (collectPerformance) {
|
|
24231
|
+
result.performance = performance;
|
|
24232
|
+
}
|
|
24233
|
+
|
|
24234
|
+
if (coverageEnabled) {
|
|
24235
|
+
if (coverage) {
|
|
24236
|
+
// we do not keep coverage in memory, it can grow very big
|
|
24237
|
+
// instead we store it on the filesystem
|
|
24238
|
+
// and they can be read later at "coverageFileUrl"
|
|
24239
|
+
const coverageFileUrl = new URL(`./${runtime.name}/${cuid()}.json`, coverageTempDirectoryUrl);
|
|
24240
|
+
writeFileSync(coverageFileUrl, JSON.stringify(coverage, null, " "));
|
|
24241
|
+
result.coverageFileUrl = coverageFileUrl.href;
|
|
24242
|
+
} else {// will eventually log a warning in report_to_coverage.js
|
|
24243
|
+
}
|
|
24244
|
+
}
|
|
24245
|
+
|
|
24246
|
+
callbacks.forEach(callback => {
|
|
24247
|
+
callback();
|
|
24248
|
+
});
|
|
24726
24249
|
return result;
|
|
24727
24250
|
} catch (e) {
|
|
24728
|
-
|
|
24251
|
+
result = {
|
|
24729
24252
|
status: "errored",
|
|
24730
24253
|
error: e
|
|
24731
24254
|
};
|
|
24732
|
-
|
|
24255
|
+
callbacks.forEach(callback => {
|
|
24256
|
+
callback();
|
|
24257
|
+
});
|
|
24733
24258
|
return result;
|
|
24734
24259
|
} finally {
|
|
24735
24260
|
await runOperation.end();
|
|
24736
24261
|
}
|
|
24737
24262
|
};
|
|
24738
24263
|
|
|
24739
|
-
const composeTransformer$1 = (previousTransformer, transformer) => {
|
|
24740
|
-
return async value => {
|
|
24741
|
-
const transformedValue = await previousTransformer(value);
|
|
24742
|
-
return transformer(transformedValue);
|
|
24743
|
-
};
|
|
24744
|
-
};
|
|
24745
|
-
|
|
24746
|
-
const createAbortedResult = () => {
|
|
24747
|
-
return {
|
|
24748
|
-
status: "aborted"
|
|
24749
|
-
};
|
|
24750
|
-
};
|
|
24751
|
-
|
|
24752
|
-
const createTimedoutResult = () => {
|
|
24753
|
-
return {
|
|
24754
|
-
status: "timedout"
|
|
24755
|
-
};
|
|
24756
|
-
};
|
|
24757
|
-
|
|
24758
24264
|
const ensureGlobalGc = () => {
|
|
24759
24265
|
if (!global.gc) {
|
|
24760
24266
|
v8.setFlagsFromString("--expose_gc");
|
|
@@ -24839,6 +24345,8 @@ const createExecutionLog = ({
|
|
|
24839
24345
|
}, {
|
|
24840
24346
|
completedExecutionLogAbbreviation,
|
|
24841
24347
|
counters,
|
|
24348
|
+
logRuntime,
|
|
24349
|
+
logEachDuration,
|
|
24842
24350
|
timeEllapsed,
|
|
24843
24351
|
memoryHeap
|
|
24844
24352
|
}) => {
|
|
@@ -24871,8 +24379,12 @@ const createExecutionLog = ({
|
|
|
24871
24379
|
label: `${description}${summary}`,
|
|
24872
24380
|
details: {
|
|
24873
24381
|
file: fileRelativeUrl,
|
|
24874
|
-
|
|
24875
|
-
|
|
24382
|
+
...(logRuntime ? {
|
|
24383
|
+
runtime: `${runtimeName}/${runtimeVersion}`
|
|
24384
|
+
} : {}),
|
|
24385
|
+
...(logEachDuration ? {
|
|
24386
|
+
duration: status === "executing" ? msAsEllapsedTime(Date.now() - startMs) : msAsDuration(endMs - startMs)
|
|
24387
|
+
} : {}),
|
|
24876
24388
|
...(error ? {
|
|
24877
24389
|
error: error.stack || error.message || error
|
|
24878
24390
|
} : {})
|
|
@@ -25026,22 +24538,93 @@ const descriptionFormatters = {
|
|
|
25026
24538
|
};
|
|
25027
24539
|
|
|
25028
24540
|
const formatConsoleCalls = consoleCalls => {
|
|
25029
|
-
|
|
25030
|
-
text
|
|
25031
|
-
}) => {
|
|
25032
|
-
return `${previous}${text}`;
|
|
25033
|
-
}, "");
|
|
25034
|
-
const consoleOutputTrimmed = consoleOutput.trim();
|
|
25035
|
-
|
|
25036
|
-
if (consoleOutputTrimmed === "") {
|
|
24541
|
+
if (consoleCalls.length === 0) {
|
|
25037
24542
|
return "";
|
|
25038
24543
|
}
|
|
25039
24544
|
|
|
25040
|
-
|
|
25041
|
-
|
|
24545
|
+
const repartition = {
|
|
24546
|
+
debug: 0,
|
|
24547
|
+
info: 0,
|
|
24548
|
+
warning: 0,
|
|
24549
|
+
error: 0,
|
|
24550
|
+
log: 0
|
|
24551
|
+
};
|
|
24552
|
+
let consoleOutput = ``;
|
|
24553
|
+
consoleCalls.forEach(consoleCall => {
|
|
24554
|
+
repartition[consoleCall.type]++;
|
|
24555
|
+
const text = consoleCall.text;
|
|
24556
|
+
const textFormatted = prefixFirstAndIndentRemainingLines({
|
|
24557
|
+
prefix: CONSOLE_ICONS[consoleCall.type],
|
|
24558
|
+
text,
|
|
24559
|
+
trimLastLine: consoleCall === consoleCalls[consoleCalls.length - 1]
|
|
24560
|
+
});
|
|
24561
|
+
consoleOutput += textFormatted;
|
|
24562
|
+
});
|
|
24563
|
+
return `${ANSI.color(`-------- ${formatConsoleSummary(repartition)} --------`, ANSI.GREY)}
|
|
24564
|
+
${consoleOutput}
|
|
25042
24565
|
${ANSI.color(`-------------------------`, ANSI.GREY)}`;
|
|
25043
24566
|
};
|
|
25044
24567
|
|
|
24568
|
+
const CONSOLE_ICONS = {
|
|
24569
|
+
debug: UNICODE.DEBUG,
|
|
24570
|
+
info: UNICODE.INFO,
|
|
24571
|
+
warning: UNICODE.WARNING,
|
|
24572
|
+
error: UNICODE.FAILURE,
|
|
24573
|
+
log: " "
|
|
24574
|
+
};
|
|
24575
|
+
|
|
24576
|
+
const formatConsoleSummary = repartition => {
|
|
24577
|
+
const {
|
|
24578
|
+
debug,
|
|
24579
|
+
info,
|
|
24580
|
+
warning,
|
|
24581
|
+
error
|
|
24582
|
+
} = repartition;
|
|
24583
|
+
const parts = [];
|
|
24584
|
+
|
|
24585
|
+
if (error) {
|
|
24586
|
+
parts.push(`${CONSOLE_ICONS.error} ${error}`);
|
|
24587
|
+
}
|
|
24588
|
+
|
|
24589
|
+
if (warning) {
|
|
24590
|
+
parts.push(`${CONSOLE_ICONS.warning} ${warning}`);
|
|
24591
|
+
}
|
|
24592
|
+
|
|
24593
|
+
if (info) {
|
|
24594
|
+
parts.push(`${CONSOLE_ICONS.info} ${info}`);
|
|
24595
|
+
}
|
|
24596
|
+
|
|
24597
|
+
if (debug) {
|
|
24598
|
+
parts.push(`${CONSOLE_ICONS.debug} ${debug}`);
|
|
24599
|
+
}
|
|
24600
|
+
|
|
24601
|
+
if (parts.length === 0) {
|
|
24602
|
+
return `console`;
|
|
24603
|
+
}
|
|
24604
|
+
|
|
24605
|
+
return `console (${parts.join(" ")})`;
|
|
24606
|
+
};
|
|
24607
|
+
|
|
24608
|
+
const prefixFirstAndIndentRemainingLines = ({
|
|
24609
|
+
prefix,
|
|
24610
|
+
text,
|
|
24611
|
+
trimLastLine
|
|
24612
|
+
}) => {
|
|
24613
|
+
const lines = text.split(/\r?\n/);
|
|
24614
|
+
const firstLine = lines.shift();
|
|
24615
|
+
let result = `${prefix} ${firstLine}`;
|
|
24616
|
+
let i = 0;
|
|
24617
|
+
const indentation = ` `;
|
|
24618
|
+
|
|
24619
|
+
while (i < lines.length) {
|
|
24620
|
+
const line = lines[i].trim();
|
|
24621
|
+
i++;
|
|
24622
|
+
result += line.length ? `\n${indentation}${line}` : trimLastLine && i === lines.length ? "" : `\n`;
|
|
24623
|
+
}
|
|
24624
|
+
|
|
24625
|
+
return result;
|
|
24626
|
+
};
|
|
24627
|
+
|
|
25045
24628
|
const formatExecution = ({
|
|
25046
24629
|
label,
|
|
25047
24630
|
details = {},
|
|
@@ -25066,6 +24649,8 @@ const executePlan = async (plan, {
|
|
|
25066
24649
|
signal,
|
|
25067
24650
|
handleSIGINT,
|
|
25068
24651
|
logger,
|
|
24652
|
+
logRuntime,
|
|
24653
|
+
logEachDuration,
|
|
25069
24654
|
logSummary,
|
|
25070
24655
|
logTimeUsage,
|
|
25071
24656
|
logMemoryHeapUsage,
|
|
@@ -25079,10 +24664,11 @@ const executePlan = async (plan, {
|
|
|
25079
24664
|
failFast,
|
|
25080
24665
|
gcBetweenExecutions,
|
|
25081
24666
|
cooldownBetweenExecutions,
|
|
25082
|
-
|
|
24667
|
+
coverageEnabled,
|
|
25083
24668
|
coverageConfig,
|
|
25084
24669
|
coverageIncludeMissing,
|
|
25085
|
-
|
|
24670
|
+
coverageMethodForBrowsers,
|
|
24671
|
+
coverageMethodForNodeJs,
|
|
25086
24672
|
coverageV8ConflictWarning,
|
|
25087
24673
|
coverageTempDirectoryRelativeUrl,
|
|
25088
24674
|
scenario,
|
|
@@ -25100,10 +24686,14 @@ const executePlan = async (plan, {
|
|
|
25100
24686
|
beforeExecutionCallback = () => {},
|
|
25101
24687
|
afterExecutionCallback = () => {}
|
|
25102
24688
|
} = {}) => {
|
|
24689
|
+
const executePlanReturnValue = {};
|
|
24690
|
+
const report = {};
|
|
24691
|
+
const callbacks = [];
|
|
25103
24692
|
const stopAfterAllSignal = {
|
|
25104
24693
|
notify: () => {}
|
|
25105
24694
|
};
|
|
25106
24695
|
let someNeedsServer = false;
|
|
24696
|
+
let someNodeRuntime = false;
|
|
25107
24697
|
const runtimes = {};
|
|
25108
24698
|
Object.keys(plan).forEach(filePattern => {
|
|
25109
24699
|
const filePlan = plan[filePattern];
|
|
@@ -25119,6 +24709,10 @@ const executePlan = async (plan, {
|
|
|
25119
24709
|
if (runtime.needsServer) {
|
|
25120
24710
|
someNeedsServer = true;
|
|
25121
24711
|
}
|
|
24712
|
+
|
|
24713
|
+
if (runtime.type === "node") {
|
|
24714
|
+
someNodeRuntime = true;
|
|
24715
|
+
}
|
|
25122
24716
|
}
|
|
25123
24717
|
});
|
|
25124
24718
|
});
|
|
@@ -25146,10 +24740,67 @@ const executePlan = async (plan, {
|
|
|
25146
24740
|
}
|
|
25147
24741
|
|
|
25148
24742
|
try {
|
|
24743
|
+
const coverageTempDirectoryUrl = new URL(coverageTempDirectoryRelativeUrl, rootDirectoryUrl).href;
|
|
24744
|
+
|
|
24745
|
+
if (someNodeRuntime && coverageEnabled && coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
|
|
24746
|
+
if (process.env.NODE_V8_COVERAGE) {
|
|
24747
|
+
// when runned multiple times, we don't want to keep previous files in this directory
|
|
24748
|
+
await ensureEmptyDirectory(process.env.NODE_V8_COVERAGE);
|
|
24749
|
+
} else {
|
|
24750
|
+
coverageMethodForNodeJs = "Profiler";
|
|
24751
|
+
logger.warn(createDetailedMessage$1(`process.env.NODE_V8_COVERAGE is required to generate coverage for Node.js subprocesses`, {
|
|
24752
|
+
"suggestion": `Preprend NODE_V8_COVERAGE=.coverage/node to the command executing this process`,
|
|
24753
|
+
"suggestion 2": `use coverageMethodForNodeJs: "Profiler". But it means coverage for child_process and worker_thread cannot be collected`
|
|
24754
|
+
}));
|
|
24755
|
+
}
|
|
24756
|
+
}
|
|
24757
|
+
|
|
24758
|
+
if (gcBetweenExecutions) {
|
|
24759
|
+
ensureGlobalGc();
|
|
24760
|
+
}
|
|
24761
|
+
|
|
24762
|
+
if (coverageEnabled) {
|
|
24763
|
+
// when runned multiple times, we don't want to keep previous files in this directory
|
|
24764
|
+
await ensureEmptyDirectory(coverageTempDirectoryUrl);
|
|
24765
|
+
callbacks.push(async () => {
|
|
24766
|
+
if (multipleExecutionsOperation.signal.aborted) {
|
|
24767
|
+
// don't try to do the coverage stuff
|
|
24768
|
+
return;
|
|
24769
|
+
}
|
|
24770
|
+
|
|
24771
|
+
try {
|
|
24772
|
+
if (coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
|
|
24773
|
+
takeCoverage(); // conceptually we don't need coverage anymore so it would be
|
|
24774
|
+
// good to call v8.stopCoverage()
|
|
24775
|
+
// but it logs a strange message about "result is not an object"
|
|
24776
|
+
}
|
|
24777
|
+
|
|
24778
|
+
const planCoverage = await reportToCoverage(report, {
|
|
24779
|
+
signal: multipleExecutionsOperation.signal,
|
|
24780
|
+
logger,
|
|
24781
|
+
rootDirectoryUrl,
|
|
24782
|
+
coverageConfig,
|
|
24783
|
+
coverageIncludeMissing,
|
|
24784
|
+
coverageMethodForBrowsers,
|
|
24785
|
+
coverageV8ConflictWarning
|
|
24786
|
+
});
|
|
24787
|
+
executePlanReturnValue.planCoverage = planCoverage;
|
|
24788
|
+
} catch (e) {
|
|
24789
|
+
if (Abort.isAbortError(e)) {
|
|
24790
|
+
return;
|
|
24791
|
+
}
|
|
24792
|
+
|
|
24793
|
+
throw e;
|
|
24794
|
+
}
|
|
24795
|
+
});
|
|
24796
|
+
}
|
|
24797
|
+
|
|
25149
24798
|
let runtimeParams = {
|
|
25150
24799
|
rootDirectoryUrl,
|
|
25151
|
-
|
|
25152
|
-
|
|
24800
|
+
coverageEnabled,
|
|
24801
|
+
coverageConfig,
|
|
24802
|
+
coverageMethodForBrowsers,
|
|
24803
|
+
coverageMethodForNodeJs,
|
|
25153
24804
|
stopAfterAllSignal
|
|
25154
24805
|
};
|
|
25155
24806
|
|
|
@@ -25176,7 +24827,7 @@ const executePlan = async (plan, {
|
|
|
25176
24827
|
getCustomBabelPlugins: ({
|
|
25177
24828
|
clientRuntimeCompat
|
|
25178
24829
|
}) => {
|
|
25179
|
-
if (
|
|
24830
|
+
if (coverageEnabled && Object.keys(clientRuntimeCompat)[0] !== "chrome") {
|
|
25180
24831
|
return {
|
|
25181
24832
|
"transform-instrument": [babelPluginInstrument, {
|
|
25182
24833
|
rootDirectoryUrl,
|
|
@@ -25232,79 +24883,7 @@ const executePlan = async (plan, {
|
|
|
25232
24883
|
// so we enable spinner only when !process.exitCode (no error so far)
|
|
25233
24884
|
process.exitCode !== 1;
|
|
25234
24885
|
const startMs = Date.now();
|
|
25235
|
-
const report = {};
|
|
25236
24886
|
let rawOutput = "";
|
|
25237
|
-
|
|
25238
|
-
let transformReturnValue = value => value;
|
|
25239
|
-
|
|
25240
|
-
if (gcBetweenExecutions) {
|
|
25241
|
-
ensureGlobalGc();
|
|
25242
|
-
}
|
|
25243
|
-
|
|
25244
|
-
const coverageTempDirectoryUrl = new URL(coverageTempDirectoryRelativeUrl, rootDirectoryUrl).href;
|
|
25245
|
-
|
|
25246
|
-
if (coverage) {
|
|
25247
|
-
const associations = URL_META.resolveAssociations({
|
|
25248
|
-
cover: coverageConfig
|
|
25249
|
-
}, rootDirectoryUrl);
|
|
25250
|
-
|
|
25251
|
-
const urlShouldBeCovered = url => {
|
|
25252
|
-
const {
|
|
25253
|
-
cover
|
|
25254
|
-
} = URL_META.applyAssociations({
|
|
25255
|
-
url: new URL(url, rootDirectoryUrl).href,
|
|
25256
|
-
associations
|
|
25257
|
-
});
|
|
25258
|
-
return cover;
|
|
25259
|
-
};
|
|
25260
|
-
|
|
25261
|
-
runtimeParams.urlShouldBeCovered = urlShouldBeCovered; // in case runned multiple times, we don't want to keep writing lot of files in this directory
|
|
25262
|
-
|
|
25263
|
-
if (!process.env.NODE_V8_COVERAGE) {
|
|
25264
|
-
await ensureEmptyDirectory(coverageTempDirectoryUrl);
|
|
25265
|
-
}
|
|
25266
|
-
|
|
25267
|
-
if (runtimes.node) {
|
|
25268
|
-
// v8 coverage is written in a directoy and auto propagate to subprocesses
|
|
25269
|
-
// through process.env.NODE_V8_COVERAGE.
|
|
25270
|
-
if (!coverageForceIstanbul && !process.env.NODE_V8_COVERAGE) {
|
|
25271
|
-
const v8CoverageDirectory = new URL(`./node_v8/${cuid()}`, coverageTempDirectoryUrl).href;
|
|
25272
|
-
await writeDirectory(v8CoverageDirectory, {
|
|
25273
|
-
allowUseless: true
|
|
25274
|
-
});
|
|
25275
|
-
process.env.NODE_V8_COVERAGE = urlToFileSystemPath(v8CoverageDirectory);
|
|
25276
|
-
}
|
|
25277
|
-
}
|
|
25278
|
-
|
|
25279
|
-
transformReturnValue = async value => {
|
|
25280
|
-
if (multipleExecutionsOperation.signal.aborted) {
|
|
25281
|
-
// don't try to do the coverage stuff
|
|
25282
|
-
return value;
|
|
25283
|
-
}
|
|
25284
|
-
|
|
25285
|
-
try {
|
|
25286
|
-
value.coverage = await reportToCoverage(value.report, {
|
|
25287
|
-
signal: multipleExecutionsOperation.signal,
|
|
25288
|
-
logger,
|
|
25289
|
-
rootDirectoryUrl,
|
|
25290
|
-
coverageConfig,
|
|
25291
|
-
coverageIncludeMissing,
|
|
25292
|
-
coverageForceIstanbul,
|
|
25293
|
-
urlShouldBeCovered,
|
|
25294
|
-
coverageV8ConflictWarning
|
|
25295
|
-
});
|
|
25296
|
-
} catch (e) {
|
|
25297
|
-
if (Abort.isAbortError(e)) {
|
|
25298
|
-
return value;
|
|
25299
|
-
}
|
|
25300
|
-
|
|
25301
|
-
throw e;
|
|
25302
|
-
}
|
|
25303
|
-
|
|
25304
|
-
return value;
|
|
25305
|
-
};
|
|
25306
|
-
}
|
|
25307
|
-
|
|
25308
24887
|
logger.info("");
|
|
25309
24888
|
let executionLog = createLog({
|
|
25310
24889
|
newLine: ""
|
|
@@ -25329,6 +24908,7 @@ const executePlan = async (plan, {
|
|
|
25329
24908
|
fileRelativeUrl,
|
|
25330
24909
|
runtime
|
|
25331
24910
|
} = paramsFromStep;
|
|
24911
|
+
const runtimeType = runtime.type;
|
|
25332
24912
|
const runtimeName = runtime.name;
|
|
25333
24913
|
const runtimeVersion = runtime.version;
|
|
25334
24914
|
const executionParams = {
|
|
@@ -25344,6 +24924,7 @@ const executePlan = async (plan, {
|
|
|
25344
24924
|
};
|
|
25345
24925
|
const beforeExecutionInfo = {
|
|
25346
24926
|
fileRelativeUrl,
|
|
24927
|
+
runtimeType,
|
|
25347
24928
|
runtimeName,
|
|
25348
24929
|
runtimeVersion,
|
|
25349
24930
|
executionIndex,
|
|
@@ -25361,6 +24942,8 @@ const executePlan = async (plan, {
|
|
|
25361
24942
|
render: () => {
|
|
25362
24943
|
return createExecutionLog(beforeExecutionInfo, {
|
|
25363
24944
|
counters,
|
|
24945
|
+
logRuntime,
|
|
24946
|
+
logEachDuration,
|
|
25364
24947
|
...(logTimeUsage ? {
|
|
25365
24948
|
timeEllapsed: Date.now() - startMs
|
|
25366
24949
|
} : {}),
|
|
@@ -25385,7 +24968,7 @@ const executePlan = async (plan, {
|
|
|
25385
24968
|
mirrorConsole: false,
|
|
25386
24969
|
// file are executed in parallel, log would be a mess to read
|
|
25387
24970
|
collectConsole: executionParams.collectConsole,
|
|
25388
|
-
|
|
24971
|
+
coverageEnabled,
|
|
25389
24972
|
coverageTempDirectoryUrl,
|
|
25390
24973
|
runtime: executionParams.runtime,
|
|
25391
24974
|
runtimeParams: { ...runtimeParams,
|
|
@@ -25434,6 +25017,8 @@ const executePlan = async (plan, {
|
|
|
25434
25017
|
let log = createExecutionLog(afterExecutionInfo, {
|
|
25435
25018
|
completedExecutionLogAbbreviation,
|
|
25436
25019
|
counters,
|
|
25020
|
+
logRuntime,
|
|
25021
|
+
logEachDuration,
|
|
25437
25022
|
...(logTimeUsage ? {
|
|
25438
25023
|
timeEllapsed: Date.now() - startMs
|
|
25439
25024
|
} : {}),
|
|
@@ -25501,16 +25086,14 @@ const executePlan = async (plan, {
|
|
|
25501
25086
|
logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`);
|
|
25502
25087
|
}
|
|
25503
25088
|
|
|
25504
|
-
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25508
|
-
|
|
25509
|
-
|
|
25510
|
-
|
|
25511
|
-
|
|
25512
|
-
planCoverage: result.coverage
|
|
25513
|
-
};
|
|
25089
|
+
executePlanReturnValue.aborted = multipleExecutionsOperation.signal.aborted;
|
|
25090
|
+
executePlanReturnValue.planSummary = summary;
|
|
25091
|
+
executePlanReturnValue.planReport = report;
|
|
25092
|
+
await callbacks.reduce(async (previous, callback) => {
|
|
25093
|
+
await previous;
|
|
25094
|
+
await callback();
|
|
25095
|
+
}, Promise.resolve());
|
|
25096
|
+
return executePlanReturnValue;
|
|
25514
25097
|
} finally {
|
|
25515
25098
|
await multipleExecutionsOperation.end();
|
|
25516
25099
|
}
|
|
@@ -25631,7 +25214,7 @@ const executeInParallel = async ({
|
|
|
25631
25214
|
* @param {boolean} [testPlanParameters.failFast=false] Fails immediatly when a test execution fails
|
|
25632
25215
|
* @param {number} [testPlanParameters.cooldownBetweenExecutions=0] Millisecond to wait between each execution
|
|
25633
25216
|
* @param {boolean} [testPlanParameters.logMemoryHeapUsage=false] Add memory heap usage during logs
|
|
25634
|
-
* @param {boolean} [testPlanParameters.
|
|
25217
|
+
* @param {boolean} [testPlanParameters.coverageEnabled=false] Controls if coverage is collected during files executions
|
|
25635
25218
|
* @param {boolean} [testPlanParameters.coverageV8ConflictWarning=true] Warn when coverage from 2 executions cannot be merged
|
|
25636
25219
|
* @return {Object} An object containing the result of all file executions
|
|
25637
25220
|
*/
|
|
@@ -25640,6 +25223,8 @@ const executeTestPlan = async ({
|
|
|
25640
25223
|
signal = new AbortController().signal,
|
|
25641
25224
|
handleSIGINT = true,
|
|
25642
25225
|
logLevel = "info",
|
|
25226
|
+
logRuntime = true,
|
|
25227
|
+
logEachDuration = true,
|
|
25643
25228
|
logSummary = true,
|
|
25644
25229
|
logTimeUsage = false,
|
|
25645
25230
|
logMemoryHeapUsage = false,
|
|
@@ -25660,22 +25245,25 @@ const executeTestPlan = async ({
|
|
|
25660
25245
|
keepRunning = false,
|
|
25661
25246
|
cooldownBetweenExecutions = 0,
|
|
25662
25247
|
gcBetweenExecutions = logMemoryHeapUsage,
|
|
25663
|
-
|
|
25664
|
-
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
25248
|
+
coverageEnabled = process.argv.includes("--cover") || process.argv.includes("--coverage"),
|
|
25665
25249
|
coverageConfig = {
|
|
25666
25250
|
"./src/": true
|
|
25667
25251
|
},
|
|
25668
25252
|
coverageIncludeMissing = true,
|
|
25669
25253
|
coverageAndExecutionAllowed = false,
|
|
25670
|
-
|
|
25254
|
+
coverageMethodForNodeJs = "NODE_V8_COVERAGE",
|
|
25255
|
+
// "Profiler" also accepted
|
|
25256
|
+
coverageMethodForBrowsers = "playwright_api",
|
|
25257
|
+
// "istanbul" also accepted
|
|
25671
25258
|
coverageV8ConflictWarning = true,
|
|
25672
|
-
|
|
25673
|
-
coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
|
|
25674
|
-
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null,
|
|
25259
|
+
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
25675
25260
|
// skip empty means empty files won't appear in the coverage reports (json and html)
|
|
25676
25261
|
coverageReportSkipEmpty = false,
|
|
25677
25262
|
// skip full means file with 100% coverage won't appear in coverage reports (json and html)
|
|
25678
25263
|
coverageReportSkipFull = false,
|
|
25264
|
+
coverageReportTextLog = true,
|
|
25265
|
+
coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
|
|
25266
|
+
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null,
|
|
25679
25267
|
sourcemaps = "inline",
|
|
25680
25268
|
plugins = [],
|
|
25681
25269
|
nodeEsmResolution,
|
|
@@ -25696,7 +25284,7 @@ const executeTestPlan = async ({
|
|
|
25696
25284
|
throw new Error(`testPlan must be an object, got ${testPlan}`);
|
|
25697
25285
|
}
|
|
25698
25286
|
|
|
25699
|
-
if (
|
|
25287
|
+
if (coverageEnabled) {
|
|
25700
25288
|
if (typeof coverageConfig !== "object") {
|
|
25701
25289
|
throw new TypeError(`coverageConfig must be an object, got ${coverageConfig}`);
|
|
25702
25290
|
}
|
|
@@ -25737,6 +25325,8 @@ const executeTestPlan = async ({
|
|
|
25737
25325
|
logger,
|
|
25738
25326
|
logLevel,
|
|
25739
25327
|
logSummary,
|
|
25328
|
+
logRuntime,
|
|
25329
|
+
logEachDuration,
|
|
25740
25330
|
logTimeUsage,
|
|
25741
25331
|
logMemoryHeapUsage,
|
|
25742
25332
|
logFileRelativeUrl,
|
|
@@ -25749,10 +25339,11 @@ const executeTestPlan = async ({
|
|
|
25749
25339
|
keepRunning,
|
|
25750
25340
|
cooldownBetweenExecutions,
|
|
25751
25341
|
gcBetweenExecutions,
|
|
25752
|
-
|
|
25342
|
+
coverageEnabled,
|
|
25753
25343
|
coverageConfig,
|
|
25754
25344
|
coverageIncludeMissing,
|
|
25755
|
-
|
|
25345
|
+
coverageMethodForBrowsers,
|
|
25346
|
+
coverageMethodForNodeJs,
|
|
25756
25347
|
coverageV8ConflictWarning,
|
|
25757
25348
|
coverageTempDirectoryRelativeUrl,
|
|
25758
25349
|
scenario: "test",
|
|
@@ -25779,7 +25370,7 @@ const executeTestPlan = async ({
|
|
|
25779
25370
|
// and in case coverage json file gets written in the same directory
|
|
25780
25371
|
// it must be done before
|
|
25781
25372
|
|
|
25782
|
-
if (
|
|
25373
|
+
if (coverageEnabled && coverageReportHtmlDirectory) {
|
|
25783
25374
|
const coverageHtmlDirectoryUrl = resolveDirectoryUrl(coverageReportHtmlDirectory, rootDirectoryUrl);
|
|
25784
25375
|
|
|
25785
25376
|
if (!urlIsInsideOf(coverageHtmlDirectoryUrl, rootDirectoryUrl)) {
|
|
@@ -25797,7 +25388,7 @@ const executeTestPlan = async ({
|
|
|
25797
25388
|
}));
|
|
25798
25389
|
}
|
|
25799
25390
|
|
|
25800
|
-
if (
|
|
25391
|
+
if (coverageEnabled && coverageReportJsonFile) {
|
|
25801
25392
|
const coverageJsonFileUrl = new URL(coverageReportJsonFile, rootDirectoryUrl).href;
|
|
25802
25393
|
promises.push(generateCoverageJsonFile({
|
|
25803
25394
|
coverage: result.planCoverage,
|
|
@@ -25806,7 +25397,7 @@ const executeTestPlan = async ({
|
|
|
25806
25397
|
}));
|
|
25807
25398
|
}
|
|
25808
25399
|
|
|
25809
|
-
if (
|
|
25400
|
+
if (coverageEnabled && coverageReportTextLog) {
|
|
25810
25401
|
promises.push(generateCoverageTextLog(result.planCoverage, {
|
|
25811
25402
|
coverageReportSkipEmpty,
|
|
25812
25403
|
coverageReportSkipFull
|
|
@@ -25881,6 +25472,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
25881
25472
|
isolatedTab = false
|
|
25882
25473
|
}) => {
|
|
25883
25474
|
const runtime = {
|
|
25475
|
+
type: "browser",
|
|
25884
25476
|
name: browserName,
|
|
25885
25477
|
version: browserVersion,
|
|
25886
25478
|
needsServer: true
|
|
@@ -25895,9 +25487,9 @@ const createRuntimeFromPlaywright = ({
|
|
|
25895
25487
|
server,
|
|
25896
25488
|
// measurePerformance,
|
|
25897
25489
|
collectPerformance,
|
|
25898
|
-
|
|
25899
|
-
|
|
25900
|
-
|
|
25490
|
+
coverageEnabled = false,
|
|
25491
|
+
coverageConfig,
|
|
25492
|
+
coverageMethodForBrowsers,
|
|
25901
25493
|
stopAfterAllSignal,
|
|
25902
25494
|
stopSignal,
|
|
25903
25495
|
keepRunning,
|
|
@@ -25982,8 +25574,8 @@ const createRuntimeFromPlaywright = ({
|
|
|
25982
25574
|
|
|
25983
25575
|
let resultTransformer = result => result;
|
|
25984
25576
|
|
|
25985
|
-
if (
|
|
25986
|
-
if (coveragePlaywrightAPIAvailable &&
|
|
25577
|
+
if (coverageEnabled) {
|
|
25578
|
+
if (coveragePlaywrightAPIAvailable && coverageMethodForBrowsers === "playwright_api") {
|
|
25987
25579
|
await page.coverage.startJSCoverage({// reportAnonymousScripts: true,
|
|
25988
25580
|
});
|
|
25989
25581
|
resultTransformer = composeTransformer(resultTransformer, async result => {
|
|
@@ -26001,10 +25593,11 @@ const createRuntimeFromPlaywright = ({
|
|
|
26001
25593
|
url: fsUrl
|
|
26002
25594
|
};
|
|
26003
25595
|
});
|
|
26004
|
-
const coverage = filterV8Coverage({
|
|
25596
|
+
const coverage = await filterV8Coverage({
|
|
26005
25597
|
result: v8CoveragesWithFsUrls
|
|
26006
25598
|
}, {
|
|
26007
|
-
|
|
25599
|
+
rootDirectoryUrl,
|
|
25600
|
+
coverageConfig
|
|
26008
25601
|
});
|
|
26009
25602
|
return { ...result,
|
|
26010
25603
|
coverage
|
|
@@ -26741,13 +26334,24 @@ const killProcessTree = async (processId, {
|
|
|
26741
26334
|
await check();
|
|
26742
26335
|
};
|
|
26743
26336
|
|
|
26744
|
-
|
|
26745
|
-
const
|
|
26746
|
-
|
|
26337
|
+
// https://nodejs.org/api/process.html#process_signal_events
|
|
26338
|
+
const SIGINT_SIGNAL_NUMBER = 2;
|
|
26339
|
+
const SIGABORT_SIGNAL_NUMBER = 6;
|
|
26340
|
+
const SIGTERM_SIGNAL_NUMBER = 15;
|
|
26341
|
+
const EXIT_CODES = {
|
|
26342
|
+
SIGINT: 128 + SIGINT_SIGNAL_NUMBER,
|
|
26343
|
+
SIGABORT: 128 + SIGABORT_SIGNAL_NUMBER,
|
|
26344
|
+
SIGTERM: 128 + SIGTERM_SIGNAL_NUMBER
|
|
26345
|
+
};
|
|
26346
|
+
|
|
26347
|
+
const CONTROLLABLE_CHILD_PROCESS_URL = new URL("./controllable_child_process.mjs", import.meta.url).href;
|
|
26348
|
+
const nodeChildProcess = {
|
|
26349
|
+
type: "node",
|
|
26350
|
+
name: "node_child_process",
|
|
26747
26351
|
version: process.version.slice(1)
|
|
26748
26352
|
};
|
|
26749
26353
|
|
|
26750
|
-
|
|
26354
|
+
nodeChildProcess.run = async ({
|
|
26751
26355
|
signal = new AbortController().signal,
|
|
26752
26356
|
logger,
|
|
26753
26357
|
logProcessCommand = false,
|
|
@@ -26757,13 +26361,14 @@ nodeProcess.run = async ({
|
|
|
26757
26361
|
gracefulStopAllocatedMs = 4000,
|
|
26758
26362
|
stopSignal,
|
|
26759
26363
|
onConsole,
|
|
26760
|
-
|
|
26761
|
-
|
|
26364
|
+
coverageEnabled = false,
|
|
26365
|
+
coverageConfig,
|
|
26366
|
+
coverageMethodForNodeJs,
|
|
26762
26367
|
collectPerformance,
|
|
26368
|
+
env,
|
|
26763
26369
|
debugPort,
|
|
26764
26370
|
debugMode,
|
|
26765
26371
|
debugModeInheritBreak,
|
|
26766
|
-
env,
|
|
26767
26372
|
inheritProcessEnv = true,
|
|
26768
26373
|
commandLineOptions = [],
|
|
26769
26374
|
stdin = "pipe",
|
|
@@ -26775,13 +26380,10 @@ nodeProcess.run = async ({
|
|
|
26775
26380
|
}
|
|
26776
26381
|
|
|
26777
26382
|
env = { ...env,
|
|
26778
|
-
COVERAGE_ENABLED: collectCoverage,
|
|
26779
26383
|
JSENV: true
|
|
26780
26384
|
};
|
|
26781
26385
|
|
|
26782
|
-
if (
|
|
26783
|
-
// if we want to force istanbul, we will set process.env.NODE_V8_COVERAGE = ''
|
|
26784
|
-
// into the child_process
|
|
26386
|
+
if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
|
|
26785
26387
|
env.NODE_V8_COVERAGE = "";
|
|
26786
26388
|
}
|
|
26787
26389
|
|
|
@@ -26806,8 +26408,8 @@ nodeProcess.run = async ({
|
|
|
26806
26408
|
const envForChildProcess = { ...(inheritProcessEnv ? process.env : {}),
|
|
26807
26409
|
...env
|
|
26808
26410
|
};
|
|
26809
|
-
logger[logProcessCommand ? "info" : "debug"](`${process.argv[0]} ${execArgv.join(" ")} ${
|
|
26810
|
-
const childProcess = fork(
|
|
26411
|
+
logger[logProcessCommand ? "info" : "debug"](`${process.argv[0]} ${execArgv.join(" ")} ${fileURLToPath(CONTROLLABLE_CHILD_PROCESS_URL)}`);
|
|
26412
|
+
const childProcess = fork(fileURLToPath(CONTROLLABLE_CHILD_PROCESS_URL), {
|
|
26811
26413
|
execArgv,
|
|
26812
26414
|
// silent: true
|
|
26813
26415
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
@@ -26831,9 +26433,9 @@ nodeProcess.run = async ({
|
|
|
26831
26433
|
}
|
|
26832
26434
|
|
|
26833
26435
|
const childProcessReadyPromise = new Promise(resolve => {
|
|
26834
|
-
|
|
26436
|
+
onceChildProcessMessage(childProcess, "ready", resolve);
|
|
26835
26437
|
});
|
|
26836
|
-
const removeOutputListener =
|
|
26438
|
+
const removeOutputListener = installChildProcessOutputListener(childProcess, ({
|
|
26837
26439
|
type,
|
|
26838
26440
|
text
|
|
26839
26441
|
}) => {
|
|
@@ -26894,10 +26496,10 @@ nodeProcess.run = async ({
|
|
|
26894
26496
|
// },
|
|
26895
26497
|
// https://nodejs.org/api/child_process.html#child_process_event_error
|
|
26896
26498
|
error: cb => {
|
|
26897
|
-
return
|
|
26499
|
+
return onceChildProcessEvent(childProcess, "error", cb);
|
|
26898
26500
|
},
|
|
26899
26501
|
exit: cb => {
|
|
26900
|
-
return
|
|
26502
|
+
return onceChildProcessEvent(childProcess, "exit", (code, signal) => {
|
|
26901
26503
|
cb({
|
|
26902
26504
|
code,
|
|
26903
26505
|
signal
|
|
@@ -26905,7 +26507,7 @@ nodeProcess.run = async ({
|
|
|
26905
26507
|
});
|
|
26906
26508
|
},
|
|
26907
26509
|
response: cb => {
|
|
26908
|
-
|
|
26510
|
+
return onceChildProcessMessage(childProcess, "action-result", cb);
|
|
26909
26511
|
}
|
|
26910
26512
|
}, resolve);
|
|
26911
26513
|
});
|
|
@@ -26914,11 +26516,19 @@ nodeProcess.run = async ({
|
|
|
26914
26516
|
actionOperation.throwIfAborted();
|
|
26915
26517
|
await childProcessReadyPromise;
|
|
26916
26518
|
actionOperation.throwIfAborted();
|
|
26917
|
-
await
|
|
26918
|
-
|
|
26919
|
-
|
|
26920
|
-
|
|
26921
|
-
|
|
26519
|
+
await sendToChildProcess(childProcess, {
|
|
26520
|
+
type: "action",
|
|
26521
|
+
data: {
|
|
26522
|
+
actionType: "execute-using-dynamic-import",
|
|
26523
|
+
actionParams: {
|
|
26524
|
+
rootDirectoryUrl,
|
|
26525
|
+
fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
|
|
26526
|
+
collectPerformance,
|
|
26527
|
+
coverageEnabled,
|
|
26528
|
+
coverageConfig,
|
|
26529
|
+
coverageMethodForNodeJs,
|
|
26530
|
+
exitAfterAction: true
|
|
26531
|
+
}
|
|
26922
26532
|
}
|
|
26923
26533
|
});
|
|
26924
26534
|
const winner = await winnerPromise;
|
|
@@ -26951,7 +26561,7 @@ nodeProcess.run = async ({
|
|
|
26951
26561
|
};
|
|
26952
26562
|
}
|
|
26953
26563
|
|
|
26954
|
-
if (code === null || code === 0 || code ===
|
|
26564
|
+
if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
|
|
26955
26565
|
return {
|
|
26956
26566
|
status: "errored",
|
|
26957
26567
|
error: new Error(`node process exited during execution`)
|
|
@@ -27005,31 +26615,25 @@ nodeProcess.run = async ({
|
|
|
27005
26615
|
|
|
27006
26616
|
await actionOperation.end();
|
|
27007
26617
|
return result;
|
|
27008
|
-
}; //
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
const SIGINT_SIGNAL_NUMBER = 2;
|
|
27012
|
-
const SIGABORT_SIGNAL_NUMBER = 6;
|
|
27013
|
-
const SIGTERM_SIGNAL_NUMBER = 15;
|
|
27014
|
-
const SIGINT_EXIT_CODE = 128 + SIGINT_SIGNAL_NUMBER;
|
|
27015
|
-
const SIGABORT_EXIT_CODE = 128 + SIGABORT_SIGNAL_NUMBER;
|
|
27016
|
-
const SIGTERM_EXIT_CODE = 128 + SIGTERM_SIGNAL_NUMBER; // http://man7.org/linux/man-pages/man7/signal.7.html
|
|
26618
|
+
}; // http://man7.org/linux/man-pages/man7/signal.7.html
|
|
27017
26619
|
// https:// github.com/nodejs/node/blob/1d9511127c419ec116b3ddf5fc7a59e8f0f1c1e4/lib/internal/child_process.js#L472
|
|
27018
26620
|
|
|
26621
|
+
|
|
27019
26622
|
const GRACEFUL_STOP_SIGNAL = "SIGTERM";
|
|
27020
26623
|
const STOP_SIGNAL = "SIGKILL"; // it would be more correct if GRACEFUL_STOP_FAILED_SIGNAL was SIGHUP instead of SIGKILL.
|
|
27021
26624
|
// but I'm not sure and it changes nothing so just use SIGKILL
|
|
27022
26625
|
|
|
27023
26626
|
const GRACEFUL_STOP_FAILED_SIGNAL = "SIGKILL";
|
|
27024
26627
|
|
|
27025
|
-
const
|
|
27026
|
-
|
|
27027
|
-
|
|
27028
|
-
|
|
26628
|
+
const sendToChildProcess = async (childProcess, {
|
|
26629
|
+
type,
|
|
26630
|
+
data
|
|
26631
|
+
}) => {
|
|
27029
26632
|
return new Promise((resolve, reject) => {
|
|
27030
26633
|
childProcess.send({
|
|
26634
|
+
jsenv: true,
|
|
27031
26635
|
type,
|
|
27032
|
-
data
|
|
26636
|
+
data
|
|
27033
26637
|
}, error => {
|
|
27034
26638
|
if (error) {
|
|
27035
26639
|
reject(error);
|
|
@@ -27040,7 +26644,7 @@ const sendToProcess = async (childProcess, type, data) => {
|
|
|
27040
26644
|
});
|
|
27041
26645
|
};
|
|
27042
26646
|
|
|
27043
|
-
const
|
|
26647
|
+
const installChildProcessOutputListener = (childProcess, callback) => {
|
|
27044
26648
|
// beware that we may receive ansi output here, should not be a problem but keep that in mind
|
|
27045
26649
|
const stdoutDataCallback = chunk => {
|
|
27046
26650
|
callback({
|
|
@@ -27065,9 +26669,9 @@ const installProcessOutputListener = (childProcess, callback) => {
|
|
|
27065
26669
|
};
|
|
27066
26670
|
};
|
|
27067
26671
|
|
|
27068
|
-
const
|
|
26672
|
+
const onceChildProcessMessage = (childProcess, type, callback) => {
|
|
27069
26673
|
const onmessage = message => {
|
|
27070
|
-
if (message.type === type) {
|
|
26674
|
+
if (message && message.jsenv && message.type === type) {
|
|
27071
26675
|
childProcess.removeListener("message", onmessage); // eslint-disable-next-line no-eval
|
|
27072
26676
|
|
|
27073
26677
|
callback(message.data ? eval(`(${message.data})`) : "");
|
|
@@ -27080,13 +26684,290 @@ const onceProcessMessage = (childProcess, type, callback) => {
|
|
|
27080
26684
|
};
|
|
27081
26685
|
};
|
|
27082
26686
|
|
|
27083
|
-
const
|
|
26687
|
+
const onceChildProcessEvent = (childProcess, type, callback) => {
|
|
27084
26688
|
childProcess.once(type, callback);
|
|
27085
26689
|
return () => {
|
|
27086
26690
|
childProcess.removeListener(type, callback);
|
|
27087
26691
|
};
|
|
27088
26692
|
};
|
|
27089
26693
|
|
|
26694
|
+
// https://github.com/avajs/ava/blob/576f534b345259055c95fa0c2b33bef10847a2af/lib/fork.js#L23
|
|
26695
|
+
const CONTROLLABLE_WORKER_THREAD_URL = new URL("./controllable_worker_thread.mjs", import.meta.url).href;
|
|
26696
|
+
const nodeWorkerThread = {
|
|
26697
|
+
type: "node",
|
|
26698
|
+
name: "node_worker_thread",
|
|
26699
|
+
version: process.version.slice(1)
|
|
26700
|
+
};
|
|
26701
|
+
|
|
26702
|
+
nodeWorkerThread.run = async ({
|
|
26703
|
+
signal = new AbortController().signal,
|
|
26704
|
+
// logger,
|
|
26705
|
+
rootDirectoryUrl,
|
|
26706
|
+
fileRelativeUrl,
|
|
26707
|
+
keepRunning,
|
|
26708
|
+
stopSignal,
|
|
26709
|
+
onConsole,
|
|
26710
|
+
coverageConfig,
|
|
26711
|
+
coverageMethodForNodeJs,
|
|
26712
|
+
coverageEnabled = false,
|
|
26713
|
+
collectPerformance,
|
|
26714
|
+
env,
|
|
26715
|
+
debugPort,
|
|
26716
|
+
debugMode,
|
|
26717
|
+
debugModeInheritBreak,
|
|
26718
|
+
inheritProcessEnv = true,
|
|
26719
|
+
commandLineOptions = []
|
|
26720
|
+
}) => {
|
|
26721
|
+
if (env !== undefined && typeof env !== "object") {
|
|
26722
|
+
throw new TypeError(`env must be an object, got ${env}`);
|
|
26723
|
+
}
|
|
26724
|
+
|
|
26725
|
+
env = { ...env,
|
|
26726
|
+
JSENV: true
|
|
26727
|
+
};
|
|
26728
|
+
|
|
26729
|
+
if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
|
|
26730
|
+
env.NODE_V8_COVERAGE = "";
|
|
26731
|
+
}
|
|
26732
|
+
|
|
26733
|
+
const workerThreadExecOptions = await createChildExecOptions({
|
|
26734
|
+
signal,
|
|
26735
|
+
debugPort,
|
|
26736
|
+
debugMode,
|
|
26737
|
+
debugModeInheritBreak
|
|
26738
|
+
});
|
|
26739
|
+
const execArgvForWorkerThread = ExecOptions.toExecArgv({ ...workerThreadExecOptions,
|
|
26740
|
+
...ExecOptions.fromExecArgv(commandLineOptions)
|
|
26741
|
+
});
|
|
26742
|
+
const envForWorkerThread = { ...(inheritProcessEnv ? process.env : {}),
|
|
26743
|
+
...env
|
|
26744
|
+
};
|
|
26745
|
+
const cleanupCallbackList = createCallbackListNotifiedOnce();
|
|
26746
|
+
|
|
26747
|
+
const cleanup = async reason => {
|
|
26748
|
+
await cleanupCallbackList.notify({
|
|
26749
|
+
reason
|
|
26750
|
+
});
|
|
26751
|
+
};
|
|
26752
|
+
|
|
26753
|
+
const actionOperation = Abort.startOperation();
|
|
26754
|
+
actionOperation.addAbortSignal(signal); // https://nodejs.org/api/worker_threads.html#new-workerfilename-options
|
|
26755
|
+
|
|
26756
|
+
const workerThread = new Worker(fileURLToPath(CONTROLLABLE_WORKER_THREAD_URL), {
|
|
26757
|
+
env: envForWorkerThread,
|
|
26758
|
+
execArgv: execArgvForWorkerThread,
|
|
26759
|
+
// workerData: { options },
|
|
26760
|
+
// trackUnmanagedFds: true,
|
|
26761
|
+
stdin: true,
|
|
26762
|
+
stdout: true,
|
|
26763
|
+
stderr: true
|
|
26764
|
+
});
|
|
26765
|
+
const removeOutputListener = installWorkerThreadOutputListener(workerThread, ({
|
|
26766
|
+
type,
|
|
26767
|
+
text
|
|
26768
|
+
}) => {
|
|
26769
|
+
onConsole({
|
|
26770
|
+
type,
|
|
26771
|
+
text
|
|
26772
|
+
});
|
|
26773
|
+
});
|
|
26774
|
+
const workerThreadReadyPromise = new Promise(resolve => {
|
|
26775
|
+
onceWorkerThreadMessage(workerThread, "ready", resolve);
|
|
26776
|
+
});
|
|
26777
|
+
const stop = memoize(async () => {
|
|
26778
|
+
await workerThreadReadyPromise;
|
|
26779
|
+
await workerThread.terminate();
|
|
26780
|
+
});
|
|
26781
|
+
const winnerPromise = new Promise(resolve => {
|
|
26782
|
+
raceCallbacks({
|
|
26783
|
+
aborted: cb => {
|
|
26784
|
+
return actionOperation.addAbortCallback(cb);
|
|
26785
|
+
},
|
|
26786
|
+
error: cb => {
|
|
26787
|
+
return onceWorkerThreadEvent(workerThread, "error", cb);
|
|
26788
|
+
},
|
|
26789
|
+
exit: cb => {
|
|
26790
|
+
return onceWorkerThreadEvent(workerThread, "exit", (code, signal) => {
|
|
26791
|
+
cb({
|
|
26792
|
+
code,
|
|
26793
|
+
signal
|
|
26794
|
+
});
|
|
26795
|
+
});
|
|
26796
|
+
},
|
|
26797
|
+
response: cb => {
|
|
26798
|
+
return onceWorkerThreadMessage(workerThread, "action-result", cb);
|
|
26799
|
+
}
|
|
26800
|
+
}, resolve);
|
|
26801
|
+
});
|
|
26802
|
+
|
|
26803
|
+
const getResult = async () => {
|
|
26804
|
+
actionOperation.throwIfAborted();
|
|
26805
|
+
await workerThreadReadyPromise;
|
|
26806
|
+
actionOperation.throwIfAborted();
|
|
26807
|
+
await sendToWorkerThread(workerThread, {
|
|
26808
|
+
type: "action",
|
|
26809
|
+
data: {
|
|
26810
|
+
actionType: "execute-using-dynamic-import",
|
|
26811
|
+
actionParams: {
|
|
26812
|
+
rootDirectoryUrl,
|
|
26813
|
+
fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
|
|
26814
|
+
collectPerformance,
|
|
26815
|
+
coverageEnabled,
|
|
26816
|
+
coverageConfig,
|
|
26817
|
+
coverageMethodForNodeJs,
|
|
26818
|
+
exitAfterAction: true
|
|
26819
|
+
}
|
|
26820
|
+
}
|
|
26821
|
+
});
|
|
26822
|
+
const winner = await winnerPromise;
|
|
26823
|
+
|
|
26824
|
+
if (winner.name === "aborted") {
|
|
26825
|
+
return {
|
|
26826
|
+
status: "aborted"
|
|
26827
|
+
};
|
|
26828
|
+
}
|
|
26829
|
+
|
|
26830
|
+
if (winner.name === "error") {
|
|
26831
|
+
const error = winner.data;
|
|
26832
|
+
removeOutputListener();
|
|
26833
|
+
return {
|
|
26834
|
+
status: "errored",
|
|
26835
|
+
error
|
|
26836
|
+
};
|
|
26837
|
+
}
|
|
26838
|
+
|
|
26839
|
+
if (winner.name === "exit") {
|
|
26840
|
+
const {
|
|
26841
|
+
code
|
|
26842
|
+
} = winner.data;
|
|
26843
|
+
await cleanup("process exit");
|
|
26844
|
+
|
|
26845
|
+
if (code === 12) {
|
|
26846
|
+
return {
|
|
26847
|
+
status: "errored",
|
|
26848
|
+
error: new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`)
|
|
26849
|
+
};
|
|
26850
|
+
}
|
|
26851
|
+
|
|
26852
|
+
if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
|
|
26853
|
+
return {
|
|
26854
|
+
status: "errored",
|
|
26855
|
+
error: new Error(`node worker thread exited during execution`)
|
|
26856
|
+
};
|
|
26857
|
+
} // process.exit(1) in child process or process.exitCode = 1 + process.exit()
|
|
26858
|
+
// means there was an error even if we don't know exactly what.
|
|
26859
|
+
|
|
26860
|
+
|
|
26861
|
+
return {
|
|
26862
|
+
status: "errored",
|
|
26863
|
+
error: new Error(`node worker thread exited with code ${code} during execution`)
|
|
26864
|
+
};
|
|
26865
|
+
}
|
|
26866
|
+
|
|
26867
|
+
const {
|
|
26868
|
+
status,
|
|
26869
|
+
value
|
|
26870
|
+
} = winner.data;
|
|
26871
|
+
|
|
26872
|
+
if (status === "action-failed") {
|
|
26873
|
+
return {
|
|
26874
|
+
status: "errored",
|
|
26875
|
+
error: value
|
|
26876
|
+
};
|
|
26877
|
+
}
|
|
26878
|
+
|
|
26879
|
+
const {
|
|
26880
|
+
namespace,
|
|
26881
|
+
performance,
|
|
26882
|
+
coverage
|
|
26883
|
+
} = value;
|
|
26884
|
+
return {
|
|
26885
|
+
status: "completed",
|
|
26886
|
+
namespace,
|
|
26887
|
+
performance,
|
|
26888
|
+
coverage
|
|
26889
|
+
};
|
|
26890
|
+
};
|
|
26891
|
+
|
|
26892
|
+
let result;
|
|
26893
|
+
|
|
26894
|
+
try {
|
|
26895
|
+
result = await getResult();
|
|
26896
|
+
} catch (e) {
|
|
26897
|
+
result = {
|
|
26898
|
+
status: "errored",
|
|
26899
|
+
error: e
|
|
26900
|
+
};
|
|
26901
|
+
}
|
|
26902
|
+
|
|
26903
|
+
if (keepRunning) {
|
|
26904
|
+
stopSignal.notify = stop;
|
|
26905
|
+
} else {
|
|
26906
|
+
await stop();
|
|
26907
|
+
}
|
|
26908
|
+
|
|
26909
|
+
await actionOperation.end();
|
|
26910
|
+
return result;
|
|
26911
|
+
};
|
|
26912
|
+
|
|
26913
|
+
const installWorkerThreadOutputListener = (workerThread, callback) => {
|
|
26914
|
+
// beware that we may receive ansi output here, should not be a problem but keep that in mind
|
|
26915
|
+
const stdoutDataCallback = chunk => {
|
|
26916
|
+
callback({
|
|
26917
|
+
type: "log",
|
|
26918
|
+
text: String(chunk)
|
|
26919
|
+
});
|
|
26920
|
+
};
|
|
26921
|
+
|
|
26922
|
+
workerThread.stdout.on("data", stdoutDataCallback);
|
|
26923
|
+
|
|
26924
|
+
const stdErrorDataCallback = chunk => {
|
|
26925
|
+
callback({
|
|
26926
|
+
type: "error",
|
|
26927
|
+
text: String(chunk)
|
|
26928
|
+
});
|
|
26929
|
+
};
|
|
26930
|
+
|
|
26931
|
+
workerThread.stderr.on("data", stdErrorDataCallback);
|
|
26932
|
+
return () => {
|
|
26933
|
+
workerThread.stdout.removeListener("data", stdoutDataCallback);
|
|
26934
|
+
workerThread.stderr.removeListener("data", stdoutDataCallback);
|
|
26935
|
+
};
|
|
26936
|
+
};
|
|
26937
|
+
|
|
26938
|
+
const sendToWorkerThread = (worker, {
|
|
26939
|
+
type,
|
|
26940
|
+
data
|
|
26941
|
+
}) => {
|
|
26942
|
+
worker.postMessage({
|
|
26943
|
+
jsenv: true,
|
|
26944
|
+
type,
|
|
26945
|
+
data
|
|
26946
|
+
});
|
|
26947
|
+
};
|
|
26948
|
+
|
|
26949
|
+
const onceWorkerThreadMessage = (workerThread, type, callback) => {
|
|
26950
|
+
const onmessage = message => {
|
|
26951
|
+
if (message && message.jsenv && message.type === type) {
|
|
26952
|
+
workerThread.removeListener("message", onmessage); // eslint-disable-next-line no-eval
|
|
26953
|
+
|
|
26954
|
+
callback(message.data ? eval(`(${message.data})`) : undefined);
|
|
26955
|
+
}
|
|
26956
|
+
};
|
|
26957
|
+
|
|
26958
|
+
workerThread.on("message", onmessage);
|
|
26959
|
+
return () => {
|
|
26960
|
+
workerThread.removeListener("message", onmessage);
|
|
26961
|
+
};
|
|
26962
|
+
};
|
|
26963
|
+
|
|
26964
|
+
const onceWorkerThreadEvent = (worker, type, callback) => {
|
|
26965
|
+
worker.once(type, callback);
|
|
26966
|
+
return () => {
|
|
26967
|
+
worker.removeListener(type, callback);
|
|
26968
|
+
};
|
|
26969
|
+
};
|
|
26970
|
+
|
|
27090
26971
|
const loadUrlGraph = async ({
|
|
27091
26972
|
operation,
|
|
27092
26973
|
urlGraph,
|
|
@@ -27156,7 +27037,6 @@ const loadUrlGraph = async ({
|
|
|
27156
27037
|
type,
|
|
27157
27038
|
specifier
|
|
27158
27039
|
});
|
|
27159
|
-
entryUrlInfo.data.isEntryPoint = true;
|
|
27160
27040
|
cook(entryUrlInfo, {
|
|
27161
27041
|
reference: entryReference
|
|
27162
27042
|
});
|
|
@@ -27530,7 +27410,7 @@ const determineDirectoryPath = ({
|
|
|
27530
27410
|
return parentDirectoryPath;
|
|
27531
27411
|
}
|
|
27532
27412
|
|
|
27533
|
-
if (urlInfo.
|
|
27413
|
+
if (urlInfo.isEntryPoint) {
|
|
27534
27414
|
return "";
|
|
27535
27415
|
}
|
|
27536
27416
|
|
|
@@ -27564,7 +27444,7 @@ const injectGlobalVersionMapping = async ({
|
|
|
27564
27444
|
versionMappings
|
|
27565
27445
|
}) => {
|
|
27566
27446
|
await Promise.all(GRAPH.map(finalGraph, async urlInfo => {
|
|
27567
|
-
if (urlInfo.
|
|
27447
|
+
if (urlInfo.isEntryPoint) {
|
|
27568
27448
|
await injectVersionMappings({
|
|
27569
27449
|
urlInfo,
|
|
27570
27450
|
kitchen: finalGraphKitchen,
|
|
@@ -27600,7 +27480,7 @@ const jsInjector = (urlInfo, {
|
|
|
27600
27480
|
}) => {
|
|
27601
27481
|
const magicSource = createMagicSource(urlInfo.content);
|
|
27602
27482
|
magicSource.prepend(generateClientCodeForVersionMappings(versionMappings, {
|
|
27603
|
-
globalName: urlInfo
|
|
27483
|
+
globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window"
|
|
27604
27484
|
}));
|
|
27605
27485
|
return magicSource.toContentAndSourcemap();
|
|
27606
27486
|
};
|
|
@@ -27706,7 +27586,7 @@ const injectServiceWorkerUrls = async ({
|
|
|
27706
27586
|
lineBreakNormalization
|
|
27707
27587
|
}) => {
|
|
27708
27588
|
const serviceWorkerEntryUrlInfos = GRAPH.filter(finalGraph, finalUrlInfo => {
|
|
27709
|
-
return finalUrlInfo.subtype === "service_worker" && finalUrlInfo.
|
|
27589
|
+
return finalUrlInfo.subtype === "service_worker" && finalUrlInfo.isEntryPoint;
|
|
27710
27590
|
});
|
|
27711
27591
|
|
|
27712
27592
|
if (serviceWorkerEntryUrlInfos.length === 0) {
|
|
@@ -28122,7 +28002,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
28122
28002
|
};
|
|
28123
28003
|
|
|
28124
28004
|
GRAPH.forEach(rawGraph, rawUrlInfo => {
|
|
28125
|
-
if (rawUrlInfo.
|
|
28005
|
+
if (rawUrlInfo.isEntryPoint) {
|
|
28126
28006
|
addToBundlerIfAny(rawUrlInfo);
|
|
28127
28007
|
|
|
28128
28008
|
if (rawUrlInfo.type === "html") {
|
|
@@ -28200,6 +28080,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
28200
28080
|
const bundleUrlInfo = {
|
|
28201
28081
|
type,
|
|
28202
28082
|
subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
|
|
28083
|
+
isEntryPoint: rawUrlInfo ? rawUrlInfo.isEntryPoint : undefined,
|
|
28203
28084
|
filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
|
|
28204
28085
|
originalUrl: rawUrlInfo ? rawUrlInfo.originalUrl : undefined,
|
|
28205
28086
|
originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
|
|
@@ -28337,9 +28218,8 @@ build ${entryPointKeys.length} entry points`);
|
|
|
28337
28218
|
|
|
28338
28219
|
const buildUrl = buildUrlsGenerator.generate(rawUrl, {
|
|
28339
28220
|
urlInfo: {
|
|
28340
|
-
data:
|
|
28341
|
-
|
|
28342
|
-
},
|
|
28221
|
+
data: reference.data,
|
|
28222
|
+
isEntryPoint: reference.isEntryPoint || isWebWorkerEntryPointReference(reference),
|
|
28343
28223
|
type: reference.expectedType,
|
|
28344
28224
|
subtype: reference.expectedSubtype,
|
|
28345
28225
|
filename: reference.filename
|
|
@@ -28631,7 +28511,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`);
|
|
|
28631
28511
|
// nothing uses this url anymore
|
|
28632
28512
|
// - versioning update inline content
|
|
28633
28513
|
// - file converted for import assertion of js_classic conversion
|
|
28634
|
-
if (!urlInfo.
|
|
28514
|
+
if (!urlInfo.isEntryPoint && urlInfo.type !== "sourcemap" && urlInfo.dependents.size === 0) {
|
|
28635
28515
|
cleanupActions.push(() => {
|
|
28636
28516
|
finalGraph.deleteUrlInfo(urlInfo.url);
|
|
28637
28517
|
});
|
|
@@ -28853,7 +28733,7 @@ const applyUrlVersioning = async ({
|
|
|
28853
28733
|
return;
|
|
28854
28734
|
}
|
|
28855
28735
|
|
|
28856
|
-
if (!urlInfo.
|
|
28736
|
+
if (!urlInfo.isEntryPoint && urlInfo.dependents.size === 0) {
|
|
28857
28737
|
return;
|
|
28858
28738
|
}
|
|
28859
28739
|
|
|
@@ -29099,7 +28979,7 @@ const assertEntryPoints = ({
|
|
|
29099
28979
|
};
|
|
29100
28980
|
|
|
29101
28981
|
const canUseVersionedUrl = urlInfo => {
|
|
29102
|
-
if (urlInfo.
|
|
28982
|
+
if (urlInfo.isEntryPoint) {
|
|
29103
28983
|
return false;
|
|
29104
28984
|
}
|
|
29105
28985
|
|
|
@@ -29107,10 +28987,6 @@ const canUseVersionedUrl = urlInfo => {
|
|
|
29107
28987
|
return false;
|
|
29108
28988
|
}
|
|
29109
28989
|
|
|
29110
|
-
if (urlInfo.subtype === "service_worker") {
|
|
29111
|
-
return !urlInfo.data.isWebWorkerEntryPoint;
|
|
29112
|
-
}
|
|
29113
|
-
|
|
29114
28990
|
return true;
|
|
29115
28991
|
};
|
|
29116
28992
|
|
|
@@ -29572,4 +29448,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
29572
29448
|
};
|
|
29573
29449
|
};
|
|
29574
29450
|
|
|
29575
|
-
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals,
|
|
29451
|
+
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|