@jsenv/core 27.7.0 → 28.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/js/server_events_client.js +1 -1
- package/dist/main.js +504 -457
- package/package.json +2 -2
- package/src/build/build.js +4 -5
- package/src/build/start_build_server.js +2 -2
- package/src/dev/start_dev_server.js +3 -3
- package/src/execute/execute.js +14 -52
- package/src/execute/runtimes/browsers/from_playwright.js +19 -8
- package/src/main.js +3 -0
- package/src/omega/kitchen.js +9 -14
- package/src/omega/omega_server.js +4 -4
- package/src/omega/server/file_service.js +11 -11
- package/src/ping_server.js +30 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -1
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +1 -1
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +1 -1
- package/src/plugins/bundling/jsenv_plugin_bundling.js +1 -3
- package/src/plugins/cache_control/jsenv_plugin_cache_control.js +2 -5
- package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -8
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +1 -4
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +2 -2
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +12 -26
- package/src/plugins/importmap/jsenv_plugin_importmap.js +1 -1
- package/src/plugins/minification/jsenv_plugin_minification.js +1 -3
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +9 -7
- package/src/plugins/plugin_controller.js +17 -6
- package/src/plugins/plugins.js +0 -2
- package/src/plugins/server_events/client/server_events_client.js +1 -1
- package/src/plugins/toolbar/jsenv_plugin_toolbar.js +1 -3
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +13 -0
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
- package/src/plugins/url_analysis/html/html_urls.js +2 -2
- package/src/test/execute_plan.js +15 -68
- package/src/test/execute_test_plan.js +4 -26
package/dist/main.js
CHANGED
|
@@ -12,10 +12,10 @@ import { createMagicSource, composeTwoSourcemaps, getOriginalPosition, sourcemap
|
|
|
12
12
|
import { parseHtmlString, stringifyHtmlAst, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, getHtmlNodeText, setHtmlNodeText, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode } from "@jsenv/ast";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import babelParser from "@babel/parser";
|
|
15
|
+
import net, { createServer, isIP } from "node:net";
|
|
15
16
|
import http from "node:http";
|
|
16
17
|
import cluster from "node:cluster";
|
|
17
18
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
18
|
-
import net, { createServer } from "node:net";
|
|
19
19
|
import { Readable, Stream, Writable } from "node:stream";
|
|
20
20
|
import { Http2ServerResponse } from "node:http2";
|
|
21
21
|
import { lookup } from "node:dns";
|
|
@@ -4217,11 +4217,11 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
4217
4217
|
const url = urlInfo.originalUrl;
|
|
4218
4218
|
const content = urlInfo.content;
|
|
4219
4219
|
const {
|
|
4220
|
-
|
|
4220
|
+
scenarios,
|
|
4221
4221
|
referenceUtils
|
|
4222
4222
|
} = context;
|
|
4223
4223
|
const htmlAst = parseHtmlString(content, {
|
|
4224
|
-
storeOriginalPositions:
|
|
4224
|
+
storeOriginalPositions: scenarios.dev
|
|
4225
4225
|
});
|
|
4226
4226
|
const actions = [];
|
|
4227
4227
|
visitHtmlUrls({
|
|
@@ -11464,7 +11464,7 @@ const jsenvPluginImportmap = () => {
|
|
|
11464
11464
|
// Duing build we get rid of it
|
|
11465
11465
|
|
|
11466
11466
|
|
|
11467
|
-
if (context.
|
|
11467
|
+
if (context.scenarios.build) {
|
|
11468
11468
|
removeHtmlNode(importmap);
|
|
11469
11469
|
}
|
|
11470
11470
|
|
|
@@ -12801,13 +12801,8 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
12801
12801
|
return {
|
|
12802
12802
|
name: "jsenv:node_esm_resolution",
|
|
12803
12803
|
appliesDuring: "*",
|
|
12804
|
-
init:
|
|
12805
|
-
|
|
12806
|
-
scenario,
|
|
12807
|
-
runtimeCompat,
|
|
12808
|
-
urlGraph
|
|
12809
|
-
}) => {
|
|
12810
|
-
const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node"); // https://nodejs.org/api/esm.html#resolver-algorithm-specification
|
|
12804
|
+
init: context => {
|
|
12805
|
+
const nodeRuntimeEnabled = Object.keys(context.runtimeCompat).includes("node"); // https://nodejs.org/api/esm.html#resolver-algorithm-specification
|
|
12811
12806
|
|
|
12812
12807
|
packageConditions = packageConditions || [...readCustomConditionsFromProcessArgs(), nodeRuntimeEnabled ? "node" : "browser", "import"];
|
|
12813
12808
|
const packageScopesCache = new Map();
|
|
@@ -12838,19 +12833,19 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
12838
12833
|
return packageJson;
|
|
12839
12834
|
};
|
|
12840
12835
|
|
|
12841
|
-
if (
|
|
12836
|
+
if (context.scenarios.dev) {
|
|
12842
12837
|
const onFileChange = () => {
|
|
12843
12838
|
packageScopesCache.clear();
|
|
12844
12839
|
packageJsonsCache.clear();
|
|
12845
|
-
urlGraph.urlInfoMap.forEach(urlInfo => {
|
|
12840
|
+
context.urlGraph.urlInfoMap.forEach(urlInfo => {
|
|
12846
12841
|
if (urlInfo.dependsOnPackageJson) {
|
|
12847
|
-
urlGraph.considerModified(urlInfo);
|
|
12842
|
+
context.urlGraph.considerModified(urlInfo);
|
|
12848
12843
|
}
|
|
12849
12844
|
});
|
|
12850
12845
|
};
|
|
12851
12846
|
|
|
12852
12847
|
filesInvalidatingCache.forEach(file => {
|
|
12853
|
-
const unregister = registerFileLifecycle(new URL(file, rootDirectoryUrl), {
|
|
12848
|
+
const unregister = registerFileLifecycle(new URL(file, context.rootDirectoryUrl), {
|
|
12854
12849
|
added: () => {
|
|
12855
12850
|
onFileChange();
|
|
12856
12851
|
},
|
|
@@ -12912,7 +12907,7 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
12912
12907
|
return null;
|
|
12913
12908
|
},
|
|
12914
12909
|
transformUrlSearchParams: (reference, context) => {
|
|
12915
|
-
if (context.
|
|
12910
|
+
if (context.scenarios.build) {
|
|
12916
12911
|
return null;
|
|
12917
12912
|
}
|
|
12918
12913
|
|
|
@@ -13091,14 +13086,10 @@ const jsenvPluginFileUrls = ({
|
|
|
13091
13086
|
}
|
|
13092
13087
|
}, {
|
|
13093
13088
|
name: "jsenv:@fs_resolution",
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
test: true,
|
|
13099
|
-
// during build it's fine to use file:// urls
|
|
13100
|
-
build: false
|
|
13101
|
-
},
|
|
13089
|
+
// during dev and test it's a browser running the code
|
|
13090
|
+
// so absolute file urls needs to be relativized
|
|
13091
|
+
// during build it's fine to use file:// urls
|
|
13092
|
+
appliesDuring: "dev",
|
|
13102
13093
|
resolveUrl: reference => {
|
|
13103
13094
|
if (reference.specifier.startsWith("/@fs/")) {
|
|
13104
13095
|
const fsRootRelativeUrl = reference.specifier.slice("/@fs/".length);
|
|
@@ -13197,10 +13188,7 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
13197
13188
|
const htmlSupervisorInstallerFileUrl = new URL("./js/html_supervisor_installer.js", import.meta.url).href;
|
|
13198
13189
|
return {
|
|
13199
13190
|
name: "jsenv:html_supervisor",
|
|
13200
|
-
appliesDuring:
|
|
13201
|
-
dev: true,
|
|
13202
|
-
test: true
|
|
13203
|
-
},
|
|
13191
|
+
appliesDuring: "dev",
|
|
13204
13192
|
serve: async (request, context) => {
|
|
13205
13193
|
if (request.ressource.startsWith("/__get_code_frame__/")) {
|
|
13206
13194
|
const {
|
|
@@ -13569,16 +13557,14 @@ const generateCodeToSuperviseScript = ({
|
|
|
13569
13557
|
* - global
|
|
13570
13558
|
*/
|
|
13571
13559
|
const jsenvPluginCommonJsGlobals = () => {
|
|
13572
|
-
const transformCommonJsGlobals = async (urlInfo, {
|
|
13573
|
-
scenario
|
|
13574
|
-
}) => {
|
|
13560
|
+
const transformCommonJsGlobals = async (urlInfo, context) => {
|
|
13575
13561
|
if (!urlInfo.content.includes("process.env.NODE_ENV") && !urlInfo.content.includes("__filename") && !urlInfo.content.includes("__dirname")) {
|
|
13576
13562
|
return null;
|
|
13577
13563
|
}
|
|
13578
13564
|
|
|
13579
13565
|
const isJsModule = urlInfo.type === "js_module";
|
|
13580
13566
|
const replaceMap = {
|
|
13581
|
-
"process.env.NODE_ENV": `("${
|
|
13567
|
+
"process.env.NODE_ENV": `("${context.scenarios.dev ? "development" : "production"}")`,
|
|
13582
13568
|
"global": "globalThis",
|
|
13583
13569
|
"__filename": isJsModule ? `import.meta.url.slice('file:///'.length)` : `document.currentScript.src`,
|
|
13584
13570
|
"__dirname": isJsModule ? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')` : `new URL('./', document.currentScript.src).href`
|
|
@@ -13732,11 +13718,10 @@ const babelPluginMetadataExpressionPaths = (babel, {
|
|
|
13732
13718
|
/*
|
|
13733
13719
|
* Source code can contain the following
|
|
13734
13720
|
* - import.meta.dev
|
|
13735
|
-
* - import.meta.test
|
|
13736
13721
|
* - import.meta.build
|
|
13737
13722
|
* They are either:
|
|
13738
13723
|
* - replaced by true: When scenario matches (import.meta.dev and it's the dev server)
|
|
13739
|
-
* - left as is to be evaluated to undefined (import.meta.
|
|
13724
|
+
* - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
|
|
13740
13725
|
* - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
|
|
13741
13726
|
*/
|
|
13742
13727
|
const jsenvPluginImportMetaScenarios = () => {
|
|
@@ -13744,9 +13729,7 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13744
13729
|
name: "jsenv:import_meta_scenario",
|
|
13745
13730
|
appliesDuring: "*",
|
|
13746
13731
|
transformUrlContent: {
|
|
13747
|
-
js_module: async (urlInfo, {
|
|
13748
|
-
scenario
|
|
13749
|
-
}) => {
|
|
13732
|
+
js_module: async (urlInfo, context) => {
|
|
13750
13733
|
if (!urlInfo.content.includes("import.meta.dev") && !urlInfo.content.includes("import.meta.test") && !urlInfo.content.includes("import.meta.build")) {
|
|
13751
13734
|
return null;
|
|
13752
13735
|
}
|
|
@@ -13759,7 +13742,6 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13759
13742
|
});
|
|
13760
13743
|
const {
|
|
13761
13744
|
dev = [],
|
|
13762
|
-
test = [],
|
|
13763
13745
|
build = []
|
|
13764
13746
|
} = metadata.importMetaScenarios;
|
|
13765
13747
|
const replacements = [];
|
|
@@ -13771,32 +13753,20 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
13771
13753
|
});
|
|
13772
13754
|
};
|
|
13773
13755
|
|
|
13774
|
-
if (
|
|
13756
|
+
if (context.scenarios.build) {
|
|
13757
|
+
// during build ensure replacement for tree-shaking
|
|
13775
13758
|
dev.forEach(path => {
|
|
13776
|
-
replace(path, "
|
|
13777
|
-
});
|
|
13778
|
-
} else if (scenario === "test") {
|
|
13779
|
-
// test is also considered a dev environment
|
|
13780
|
-
// just like the dev server can be used to debug test files
|
|
13781
|
-
// without this people would have to write
|
|
13782
|
-
// if (import.meta.dev || import.meta.test) or if (!import.meta.build)
|
|
13783
|
-
dev.forEach(path => {
|
|
13784
|
-
replace(path, "true");
|
|
13759
|
+
replace(path, "undefined");
|
|
13785
13760
|
});
|
|
13786
|
-
|
|
13761
|
+
build.forEach(path => {
|
|
13787
13762
|
replace(path, "true");
|
|
13788
13763
|
});
|
|
13789
|
-
} else
|
|
13790
|
-
//
|
|
13791
|
-
//
|
|
13792
|
-
//
|
|
13764
|
+
} else {
|
|
13765
|
+
// during dev we can let "import.meta.build" untouched
|
|
13766
|
+
// it will be evaluated to undefined.
|
|
13767
|
+
// Moreover it can be surprising to see some "undefined"
|
|
13768
|
+
// when source file contains "import.meta.build"
|
|
13793
13769
|
dev.forEach(path => {
|
|
13794
|
-
replace(path, "undefined");
|
|
13795
|
-
});
|
|
13796
|
-
test.forEach(path => {
|
|
13797
|
-
replace(path, "undefined");
|
|
13798
|
-
});
|
|
13799
|
-
build.forEach(path => {
|
|
13800
13770
|
replace(path, "true");
|
|
13801
13771
|
});
|
|
13802
13772
|
}
|
|
@@ -13863,7 +13833,6 @@ const babelPluginMetadataImportMetaScenarios = () => {
|
|
|
13863
13833
|
});
|
|
13864
13834
|
state.file.metadata.importMetaScenarios = {
|
|
13865
13835
|
dev: importMetas.dev,
|
|
13866
|
-
test: importMetas.test,
|
|
13867
13836
|
build: importMetas.build
|
|
13868
13837
|
};
|
|
13869
13838
|
}
|
|
@@ -13933,7 +13902,7 @@ const jsenvPluginImportAssertions = ({
|
|
|
13933
13902
|
// We would have to tell rollup to ignore import with assertion
|
|
13934
13903
|
// - means rollup can bundle more js file together
|
|
13935
13904
|
// - means url versioning can work for css inlined in js
|
|
13936
|
-
if (context.
|
|
13905
|
+
if (context.scenarios.build) {
|
|
13937
13906
|
json = true;
|
|
13938
13907
|
css = true;
|
|
13939
13908
|
text = true;
|
|
@@ -14083,6 +14052,87 @@ export default inlineContent.text`,
|
|
|
14083
14052
|
return [asJsonModule, asCssModule, asTextModule];
|
|
14084
14053
|
};
|
|
14085
14054
|
|
|
14055
|
+
const babelPluginInstrument = (api, {
|
|
14056
|
+
rootDirectoryUrl,
|
|
14057
|
+
useInlineSourceMaps = false,
|
|
14058
|
+
coverageConfig = {
|
|
14059
|
+
"./**/*": true
|
|
14060
|
+
}
|
|
14061
|
+
}) => {
|
|
14062
|
+
const {
|
|
14063
|
+
programVisitor
|
|
14064
|
+
} = requireFromJsenv("istanbul-lib-instrument");
|
|
14065
|
+
const {
|
|
14066
|
+
types
|
|
14067
|
+
} = api;
|
|
14068
|
+
const associations = URL_META.resolveAssociations({
|
|
14069
|
+
cover: coverageConfig
|
|
14070
|
+
}, rootDirectoryUrl);
|
|
14071
|
+
|
|
14072
|
+
const shouldInstrument = url => {
|
|
14073
|
+
return URL_META.applyAssociations({
|
|
14074
|
+
url,
|
|
14075
|
+
associations
|
|
14076
|
+
}).cover;
|
|
14077
|
+
};
|
|
14078
|
+
|
|
14079
|
+
return {
|
|
14080
|
+
name: "transform-instrument",
|
|
14081
|
+
visitor: {
|
|
14082
|
+
Program: {
|
|
14083
|
+
enter(path) {
|
|
14084
|
+
const {
|
|
14085
|
+
file
|
|
14086
|
+
} = this;
|
|
14087
|
+
const {
|
|
14088
|
+
opts
|
|
14089
|
+
} = file;
|
|
14090
|
+
|
|
14091
|
+
if (!opts.sourceFileName) {
|
|
14092
|
+
console.warn(`cannot instrument file when "sourceFileName" option is not set`);
|
|
14093
|
+
return;
|
|
14094
|
+
}
|
|
14095
|
+
|
|
14096
|
+
const fileUrl = fileSystemPathToUrl$1(opts.sourceFileName);
|
|
14097
|
+
|
|
14098
|
+
if (!shouldInstrument(fileUrl)) {
|
|
14099
|
+
return;
|
|
14100
|
+
}
|
|
14101
|
+
|
|
14102
|
+
this.__dv__ = null;
|
|
14103
|
+
let inputSourceMap;
|
|
14104
|
+
|
|
14105
|
+
if (useInlineSourceMaps) {
|
|
14106
|
+
// https://github.com/istanbuljs/babel-plugin-istanbul/commit/a9e15643d249a2985e4387e4308022053b2cd0ad#diff-1fdf421c05c1140f6d71444ea2b27638R65
|
|
14107
|
+
inputSourceMap = opts.inputSourceMap || file.inputMap ? file.inputMap.sourcemap : null;
|
|
14108
|
+
} else {
|
|
14109
|
+
inputSourceMap = opts.inputSourceMap;
|
|
14110
|
+
}
|
|
14111
|
+
|
|
14112
|
+
this.__dv__ = programVisitor(types, opts.filenameRelative || opts.filename, {
|
|
14113
|
+
coverageVariable: "__coverage__",
|
|
14114
|
+
inputSourceMap
|
|
14115
|
+
});
|
|
14116
|
+
|
|
14117
|
+
this.__dv__.enter(path);
|
|
14118
|
+
},
|
|
14119
|
+
|
|
14120
|
+
exit(path) {
|
|
14121
|
+
if (!this.__dv__) {
|
|
14122
|
+
return;
|
|
14123
|
+
}
|
|
14124
|
+
|
|
14125
|
+
const object = this.__dv__.exit(path); // object got two properties: fileCoverage and sourceMappingURL
|
|
14126
|
+
|
|
14127
|
+
|
|
14128
|
+
this.file.metadata.coverage = object.fileCoverage;
|
|
14129
|
+
}
|
|
14130
|
+
|
|
14131
|
+
}
|
|
14132
|
+
}
|
|
14133
|
+
};
|
|
14134
|
+
};
|
|
14135
|
+
|
|
14086
14136
|
const versionFromValue = value => {
|
|
14087
14137
|
if (typeof value === "number") {
|
|
14088
14138
|
return numberToVersion(value);
|
|
@@ -15264,6 +15314,17 @@ const jsenvPluginBabel = ({
|
|
|
15264
15314
|
getImportSpecifier
|
|
15265
15315
|
});
|
|
15266
15316
|
|
|
15317
|
+
if (context.scenarios.dev) {
|
|
15318
|
+
const requestHeaders = context.request.headers;
|
|
15319
|
+
|
|
15320
|
+
if (requestHeaders["x-coverage-instanbul"]) {
|
|
15321
|
+
babelPluginStructure["transform-instrument"] = [babelPluginInstrument, {
|
|
15322
|
+
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
15323
|
+
coverageConfig: JSON.parse(requestHeaders["x-coverage-instanbul"])
|
|
15324
|
+
}];
|
|
15325
|
+
}
|
|
15326
|
+
}
|
|
15327
|
+
|
|
15267
15328
|
if (getCustomBabelPlugins) {
|
|
15268
15329
|
Object.assign(babelPluginStructure, getCustomBabelPlugins(context));
|
|
15269
15330
|
}
|
|
@@ -16034,9 +16095,7 @@ const jsenvPluginBundling = bundling => {
|
|
|
16034
16095
|
});
|
|
16035
16096
|
return {
|
|
16036
16097
|
name: "jsenv:bundling",
|
|
16037
|
-
appliesDuring:
|
|
16038
|
-
build: true
|
|
16039
|
-
},
|
|
16098
|
+
appliesDuring: "build",
|
|
16040
16099
|
bundle: {
|
|
16041
16100
|
css: bundling.css ? (cssUrlInfos, context) => {
|
|
16042
16101
|
return bundleCss({
|
|
@@ -16172,9 +16231,7 @@ const jsenvPluginMinification = minification => {
|
|
|
16172
16231
|
}) : null;
|
|
16173
16232
|
return {
|
|
16174
16233
|
name: "jsenv:minification",
|
|
16175
|
-
appliesDuring:
|
|
16176
|
-
build: true
|
|
16177
|
-
},
|
|
16234
|
+
appliesDuring: "build",
|
|
16178
16235
|
optimizeUrlContent: {
|
|
16179
16236
|
html: htmlOptimizer,
|
|
16180
16237
|
svg: htmlOptimizer,
|
|
@@ -16494,7 +16551,7 @@ const jsenvPluginImportMetaHot = () => {
|
|
|
16494
16551
|
transformUrlContent: {
|
|
16495
16552
|
html: (htmlUrlInfo, context) => {
|
|
16496
16553
|
// during build we don't really care to parse html hot dependencies
|
|
16497
|
-
if (context.
|
|
16554
|
+
if (context.scenarios.build) {
|
|
16498
16555
|
return;
|
|
16499
16556
|
}
|
|
16500
16557
|
|
|
@@ -16543,7 +16600,7 @@ const jsenvPluginImportMetaHot = () => {
|
|
|
16543
16600
|
return null;
|
|
16544
16601
|
}
|
|
16545
16602
|
|
|
16546
|
-
if (context.
|
|
16603
|
+
if (context.scenarios.build) {
|
|
16547
16604
|
return removeImportMetaHots(urlInfo, importMetaHotPaths);
|
|
16548
16605
|
}
|
|
16549
16606
|
|
|
@@ -16587,7 +16644,8 @@ const jsenvPluginHmr = () => {
|
|
|
16587
16644
|
return {
|
|
16588
16645
|
name: "jsenv:hmr",
|
|
16589
16646
|
appliesDuring: {
|
|
16590
|
-
dev: true
|
|
16647
|
+
dev: true,
|
|
16648
|
+
test: false
|
|
16591
16649
|
},
|
|
16592
16650
|
redirectUrl: reference => {
|
|
16593
16651
|
const urlObject = new URL(reference.url);
|
|
@@ -16632,7 +16690,8 @@ const jsenvPluginAutoreloadClient = () => {
|
|
|
16632
16690
|
return {
|
|
16633
16691
|
name: "jsenv:autoreload_client",
|
|
16634
16692
|
appliesDuring: {
|
|
16635
|
-
dev: true
|
|
16693
|
+
dev: true,
|
|
16694
|
+
test: false
|
|
16636
16695
|
},
|
|
16637
16696
|
transformUrlContent: {
|
|
16638
16697
|
html: (htmlUrlInfo, context) => {
|
|
@@ -16664,7 +16723,8 @@ const jsenvPluginAutoreloadServer = ({
|
|
|
16664
16723
|
return {
|
|
16665
16724
|
name: "jsenv:autoreload_server",
|
|
16666
16725
|
appliesDuring: {
|
|
16667
|
-
dev: true
|
|
16726
|
+
dev: true,
|
|
16727
|
+
test: false
|
|
16668
16728
|
},
|
|
16669
16729
|
serverEvents: {
|
|
16670
16730
|
reload: ({
|
|
@@ -16892,14 +16952,9 @@ const jsenvPluginAutoreloadServer = ({
|
|
|
16892
16952
|
};
|
|
16893
16953
|
|
|
16894
16954
|
const jsenvPluginAutoreload = ({
|
|
16895
|
-
scenario,
|
|
16896
16955
|
clientFileChangeCallbackList,
|
|
16897
16956
|
clientFilesPruneCallbackList
|
|
16898
16957
|
}) => {
|
|
16899
|
-
if (scenario === "build") {
|
|
16900
|
-
return [];
|
|
16901
|
-
}
|
|
16902
|
-
|
|
16903
16958
|
return [jsenvPluginHmr(), jsenvPluginAutoreloadClient(), jsenvPluginAutoreloadServer({
|
|
16904
16959
|
clientFileChangeCallbackList,
|
|
16905
16960
|
clientFilesPruneCallbackList
|
|
@@ -16909,14 +16964,11 @@ const jsenvPluginAutoreload = ({
|
|
|
16909
16964
|
const jsenvPluginCacheControl = () => {
|
|
16910
16965
|
return {
|
|
16911
16966
|
name: "jsenv:cache_control",
|
|
16912
|
-
appliesDuring:
|
|
16913
|
-
dev: true,
|
|
16914
|
-
test: true
|
|
16915
|
-
},
|
|
16967
|
+
appliesDuring: "dev",
|
|
16916
16968
|
augmentResponse: ({
|
|
16917
16969
|
reference
|
|
16918
16970
|
}, context) => {
|
|
16919
|
-
if (context.
|
|
16971
|
+
if (context.scenarios.test) {
|
|
16920
16972
|
// During dev, all files are put into browser cache for 1 hour because:
|
|
16921
16973
|
// 1: Browser cache is a temporary directory created by playwright
|
|
16922
16974
|
// 2: We assume source files won't be modified while tests are running
|
|
@@ -17003,7 +17055,6 @@ const jsenvPluginExplorer = ({
|
|
|
17003
17055
|
|
|
17004
17056
|
const getCorePlugins = ({
|
|
17005
17057
|
rootDirectoryUrl,
|
|
17006
|
-
scenario,
|
|
17007
17058
|
runtimeCompat,
|
|
17008
17059
|
urlAnalysis = {},
|
|
17009
17060
|
htmlSupervisor,
|
|
@@ -17048,7 +17099,6 @@ const getCorePlugins = ({
|
|
|
17048
17099
|
jsenvPluginNodeEsmResolution(nodeEsmResolution), jsenvPluginUrlResolution(), jsenvPluginUrlVersion(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginNodeRuntime({
|
|
17049
17100
|
runtimeCompat
|
|
17050
17101
|
}), jsenvPluginBundling(bundling), jsenvPluginMinification(minification), jsenvPluginImportMetaHot(), ...(clientAutoreload ? [jsenvPluginAutoreload({ ...clientAutoreload,
|
|
17051
|
-
scenario,
|
|
17052
17102
|
clientFileChangeCallbackList,
|
|
17053
17103
|
clientFilesPruneCallbackList
|
|
17054
17104
|
})] : []), jsenvPluginCacheControl(), ...(explorer ? [jsenvPluginExplorer(explorer)] : [])];
|
|
@@ -18399,101 +18449,12 @@ const statusIsClientError = status => status >= 400 && status < 500;
|
|
|
18399
18449
|
|
|
18400
18450
|
const statusIsServerError = status => status >= 500 && status < 600;
|
|
18401
18451
|
|
|
18402
|
-
const applyDnsResolution = async (hostname, {
|
|
18403
|
-
verbatim = false
|
|
18404
|
-
} = {}) => {
|
|
18405
|
-
const dnsResolution = await new Promise((resolve, reject) => {
|
|
18406
|
-
lookup(hostname, {
|
|
18407
|
-
verbatim
|
|
18408
|
-
}, (error, address, family) => {
|
|
18409
|
-
if (error) {
|
|
18410
|
-
reject(error);
|
|
18411
|
-
} else {
|
|
18412
|
-
resolve({
|
|
18413
|
-
address,
|
|
18414
|
-
family
|
|
18415
|
-
});
|
|
18416
|
-
}
|
|
18417
|
-
});
|
|
18418
|
-
});
|
|
18419
|
-
return dnsResolution;
|
|
18420
|
-
};
|
|
18421
|
-
|
|
18422
|
-
const getServerOrigins = async ({
|
|
18423
|
-
protocol,
|
|
18424
|
-
host,
|
|
18425
|
-
port
|
|
18426
|
-
}) => {
|
|
18427
|
-
const isLocal = LOOPBACK_HOSTNAMES.includes(host);
|
|
18428
|
-
const localhostDnsResolution = await applyDnsResolution("localhost");
|
|
18429
|
-
const localOrigin = createServerOrigin({
|
|
18430
|
-
protocol,
|
|
18431
|
-
hostname: localhostDnsResolution.address === "127.0.0.1" ? "localhost" : "127.0.0.1",
|
|
18432
|
-
port
|
|
18433
|
-
});
|
|
18434
|
-
|
|
18435
|
-
if (isLocal) {
|
|
18436
|
-
return {
|
|
18437
|
-
local: localOrigin
|
|
18438
|
-
};
|
|
18439
|
-
}
|
|
18440
|
-
|
|
18441
|
-
const isAnyIp = WILDCARD_HOSTNAMES.includes(host);
|
|
18442
|
-
const networkOrigin = createServerOrigin({
|
|
18443
|
-
protocol,
|
|
18444
|
-
hostname: isAnyIp ? getExternalIp() : host,
|
|
18445
|
-
port
|
|
18446
|
-
});
|
|
18447
|
-
return {
|
|
18448
|
-
local: localOrigin,
|
|
18449
|
-
network: networkOrigin
|
|
18450
|
-
};
|
|
18451
|
-
};
|
|
18452
|
-
const LOOPBACK_HOSTNAMES = ["localhost", "127.0.0.1", "::1", "0000:0000:0000:0000:0000:0000:0000:0001"];
|
|
18453
|
-
const WILDCARD_HOSTNAMES = [undefined, "0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"];
|
|
18454
|
-
|
|
18455
|
-
const createServerOrigin = ({
|
|
18456
|
-
protocol,
|
|
18457
|
-
hostname,
|
|
18458
|
-
port
|
|
18459
|
-
}) => {
|
|
18460
|
-
const url = new URL("https://127.0.0.1:80");
|
|
18461
|
-
url.protocol = protocol;
|
|
18462
|
-
url.hostname = hostname;
|
|
18463
|
-
url.port = port;
|
|
18464
|
-
return url.origin;
|
|
18465
|
-
};
|
|
18466
|
-
|
|
18467
|
-
const getExternalIp = () => {
|
|
18468
|
-
const networkInterfaceMap = networkInterfaces();
|
|
18469
|
-
let internalIPV4NetworkAddress;
|
|
18470
|
-
Object.keys(networkInterfaceMap).find(key => {
|
|
18471
|
-
const networkAddressArray = networkInterfaceMap[key];
|
|
18472
|
-
return networkAddressArray.find(networkAddress => {
|
|
18473
|
-
if (networkAddress.internal) return false;
|
|
18474
|
-
if (!isIpV4(networkAddress)) return false;
|
|
18475
|
-
internalIPV4NetworkAddress = networkAddress;
|
|
18476
|
-
return true;
|
|
18477
|
-
});
|
|
18478
|
-
});
|
|
18479
|
-
return internalIPV4NetworkAddress ? internalIPV4NetworkAddress.address : null;
|
|
18480
|
-
};
|
|
18481
|
-
|
|
18482
|
-
const isIpV4 = networkAddress => {
|
|
18483
|
-
// node 18+
|
|
18484
|
-
if (typeof networkAddress.family === "number") {
|
|
18485
|
-
return networkAddress.family === 4;
|
|
18486
|
-
}
|
|
18487
|
-
|
|
18488
|
-
return networkAddress.family === "IPv4";
|
|
18489
|
-
};
|
|
18490
|
-
|
|
18491
18452
|
const listen = async ({
|
|
18492
18453
|
signal = new AbortController().signal,
|
|
18493
18454
|
server,
|
|
18494
18455
|
port,
|
|
18495
18456
|
portHint,
|
|
18496
|
-
|
|
18457
|
+
hostname
|
|
18497
18458
|
}) => {
|
|
18498
18459
|
const listeningOperation = Abort.startOperation();
|
|
18499
18460
|
|
|
@@ -18504,7 +18465,7 @@ const listen = async ({
|
|
|
18504
18465
|
listeningOperation.throwIfAborted();
|
|
18505
18466
|
port = await findFreePort(portHint, {
|
|
18506
18467
|
signal: listeningOperation.signal,
|
|
18507
|
-
|
|
18468
|
+
hostname
|
|
18508
18469
|
});
|
|
18509
18470
|
}
|
|
18510
18471
|
|
|
@@ -18512,7 +18473,7 @@ const listen = async ({
|
|
|
18512
18473
|
port = await startListening({
|
|
18513
18474
|
server,
|
|
18514
18475
|
port,
|
|
18515
|
-
|
|
18476
|
+
hostname
|
|
18516
18477
|
});
|
|
18517
18478
|
listeningOperation.addAbortCallback(() => stopListening(server));
|
|
18518
18479
|
listeningOperation.throwIfAborted();
|
|
@@ -18524,7 +18485,7 @@ const listen = async ({
|
|
|
18524
18485
|
|
|
18525
18486
|
const findFreePort = async (initialPort = 1, {
|
|
18526
18487
|
signal = new AbortController().signal,
|
|
18527
|
-
|
|
18488
|
+
hostname = "127.0.0.1",
|
|
18528
18489
|
min = 1,
|
|
18529
18490
|
max = 65534,
|
|
18530
18491
|
next = port => port + 1
|
|
@@ -18546,27 +18507,27 @@ const findFreePort = async (initialPort = 1, {
|
|
|
18546
18507
|
const nextPort = next(port);
|
|
18547
18508
|
|
|
18548
18509
|
if (nextPort > max) {
|
|
18549
|
-
throw new Error(`${
|
|
18510
|
+
throw new Error(`${hostname} has no available port between ${min} and ${max}`);
|
|
18550
18511
|
}
|
|
18551
18512
|
|
|
18552
|
-
return testUntil(nextPort,
|
|
18513
|
+
return testUntil(nextPort, hostname);
|
|
18553
18514
|
};
|
|
18554
18515
|
|
|
18555
|
-
const freePort = await testUntil(initialPort,
|
|
18516
|
+
const freePort = await testUntil(initialPort, hostname);
|
|
18556
18517
|
return freePort;
|
|
18557
18518
|
} finally {
|
|
18558
18519
|
await findFreePortOperation.end();
|
|
18559
18520
|
}
|
|
18560
18521
|
};
|
|
18561
18522
|
|
|
18562
|
-
const portIsFree = async (port,
|
|
18523
|
+
const portIsFree = async (port, hostname) => {
|
|
18563
18524
|
const server = createServer();
|
|
18564
18525
|
|
|
18565
18526
|
try {
|
|
18566
18527
|
await startListening({
|
|
18567
18528
|
server,
|
|
18568
18529
|
port,
|
|
18569
|
-
|
|
18530
|
+
hostname
|
|
18570
18531
|
});
|
|
18571
18532
|
} catch (error) {
|
|
18572
18533
|
if (error && error.code === "EADDRINUSE") {
|
|
@@ -18587,7 +18548,7 @@ const portIsFree = async (port, host) => {
|
|
|
18587
18548
|
const startListening = ({
|
|
18588
18549
|
server,
|
|
18589
18550
|
port,
|
|
18590
|
-
|
|
18551
|
+
hostname
|
|
18591
18552
|
}) => {
|
|
18592
18553
|
return new Promise((resolve, reject) => {
|
|
18593
18554
|
server.on("error", reject);
|
|
@@ -18596,7 +18557,7 @@ const startListening = ({
|
|
|
18596
18557
|
// https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback
|
|
18597
18558
|
resolve(server.address().port);
|
|
18598
18559
|
});
|
|
18599
|
-
server.listen(port,
|
|
18560
|
+
server.listen(port, hostname);
|
|
18600
18561
|
});
|
|
18601
18562
|
};
|
|
18602
18563
|
|
|
@@ -18835,6 +18796,134 @@ const STOP_REASON_PROCESS_BEFORE_EXIT = createReason("process before exit");
|
|
|
18835
18796
|
const STOP_REASON_PROCESS_EXIT = createReason("process exit");
|
|
18836
18797
|
const STOP_REASON_NOT_SPECIFIED = createReason("not specified");
|
|
18837
18798
|
|
|
18799
|
+
const createIpGetters = () => {
|
|
18800
|
+
const networkAddresses = [];
|
|
18801
|
+
const networkInterfaceMap = networkInterfaces();
|
|
18802
|
+
|
|
18803
|
+
for (const key of Object.keys(networkInterfaceMap)) {
|
|
18804
|
+
for (const networkAddress of networkInterfaceMap[key]) {
|
|
18805
|
+
networkAddresses.push(networkAddress);
|
|
18806
|
+
}
|
|
18807
|
+
}
|
|
18808
|
+
|
|
18809
|
+
return {
|
|
18810
|
+
getFirstInternalIp: ({
|
|
18811
|
+
preferIpv6
|
|
18812
|
+
}) => {
|
|
18813
|
+
const isPref = preferIpv6 ? isIpV6 : isIpV4;
|
|
18814
|
+
let firstInternalIp;
|
|
18815
|
+
|
|
18816
|
+
for (const networkAddress of networkAddresses) {
|
|
18817
|
+
if (networkAddress.internal) {
|
|
18818
|
+
firstInternalIp = networkAddress.address;
|
|
18819
|
+
|
|
18820
|
+
if (isPref(networkAddress)) {
|
|
18821
|
+
break;
|
|
18822
|
+
}
|
|
18823
|
+
}
|
|
18824
|
+
}
|
|
18825
|
+
|
|
18826
|
+
return firstInternalIp;
|
|
18827
|
+
},
|
|
18828
|
+
getFirstExternalIp: ({
|
|
18829
|
+
preferIpv6
|
|
18830
|
+
}) => {
|
|
18831
|
+
const isPref = preferIpv6 ? isIpV6 : isIpV4;
|
|
18832
|
+
let firstExternalIp;
|
|
18833
|
+
|
|
18834
|
+
for (const networkAddress of networkAddresses) {
|
|
18835
|
+
if (!networkAddress.internal) {
|
|
18836
|
+
firstExternalIp = networkAddress.address;
|
|
18837
|
+
|
|
18838
|
+
if (isPref(networkAddress)) {
|
|
18839
|
+
break;
|
|
18840
|
+
}
|
|
18841
|
+
}
|
|
18842
|
+
}
|
|
18843
|
+
|
|
18844
|
+
return firstExternalIp;
|
|
18845
|
+
}
|
|
18846
|
+
};
|
|
18847
|
+
};
|
|
18848
|
+
|
|
18849
|
+
const isIpV4 = networkAddress => {
|
|
18850
|
+
// node 18.5
|
|
18851
|
+
if (typeof networkAddress.family === "number") {
|
|
18852
|
+
return networkAddress.family === 4;
|
|
18853
|
+
}
|
|
18854
|
+
|
|
18855
|
+
return networkAddress.family === "IPv4";
|
|
18856
|
+
};
|
|
18857
|
+
|
|
18858
|
+
const isIpV6 = networkAddress => !isIpV4(networkAddress);
|
|
18859
|
+
|
|
18860
|
+
const parseHostname = hostname => {
|
|
18861
|
+
if (hostname === "0.0.0.0") {
|
|
18862
|
+
return {
|
|
18863
|
+
type: "ip",
|
|
18864
|
+
label: "unspecified",
|
|
18865
|
+
version: 4
|
|
18866
|
+
};
|
|
18867
|
+
}
|
|
18868
|
+
|
|
18869
|
+
if (hostname === "::" || hostname === "0000:0000:0000:0000:0000:0000:0000:0000") {
|
|
18870
|
+
return {
|
|
18871
|
+
type: "ip",
|
|
18872
|
+
label: "unspecified",
|
|
18873
|
+
version: 6
|
|
18874
|
+
};
|
|
18875
|
+
}
|
|
18876
|
+
|
|
18877
|
+
if (hostname === "127.0.0.1") {
|
|
18878
|
+
return {
|
|
18879
|
+
type: "ip",
|
|
18880
|
+
label: "loopback",
|
|
18881
|
+
version: 4
|
|
18882
|
+
};
|
|
18883
|
+
}
|
|
18884
|
+
|
|
18885
|
+
if (hostname === "::1" || hostname === "0000:0000:0000:0000:0000:0000:0000:0001") {
|
|
18886
|
+
return {
|
|
18887
|
+
type: "ip",
|
|
18888
|
+
label: "loopback",
|
|
18889
|
+
version: 6
|
|
18890
|
+
};
|
|
18891
|
+
}
|
|
18892
|
+
|
|
18893
|
+
const ipVersion = isIP(hostname);
|
|
18894
|
+
|
|
18895
|
+
if (ipVersion === 0) {
|
|
18896
|
+
return {
|
|
18897
|
+
type: "hostname"
|
|
18898
|
+
};
|
|
18899
|
+
}
|
|
18900
|
+
|
|
18901
|
+
return {
|
|
18902
|
+
type: "ip",
|
|
18903
|
+
version: ipVersion
|
|
18904
|
+
};
|
|
18905
|
+
};
|
|
18906
|
+
|
|
18907
|
+
const applyDnsResolution = async (hostname, {
|
|
18908
|
+
verbatim = false
|
|
18909
|
+
} = {}) => {
|
|
18910
|
+
const dnsResolution = await new Promise((resolve, reject) => {
|
|
18911
|
+
lookup(hostname, {
|
|
18912
|
+
verbatim
|
|
18913
|
+
}, (error, address, family) => {
|
|
18914
|
+
if (error) {
|
|
18915
|
+
reject(error);
|
|
18916
|
+
} else {
|
|
18917
|
+
resolve({
|
|
18918
|
+
address,
|
|
18919
|
+
family
|
|
18920
|
+
});
|
|
18921
|
+
}
|
|
18922
|
+
});
|
|
18923
|
+
});
|
|
18924
|
+
return dnsResolution;
|
|
18925
|
+
};
|
|
18926
|
+
|
|
18838
18927
|
const startServer = async ({
|
|
18839
18928
|
signal = new AbortController().signal,
|
|
18840
18929
|
logLevel,
|
|
@@ -18846,7 +18935,8 @@ const startServer = async ({
|
|
|
18846
18935
|
redirectHttpToHttps,
|
|
18847
18936
|
allowHttpRequestOnHttps = false,
|
|
18848
18937
|
acceptAnyIp = false,
|
|
18849
|
-
|
|
18938
|
+
preferIpv6,
|
|
18939
|
+
hostname = "localhost",
|
|
18850
18940
|
port = 0,
|
|
18851
18941
|
// assign a random available port
|
|
18852
18942
|
portHint,
|
|
@@ -18876,6 +18966,10 @@ const startServer = async ({
|
|
|
18876
18966
|
}));
|
|
18877
18967
|
}
|
|
18878
18968
|
} = {}) => {
|
|
18969
|
+
const logger = createLogger({
|
|
18970
|
+
logLevel
|
|
18971
|
+
});
|
|
18972
|
+
|
|
18879
18973
|
if (protocol !== "http" && protocol !== "https") {
|
|
18880
18974
|
throw new Error(`protocol must be http or https, got ${protocol}`);
|
|
18881
18975
|
}
|
|
@@ -18894,10 +18988,6 @@ const startServer = async ({
|
|
|
18894
18988
|
throw new Error(`http2 needs "https" but protocol is "${protocol}"`);
|
|
18895
18989
|
}
|
|
18896
18990
|
|
|
18897
|
-
const logger = createLogger({
|
|
18898
|
-
logLevel
|
|
18899
|
-
});
|
|
18900
|
-
|
|
18901
18991
|
if (redirectHttpToHttps === undefined && protocol === "https" && !allowHttpRequestOnHttps) {
|
|
18902
18992
|
redirectHttpToHttps = true;
|
|
18903
18993
|
}
|
|
@@ -18930,6 +19020,10 @@ const startServer = async ({
|
|
|
18930
19020
|
let nodeServer;
|
|
18931
19021
|
const startServerOperation = Abort.startOperation();
|
|
18932
19022
|
const stopCallbackList = createCallbackListNotifiedOnce();
|
|
19023
|
+
const serverOrigins = {
|
|
19024
|
+
local: "" // favors hostname when possible
|
|
19025
|
+
|
|
19026
|
+
};
|
|
18933
19027
|
|
|
18934
19028
|
try {
|
|
18935
19029
|
startServerOperation.addAbortSignal(signal);
|
|
@@ -18957,12 +19051,85 @@ const startServer = async ({
|
|
|
18957
19051
|
nodeServer.unref();
|
|
18958
19052
|
}
|
|
18959
19053
|
|
|
19054
|
+
const createOrigin = hostname => {
|
|
19055
|
+
if (isIP(hostname) === 6) {
|
|
19056
|
+
return `${protocol}://[${hostname}]`;
|
|
19057
|
+
}
|
|
19058
|
+
|
|
19059
|
+
return `${protocol}://${hostname}`;
|
|
19060
|
+
};
|
|
19061
|
+
|
|
19062
|
+
const ipGetters = createIpGetters();
|
|
19063
|
+
let hostnameToListen;
|
|
19064
|
+
|
|
19065
|
+
if (acceptAnyIp) {
|
|
19066
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19067
|
+
preferIpv6
|
|
19068
|
+
});
|
|
19069
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19070
|
+
serverOrigins.localip = createOrigin(firstInternalIp);
|
|
19071
|
+
const firstExternalIp = ipGetters.getFirstExternalIp({
|
|
19072
|
+
preferIpv6
|
|
19073
|
+
});
|
|
19074
|
+
serverOrigins.externalip = createOrigin(firstExternalIp);
|
|
19075
|
+
hostnameToListen = preferIpv6 ? "::" : "0.0.0.0";
|
|
19076
|
+
} else {
|
|
19077
|
+
hostnameToListen = hostname;
|
|
19078
|
+
}
|
|
19079
|
+
|
|
19080
|
+
const hostnameInfo = parseHostname(hostname);
|
|
19081
|
+
|
|
19082
|
+
if (hostnameInfo.type === "ip") {
|
|
19083
|
+
if (acceptAnyIp) {
|
|
19084
|
+
throw new Error(`hostname cannot be an ip when acceptAnyIp is enabled, got ${hostname}`);
|
|
19085
|
+
}
|
|
19086
|
+
|
|
19087
|
+
preferIpv6 = hostnameInfo.version === 6;
|
|
19088
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19089
|
+
preferIpv6
|
|
19090
|
+
});
|
|
19091
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19092
|
+
serverOrigins.localip = createOrigin(firstInternalIp);
|
|
19093
|
+
|
|
19094
|
+
if (hostnameInfo.label === "unspecified") {
|
|
19095
|
+
const firstExternalIp = ipGetters.getFirstExternalIp({
|
|
19096
|
+
preferIpv6
|
|
19097
|
+
});
|
|
19098
|
+
serverOrigins.externalip = createOrigin(firstExternalIp);
|
|
19099
|
+
} else if (hostnameInfo.label === "loopback") {} else {
|
|
19100
|
+
serverOrigins.local = createOrigin(hostname);
|
|
19101
|
+
}
|
|
19102
|
+
} else {
|
|
19103
|
+
const hostnameDnsResolution = await applyDnsResolution(hostname, {
|
|
19104
|
+
verbatim: true
|
|
19105
|
+
});
|
|
19106
|
+
|
|
19107
|
+
if (hostnameDnsResolution) {
|
|
19108
|
+
const hostnameIp = hostnameDnsResolution.address;
|
|
19109
|
+
serverOrigins.localip = createOrigin(hostnameIp);
|
|
19110
|
+
serverOrigins.local = createOrigin(hostname);
|
|
19111
|
+
} else {
|
|
19112
|
+
const firstInternalIp = ipGetters.getFirstInternalIp({
|
|
19113
|
+
preferIpv6
|
|
19114
|
+
}); // fallback to internal ip because there is no ip
|
|
19115
|
+
// associated to this hostname on operating system (in hosts file)
|
|
19116
|
+
|
|
19117
|
+
hostname = firstInternalIp;
|
|
19118
|
+
hostnameToListen = firstInternalIp;
|
|
19119
|
+
serverOrigins.local = createOrigin(firstInternalIp);
|
|
19120
|
+
}
|
|
19121
|
+
}
|
|
19122
|
+
|
|
18960
19123
|
port = await listen({
|
|
18961
19124
|
signal: startServerOperation.signal,
|
|
18962
19125
|
server: nodeServer,
|
|
18963
19126
|
port,
|
|
18964
19127
|
portHint,
|
|
18965
|
-
|
|
19128
|
+
hostname: hostnameToListen
|
|
19129
|
+
}); // normalize origins (remove :80 when port is 80 for instance)
|
|
19130
|
+
|
|
19131
|
+
Object.keys(serverOrigins).forEach(key => {
|
|
19132
|
+
serverOrigins[key] = new URL(`${serverOrigins[key]}:${port}`).origin;
|
|
18966
19133
|
});
|
|
18967
19134
|
serviceController.callHooks("serverListening", {
|
|
18968
19135
|
port
|
|
@@ -18973,12 +19140,23 @@ const startServer = async ({
|
|
|
18973
19140
|
startServerOperation.throwIfAborted();
|
|
18974
19141
|
} finally {
|
|
18975
19142
|
await startServerOperation.end();
|
|
18976
|
-
} //
|
|
19143
|
+
} // the main server origin
|
|
19144
|
+
// - when protocol is http
|
|
19145
|
+
// node-fetch do not apply local dns resolution to map localhost back to 127.0.0.1
|
|
19146
|
+
// despites localhost being mapped so we prefer to use the internal ip
|
|
19147
|
+
// (127.0.0.1)
|
|
19148
|
+
// - when protocol is https
|
|
19149
|
+
// using the hostname becomes important because the certificate is generated
|
|
19150
|
+
// for hostnames, not for ips
|
|
19151
|
+
// so we prefer https://locahost or https://local_hostname
|
|
19152
|
+
// over the ip
|
|
19153
|
+
|
|
19154
|
+
|
|
19155
|
+
const serverOrigin = serverOrigins.local; // now the server is started (listening) it cannot be aborted anymore
|
|
18977
19156
|
// (otherwise an AbortError is thrown to the code calling "startServer")
|
|
18978
19157
|
// we can proceed to create a stop function to stop it gacefully
|
|
18979
19158
|
// and add a request handler
|
|
18980
19159
|
|
|
18981
|
-
|
|
18982
19160
|
stopCallbackList.add(({
|
|
18983
19161
|
reason
|
|
18984
19162
|
}) => {
|
|
@@ -19016,12 +19194,6 @@ const startServer = async ({
|
|
|
19016
19194
|
};
|
|
19017
19195
|
|
|
19018
19196
|
status = "opened";
|
|
19019
|
-
const serverOrigins = await getServerOrigins({
|
|
19020
|
-
protocol,
|
|
19021
|
-
host,
|
|
19022
|
-
port
|
|
19023
|
-
});
|
|
19024
|
-
const serverOrigin = serverOrigins.local;
|
|
19025
19197
|
const removeConnectionErrorListener = listenServerConnectionError(nodeServer, onError);
|
|
19026
19198
|
stopCallbackList.add(removeConnectionErrorListener);
|
|
19027
19199
|
const connectionsTracker = trackServerPendingConnections(nodeServer, {
|
|
@@ -19641,7 +19813,7 @@ const startServer = async ({
|
|
|
19641
19813
|
let websocketServer = new WebSocketServer({
|
|
19642
19814
|
noServer: true
|
|
19643
19815
|
});
|
|
19644
|
-
const websocketOrigin = protocol === "https" ? `wss://${
|
|
19816
|
+
const websocketOrigin = protocol === "https" ? `wss://${hostname}:${port}` : `ws://${hostname}:${port}`;
|
|
19645
19817
|
server.websocketOrigin = websocketOrigin;
|
|
19646
19818
|
|
|
19647
19819
|
const upgradeCallback = (nodeRequest, socket, head) => {
|
|
@@ -19682,6 +19854,7 @@ const startServer = async ({
|
|
|
19682
19854
|
Object.assign(server, {
|
|
19683
19855
|
getStatus: () => status,
|
|
19684
19856
|
port,
|
|
19857
|
+
hostname,
|
|
19685
19858
|
origin: serverOrigin,
|
|
19686
19859
|
origins: serverOrigins,
|
|
19687
19860
|
nodeServer,
|
|
@@ -20743,10 +20916,10 @@ const HOOK_NAMES = ["init", "serve", // is called only during dev/tests
|
|
|
20743
20916
|
"destroy"];
|
|
20744
20917
|
const createPluginController = ({
|
|
20745
20918
|
plugins,
|
|
20746
|
-
|
|
20919
|
+
scenarios
|
|
20747
20920
|
}) => {
|
|
20748
20921
|
const flatPlugins = flattenAndFilterPlugins(plugins, {
|
|
20749
|
-
|
|
20922
|
+
scenarios
|
|
20750
20923
|
}); // precompute a list of hooks per hookName for one major reason:
|
|
20751
20924
|
// - When debugging, there is less iteration
|
|
20752
20925
|
// also it should increase perf as there is less work to do
|
|
@@ -20953,7 +21126,7 @@ const createPluginController = ({
|
|
|
20953
21126
|
};
|
|
20954
21127
|
|
|
20955
21128
|
const flattenAndFilterPlugins = (plugins, {
|
|
20956
|
-
|
|
21129
|
+
scenarios
|
|
20957
21130
|
}) => {
|
|
20958
21131
|
const flatPlugins = [];
|
|
20959
21132
|
|
|
@@ -20983,12 +21156,13 @@ const flattenAndFilterPlugins = (plugins, {
|
|
|
20983
21156
|
}
|
|
20984
21157
|
|
|
20985
21158
|
if (typeof appliesDuring === "string") {
|
|
20986
|
-
if (!["dev", "
|
|
21159
|
+
if (!["dev", "test", "build"].includes(appliesDuring)) {
|
|
20987
21160
|
throw new Error(`"appliesDuring" must be "dev", "test" or "build", got ${appliesDuring}`);
|
|
20988
21161
|
}
|
|
20989
21162
|
|
|
20990
|
-
if (appliesDuring
|
|
21163
|
+
if (scenarios[appliesDuring]) {
|
|
20991
21164
|
flatPlugins.push(pluginEntry);
|
|
21165
|
+
return;
|
|
20992
21166
|
}
|
|
20993
21167
|
|
|
20994
21168
|
return;
|
|
@@ -20998,7 +21172,20 @@ const flattenAndFilterPlugins = (plugins, {
|
|
|
20998
21172
|
throw new Error(`"appliesDuring" must be an object or a string, got ${appliesDuring}`);
|
|
20999
21173
|
}
|
|
21000
21174
|
|
|
21001
|
-
|
|
21175
|
+
let applies;
|
|
21176
|
+
|
|
21177
|
+
for (const key of Object.keys(appliesDuring)) {
|
|
21178
|
+
if (!appliesDuring[key] && scenarios[key]) {
|
|
21179
|
+
applies = false;
|
|
21180
|
+
break;
|
|
21181
|
+
}
|
|
21182
|
+
|
|
21183
|
+
if (appliesDuring[key] && scenarios[key]) {
|
|
21184
|
+
applies = true;
|
|
21185
|
+
}
|
|
21186
|
+
}
|
|
21187
|
+
|
|
21188
|
+
if (applies) {
|
|
21002
21189
|
flatPlugins.push(pluginEntry);
|
|
21003
21190
|
return;
|
|
21004
21191
|
}
|
|
@@ -21710,19 +21897,15 @@ const createKitchen = ({
|
|
|
21710
21897
|
signal,
|
|
21711
21898
|
logLevel,
|
|
21712
21899
|
rootDirectoryUrl,
|
|
21713
|
-
|
|
21900
|
+
scenarios,
|
|
21714
21901
|
runtimeCompat,
|
|
21715
21902
|
// during dev/test clientRuntimeCompat is a single runtime
|
|
21716
21903
|
// during build clientRuntimeCompat is runtimeCompat
|
|
21717
21904
|
clientRuntimeCompat = runtimeCompat,
|
|
21718
21905
|
urlGraph,
|
|
21719
21906
|
plugins,
|
|
21720
|
-
sourcemaps =
|
|
21721
|
-
|
|
21722
|
-
// "programmatic" and "file" also allowed
|
|
21723
|
-
test: "inline",
|
|
21724
|
-
build: "none"
|
|
21725
|
-
}[scenario],
|
|
21907
|
+
sourcemaps = scenarios.dev ? "inline" : "none",
|
|
21908
|
+
// "programmatic" and "file" also allowed
|
|
21726
21909
|
sourcemapsSourcesProtocol,
|
|
21727
21910
|
sourcemapsSourcesContent,
|
|
21728
21911
|
sourcemapsRelativeSources,
|
|
@@ -21733,7 +21916,7 @@ const createKitchen = ({
|
|
|
21733
21916
|
});
|
|
21734
21917
|
const pluginController = createPluginController({
|
|
21735
21918
|
plugins,
|
|
21736
|
-
|
|
21919
|
+
scenarios
|
|
21737
21920
|
});
|
|
21738
21921
|
const jsenvDirectoryUrl = new URL(".jsenv/", rootDirectoryUrl).href;
|
|
21739
21922
|
const kitchenContext = {
|
|
@@ -21741,7 +21924,7 @@ const createKitchen = ({
|
|
|
21741
21924
|
logger,
|
|
21742
21925
|
rootDirectoryUrl,
|
|
21743
21926
|
urlGraph,
|
|
21744
|
-
|
|
21927
|
+
scenarios,
|
|
21745
21928
|
runtimeCompat,
|
|
21746
21929
|
clientRuntimeCompat,
|
|
21747
21930
|
isSupportedOnCurrentClients: feature => {
|
|
@@ -22446,7 +22629,7 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
|
22446
22629
|
column: reference.specifierColumn
|
|
22447
22630
|
};
|
|
22448
22631
|
urlInfo.contentType = reference.contentType;
|
|
22449
|
-
urlInfo.originalContent = context.
|
|
22632
|
+
urlInfo.originalContent = context.scenarios.build ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
|
|
22450
22633
|
urlInfo.content = reference.content;
|
|
22451
22634
|
}
|
|
22452
22635
|
};
|
|
@@ -23581,7 +23764,9 @@ build ${entryPointKeys.length} entry points`);
|
|
|
23581
23764
|
logger,
|
|
23582
23765
|
rootDirectoryUrl,
|
|
23583
23766
|
urlGraph: rawGraph,
|
|
23584
|
-
|
|
23767
|
+
scenarios: {
|
|
23768
|
+
build: true
|
|
23769
|
+
},
|
|
23585
23770
|
sourcemaps,
|
|
23586
23771
|
sourcemapsSourcesContent,
|
|
23587
23772
|
runtimeCompat,
|
|
@@ -23603,7 +23788,6 @@ build ${entryPointKeys.length} entry points`);
|
|
|
23603
23788
|
}, ...getCorePlugins({
|
|
23604
23789
|
rootDirectoryUrl,
|
|
23605
23790
|
urlGraph: rawGraph,
|
|
23606
|
-
scenario: "build",
|
|
23607
23791
|
runtimeCompat,
|
|
23608
23792
|
urlAnalysis,
|
|
23609
23793
|
nodeEsmResolution,
|
|
@@ -23821,7 +24005,9 @@ build ${entryPointKeys.length} entry points`);
|
|
|
23821
24005
|
logger,
|
|
23822
24006
|
rootDirectoryUrl,
|
|
23823
24007
|
urlGraph: finalGraph,
|
|
23824
|
-
|
|
24008
|
+
scenarios: {
|
|
24009
|
+
build: true
|
|
24010
|
+
},
|
|
23825
24011
|
sourcemaps,
|
|
23826
24012
|
sourcemapsSourcesContent,
|
|
23827
24013
|
sourcemapsRelativeSources: !versioning,
|
|
@@ -24483,7 +24669,9 @@ const applyUrlVersioning = async ({
|
|
|
24483
24669
|
logger,
|
|
24484
24670
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
24485
24671
|
urlGraph: finalGraph,
|
|
24486
|
-
|
|
24672
|
+
scenarios: {
|
|
24673
|
+
build: true
|
|
24674
|
+
},
|
|
24487
24675
|
sourcemaps,
|
|
24488
24676
|
sourcemapsSourcesContent,
|
|
24489
24677
|
sourcemapsRelativeSources: true,
|
|
@@ -24496,9 +24684,7 @@ const applyUrlVersioning = async ({
|
|
|
24496
24684
|
allowEscapeForVersioning: true
|
|
24497
24685
|
}), {
|
|
24498
24686
|
name: "jsenv:versioning",
|
|
24499
|
-
appliesDuring:
|
|
24500
|
-
build: true
|
|
24501
|
-
},
|
|
24687
|
+
appliesDuring: "build",
|
|
24502
24688
|
resolveUrl: reference => {
|
|
24503
24689
|
const buildUrl = buildUrls[reference.specifier];
|
|
24504
24690
|
|
|
@@ -24893,7 +25079,7 @@ const createFileService = ({
|
|
|
24893
25079
|
serverStopCallbacks,
|
|
24894
25080
|
serverEventsDispatcher,
|
|
24895
25081
|
rootDirectoryUrl,
|
|
24896
|
-
|
|
25082
|
+
scenarios,
|
|
24897
25083
|
runtimeCompat,
|
|
24898
25084
|
plugins,
|
|
24899
25085
|
urlAnalysis,
|
|
@@ -24931,7 +25117,7 @@ const createFileService = ({
|
|
|
24931
25117
|
".jsenv/": false
|
|
24932
25118
|
};
|
|
24933
25119
|
|
|
24934
|
-
if (
|
|
25120
|
+
if (scenarios.dev) {
|
|
24935
25121
|
const stopWatchingClientFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
|
|
24936
25122
|
watchPatterns: clientFilePatterns,
|
|
24937
25123
|
cooldownBetweenFileEvents,
|
|
@@ -24995,13 +25181,13 @@ const createFileService = ({
|
|
|
24995
25181
|
|
|
24996
25182
|
urlInfo.isValid = () => watch;
|
|
24997
25183
|
},
|
|
24998
|
-
includeOriginalUrls:
|
|
25184
|
+
includeOriginalUrls: scenarios.dev
|
|
24999
25185
|
});
|
|
25000
25186
|
const kitchen = createKitchen({
|
|
25001
25187
|
signal,
|
|
25002
25188
|
logLevel,
|
|
25003
25189
|
rootDirectoryUrl,
|
|
25004
|
-
|
|
25190
|
+
scenarios,
|
|
25005
25191
|
runtimeCompat,
|
|
25006
25192
|
clientRuntimeCompat: {
|
|
25007
25193
|
[runtimeName]: runtimeVersion
|
|
@@ -25009,7 +25195,6 @@ const createFileService = ({
|
|
|
25009
25195
|
urlGraph,
|
|
25010
25196
|
plugins: [...plugins, ...getCorePlugins({
|
|
25011
25197
|
rootDirectoryUrl,
|
|
25012
|
-
scenario,
|
|
25013
25198
|
runtimeCompat,
|
|
25014
25199
|
urlAnalysis,
|
|
25015
25200
|
htmlSupervisor,
|
|
@@ -25052,7 +25237,7 @@ const createFileService = ({
|
|
|
25052
25237
|
allServerEvents[serverEventName]({
|
|
25053
25238
|
rootDirectoryUrl,
|
|
25054
25239
|
urlGraph,
|
|
25055
|
-
|
|
25240
|
+
scenarios,
|
|
25056
25241
|
sendServerEvent: data => {
|
|
25057
25242
|
serverEventsDispatcher.dispatch({
|
|
25058
25243
|
type: serverEventName,
|
|
@@ -25068,7 +25253,7 @@ const createFileService = ({
|
|
|
25068
25253
|
|
|
25069
25254
|
const context = {
|
|
25070
25255
|
rootDirectoryUrl,
|
|
25071
|
-
|
|
25256
|
+
scenarios,
|
|
25072
25257
|
runtimeName,
|
|
25073
25258
|
runtimeVersion,
|
|
25074
25259
|
urlGraph,
|
|
@@ -25155,7 +25340,7 @@ const createFileService = ({
|
|
|
25155
25340
|
await kitchen.cook(urlInfo, {
|
|
25156
25341
|
request,
|
|
25157
25342
|
reference,
|
|
25158
|
-
outDirectoryUrl:
|
|
25343
|
+
outDirectoryUrl: scenarios.dev ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/` : `${rootDirectoryUrl}.jsenv/${scenarios.test ? "test" : "build"}/${runtimeName}@${runtimeVersion}/`
|
|
25159
25344
|
});
|
|
25160
25345
|
let {
|
|
25161
25346
|
response
|
|
@@ -25281,13 +25466,13 @@ const startOmegaServer = async ({
|
|
|
25281
25466
|
privateKey,
|
|
25282
25467
|
certificate,
|
|
25283
25468
|
acceptAnyIp,
|
|
25284
|
-
|
|
25469
|
+
hostname,
|
|
25285
25470
|
port = 0,
|
|
25286
25471
|
keepProcessAlive = false,
|
|
25287
25472
|
onStop = () => {},
|
|
25288
25473
|
services = [],
|
|
25289
25474
|
rootDirectoryUrl,
|
|
25290
|
-
|
|
25475
|
+
scenarios,
|
|
25291
25476
|
runtimeCompat,
|
|
25292
25477
|
plugins,
|
|
25293
25478
|
urlAnalysis,
|
|
@@ -25322,7 +25507,7 @@ const startOmegaServer = async ({
|
|
|
25322
25507
|
certificate,
|
|
25323
25508
|
privateKey,
|
|
25324
25509
|
acceptAnyIp,
|
|
25325
|
-
|
|
25510
|
+
hostname,
|
|
25326
25511
|
port,
|
|
25327
25512
|
requestWaitingMs: 60_1000,
|
|
25328
25513
|
services: [jsenvServiceCORS({
|
|
@@ -25340,7 +25525,7 @@ const startOmegaServer = async ({
|
|
|
25340
25525
|
serverStopCallbacks,
|
|
25341
25526
|
serverEventsDispatcher,
|
|
25342
25527
|
rootDirectoryUrl,
|
|
25343
|
-
|
|
25528
|
+
scenarios,
|
|
25344
25529
|
runtimeCompat,
|
|
25345
25530
|
plugins,
|
|
25346
25531
|
urlAnalysis,
|
|
@@ -25428,7 +25613,7 @@ const startDevServer = async ({
|
|
|
25428
25613
|
http2 = false,
|
|
25429
25614
|
certificate,
|
|
25430
25615
|
privateKey,
|
|
25431
|
-
|
|
25616
|
+
hostname,
|
|
25432
25617
|
port = 3456,
|
|
25433
25618
|
acceptAnyIp,
|
|
25434
25619
|
keepProcessAlive = true,
|
|
@@ -25568,11 +25753,13 @@ const startDevServer = async ({
|
|
|
25568
25753
|
http2,
|
|
25569
25754
|
certificate,
|
|
25570
25755
|
privateKey,
|
|
25571
|
-
|
|
25756
|
+
hostname,
|
|
25572
25757
|
port,
|
|
25573
25758
|
services,
|
|
25574
25759
|
rootDirectoryUrl,
|
|
25575
|
-
|
|
25760
|
+
scenarios: {
|
|
25761
|
+
dev: true
|
|
25762
|
+
},
|
|
25576
25763
|
runtimeCompat,
|
|
25577
25764
|
plugins,
|
|
25578
25765
|
urlAnalysis,
|
|
@@ -25669,87 +25856,6 @@ const generateCoverageTextLog = (coverage, {
|
|
|
25669
25856
|
report.execute(context);
|
|
25670
25857
|
};
|
|
25671
25858
|
|
|
25672
|
-
const babelPluginInstrument = (api, {
|
|
25673
|
-
rootDirectoryUrl,
|
|
25674
|
-
useInlineSourceMaps = false,
|
|
25675
|
-
coverageConfig = {
|
|
25676
|
-
"./**/*": true
|
|
25677
|
-
}
|
|
25678
|
-
}) => {
|
|
25679
|
-
const {
|
|
25680
|
-
programVisitor
|
|
25681
|
-
} = requireFromJsenv("istanbul-lib-instrument");
|
|
25682
|
-
const {
|
|
25683
|
-
types
|
|
25684
|
-
} = api;
|
|
25685
|
-
const associations = URL_META.resolveAssociations({
|
|
25686
|
-
cover: coverageConfig
|
|
25687
|
-
}, rootDirectoryUrl);
|
|
25688
|
-
|
|
25689
|
-
const shouldInstrument = url => {
|
|
25690
|
-
return URL_META.applyAssociations({
|
|
25691
|
-
url,
|
|
25692
|
-
associations
|
|
25693
|
-
}).cover;
|
|
25694
|
-
};
|
|
25695
|
-
|
|
25696
|
-
return {
|
|
25697
|
-
name: "transform-instrument",
|
|
25698
|
-
visitor: {
|
|
25699
|
-
Program: {
|
|
25700
|
-
enter(path) {
|
|
25701
|
-
const {
|
|
25702
|
-
file
|
|
25703
|
-
} = this;
|
|
25704
|
-
const {
|
|
25705
|
-
opts
|
|
25706
|
-
} = file;
|
|
25707
|
-
|
|
25708
|
-
if (!opts.sourceFileName) {
|
|
25709
|
-
console.warn(`cannot instrument file when "sourceFileName" option is not set`);
|
|
25710
|
-
return;
|
|
25711
|
-
}
|
|
25712
|
-
|
|
25713
|
-
const fileUrl = fileSystemPathToUrl$1(opts.sourceFileName);
|
|
25714
|
-
|
|
25715
|
-
if (!shouldInstrument(fileUrl)) {
|
|
25716
|
-
return;
|
|
25717
|
-
}
|
|
25718
|
-
|
|
25719
|
-
this.__dv__ = null;
|
|
25720
|
-
let inputSourceMap;
|
|
25721
|
-
|
|
25722
|
-
if (useInlineSourceMaps) {
|
|
25723
|
-
// https://github.com/istanbuljs/babel-plugin-istanbul/commit/a9e15643d249a2985e4387e4308022053b2cd0ad#diff-1fdf421c05c1140f6d71444ea2b27638R65
|
|
25724
|
-
inputSourceMap = opts.inputSourceMap || file.inputMap ? file.inputMap.sourcemap : null;
|
|
25725
|
-
} else {
|
|
25726
|
-
inputSourceMap = opts.inputSourceMap;
|
|
25727
|
-
}
|
|
25728
|
-
|
|
25729
|
-
this.__dv__ = programVisitor(types, opts.filenameRelative || opts.filename, {
|
|
25730
|
-
coverageVariable: "__coverage__",
|
|
25731
|
-
inputSourceMap
|
|
25732
|
-
});
|
|
25733
|
-
|
|
25734
|
-
this.__dv__.enter(path);
|
|
25735
|
-
},
|
|
25736
|
-
|
|
25737
|
-
exit(path) {
|
|
25738
|
-
if (!this.__dv__) {
|
|
25739
|
-
return;
|
|
25740
|
-
}
|
|
25741
|
-
|
|
25742
|
-
const object = this.__dv__.exit(path); // object got two properties: fileCoverage and sourceMappingURL
|
|
25743
|
-
|
|
25744
|
-
|
|
25745
|
-
this.file.metadata.coverage = object.fileCoverage;
|
|
25746
|
-
}
|
|
25747
|
-
|
|
25748
|
-
}
|
|
25749
|
-
}
|
|
25750
|
-
};
|
|
25751
|
-
};
|
|
25752
|
-
|
|
25753
25859
|
const readNodeV8CoverageDirectory = async ({
|
|
25754
25860
|
logger,
|
|
25755
25861
|
signal,
|
|
@@ -26442,6 +26548,41 @@ const run = async ({
|
|
|
26442
26548
|
}
|
|
26443
26549
|
};
|
|
26444
26550
|
|
|
26551
|
+
const pingServer = async url => {
|
|
26552
|
+
const server = createServer();
|
|
26553
|
+
const {
|
|
26554
|
+
hostname,
|
|
26555
|
+
port
|
|
26556
|
+
} = new URL(url);
|
|
26557
|
+
|
|
26558
|
+
try {
|
|
26559
|
+
await new Promise((resolve, reject) => {
|
|
26560
|
+
server.on("error", reject);
|
|
26561
|
+
server.on("listening", () => {
|
|
26562
|
+
resolve();
|
|
26563
|
+
});
|
|
26564
|
+
server.listen(port, hostname);
|
|
26565
|
+
});
|
|
26566
|
+
} catch (error) {
|
|
26567
|
+
if (error && error.code === "EADDRINUSE") {
|
|
26568
|
+
return true;
|
|
26569
|
+
}
|
|
26570
|
+
|
|
26571
|
+
if (error && error.code === "EACCES") {
|
|
26572
|
+
return true;
|
|
26573
|
+
}
|
|
26574
|
+
|
|
26575
|
+
throw error;
|
|
26576
|
+
}
|
|
26577
|
+
|
|
26578
|
+
await new Promise((resolve, reject) => {
|
|
26579
|
+
server.on("error", reject);
|
|
26580
|
+
server.on("close", resolve);
|
|
26581
|
+
server.close();
|
|
26582
|
+
});
|
|
26583
|
+
return false;
|
|
26584
|
+
};
|
|
26585
|
+
|
|
26445
26586
|
const ensureGlobalGc = () => {
|
|
26446
26587
|
if (!global.gc) {
|
|
26447
26588
|
v8.setFlagsFromString("--expose_gc");
|
|
@@ -26877,8 +27018,8 @@ const executePlan = async (plan, {
|
|
|
26877
27018
|
completedExecutionLogMerging,
|
|
26878
27019
|
completedExecutionLogAbbreviation,
|
|
26879
27020
|
rootDirectoryUrl,
|
|
27021
|
+
devServerOrigin,
|
|
26880
27022
|
keepRunning,
|
|
26881
|
-
services,
|
|
26882
27023
|
defaultMsAllocatedPerExecution,
|
|
26883
27024
|
maxExecutionsInParallel,
|
|
26884
27025
|
failFast,
|
|
@@ -26891,18 +27032,6 @@ const executePlan = async (plan, {
|
|
|
26891
27032
|
coverageMethodForNodeJs,
|
|
26892
27033
|
coverageV8ConflictWarning,
|
|
26893
27034
|
coverageTempDirectoryRelativeUrl,
|
|
26894
|
-
scenario,
|
|
26895
|
-
sourcemaps,
|
|
26896
|
-
plugins,
|
|
26897
|
-
nodeEsmResolution,
|
|
26898
|
-
fileSystemMagicResolution,
|
|
26899
|
-
transpilation,
|
|
26900
|
-
writeGeneratedFiles,
|
|
26901
|
-
protocol,
|
|
26902
|
-
privateKey,
|
|
26903
|
-
certificate,
|
|
26904
|
-
host,
|
|
26905
|
-
port,
|
|
26906
27035
|
beforeExecutionCallback = () => {},
|
|
26907
27036
|
afterExecutionCallback = () => {}
|
|
26908
27037
|
} = {}) => {
|
|
@@ -26926,7 +27055,7 @@ const executePlan = async (plan, {
|
|
|
26926
27055
|
if (runtime) {
|
|
26927
27056
|
runtimes[runtime.name] = runtime.version;
|
|
26928
27057
|
|
|
26929
|
-
if (runtime.
|
|
27058
|
+
if (runtime.type === "browser") {
|
|
26930
27059
|
someNeedsServer = true;
|
|
26931
27060
|
}
|
|
26932
27061
|
|
|
@@ -27017,6 +27146,7 @@ const executePlan = async (plan, {
|
|
|
27017
27146
|
|
|
27018
27147
|
let runtimeParams = {
|
|
27019
27148
|
rootDirectoryUrl,
|
|
27149
|
+
devServerOrigin,
|
|
27020
27150
|
coverageEnabled,
|
|
27021
27151
|
coverageConfig,
|
|
27022
27152
|
coverageMethodForBrowsers,
|
|
@@ -27025,48 +27155,15 @@ const executePlan = async (plan, {
|
|
|
27025
27155
|
};
|
|
27026
27156
|
|
|
27027
27157
|
if (someNeedsServer) {
|
|
27028
|
-
|
|
27029
|
-
|
|
27030
|
-
|
|
27031
|
-
keepProcessAlive: false,
|
|
27032
|
-
port,
|
|
27033
|
-
host,
|
|
27034
|
-
protocol,
|
|
27035
|
-
certificate,
|
|
27036
|
-
privateKey,
|
|
27037
|
-
services,
|
|
27038
|
-
rootDirectoryUrl,
|
|
27039
|
-
scenario,
|
|
27040
|
-
runtimeCompat: runtimes,
|
|
27041
|
-
plugins,
|
|
27042
|
-
htmlSupervisor: true,
|
|
27043
|
-
nodeEsmResolution,
|
|
27044
|
-
fileSystemMagicResolution,
|
|
27045
|
-
transpilation: { ...transpilation,
|
|
27046
|
-
getCustomBabelPlugins: ({
|
|
27047
|
-
clientRuntimeCompat
|
|
27048
|
-
}) => {
|
|
27049
|
-
if (coverageEnabled && (coverageMethodForBrowsers !== "playwright_api" || Object.keys(clientRuntimeCompat)[0] !== "chrome")) {
|
|
27050
|
-
return {
|
|
27051
|
-
"transform-instrument": [babelPluginInstrument, {
|
|
27052
|
-
rootDirectoryUrl,
|
|
27053
|
-
coverageConfig
|
|
27054
|
-
}]
|
|
27055
|
-
};
|
|
27056
|
-
}
|
|
27158
|
+
if (!devServerOrigin) {
|
|
27159
|
+
throw new TypeError(`devServerOrigin is required when running tests on browser(s)`);
|
|
27160
|
+
}
|
|
27057
27161
|
|
|
27058
|
-
|
|
27059
|
-
|
|
27060
|
-
|
|
27061
|
-
|
|
27062
|
-
|
|
27063
|
-
});
|
|
27064
|
-
multipleExecutionsOperation.addEndCallback(async () => {
|
|
27065
|
-
await server.stop();
|
|
27066
|
-
});
|
|
27067
|
-
runtimeParams = { ...runtimeParams,
|
|
27068
|
-
server
|
|
27069
|
-
};
|
|
27162
|
+
const devServerStarted = await pingServer(devServerOrigin);
|
|
27163
|
+
|
|
27164
|
+
if (!devServerStarted) {
|
|
27165
|
+
throw new Error(`dev server not started at ${devServerOrigin}. It is required to run tests`);
|
|
27166
|
+
}
|
|
27070
27167
|
}
|
|
27071
27168
|
|
|
27072
27169
|
logger.debug(`Generate executions`);
|
|
@@ -27409,9 +27506,10 @@ const executeInParallel = async ({
|
|
|
27409
27506
|
};
|
|
27410
27507
|
|
|
27411
27508
|
/**
|
|
27412
|
-
* Execute a list of files and log how it goes
|
|
27509
|
+
* Execute a list of files and log how it goes.
|
|
27413
27510
|
* @param {Object} testPlanParameters
|
|
27414
27511
|
* @param {string|url} testPlanParameters.rootDirectoryUrl Root directory of the project
|
|
27512
|
+
* @param {string|url} [testPlanParameters.serverOrigin=undefined] Jsenv dev server origin; required when executing test on browsers
|
|
27415
27513
|
* @param {Object} testPlanParameters.testPlan Object associating patterns leading to files to runtimes where they should be executed
|
|
27416
27514
|
* @param {boolean} [testPlanParameters.completedExecutionLogAbbreviation=false] Abbreviate completed execution information to shorten terminal output
|
|
27417
27515
|
* @param {boolean} [testPlanParameters.completedExecutionLogMerging=false] Merge completed execution logs to shorten terminal output
|
|
@@ -27438,6 +27536,7 @@ const executeTestPlan = async ({
|
|
|
27438
27536
|
completedExecutionLogAbbreviation = false,
|
|
27439
27537
|
completedExecutionLogMerging = false,
|
|
27440
27538
|
rootDirectoryUrl,
|
|
27539
|
+
devServerOrigin,
|
|
27441
27540
|
testPlan,
|
|
27442
27541
|
updateProcessExitCode = true,
|
|
27443
27542
|
maxExecutionsInParallel = 1,
|
|
@@ -27468,17 +27567,7 @@ const executeTestPlan = async ({
|
|
|
27468
27567
|
coverageReportSkipFull = false,
|
|
27469
27568
|
coverageReportTextLog = true,
|
|
27470
27569
|
coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
|
|
27471
|
-
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null
|
|
27472
|
-
sourcemaps = "inline",
|
|
27473
|
-
plugins = [],
|
|
27474
|
-
nodeEsmResolution,
|
|
27475
|
-
fileSystemMagicResolution,
|
|
27476
|
-
writeGeneratedFiles = false,
|
|
27477
|
-
protocol,
|
|
27478
|
-
privateKey,
|
|
27479
|
-
certificate,
|
|
27480
|
-
host,
|
|
27481
|
-
port
|
|
27570
|
+
coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null
|
|
27482
27571
|
}) => {
|
|
27483
27572
|
const logger = createLogger({
|
|
27484
27573
|
logLevel
|
|
@@ -27538,6 +27627,7 @@ const executeTestPlan = async ({
|
|
|
27538
27627
|
completedExecutionLogMerging,
|
|
27539
27628
|
completedExecutionLogAbbreviation,
|
|
27540
27629
|
rootDirectoryUrl,
|
|
27630
|
+
devServerOrigin,
|
|
27541
27631
|
maxExecutionsInParallel,
|
|
27542
27632
|
defaultMsAllocatedPerExecution,
|
|
27543
27633
|
failFast,
|
|
@@ -27550,18 +27640,7 @@ const executeTestPlan = async ({
|
|
|
27550
27640
|
coverageMethodForBrowsers,
|
|
27551
27641
|
coverageMethodForNodeJs,
|
|
27552
27642
|
coverageV8ConflictWarning,
|
|
27553
|
-
coverageTempDirectoryRelativeUrl
|
|
27554
|
-
scenario: "test",
|
|
27555
|
-
sourcemaps,
|
|
27556
|
-
plugins,
|
|
27557
|
-
nodeEsmResolution,
|
|
27558
|
-
fileSystemMagicResolution,
|
|
27559
|
-
writeGeneratedFiles,
|
|
27560
|
-
protocol,
|
|
27561
|
-
privateKey,
|
|
27562
|
-
certificate,
|
|
27563
|
-
host,
|
|
27564
|
-
port
|
|
27643
|
+
coverageTempDirectoryRelativeUrl
|
|
27565
27644
|
});
|
|
27566
27645
|
|
|
27567
27646
|
if (updateProcessExitCode && result.planSummary.counters.total !== result.planSummary.counters.completed) {
|
|
@@ -27679,8 +27758,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27679
27758
|
const runtime = {
|
|
27680
27759
|
type: "browser",
|
|
27681
27760
|
name: browserName,
|
|
27682
|
-
version: browserVersion
|
|
27683
|
-
needsServer: true
|
|
27761
|
+
version: browserVersion
|
|
27684
27762
|
};
|
|
27685
27763
|
let browserAndContextPromise;
|
|
27686
27764
|
|
|
@@ -27689,7 +27767,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27689
27767
|
logger,
|
|
27690
27768
|
rootDirectoryUrl,
|
|
27691
27769
|
fileRelativeUrl,
|
|
27692
|
-
|
|
27770
|
+
devServerOrigin,
|
|
27693
27771
|
// measurePerformance,
|
|
27694
27772
|
collectPerformance,
|
|
27695
27773
|
coverageEnabled = false,
|
|
@@ -27764,7 +27842,13 @@ const createRuntimeFromPlaywright = ({
|
|
|
27764
27842
|
await disconnected;
|
|
27765
27843
|
};
|
|
27766
27844
|
|
|
27767
|
-
const
|
|
27845
|
+
const coverageInHeaders = coverageEnabled && (!coveragePlaywrightAPIAvailable || coverageMethodForBrowsers !== "playwright_api");
|
|
27846
|
+
const page = await browserContext.newPage({
|
|
27847
|
+
extraHTTPHeaders: { ...(coverageInHeaders ? {
|
|
27848
|
+
"x-coverage-istanbul": JSON.stringify(coverageConfig)
|
|
27849
|
+
} : {})
|
|
27850
|
+
}
|
|
27851
|
+
});
|
|
27768
27852
|
|
|
27769
27853
|
const closePage = async () => {
|
|
27770
27854
|
try {
|
|
@@ -27792,7 +27876,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27792
27876
|
const v8CoveragesWithFsUrls = v8CoveragesWithWebUrls.map(v8CoveragesWithWebUrl => {
|
|
27793
27877
|
const fsUrl = moveUrl({
|
|
27794
27878
|
url: v8CoveragesWithWebUrl.url,
|
|
27795
|
-
from: `${
|
|
27879
|
+
from: `${devServerOrigin}/`,
|
|
27796
27880
|
to: rootDirectoryUrl,
|
|
27797
27881
|
preferAbsolute: true
|
|
27798
27882
|
});
|
|
@@ -27863,7 +27947,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27863
27947
|
});
|
|
27864
27948
|
}
|
|
27865
27949
|
|
|
27866
|
-
const fileClientUrl = new URL(fileRelativeUrl, `${
|
|
27950
|
+
const fileClientUrl = new URL(fileRelativeUrl, `${devServerOrigin}/`).href; // https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md#event-console
|
|
27867
27951
|
|
|
27868
27952
|
const removeConsoleListener = registerEvent({
|
|
27869
27953
|
object: page,
|
|
@@ -27977,7 +28061,7 @@ const createRuntimeFromPlaywright = ({
|
|
|
27977
28061
|
} = returnValue;
|
|
27978
28062
|
const error = evalException(exceptionSource, {
|
|
27979
28063
|
rootDirectoryUrl,
|
|
27980
|
-
|
|
28064
|
+
devServerOrigin,
|
|
27981
28065
|
transformErrorHook
|
|
27982
28066
|
});
|
|
27983
28067
|
cb({
|
|
@@ -28213,7 +28297,7 @@ const registerEvent = ({
|
|
|
28213
28297
|
|
|
28214
28298
|
const evalException = (exceptionSource, {
|
|
28215
28299
|
rootDirectoryUrl,
|
|
28216
|
-
|
|
28300
|
+
devServerOrigin,
|
|
28217
28301
|
transformErrorHook
|
|
28218
28302
|
}) => {
|
|
28219
28303
|
const script = new Script(exceptionSource, {
|
|
@@ -28222,7 +28306,7 @@ const evalException = (exceptionSource, {
|
|
|
28222
28306
|
const error = script.runInThisContext();
|
|
28223
28307
|
|
|
28224
28308
|
if (error && error instanceof Error) {
|
|
28225
|
-
const remoteRootRegexp = new RegExp(escapeRegexpSpecialChars(`${
|
|
28309
|
+
const remoteRootRegexp = new RegExp(escapeRegexpSpecialChars(`${devServerOrigin}/`), "g");
|
|
28226
28310
|
error.stack = error.stack.replace(remoteRootRegexp, rootDirectoryUrl);
|
|
28227
28311
|
error.message = error.message.replace(remoteRootRegexp, rootDirectoryUrl);
|
|
28228
28312
|
}
|
|
@@ -29220,7 +29304,7 @@ const startBuildServer = async ({
|
|
|
29220
29304
|
certificate,
|
|
29221
29305
|
privateKey,
|
|
29222
29306
|
acceptAnyIp,
|
|
29223
|
-
|
|
29307
|
+
hostname,
|
|
29224
29308
|
port = 9779,
|
|
29225
29309
|
services = [],
|
|
29226
29310
|
keepProcessAlive = true,
|
|
@@ -29357,7 +29441,7 @@ const startBuildServer = async ({
|
|
|
29357
29441
|
certificate,
|
|
29358
29442
|
privateKey,
|
|
29359
29443
|
acceptAnyIp,
|
|
29360
|
-
|
|
29444
|
+
hostname,
|
|
29361
29445
|
port,
|
|
29362
29446
|
serverTiming: true,
|
|
29363
29447
|
requestWaitingMs: 60_000,
|
|
@@ -29428,30 +29512,17 @@ const execute = async ({
|
|
|
29428
29512
|
handleSIGINT = true,
|
|
29429
29513
|
logLevel,
|
|
29430
29514
|
rootDirectoryUrl,
|
|
29515
|
+
devServerOrigin,
|
|
29431
29516
|
fileRelativeUrl,
|
|
29432
29517
|
allocatedMs,
|
|
29433
29518
|
mirrorConsole = true,
|
|
29434
29519
|
keepRunning = false,
|
|
29435
|
-
services,
|
|
29436
29520
|
collectConsole,
|
|
29437
29521
|
collectCoverage,
|
|
29438
29522
|
coverageTempDirectoryUrl,
|
|
29439
29523
|
collectPerformance = false,
|
|
29440
29524
|
runtime,
|
|
29441
29525
|
runtimeParams,
|
|
29442
|
-
scenario = "dev",
|
|
29443
|
-
plugins = [],
|
|
29444
|
-
nodeEsmResolution,
|
|
29445
|
-
fileSystemMagicResolution,
|
|
29446
|
-
transpilation,
|
|
29447
|
-
htmlSupervisor = true,
|
|
29448
|
-
sourcemaps = "inline",
|
|
29449
|
-
writeGeneratedFiles = false,
|
|
29450
|
-
port,
|
|
29451
|
-
protocol,
|
|
29452
|
-
http2,
|
|
29453
|
-
certificate,
|
|
29454
|
-
privateKey,
|
|
29455
29526
|
ignoreError = false
|
|
29456
29527
|
}) => {
|
|
29457
29528
|
const logger = createLogger({
|
|
@@ -29473,45 +29544,21 @@ const execute = async ({
|
|
|
29473
29544
|
|
|
29474
29545
|
runtimeParams = {
|
|
29475
29546
|
rootDirectoryUrl,
|
|
29547
|
+
devServerOrigin,
|
|
29476
29548
|
fileRelativeUrl,
|
|
29477
29549
|
...runtimeParams
|
|
29478
29550
|
};
|
|
29479
29551
|
|
|
29480
|
-
if (runtime.
|
|
29481
|
-
|
|
29482
|
-
|
|
29483
|
-
|
|
29484
|
-
keepProcessAlive: false,
|
|
29485
|
-
services,
|
|
29486
|
-
port,
|
|
29487
|
-
protocol,
|
|
29488
|
-
http2,
|
|
29489
|
-
certificate,
|
|
29490
|
-
privateKey,
|
|
29491
|
-
rootDirectoryUrl,
|
|
29492
|
-
scenario,
|
|
29493
|
-
runtimeCompat: {
|
|
29494
|
-
[runtime.name]: runtime.version
|
|
29495
|
-
},
|
|
29496
|
-
plugins,
|
|
29497
|
-
htmlSupervisor,
|
|
29498
|
-
nodeEsmResolution,
|
|
29499
|
-
fileSystemMagicResolution,
|
|
29500
|
-
transpilation,
|
|
29501
|
-
sourcemaps,
|
|
29502
|
-
writeGeneratedFiles
|
|
29503
|
-
});
|
|
29504
|
-
executeOperation.addEndCallback(async () => {
|
|
29505
|
-
await server.stop("execution done");
|
|
29506
|
-
});
|
|
29507
|
-
runtimeParams = { ...runtimeParams,
|
|
29508
|
-
server
|
|
29509
|
-
};
|
|
29552
|
+
if (runtime.type === "browser") {
|
|
29553
|
+
if (!devServerOrigin) {
|
|
29554
|
+
throw new TypeError(`devServerOrigin is required when running tests on browser(s)`);
|
|
29555
|
+
}
|
|
29510
29556
|
|
|
29511
|
-
|
|
29512
|
-
|
|
29513
|
-
|
|
29514
|
-
|
|
29557
|
+
const devServerStarted = await pingServer(devServerOrigin);
|
|
29558
|
+
|
|
29559
|
+
if (!devServerStarted) {
|
|
29560
|
+
throw new Error(`dev server not started at ${devServerOrigin}. It is required to run tests`);
|
|
29561
|
+
}
|
|
29515
29562
|
}
|
|
29516
29563
|
|
|
29517
29564
|
let result = await run({
|
|
@@ -29633,4 +29680,4 @@ const jsenvPluginInjectGlobals = urlAssociations => {
|
|
|
29633
29680
|
};
|
|
29634
29681
|
};
|
|
29635
29682
|
|
|
29636
|
-
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|
|
29683
|
+
export { build, chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, jsenvPluginInjectGlobals, nodeChildProcess, nodeWorkerThread, pingServer, startBuildServer, startDevServer, webkit, webkitIsolatedTab };
|