@jsenv/core 34.2.1 → 34.3.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/html/explorer.html +5 -4
- package/dist/importmap_node_loader.mjs +49 -0
- package/dist/js/resolveImport.js +504 -0
- package/dist/jsenv.js +392 -670
- package/dist/no_experimental_warnings.cjs +8 -0
- package/package.json +3 -2
- package/src/build/build.js +32 -14
- package/src/build/version_mappings_injection.js +20 -27
- package/src/dev/file_service.js +1 -1
- package/src/execute/execute.js +2 -0
- package/src/execute/runtimes/node/exec_options.js +15 -2
- package/src/execute/runtimes/node/importmap_node_loader.mjs +51 -0
- package/src/execute/runtimes/node/importmap_node_loader_file_url.js +4 -0
- package/src/execute/runtimes/node/no_experimental_warnings.cjs +12 -0
- package/src/execute/runtimes/node/no_experimental_warnings_file_url.js +4 -0
- package/src/execute/runtimes/node/node_child_process.js +15 -0
- package/src/execute/runtimes/node/node_worker_thread.js +13 -0
- package/src/kitchen/kitchen.js +5 -3
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +2 -2
- package/src/plugins/importmap/jsenv_plugin_importmap.js +6 -2
- package/src/plugins/{inline/jsenv_plugin_html_inline_content.js → inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js} +12 -6
- package/src/plugins/{inline/jsenv_plugin_inline.js → inline_content_analysis/jsenv_plugin_inline_content_analysis.js} +8 -10
- package/src/plugins/{inline/jsenv_plugin_js_inline_content.js → inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js} +4 -2
- package/src/plugins/inlining/jsenv_plugin_inlining.js +22 -0
- package/src/plugins/{inline/jsenv_plugin_inline_query_param.js → inlining/jsenv_plugin_inlining_as_data_url.js} +16 -9
- package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +149 -0
- package/src/plugins/plugins.js +5 -2
- package/src/plugins/ribbon/jsenv_plugin_ribbon.js +11 -10
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +2 -2
- package/src/plugins/supervisor/html_supervisor_injection.js +23 -25
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +20 -5
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +2 -2
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +3 -3
- package/src/plugins/url_analysis/html/html_urls.js +1 -1
- /package/src/plugins/{inline → inline_content_analysis}/client/inline_content.js +0 -0
- /package/src/plugins/{inline → inline_content_analysis}/jsenv_plugin_data_urls.js +0 -0
package/dist/jsenv.js
CHANGED
|
@@ -15,9 +15,10 @@ import { Readable, Stream, Writable } from "node:stream";
|
|
|
15
15
|
import { Http2ServerResponse } from "node:http2";
|
|
16
16
|
import { lookup } from "node:dns";
|
|
17
17
|
import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource, getOriginalPosition } from "@jsenv/sourcemap";
|
|
18
|
-
import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, parseCssUrls, parseJsUrls, getHtmlNodeText, setHtmlNodeText, removeHtmlNodeText, applyBabelPlugins,
|
|
18
|
+
import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, parseCssUrls, parseJsUrls, getHtmlNodeText, setHtmlNodeText, removeHtmlNodeText, applyBabelPlugins, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
19
19
|
import { createRequire } from "node:module";
|
|
20
20
|
import babelParser from "@babel/parser";
|
|
21
|
+
import { assertImportMap, resolveUrl as resolveUrl$1, normalizeImportMap, resolveImport } from "./js/resolveImport.js";
|
|
21
22
|
import v8, { takeCoverage } from "node:v8";
|
|
22
23
|
import stripAnsi from "strip-ansi";
|
|
23
24
|
import { createId } from "@paralleldrive/cuid2";
|
|
@@ -77,7 +78,7 @@ const DATA_URL = {
|
|
|
77
78
|
}
|
|
78
79
|
};
|
|
79
80
|
|
|
80
|
-
const urlToScheme
|
|
81
|
+
const urlToScheme = url => {
|
|
81
82
|
const urlString = String(url);
|
|
82
83
|
const colonIndex = urlString.indexOf(":");
|
|
83
84
|
if (colonIndex === -1) {
|
|
@@ -88,7 +89,7 @@ const urlToScheme$1 = url => {
|
|
|
88
89
|
};
|
|
89
90
|
|
|
90
91
|
const urlToResource = url => {
|
|
91
|
-
const scheme = urlToScheme
|
|
92
|
+
const scheme = urlToScheme(url);
|
|
92
93
|
if (scheme === "file") {
|
|
93
94
|
const urlAsStringWithoutFileProtocol = String(url).slice("file://".length);
|
|
94
95
|
return urlAsStringWithoutFileProtocol;
|
|
@@ -104,7 +105,7 @@ const urlToResource = url => {
|
|
|
104
105
|
return urlAsStringWithoutProtocol;
|
|
105
106
|
};
|
|
106
107
|
|
|
107
|
-
const urlToPathname
|
|
108
|
+
const urlToPathname = url => {
|
|
108
109
|
const resource = urlToResource(url);
|
|
109
110
|
const pathname = resourceToPathname(resource);
|
|
110
111
|
return pathname;
|
|
@@ -122,7 +123,7 @@ const resourceToPathname = resource => {
|
|
|
122
123
|
};
|
|
123
124
|
|
|
124
125
|
const urlToFilename$1 = url => {
|
|
125
|
-
const pathname = urlToPathname
|
|
126
|
+
const pathname = urlToPathname(url);
|
|
126
127
|
const pathnameBeforeLastSlash = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
127
128
|
const slashLastIndex = pathnameBeforeLastSlash.lastIndexOf("/");
|
|
128
129
|
const filename = slashLastIndex === -1 ? pathnameBeforeLastSlash : pathnameBeforeLastSlash.slice(slashLastIndex + 1);
|
|
@@ -319,10 +320,10 @@ const lineRangeWithinLines = ({
|
|
|
319
320
|
};
|
|
320
321
|
|
|
321
322
|
const urlToExtension$1 = url => {
|
|
322
|
-
const pathname = urlToPathname
|
|
323
|
-
return pathnameToExtension
|
|
323
|
+
const pathname = urlToPathname(url);
|
|
324
|
+
return pathnameToExtension(pathname);
|
|
324
325
|
};
|
|
325
|
-
const pathnameToExtension
|
|
326
|
+
const pathnameToExtension = pathname => {
|
|
326
327
|
const slashLastIndex = pathname.lastIndexOf("/");
|
|
327
328
|
if (slashLastIndex !== -1) {
|
|
328
329
|
pathname = pathname.slice(slashLastIndex + 1);
|
|
@@ -446,7 +447,7 @@ const getCallerPosition = () => {
|
|
|
446
447
|
};
|
|
447
448
|
};
|
|
448
449
|
|
|
449
|
-
const resolveUrl
|
|
450
|
+
const resolveUrl = (specifier, baseUrl) => {
|
|
450
451
|
if (typeof baseUrl === "undefined") {
|
|
451
452
|
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
452
453
|
}
|
|
@@ -519,7 +520,7 @@ const urlToRelativeUrl = (url, baseUrl) => {
|
|
|
519
520
|
const specificPathname = pathname.slice(commonPathname.length);
|
|
520
521
|
const baseSpecificPathname = basePathname.slice(commonPathname.length);
|
|
521
522
|
if (baseSpecificPathname.includes("/")) {
|
|
522
|
-
const baseSpecificParentPathname = pathnameToParentPathname
|
|
523
|
+
const baseSpecificParentPathname = pathnameToParentPathname(baseSpecificPathname);
|
|
523
524
|
const relativeDirectoriesNotation = baseSpecificParentPathname.replace(/.*?\//g, "../");
|
|
524
525
|
const relativeUrl = `${relativeDirectoriesNotation}${specificPathname}${search}${hash}`;
|
|
525
526
|
return relativeUrl;
|
|
@@ -527,7 +528,7 @@ const urlToRelativeUrl = (url, baseUrl) => {
|
|
|
527
528
|
const relativeUrl = `${specificPathname}${search}${hash}`;
|
|
528
529
|
return relativeUrl;
|
|
529
530
|
};
|
|
530
|
-
const pathnameToParentPathname
|
|
531
|
+
const pathnameToParentPathname = pathname => {
|
|
531
532
|
const slashLastIndex = pathname.lastIndexOf("/");
|
|
532
533
|
if (slashLastIndex === -1) {
|
|
533
534
|
return "/";
|
|
@@ -1674,7 +1675,7 @@ const removeDirectory = async (rootDirectoryUrl, {
|
|
|
1674
1675
|
removeDirectoryOperation.throwIfAborted();
|
|
1675
1676
|
const names = await readDirectory(directoryUrl);
|
|
1676
1677
|
await Promise.all(names.map(async name => {
|
|
1677
|
-
const url = resolveUrl
|
|
1678
|
+
const url = resolveUrl(name, directoryUrl);
|
|
1678
1679
|
await visit(url);
|
|
1679
1680
|
}));
|
|
1680
1681
|
};
|
|
@@ -2634,7 +2635,7 @@ const UNICODE = {
|
|
|
2634
2635
|
supported: canUseUnicode
|
|
2635
2636
|
};
|
|
2636
2637
|
|
|
2637
|
-
const createDetailedMessage
|
|
2638
|
+
const createDetailedMessage = (message, details = {}) => {
|
|
2638
2639
|
let string = `${message}`;
|
|
2639
2640
|
Object.keys(details).forEach(key => {
|
|
2640
2641
|
const value = details[key];
|
|
@@ -4967,7 +4968,7 @@ const startServer = async ({
|
|
|
4967
4968
|
warn,
|
|
4968
4969
|
requestWaitingMs
|
|
4969
4970
|
}) => {
|
|
4970
|
-
warn(createDetailedMessage
|
|
4971
|
+
warn(createDetailedMessage(`still no response found for request after ${requestWaitingMs} ms`, {
|
|
4971
4972
|
"request url": request.url,
|
|
4972
4973
|
"request headers": JSON.stringify(request.headers, null, " ")
|
|
4973
4974
|
}));
|
|
@@ -5352,7 +5353,7 @@ const startServer = async ({
|
|
|
5352
5353
|
if (error.message === "aborted") {
|
|
5353
5354
|
addRequestLog(rootRequestNode, {
|
|
5354
5355
|
type: "debug",
|
|
5355
|
-
value: createDetailedMessage
|
|
5356
|
+
value: createDetailedMessage(`request aborted by client`, {
|
|
5356
5357
|
"error message": error.message
|
|
5357
5358
|
})
|
|
5358
5359
|
});
|
|
@@ -5360,7 +5361,7 @@ const startServer = async ({
|
|
|
5360
5361
|
// I'm not sure this can happen but it's here in case
|
|
5361
5362
|
addRequestLog(rootRequestNode, {
|
|
5362
5363
|
type: "error",
|
|
5363
|
-
value: createDetailedMessage
|
|
5364
|
+
value: createDetailedMessage(`"error" event emitted on request`, {
|
|
5364
5365
|
"error stack": error.stack
|
|
5365
5366
|
})
|
|
5366
5367
|
});
|
|
@@ -5379,7 +5380,7 @@ const startServer = async ({
|
|
|
5379
5380
|
const onPushStreamError = e => {
|
|
5380
5381
|
addRequestLog(requestNode, {
|
|
5381
5382
|
type: "error",
|
|
5382
|
-
value: createDetailedMessage
|
|
5383
|
+
value: createDetailedMessage(`An error occured while pushing a stream to the response for ${request.resource}`, {
|
|
5383
5384
|
"error stack": e.stack
|
|
5384
5385
|
})
|
|
5385
5386
|
});
|
|
@@ -5610,7 +5611,7 @@ const startServer = async ({
|
|
|
5610
5611
|
}
|
|
5611
5612
|
addRequestLog(requestNode, {
|
|
5612
5613
|
type: "error",
|
|
5613
|
-
value: createDetailedMessage
|
|
5614
|
+
value: createDetailedMessage(`internal error while handling request`, {
|
|
5614
5615
|
"error stack": errorWhileHandlingRequest.stack
|
|
5615
5616
|
})
|
|
5616
5617
|
});
|
|
@@ -5704,7 +5705,7 @@ const startServer = async ({
|
|
|
5704
5705
|
onError: error => {
|
|
5705
5706
|
addRequestLog(requestNode, {
|
|
5706
5707
|
type: "error",
|
|
5707
|
-
value: createDetailedMessage
|
|
5708
|
+
value: createDetailedMessage(`An error occured while sending response`, {
|
|
5708
5709
|
"error stack": error.stack
|
|
5709
5710
|
})
|
|
5710
5711
|
});
|
|
@@ -8373,7 +8374,7 @@ const createResolveUrlError = ({
|
|
|
8373
8374
|
reason,
|
|
8374
8375
|
...details
|
|
8375
8376
|
}) => {
|
|
8376
|
-
const resolveError = new Error(createDetailedMessage
|
|
8377
|
+
const resolveError = new Error(createDetailedMessage(`Failed to resolve url reference`, {
|
|
8377
8378
|
reason,
|
|
8378
8379
|
...details,
|
|
8379
8380
|
"specifier": `"${reference.specifier}"`,
|
|
@@ -8392,7 +8393,7 @@ const createResolveUrlError = ({
|
|
|
8392
8393
|
});
|
|
8393
8394
|
}
|
|
8394
8395
|
if (error.code === "DIRECTORY_REFERENCE_NOT_ALLOWED") {
|
|
8395
|
-
error.message = createDetailedMessage
|
|
8396
|
+
error.message = createDetailedMessage(error.message, {
|
|
8396
8397
|
"reference trace": reference.trace.message
|
|
8397
8398
|
});
|
|
8398
8399
|
return error;
|
|
@@ -8413,7 +8414,7 @@ const createFetchUrlContentError = ({
|
|
|
8413
8414
|
reason,
|
|
8414
8415
|
...details
|
|
8415
8416
|
}) => {
|
|
8416
|
-
const fetchError = new Error(createDetailedMessage
|
|
8417
|
+
const fetchError = new Error(createDetailedMessage(`Failed to fetch url content`, {
|
|
8417
8418
|
reason,
|
|
8418
8419
|
...details,
|
|
8419
8420
|
"url": urlInfo.url,
|
|
@@ -8483,7 +8484,7 @@ const createTransformUrlContentError = ({
|
|
|
8483
8484
|
reason,
|
|
8484
8485
|
...details
|
|
8485
8486
|
}) => {
|
|
8486
|
-
const transformError = new Error(createDetailedMessage
|
|
8487
|
+
const transformError = new Error(createDetailedMessage(`"transformUrlContent" error on "${urlInfo.type}"`, {
|
|
8487
8488
|
reason,
|
|
8488
8489
|
...details,
|
|
8489
8490
|
"url": urlInfo.url,
|
|
@@ -8536,7 +8537,7 @@ const createFinalizeUrlContentError = ({
|
|
|
8536
8537
|
urlInfo,
|
|
8537
8538
|
error
|
|
8538
8539
|
}) => {
|
|
8539
|
-
const finalizeError = new Error(createDetailedMessage
|
|
8540
|
+
const finalizeError = new Error(createDetailedMessage(`"finalizeUrlContent" error on "${urlInfo.type}"`, {
|
|
8540
8541
|
...detailsFromValueThrown(error),
|
|
8541
8542
|
"url": urlInfo.url,
|
|
8542
8543
|
"url reference trace": reference.trace.message,
|
|
@@ -9048,7 +9049,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9048
9049
|
try {
|
|
9049
9050
|
const fetchUrlContentReturnValue = await pluginController.callAsyncHooksUntil("fetchUrlContent", urlInfo, contextDuringFetch);
|
|
9050
9051
|
if (!fetchUrlContentReturnValue) {
|
|
9051
|
-
logger.warn(createDetailedMessage
|
|
9052
|
+
logger.warn(createDetailedMessage(`no plugin has handled url during "fetchUrlContent" hook -> url will be ignored`, {
|
|
9052
9053
|
"url": urlInfo.url,
|
|
9053
9054
|
"url reference trace": reference.trace.message
|
|
9054
9055
|
}));
|
|
@@ -9372,6 +9373,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9372
9373
|
kitchenContext.injectReference = injectReference;
|
|
9373
9374
|
const getWithoutSearchParam = ({
|
|
9374
9375
|
urlInfo,
|
|
9376
|
+
reference,
|
|
9375
9377
|
context,
|
|
9376
9378
|
searchParam,
|
|
9377
9379
|
expectedType
|
|
@@ -9384,7 +9386,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9384
9386
|
return [null, null];
|
|
9385
9387
|
}
|
|
9386
9388
|
searchParams.delete(searchParam);
|
|
9387
|
-
const originalRef = context.reference.original || context.reference;
|
|
9389
|
+
const originalRef = reference || context.reference.original || context.reference;
|
|
9388
9390
|
const referenceWithoutSearchParam = {
|
|
9389
9391
|
...originalRef,
|
|
9390
9392
|
original: originalRef,
|
|
@@ -9393,8 +9395,8 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9393
9395
|
...originalRef.data
|
|
9394
9396
|
},
|
|
9395
9397
|
expectedType,
|
|
9396
|
-
specifier:
|
|
9397
|
-
url: urlObject.href,
|
|
9398
|
+
specifier: originalRef.specifier.replace(`?${searchParam}`, "").replace(`&${searchParam}`, ""),
|
|
9399
|
+
url: normalizeUrl(urlObject.href),
|
|
9398
9400
|
generatedSpecifier: null,
|
|
9399
9401
|
generatedUrl: null,
|
|
9400
9402
|
filename: null
|
|
@@ -10109,7 +10111,7 @@ const visitHtmlUrls = ({
|
|
|
10109
10111
|
if (type === "text") {
|
|
10110
10112
|
// ignore <script type="whatever" src="./file.js">
|
|
10111
10113
|
// per HTML spec https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
|
|
10112
|
-
// this will be handled by
|
|
10114
|
+
// this will be handled by jsenv_plugin_html_inline_content_analysis
|
|
10113
10115
|
return;
|
|
10114
10116
|
}
|
|
10115
10117
|
visitAttributeAsUrlSpecifier({
|
|
@@ -10426,12 +10428,211 @@ const findOriginalDirectoryReference = (urlInfo, context) => {
|
|
|
10426
10428
|
return ref;
|
|
10427
10429
|
};
|
|
10428
10430
|
|
|
10431
|
+
const jsenvPluginInliningAsDataUrl = () => {
|
|
10432
|
+
return {
|
|
10433
|
+
name: "jsenv:inlining_as_data_url",
|
|
10434
|
+
appliesDuring: "*",
|
|
10435
|
+
formatUrl: {
|
|
10436
|
+
// if the referenced url is a worker we could use
|
|
10437
|
+
// https://www.oreilly.com/library/view/web-workers/9781449322120/ch04.html
|
|
10438
|
+
// but maybe we should rather use ?object_url
|
|
10439
|
+
// or people could do this:
|
|
10440
|
+
// import workerText from './worker.js?text'
|
|
10441
|
+
// const blob = new Blob(workerText, { type: 'text/javascript' })
|
|
10442
|
+
// window.URL.createObjectURL(blob)
|
|
10443
|
+
// in any case the recommended way is to use an url
|
|
10444
|
+
// to benefit from shared worker and reuse worker between tabs
|
|
10445
|
+
"*": (reference, context) => {
|
|
10446
|
+
if (!reference.original || !reference.original.searchParams.has("inline")) {
|
|
10447
|
+
return null;
|
|
10448
|
+
}
|
|
10449
|
+
// <link rel="stylesheet"> and <script> can be inlined in the html
|
|
10450
|
+
if (reference.type === "link_href" && reference.subtype === "stylesheet") {
|
|
10451
|
+
return null;
|
|
10452
|
+
}
|
|
10453
|
+
if (reference.type === "script") {
|
|
10454
|
+
return null;
|
|
10455
|
+
}
|
|
10456
|
+
return (async () => {
|
|
10457
|
+
const urlInfo = context.urlGraph.getUrlInfo(reference.url);
|
|
10458
|
+
await context.cook(urlInfo, {
|
|
10459
|
+
reference
|
|
10460
|
+
});
|
|
10461
|
+
const specifier = DATA_URL.stringify({
|
|
10462
|
+
mediaType: urlInfo.contentType,
|
|
10463
|
+
base64Flag: true,
|
|
10464
|
+
data: Buffer.from(urlInfo.content).toString("base64")
|
|
10465
|
+
});
|
|
10466
|
+
return specifier;
|
|
10467
|
+
})();
|
|
10468
|
+
}
|
|
10469
|
+
}
|
|
10470
|
+
};
|
|
10471
|
+
};
|
|
10472
|
+
|
|
10473
|
+
const jsenvPluginInliningIntoHtml = () => {
|
|
10474
|
+
return {
|
|
10475
|
+
name: "jsenv:inlining_into_html",
|
|
10476
|
+
appliesDuring: "*",
|
|
10477
|
+
transformUrlContent: {
|
|
10478
|
+
html: async (urlInfo, context) => {
|
|
10479
|
+
const htmlAst = parseHtmlString(urlInfo.content);
|
|
10480
|
+
const mutations = [];
|
|
10481
|
+
const actions = [];
|
|
10482
|
+
const onStyleSheet = (linkNode, {
|
|
10483
|
+
href
|
|
10484
|
+
}) => {
|
|
10485
|
+
const linkReference = context.referenceUtils.find(ref => ref.generatedSpecifier === href && ref.type === "link_href" && ref.subtype === "stylesheet");
|
|
10486
|
+
if (!linkReference.original || !linkReference.original.searchParams.has("inline")) {
|
|
10487
|
+
return;
|
|
10488
|
+
}
|
|
10489
|
+
const linkUrlInfo = context.urlGraph.getUrlInfo(linkReference.url);
|
|
10490
|
+
actions.push(async () => {
|
|
10491
|
+
await context.cook(linkUrlInfo, {
|
|
10492
|
+
reference: linkReference
|
|
10493
|
+
});
|
|
10494
|
+
const {
|
|
10495
|
+
line,
|
|
10496
|
+
column,
|
|
10497
|
+
isOriginal
|
|
10498
|
+
} = getHtmlNodePosition(linkNode, {
|
|
10499
|
+
preferOriginal: true
|
|
10500
|
+
});
|
|
10501
|
+
context.referenceUtils.becomesInline(linkReference, {
|
|
10502
|
+
line: line - 1,
|
|
10503
|
+
column,
|
|
10504
|
+
isOriginal,
|
|
10505
|
+
specifier: linkReference.generatedSpecifier,
|
|
10506
|
+
content: linkUrlInfo.content,
|
|
10507
|
+
contentType: linkUrlInfo.contentType
|
|
10508
|
+
});
|
|
10509
|
+
mutations.push(() => {
|
|
10510
|
+
setHtmlNodeAttributes(linkNode, {
|
|
10511
|
+
"inlined-from-href": href,
|
|
10512
|
+
"href": undefined,
|
|
10513
|
+
"rel": undefined,
|
|
10514
|
+
"type": undefined,
|
|
10515
|
+
"as": undefined,
|
|
10516
|
+
"crossorigin": undefined,
|
|
10517
|
+
"integrity": undefined,
|
|
10518
|
+
"jsenv-inlined-by": "jsenv:inlining_into_html"
|
|
10519
|
+
});
|
|
10520
|
+
linkNode.nodeName = "style";
|
|
10521
|
+
linkNode.tagName = "style";
|
|
10522
|
+
setHtmlNodeText(linkNode, linkUrlInfo.content, {
|
|
10523
|
+
indentation: "auto"
|
|
10524
|
+
});
|
|
10525
|
+
});
|
|
10526
|
+
});
|
|
10527
|
+
};
|
|
10528
|
+
const onScriptWithSrc = (scriptNode, {
|
|
10529
|
+
src
|
|
10530
|
+
}) => {
|
|
10531
|
+
const scriptReference = context.referenceUtils.find(ref => ref.generatedSpecifier === src && ref.type === "script");
|
|
10532
|
+
if (!scriptReference.original || !scriptReference.original.searchParams.has("inline")) {
|
|
10533
|
+
return;
|
|
10534
|
+
}
|
|
10535
|
+
const scriptUrlInfo = context.urlGraph.getUrlInfo(scriptReference.url);
|
|
10536
|
+
actions.push(async () => {
|
|
10537
|
+
await context.cook(scriptUrlInfo, {
|
|
10538
|
+
reference: scriptReference
|
|
10539
|
+
});
|
|
10540
|
+
const {
|
|
10541
|
+
line,
|
|
10542
|
+
column,
|
|
10543
|
+
isOriginal
|
|
10544
|
+
} = getHtmlNodePosition(scriptNode, {
|
|
10545
|
+
preferOriginal: true
|
|
10546
|
+
});
|
|
10547
|
+
context.referenceUtils.becomesInline(scriptReference, {
|
|
10548
|
+
line: line - 1,
|
|
10549
|
+
column,
|
|
10550
|
+
isOriginal,
|
|
10551
|
+
specifier: scriptReference.generatedSpecifier,
|
|
10552
|
+
content: scriptUrlInfo.content,
|
|
10553
|
+
contentType: scriptUrlInfo.contentType
|
|
10554
|
+
});
|
|
10555
|
+
mutations.push(() => {
|
|
10556
|
+
setHtmlNodeAttributes(scriptNode, {
|
|
10557
|
+
"inlined-from-src": src,
|
|
10558
|
+
"src": undefined,
|
|
10559
|
+
"crossorigin": undefined,
|
|
10560
|
+
"integrity": undefined,
|
|
10561
|
+
"jsenv-inlined-by": "jsenv:inlining_into_html"
|
|
10562
|
+
});
|
|
10563
|
+
setHtmlNodeText(scriptNode, scriptUrlInfo.content, {
|
|
10564
|
+
indentation: "auto"
|
|
10565
|
+
});
|
|
10566
|
+
});
|
|
10567
|
+
});
|
|
10568
|
+
};
|
|
10569
|
+
visitHtmlNodes(htmlAst, {
|
|
10570
|
+
link: linkNode => {
|
|
10571
|
+
const rel = getHtmlNodeAttribute(linkNode, "rel");
|
|
10572
|
+
if (rel !== "stylesheet") {
|
|
10573
|
+
return;
|
|
10574
|
+
}
|
|
10575
|
+
const href = getHtmlNodeAttribute(linkNode, "href");
|
|
10576
|
+
if (!href) {
|
|
10577
|
+
return;
|
|
10578
|
+
}
|
|
10579
|
+
onStyleSheet(linkNode, {
|
|
10580
|
+
href
|
|
10581
|
+
});
|
|
10582
|
+
},
|
|
10583
|
+
script: scriptNode => {
|
|
10584
|
+
const {
|
|
10585
|
+
type
|
|
10586
|
+
} = analyzeScriptNode(scriptNode);
|
|
10587
|
+
const scriptNodeText = getHtmlNodeText(scriptNode);
|
|
10588
|
+
if (scriptNodeText) {
|
|
10589
|
+
return;
|
|
10590
|
+
}
|
|
10591
|
+
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
10592
|
+
if (!src) {
|
|
10593
|
+
return;
|
|
10594
|
+
}
|
|
10595
|
+
onScriptWithSrc(scriptNode, {
|
|
10596
|
+
type,
|
|
10597
|
+
src
|
|
10598
|
+
});
|
|
10599
|
+
}
|
|
10600
|
+
});
|
|
10601
|
+
if (actions.length > 0) {
|
|
10602
|
+
await Promise.all(actions.map(action => action()));
|
|
10603
|
+
}
|
|
10604
|
+
mutations.forEach(mutation => mutation());
|
|
10605
|
+
const htmlModified = stringifyHtmlAst(htmlAst);
|
|
10606
|
+
return htmlModified;
|
|
10607
|
+
}
|
|
10608
|
+
}
|
|
10609
|
+
};
|
|
10610
|
+
};
|
|
10611
|
+
|
|
10612
|
+
const jsenvPluginInlining = () => {
|
|
10613
|
+
return [{
|
|
10614
|
+
name: "jsenv:inlining",
|
|
10615
|
+
appliesDuring: "*",
|
|
10616
|
+
redirectUrl: reference => {
|
|
10617
|
+
const {
|
|
10618
|
+
searchParams
|
|
10619
|
+
} = reference;
|
|
10620
|
+
if (searchParams.has("inline")) {
|
|
10621
|
+
const urlObject = new URL(reference.url);
|
|
10622
|
+
urlObject.searchParams.delete("inline");
|
|
10623
|
+
return urlObject.href;
|
|
10624
|
+
}
|
|
10625
|
+
return null;
|
|
10626
|
+
}
|
|
10627
|
+
}, jsenvPluginInliningAsDataUrl(), jsenvPluginInliningIntoHtml()];
|
|
10628
|
+
};
|
|
10629
|
+
|
|
10429
10630
|
/*
|
|
10430
10631
|
* This plugin ensure content inlined inside HTML is cooked (inline <script> for instance)
|
|
10431
10632
|
* For <script hot-accept> the script content will be moved to a virtual file
|
|
10432
10633
|
* to enable hot reloading
|
|
10433
10634
|
*/
|
|
10434
|
-
const
|
|
10635
|
+
const jsenvPluginHtmlInlineContentAnalysis = ({
|
|
10435
10636
|
analyzeConvertedScripts
|
|
10436
10637
|
}) => {
|
|
10437
10638
|
const cookInlineContent = async ({
|
|
@@ -10457,7 +10658,7 @@ ${e.traceMessage}`);
|
|
|
10457
10658
|
}
|
|
10458
10659
|
};
|
|
10459
10660
|
return {
|
|
10460
|
-
name: "jsenv:
|
|
10661
|
+
name: "jsenv:html_inline_content_analysis",
|
|
10461
10662
|
appliesDuring: "*",
|
|
10462
10663
|
transformUrlContent: {
|
|
10463
10664
|
html: async (urlInfo, context) => {
|
|
@@ -10511,9 +10712,12 @@ ${e.traceMessage}`);
|
|
|
10511
10712
|
});
|
|
10512
10713
|
});
|
|
10513
10714
|
mutations.push(() => {
|
|
10514
|
-
setHtmlNodeText(styleNode, inlineStyleUrlInfo.content
|
|
10715
|
+
setHtmlNodeText(styleNode, inlineStyleUrlInfo.content, {
|
|
10716
|
+
indentation: false // indentation would decrease strack trace precision
|
|
10717
|
+
});
|
|
10718
|
+
|
|
10515
10719
|
setHtmlNodeAttributes(styleNode, {
|
|
10516
|
-
"jsenv-cooked-by": "jsenv:
|
|
10720
|
+
"jsenv-cooked-by": "jsenv:html_inline_content_analysis"
|
|
10517
10721
|
});
|
|
10518
10722
|
});
|
|
10519
10723
|
},
|
|
@@ -10575,7 +10779,7 @@ ${e.traceMessage}`);
|
|
|
10575
10779
|
});
|
|
10576
10780
|
mutations.push(() => {
|
|
10577
10781
|
const attributes = {
|
|
10578
|
-
"jsenv-cooked-by": "jsenv:
|
|
10782
|
+
"jsenv-cooked-by": "jsenv:html_inline_content_analysis",
|
|
10579
10783
|
// 1. <script type="jsx"> becomes <script>
|
|
10580
10784
|
// 2. <script type="module/jsx"> becomes <script type="module">
|
|
10581
10785
|
...(extension ? {
|
|
@@ -10588,7 +10792,10 @@ ${e.traceMessage}`);
|
|
|
10588
10792
|
...attributes
|
|
10589
10793
|
});
|
|
10590
10794
|
} else {
|
|
10591
|
-
setHtmlNodeText(scriptNode, inlineScriptUrlInfo.content
|
|
10795
|
+
setHtmlNodeText(scriptNode, inlineScriptUrlInfo.content, {
|
|
10796
|
+
indentation: false // indentation would decrease stack trace precision
|
|
10797
|
+
});
|
|
10798
|
+
|
|
10592
10799
|
setHtmlNodeAttributes(scriptNode, {
|
|
10593
10800
|
...attributes
|
|
10594
10801
|
});
|
|
@@ -10721,7 +10928,7 @@ const JS_QUOTE_REPLACEMENTS = {
|
|
|
10721
10928
|
}
|
|
10722
10929
|
};
|
|
10723
10930
|
|
|
10724
|
-
const
|
|
10931
|
+
const jsenvPluginJsInlineContentAnalysis = ({
|
|
10725
10932
|
allowEscapeForVersioning
|
|
10726
10933
|
}) => {
|
|
10727
10934
|
const parseAndTransformInlineContentCalls = async (urlInfo, context) => {
|
|
@@ -10783,7 +10990,7 @@ const jsenvPluginJsInlineContent = ({
|
|
|
10783
10990
|
return magicSource.toContentAndSourcemap();
|
|
10784
10991
|
};
|
|
10785
10992
|
return {
|
|
10786
|
-
name: "jsenv:
|
|
10993
|
+
name: "jsenv:js_inline_content_analysis",
|
|
10787
10994
|
appliesDuring: "*",
|
|
10788
10995
|
transformUrlContent: {
|
|
10789
10996
|
js_classic: parseAndTransformInlineContentCalls,
|
|
@@ -11099,61 +11306,20 @@ const base64ToBuffer = base64String => Buffer.from(base64String, "base64");
|
|
|
11099
11306
|
const base64ToString = base64String => Buffer.from(base64String, "base64").toString("utf8");
|
|
11100
11307
|
const dataToBase64 = data => Buffer.from(data).toString("base64");
|
|
11101
11308
|
|
|
11102
|
-
const
|
|
11103
|
-
return {
|
|
11104
|
-
name: "jsenv:inline_query_param",
|
|
11105
|
-
appliesDuring: "*",
|
|
11106
|
-
formatUrl: {
|
|
11107
|
-
// <link> and <script> can be inlined in the html
|
|
11108
|
-
// this should be done during dev and postbuild but not build
|
|
11109
|
-
// so that the bundled file gets inlined and not the entry point
|
|
11110
|
-
"link_href": () => null,
|
|
11111
|
-
"style": () => null,
|
|
11112
|
-
"script": () => null,
|
|
11113
|
-
// if the referenced url is a worker we could use
|
|
11114
|
-
// https://www.oreilly.com/library/view/web-workers/9781449322120/ch04.html
|
|
11115
|
-
// but maybe we should rather use ?object_url
|
|
11116
|
-
// or people could do this:
|
|
11117
|
-
// import workerText from './worker.js?text'
|
|
11118
|
-
// const blob = new Blob(workerText, { type: 'text/javascript' })
|
|
11119
|
-
// window.URL.createObjectURL(blob)
|
|
11120
|
-
// in any case the recommended way is to use an url
|
|
11121
|
-
// to benefit from shared worker and reuse worker between tabs
|
|
11122
|
-
"*": (reference, context) => {
|
|
11123
|
-
if (!reference.searchParams.has("inline")) {
|
|
11124
|
-
return null;
|
|
11125
|
-
}
|
|
11126
|
-
return (async () => {
|
|
11127
|
-
const urlInfo = context.urlGraph.getUrlInfo(reference.url);
|
|
11128
|
-
await context.cook(urlInfo, {
|
|
11129
|
-
reference
|
|
11130
|
-
});
|
|
11131
|
-
const specifier = DATA_URL.stringify({
|
|
11132
|
-
mediaType: urlInfo.contentType,
|
|
11133
|
-
base64Flag: true,
|
|
11134
|
-
data: Buffer.from(urlInfo.content).toString("base64")
|
|
11135
|
-
});
|
|
11136
|
-
return specifier;
|
|
11137
|
-
})();
|
|
11138
|
-
}
|
|
11139
|
-
}
|
|
11140
|
-
};
|
|
11141
|
-
};
|
|
11142
|
-
|
|
11143
|
-
const jsenvPluginInline = ({
|
|
11309
|
+
const jsenvPluginInlineContentAnalysis = ({
|
|
11144
11310
|
fetchInlineUrls = true,
|
|
11145
11311
|
analyzeConvertedScripts = false,
|
|
11146
11312
|
allowEscapeForVersioning = false
|
|
11147
11313
|
} = {}) => {
|
|
11148
|
-
return [...(fetchInlineUrls ? [
|
|
11314
|
+
return [...(fetchInlineUrls ? [jsenvPluginInlineContentFetcher()] : []), jsenvPluginHtmlInlineContentAnalysis({
|
|
11149
11315
|
analyzeConvertedScripts
|
|
11150
|
-
}),
|
|
11316
|
+
}), jsenvPluginJsInlineContentAnalysis({
|
|
11151
11317
|
allowEscapeForVersioning
|
|
11152
|
-
}), jsenvPluginDataUrls()
|
|
11318
|
+
}), jsenvPluginDataUrls()];
|
|
11153
11319
|
};
|
|
11154
|
-
const
|
|
11320
|
+
const jsenvPluginInlineContentFetcher = () => {
|
|
11155
11321
|
return {
|
|
11156
|
-
name: "jsenv:
|
|
11322
|
+
name: "jsenv:inline_content_fetcher",
|
|
11157
11323
|
appliesDuring: "*",
|
|
11158
11324
|
fetchUrlContent: urlInfo => {
|
|
11159
11325
|
if (!urlInfo.isInline) {
|
|
@@ -15176,7 +15342,7 @@ const jsenvPluginJsModuleFallbackInsideHtml = ({
|
|
|
15176
15342
|
await context.cook(systemJsUrlInfo, {
|
|
15177
15343
|
reference: systemJsReference
|
|
15178
15344
|
});
|
|
15179
|
-
|
|
15345
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
15180
15346
|
tagName: "script",
|
|
15181
15347
|
textContent: systemJsUrlInfo.content
|
|
15182
15348
|
}), "jsenv:js_module_fallback");
|
|
@@ -15209,13 +15375,13 @@ const isExpectingJsModule = reference => {
|
|
|
15209
15375
|
* when {type: "module"} cannot be used on web workers:
|
|
15210
15376
|
* - new Worker("worker.js", { type: "module" })
|
|
15211
15377
|
* transformed into
|
|
15212
|
-
* new Worker("worker.js?
|
|
15378
|
+
* new Worker("worker.js?js_module_fallback", { type: " lassic" })
|
|
15213
15379
|
* - navigator.serviceWorker.register("service_worker.js", { type: "module" })
|
|
15214
15380
|
* transformed into
|
|
15215
|
-
* navigator.serviceWorker.register("service_worker.js?
|
|
15381
|
+
* navigator.serviceWorker.register("service_worker.js?js_module_fallback", { type: "classic" })
|
|
15216
15382
|
* - new SharedWorker("shared_worker.js", { type: "module" })
|
|
15217
15383
|
* transformed into
|
|
15218
|
-
* new SharedWorker("shared_worker.js?
|
|
15384
|
+
* new SharedWorker("shared_worker.js?js_module_fallback", { type: "classic" })
|
|
15219
15385
|
*/
|
|
15220
15386
|
const jsenvPluginJsModuleFallbackOnWorkers = () => {
|
|
15221
15387
|
const turnIntoJsClassicProxy = reference => {
|
|
@@ -15294,306 +15460,6 @@ const splitFileExtension$2 = filename => {
|
|
|
15294
15460
|
return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)];
|
|
15295
15461
|
};
|
|
15296
15462
|
|
|
15297
|
-
// duplicated from @jsenv/log to avoid the dependency
|
|
15298
|
-
const createDetailedMessage = (message, details = {}) => {
|
|
15299
|
-
let string = `${message}`;
|
|
15300
|
-
Object.keys(details).forEach(key => {
|
|
15301
|
-
const value = details[key];
|
|
15302
|
-
string += `
|
|
15303
|
-
--- ${key} ---
|
|
15304
|
-
${Array.isArray(value) ? value.join(`
|
|
15305
|
-
`) : value}`;
|
|
15306
|
-
});
|
|
15307
|
-
return string;
|
|
15308
|
-
};
|
|
15309
|
-
|
|
15310
|
-
const assertImportMap = value => {
|
|
15311
|
-
if (value === null) {
|
|
15312
|
-
throw new TypeError(`an importMap must be an object, got null`);
|
|
15313
|
-
}
|
|
15314
|
-
const type = typeof value;
|
|
15315
|
-
if (type !== "object") {
|
|
15316
|
-
throw new TypeError(`an importMap must be an object, received ${value}`);
|
|
15317
|
-
}
|
|
15318
|
-
if (Array.isArray(value)) {
|
|
15319
|
-
throw new TypeError(`an importMap must be an object, received array ${value}`);
|
|
15320
|
-
}
|
|
15321
|
-
};
|
|
15322
|
-
|
|
15323
|
-
const hasScheme = string => {
|
|
15324
|
-
return /^[a-zA-Z]{2,}:/.test(string);
|
|
15325
|
-
};
|
|
15326
|
-
|
|
15327
|
-
const urlToScheme = urlString => {
|
|
15328
|
-
const colonIndex = urlString.indexOf(":");
|
|
15329
|
-
if (colonIndex === -1) return "";
|
|
15330
|
-
return urlString.slice(0, colonIndex);
|
|
15331
|
-
};
|
|
15332
|
-
|
|
15333
|
-
const urlToPathname = urlString => {
|
|
15334
|
-
return ressourceToPathname(urlToRessource(urlString));
|
|
15335
|
-
};
|
|
15336
|
-
const urlToRessource = urlString => {
|
|
15337
|
-
const scheme = urlToScheme(urlString);
|
|
15338
|
-
if (scheme === "file") {
|
|
15339
|
-
return urlString.slice("file://".length);
|
|
15340
|
-
}
|
|
15341
|
-
if (scheme === "https" || scheme === "http") {
|
|
15342
|
-
// remove origin
|
|
15343
|
-
const afterProtocol = urlString.slice(scheme.length + "://".length);
|
|
15344
|
-
const pathnameSlashIndex = afterProtocol.indexOf("/", "://".length);
|
|
15345
|
-
return afterProtocol.slice(pathnameSlashIndex);
|
|
15346
|
-
}
|
|
15347
|
-
return urlString.slice(scheme.length + 1);
|
|
15348
|
-
};
|
|
15349
|
-
const ressourceToPathname = ressource => {
|
|
15350
|
-
const searchSeparatorIndex = ressource.indexOf("?");
|
|
15351
|
-
return searchSeparatorIndex === -1 ? ressource : ressource.slice(0, searchSeparatorIndex);
|
|
15352
|
-
};
|
|
15353
|
-
|
|
15354
|
-
const urlToOrigin = urlString => {
|
|
15355
|
-
const scheme = urlToScheme(urlString);
|
|
15356
|
-
if (scheme === "file") {
|
|
15357
|
-
return "file://";
|
|
15358
|
-
}
|
|
15359
|
-
if (scheme === "http" || scheme === "https") {
|
|
15360
|
-
const secondProtocolSlashIndex = scheme.length + "://".length;
|
|
15361
|
-
const pathnameSlashIndex = urlString.indexOf("/", secondProtocolSlashIndex);
|
|
15362
|
-
if (pathnameSlashIndex === -1) return urlString;
|
|
15363
|
-
return urlString.slice(0, pathnameSlashIndex);
|
|
15364
|
-
}
|
|
15365
|
-
return urlString.slice(0, scheme.length + 1);
|
|
15366
|
-
};
|
|
15367
|
-
|
|
15368
|
-
const pathnameToParentPathname = pathname => {
|
|
15369
|
-
const slashLastIndex = pathname.lastIndexOf("/");
|
|
15370
|
-
if (slashLastIndex === -1) {
|
|
15371
|
-
return "/";
|
|
15372
|
-
}
|
|
15373
|
-
return pathname.slice(0, slashLastIndex + 1);
|
|
15374
|
-
};
|
|
15375
|
-
|
|
15376
|
-
// could be useful: https://url.spec.whatwg.org/#url-miscellaneous
|
|
15377
|
-
const resolveUrl = (specifier, baseUrl) => {
|
|
15378
|
-
if (baseUrl) {
|
|
15379
|
-
if (typeof baseUrl !== "string") {
|
|
15380
|
-
throw new TypeError(writeBaseUrlMustBeAString({
|
|
15381
|
-
baseUrl,
|
|
15382
|
-
specifier
|
|
15383
|
-
}));
|
|
15384
|
-
}
|
|
15385
|
-
if (!hasScheme(baseUrl)) {
|
|
15386
|
-
throw new Error(writeBaseUrlMustBeAbsolute({
|
|
15387
|
-
baseUrl,
|
|
15388
|
-
specifier
|
|
15389
|
-
}));
|
|
15390
|
-
}
|
|
15391
|
-
}
|
|
15392
|
-
if (hasScheme(specifier)) {
|
|
15393
|
-
return specifier;
|
|
15394
|
-
}
|
|
15395
|
-
if (!baseUrl) {
|
|
15396
|
-
throw new Error(writeBaseUrlRequired({
|
|
15397
|
-
baseUrl,
|
|
15398
|
-
specifier
|
|
15399
|
-
}));
|
|
15400
|
-
}
|
|
15401
|
-
|
|
15402
|
-
// scheme relative
|
|
15403
|
-
if (specifier.slice(0, 2) === "//") {
|
|
15404
|
-
return `${urlToScheme(baseUrl)}:${specifier}`;
|
|
15405
|
-
}
|
|
15406
|
-
|
|
15407
|
-
// origin relative
|
|
15408
|
-
if (specifier[0] === "/") {
|
|
15409
|
-
return `${urlToOrigin(baseUrl)}${specifier}`;
|
|
15410
|
-
}
|
|
15411
|
-
const baseOrigin = urlToOrigin(baseUrl);
|
|
15412
|
-
const basePathname = urlToPathname(baseUrl);
|
|
15413
|
-
if (specifier === ".") {
|
|
15414
|
-
const baseDirectoryPathname = pathnameToParentPathname(basePathname);
|
|
15415
|
-
return `${baseOrigin}${baseDirectoryPathname}`;
|
|
15416
|
-
}
|
|
15417
|
-
|
|
15418
|
-
// pathname relative inside
|
|
15419
|
-
if (specifier.slice(0, 2) === "./") {
|
|
15420
|
-
const baseDirectoryPathname = pathnameToParentPathname(basePathname);
|
|
15421
|
-
return `${baseOrigin}${baseDirectoryPathname}${specifier.slice(2)}`;
|
|
15422
|
-
}
|
|
15423
|
-
|
|
15424
|
-
// pathname relative outside
|
|
15425
|
-
if (specifier.slice(0, 3) === "../") {
|
|
15426
|
-
let unresolvedPathname = specifier;
|
|
15427
|
-
const importerFolders = basePathname.split("/");
|
|
15428
|
-
importerFolders.pop();
|
|
15429
|
-
while (unresolvedPathname.slice(0, 3) === "../") {
|
|
15430
|
-
unresolvedPathname = unresolvedPathname.slice(3);
|
|
15431
|
-
// when there is no folder left to resolved
|
|
15432
|
-
// we just ignore '../'
|
|
15433
|
-
if (importerFolders.length) {
|
|
15434
|
-
importerFolders.pop();
|
|
15435
|
-
}
|
|
15436
|
-
}
|
|
15437
|
-
const resolvedPathname = `${importerFolders.join("/")}/${unresolvedPathname}`;
|
|
15438
|
-
return `${baseOrigin}${resolvedPathname}`;
|
|
15439
|
-
}
|
|
15440
|
-
|
|
15441
|
-
// bare
|
|
15442
|
-
if (basePathname === "") {
|
|
15443
|
-
return `${baseOrigin}/${specifier}`;
|
|
15444
|
-
}
|
|
15445
|
-
if (basePathname[basePathname.length] === "/") {
|
|
15446
|
-
return `${baseOrigin}${basePathname}${specifier}`;
|
|
15447
|
-
}
|
|
15448
|
-
return `${baseOrigin}${pathnameToParentPathname(basePathname)}${specifier}`;
|
|
15449
|
-
};
|
|
15450
|
-
const writeBaseUrlMustBeAString = ({
|
|
15451
|
-
baseUrl,
|
|
15452
|
-
specifier
|
|
15453
|
-
}) => `baseUrl must be a string.
|
|
15454
|
-
--- base url ---
|
|
15455
|
-
${baseUrl}
|
|
15456
|
-
--- specifier ---
|
|
15457
|
-
${specifier}`;
|
|
15458
|
-
const writeBaseUrlMustBeAbsolute = ({
|
|
15459
|
-
baseUrl,
|
|
15460
|
-
specifier
|
|
15461
|
-
}) => `baseUrl must be absolute.
|
|
15462
|
-
--- base url ---
|
|
15463
|
-
${baseUrl}
|
|
15464
|
-
--- specifier ---
|
|
15465
|
-
${specifier}`;
|
|
15466
|
-
const writeBaseUrlRequired = ({
|
|
15467
|
-
baseUrl,
|
|
15468
|
-
specifier
|
|
15469
|
-
}) => `baseUrl required to resolve relative specifier.
|
|
15470
|
-
--- base url ---
|
|
15471
|
-
${baseUrl}
|
|
15472
|
-
--- specifier ---
|
|
15473
|
-
${specifier}`;
|
|
15474
|
-
|
|
15475
|
-
const tryUrlResolution = (string, url) => {
|
|
15476
|
-
const result = resolveUrl(string, url);
|
|
15477
|
-
return hasScheme(result) ? result : null;
|
|
15478
|
-
};
|
|
15479
|
-
|
|
15480
|
-
const resolveSpecifier = (specifier, importer) => {
|
|
15481
|
-
if (specifier === "." || specifier[0] === "/" || specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
15482
|
-
return resolveUrl(specifier, importer);
|
|
15483
|
-
}
|
|
15484
|
-
if (hasScheme(specifier)) {
|
|
15485
|
-
return specifier;
|
|
15486
|
-
}
|
|
15487
|
-
return null;
|
|
15488
|
-
};
|
|
15489
|
-
|
|
15490
|
-
const applyImportMap = ({
|
|
15491
|
-
importMap,
|
|
15492
|
-
specifier,
|
|
15493
|
-
importer,
|
|
15494
|
-
createBareSpecifierError = ({
|
|
15495
|
-
specifier,
|
|
15496
|
-
importer
|
|
15497
|
-
}) => {
|
|
15498
|
-
return new Error(createDetailedMessage(`Unmapped bare specifier.`, {
|
|
15499
|
-
specifier,
|
|
15500
|
-
importer
|
|
15501
|
-
}));
|
|
15502
|
-
},
|
|
15503
|
-
onImportMapping = () => {}
|
|
15504
|
-
}) => {
|
|
15505
|
-
assertImportMap(importMap);
|
|
15506
|
-
if (typeof specifier !== "string") {
|
|
15507
|
-
throw new TypeError(createDetailedMessage("specifier must be a string.", {
|
|
15508
|
-
specifier,
|
|
15509
|
-
importer
|
|
15510
|
-
}));
|
|
15511
|
-
}
|
|
15512
|
-
if (importer) {
|
|
15513
|
-
if (typeof importer !== "string") {
|
|
15514
|
-
throw new TypeError(createDetailedMessage("importer must be a string.", {
|
|
15515
|
-
importer,
|
|
15516
|
-
specifier
|
|
15517
|
-
}));
|
|
15518
|
-
}
|
|
15519
|
-
if (!hasScheme(importer)) {
|
|
15520
|
-
throw new Error(createDetailedMessage(`importer must be an absolute url.`, {
|
|
15521
|
-
importer,
|
|
15522
|
-
specifier
|
|
15523
|
-
}));
|
|
15524
|
-
}
|
|
15525
|
-
}
|
|
15526
|
-
const specifierUrl = resolveSpecifier(specifier, importer);
|
|
15527
|
-
const specifierNormalized = specifierUrl || specifier;
|
|
15528
|
-
const {
|
|
15529
|
-
scopes
|
|
15530
|
-
} = importMap;
|
|
15531
|
-
if (scopes && importer) {
|
|
15532
|
-
const scopeSpecifierMatching = Object.keys(scopes).find(scopeSpecifier => {
|
|
15533
|
-
return scopeSpecifier === importer || specifierIsPrefixOf(scopeSpecifier, importer);
|
|
15534
|
-
});
|
|
15535
|
-
if (scopeSpecifierMatching) {
|
|
15536
|
-
const scopeMappings = scopes[scopeSpecifierMatching];
|
|
15537
|
-
const mappingFromScopes = applyMappings(scopeMappings, specifierNormalized, scopeSpecifierMatching, onImportMapping);
|
|
15538
|
-
if (mappingFromScopes !== null) {
|
|
15539
|
-
return mappingFromScopes;
|
|
15540
|
-
}
|
|
15541
|
-
}
|
|
15542
|
-
}
|
|
15543
|
-
const {
|
|
15544
|
-
imports
|
|
15545
|
-
} = importMap;
|
|
15546
|
-
if (imports) {
|
|
15547
|
-
const mappingFromImports = applyMappings(imports, specifierNormalized, undefined, onImportMapping);
|
|
15548
|
-
if (mappingFromImports !== null) {
|
|
15549
|
-
return mappingFromImports;
|
|
15550
|
-
}
|
|
15551
|
-
}
|
|
15552
|
-
if (specifierUrl) {
|
|
15553
|
-
return specifierUrl;
|
|
15554
|
-
}
|
|
15555
|
-
throw createBareSpecifierError({
|
|
15556
|
-
specifier,
|
|
15557
|
-
importer
|
|
15558
|
-
});
|
|
15559
|
-
};
|
|
15560
|
-
const applyMappings = (mappings, specifierNormalized, scope, onImportMapping) => {
|
|
15561
|
-
const specifierCandidates = Object.keys(mappings);
|
|
15562
|
-
let i = 0;
|
|
15563
|
-
while (i < specifierCandidates.length) {
|
|
15564
|
-
const specifierCandidate = specifierCandidates[i];
|
|
15565
|
-
i++;
|
|
15566
|
-
if (specifierCandidate === specifierNormalized) {
|
|
15567
|
-
const address = mappings[specifierCandidate];
|
|
15568
|
-
onImportMapping({
|
|
15569
|
-
scope,
|
|
15570
|
-
from: specifierCandidate,
|
|
15571
|
-
to: address,
|
|
15572
|
-
before: specifierNormalized,
|
|
15573
|
-
after: address
|
|
15574
|
-
});
|
|
15575
|
-
return address;
|
|
15576
|
-
}
|
|
15577
|
-
if (specifierIsPrefixOf(specifierCandidate, specifierNormalized)) {
|
|
15578
|
-
const address = mappings[specifierCandidate];
|
|
15579
|
-
const afterSpecifier = specifierNormalized.slice(specifierCandidate.length);
|
|
15580
|
-
const addressFinal = tryUrlResolution(afterSpecifier, address);
|
|
15581
|
-
onImportMapping({
|
|
15582
|
-
scope,
|
|
15583
|
-
from: specifierCandidate,
|
|
15584
|
-
to: address,
|
|
15585
|
-
before: specifierNormalized,
|
|
15586
|
-
after: addressFinal
|
|
15587
|
-
});
|
|
15588
|
-
return addressFinal;
|
|
15589
|
-
}
|
|
15590
|
-
}
|
|
15591
|
-
return null;
|
|
15592
|
-
};
|
|
15593
|
-
const specifierIsPrefixOf = (specifierHref, href) => {
|
|
15594
|
-
return specifierHref[specifierHref.length - 1] === "/" && href.startsWith(specifierHref);
|
|
15595
|
-
};
|
|
15596
|
-
|
|
15597
15463
|
// https://github.com/systemjs/systemjs/blob/89391f92dfeac33919b0223bbf834a1f4eea5750/src/common.js#L136
|
|
15598
15464
|
const composeTwoImportMaps = (leftImportMap, rightImportMap) => {
|
|
15599
15465
|
assertImportMap(leftImportMap);
|
|
@@ -15651,8 +15517,8 @@ const composeTwoMappings = (leftMappings, rightMappings) => {
|
|
|
15651
15517
|
};
|
|
15652
15518
|
const objectHasKey = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
|
|
15653
15519
|
const compareAddressAndSpecifier = (address, specifier) => {
|
|
15654
|
-
const addressUrl = resolveUrl(address, "file:///");
|
|
15655
|
-
const specifierUrl = resolveUrl(specifier, "file:///");
|
|
15520
|
+
const addressUrl = resolveUrl$1(address, "file:///");
|
|
15521
|
+
const specifierUrl = resolveUrl$1(specifier, "file:///");
|
|
15656
15522
|
return addressUrl === specifierUrl;
|
|
15657
15523
|
};
|
|
15658
15524
|
const composeTwoScopes = (leftScopes, rightScopes, imports) => {
|
|
@@ -15684,209 +15550,6 @@ const composeTwoScopes = (leftScopes, rightScopes, imports) => {
|
|
|
15684
15550
|
return scopes;
|
|
15685
15551
|
};
|
|
15686
15552
|
|
|
15687
|
-
const sortImports = imports => {
|
|
15688
|
-
const mappingsSorted = {};
|
|
15689
|
-
Object.keys(imports).sort(compareLengthOrLocaleCompare).forEach(name => {
|
|
15690
|
-
mappingsSorted[name] = imports[name];
|
|
15691
|
-
});
|
|
15692
|
-
return mappingsSorted;
|
|
15693
|
-
};
|
|
15694
|
-
const sortScopes = scopes => {
|
|
15695
|
-
const scopesSorted = {};
|
|
15696
|
-
Object.keys(scopes).sort(compareLengthOrLocaleCompare).forEach(scopeSpecifier => {
|
|
15697
|
-
scopesSorted[scopeSpecifier] = sortImports(scopes[scopeSpecifier]);
|
|
15698
|
-
});
|
|
15699
|
-
return scopesSorted;
|
|
15700
|
-
};
|
|
15701
|
-
const compareLengthOrLocaleCompare = (a, b) => {
|
|
15702
|
-
return b.length - a.length || a.localeCompare(b);
|
|
15703
|
-
};
|
|
15704
|
-
|
|
15705
|
-
const normalizeImportMap = (importMap, baseUrl) => {
|
|
15706
|
-
assertImportMap(importMap);
|
|
15707
|
-
if (!isStringOrUrl(baseUrl)) {
|
|
15708
|
-
throw new TypeError(formulateBaseUrlMustBeStringOrUrl({
|
|
15709
|
-
baseUrl
|
|
15710
|
-
}));
|
|
15711
|
-
}
|
|
15712
|
-
const {
|
|
15713
|
-
imports,
|
|
15714
|
-
scopes
|
|
15715
|
-
} = importMap;
|
|
15716
|
-
return {
|
|
15717
|
-
imports: imports ? normalizeMappings(imports, baseUrl) : undefined,
|
|
15718
|
-
scopes: scopes ? normalizeScopes(scopes, baseUrl) : undefined
|
|
15719
|
-
};
|
|
15720
|
-
};
|
|
15721
|
-
const isStringOrUrl = value => {
|
|
15722
|
-
if (typeof value === "string") {
|
|
15723
|
-
return true;
|
|
15724
|
-
}
|
|
15725
|
-
if (typeof URL === "function" && value instanceof URL) {
|
|
15726
|
-
return true;
|
|
15727
|
-
}
|
|
15728
|
-
return false;
|
|
15729
|
-
};
|
|
15730
|
-
const normalizeMappings = (mappings, baseUrl) => {
|
|
15731
|
-
const mappingsNormalized = {};
|
|
15732
|
-
Object.keys(mappings).forEach(specifier => {
|
|
15733
|
-
const address = mappings[specifier];
|
|
15734
|
-
if (typeof address !== "string") {
|
|
15735
|
-
console.warn(formulateAddressMustBeAString({
|
|
15736
|
-
address,
|
|
15737
|
-
specifier
|
|
15738
|
-
}));
|
|
15739
|
-
return;
|
|
15740
|
-
}
|
|
15741
|
-
const specifierResolved = resolveSpecifier(specifier, baseUrl) || specifier;
|
|
15742
|
-
const addressUrl = tryUrlResolution(address, baseUrl);
|
|
15743
|
-
if (addressUrl === null) {
|
|
15744
|
-
console.warn(formulateAdressResolutionFailed({
|
|
15745
|
-
address,
|
|
15746
|
-
baseUrl,
|
|
15747
|
-
specifier
|
|
15748
|
-
}));
|
|
15749
|
-
return;
|
|
15750
|
-
}
|
|
15751
|
-
if (specifier.endsWith("/") && !addressUrl.endsWith("/")) {
|
|
15752
|
-
console.warn(formulateAddressUrlRequiresTrailingSlash({
|
|
15753
|
-
addressUrl,
|
|
15754
|
-
address,
|
|
15755
|
-
specifier
|
|
15756
|
-
}));
|
|
15757
|
-
return;
|
|
15758
|
-
}
|
|
15759
|
-
mappingsNormalized[specifierResolved] = addressUrl;
|
|
15760
|
-
});
|
|
15761
|
-
return sortImports(mappingsNormalized);
|
|
15762
|
-
};
|
|
15763
|
-
const normalizeScopes = (scopes, baseUrl) => {
|
|
15764
|
-
const scopesNormalized = {};
|
|
15765
|
-
Object.keys(scopes).forEach(scopeSpecifier => {
|
|
15766
|
-
const scopeMappings = scopes[scopeSpecifier];
|
|
15767
|
-
const scopeUrl = tryUrlResolution(scopeSpecifier, baseUrl);
|
|
15768
|
-
if (scopeUrl === null) {
|
|
15769
|
-
console.warn(formulateScopeResolutionFailed({
|
|
15770
|
-
scope: scopeSpecifier,
|
|
15771
|
-
baseUrl
|
|
15772
|
-
}));
|
|
15773
|
-
return;
|
|
15774
|
-
}
|
|
15775
|
-
const scopeValueNormalized = normalizeMappings(scopeMappings, baseUrl);
|
|
15776
|
-
scopesNormalized[scopeUrl] = scopeValueNormalized;
|
|
15777
|
-
});
|
|
15778
|
-
return sortScopes(scopesNormalized);
|
|
15779
|
-
};
|
|
15780
|
-
const formulateBaseUrlMustBeStringOrUrl = ({
|
|
15781
|
-
baseUrl
|
|
15782
|
-
}) => `baseUrl must be a string or an url.
|
|
15783
|
-
--- base url ---
|
|
15784
|
-
${baseUrl}`;
|
|
15785
|
-
const formulateAddressMustBeAString = ({
|
|
15786
|
-
specifier,
|
|
15787
|
-
address
|
|
15788
|
-
}) => `Address must be a string.
|
|
15789
|
-
--- address ---
|
|
15790
|
-
${address}
|
|
15791
|
-
--- specifier ---
|
|
15792
|
-
${specifier}`;
|
|
15793
|
-
const formulateAdressResolutionFailed = ({
|
|
15794
|
-
address,
|
|
15795
|
-
baseUrl,
|
|
15796
|
-
specifier
|
|
15797
|
-
}) => `Address url resolution failed.
|
|
15798
|
-
--- address ---
|
|
15799
|
-
${address}
|
|
15800
|
-
--- base url ---
|
|
15801
|
-
${baseUrl}
|
|
15802
|
-
--- specifier ---
|
|
15803
|
-
${specifier}`;
|
|
15804
|
-
const formulateAddressUrlRequiresTrailingSlash = ({
|
|
15805
|
-
addressURL,
|
|
15806
|
-
address,
|
|
15807
|
-
specifier
|
|
15808
|
-
}) => `Address must end with /.
|
|
15809
|
-
--- address url ---
|
|
15810
|
-
${addressURL}
|
|
15811
|
-
--- address ---
|
|
15812
|
-
${address}
|
|
15813
|
-
--- specifier ---
|
|
15814
|
-
${specifier}`;
|
|
15815
|
-
const formulateScopeResolutionFailed = ({
|
|
15816
|
-
scope,
|
|
15817
|
-
baseUrl
|
|
15818
|
-
}) => `Scope url resolution failed.
|
|
15819
|
-
--- scope ---
|
|
15820
|
-
${scope}
|
|
15821
|
-
--- base url ---
|
|
15822
|
-
${baseUrl}`;
|
|
15823
|
-
|
|
15824
|
-
const pathnameToExtension = pathname => {
|
|
15825
|
-
const slashLastIndex = pathname.lastIndexOf("/");
|
|
15826
|
-
if (slashLastIndex !== -1) {
|
|
15827
|
-
pathname = pathname.slice(slashLastIndex + 1);
|
|
15828
|
-
}
|
|
15829
|
-
const dotLastIndex = pathname.lastIndexOf(".");
|
|
15830
|
-
if (dotLastIndex === -1) return "";
|
|
15831
|
-
// if (dotLastIndex === pathname.length - 1) return ""
|
|
15832
|
-
return pathname.slice(dotLastIndex);
|
|
15833
|
-
};
|
|
15834
|
-
|
|
15835
|
-
const resolveImport = ({
|
|
15836
|
-
specifier,
|
|
15837
|
-
importer,
|
|
15838
|
-
importMap,
|
|
15839
|
-
defaultExtension = false,
|
|
15840
|
-
createBareSpecifierError,
|
|
15841
|
-
onImportMapping = () => {}
|
|
15842
|
-
}) => {
|
|
15843
|
-
let url;
|
|
15844
|
-
if (importMap) {
|
|
15845
|
-
url = applyImportMap({
|
|
15846
|
-
importMap,
|
|
15847
|
-
specifier,
|
|
15848
|
-
importer,
|
|
15849
|
-
createBareSpecifierError,
|
|
15850
|
-
onImportMapping
|
|
15851
|
-
});
|
|
15852
|
-
} else {
|
|
15853
|
-
url = resolveUrl(specifier, importer);
|
|
15854
|
-
}
|
|
15855
|
-
if (defaultExtension) {
|
|
15856
|
-
url = applyDefaultExtension({
|
|
15857
|
-
url,
|
|
15858
|
-
importer,
|
|
15859
|
-
defaultExtension
|
|
15860
|
-
});
|
|
15861
|
-
}
|
|
15862
|
-
return url;
|
|
15863
|
-
};
|
|
15864
|
-
const applyDefaultExtension = ({
|
|
15865
|
-
url,
|
|
15866
|
-
importer,
|
|
15867
|
-
defaultExtension
|
|
15868
|
-
}) => {
|
|
15869
|
-
if (urlToPathname(url).endsWith("/")) {
|
|
15870
|
-
return url;
|
|
15871
|
-
}
|
|
15872
|
-
if (typeof defaultExtension === "string") {
|
|
15873
|
-
const extension = pathnameToExtension(url);
|
|
15874
|
-
if (extension === "") {
|
|
15875
|
-
return `${url}${defaultExtension}`;
|
|
15876
|
-
}
|
|
15877
|
-
return url;
|
|
15878
|
-
}
|
|
15879
|
-
if (defaultExtension === true) {
|
|
15880
|
-
const extension = pathnameToExtension(url);
|
|
15881
|
-
if (extension === "" && importer) {
|
|
15882
|
-
const importerPathname = urlToPathname(importer);
|
|
15883
|
-
const importerExtension = pathnameToExtension(importerPathname);
|
|
15884
|
-
return `${url}${importerExtension}`;
|
|
15885
|
-
}
|
|
15886
|
-
}
|
|
15887
|
-
return url;
|
|
15888
|
-
};
|
|
15889
|
-
|
|
15890
15553
|
/*
|
|
15891
15554
|
* Plugin to read and apply importmap files found in html files.
|
|
15892
15555
|
* - feeds importmap files to jsenv kitchen
|
|
@@ -16003,7 +15666,9 @@ const jsenvPluginImportmap = () => {
|
|
|
16003
15666
|
await context.cook(inlineImportmapUrlInfo, {
|
|
16004
15667
|
reference: inlineImportmapReference
|
|
16005
15668
|
});
|
|
16006
|
-
setHtmlNodeText(importmap, inlineImportmapUrlInfo.content
|
|
15669
|
+
setHtmlNodeText(importmap, inlineImportmapUrlInfo.content, {
|
|
15670
|
+
indentation: "auto"
|
|
15671
|
+
});
|
|
16007
15672
|
setHtmlNodeAttributes(importmap, {
|
|
16008
15673
|
"jsenv-cooked-by": "jsenv:importmap"
|
|
16009
15674
|
});
|
|
@@ -16021,7 +15686,9 @@ const jsenvPluginImportmap = () => {
|
|
|
16021
15686
|
reference: importmapReference
|
|
16022
15687
|
});
|
|
16023
15688
|
onHtmlImportmapParsed(JSON.parse(importmapUrlInfo.content), htmlUrlInfo.url);
|
|
16024
|
-
setHtmlNodeText(importmap, importmapUrlInfo.content
|
|
15689
|
+
setHtmlNodeText(importmap, importmapUrlInfo.content, {
|
|
15690
|
+
indentation: "auto"
|
|
15691
|
+
});
|
|
16025
15692
|
setHtmlNodeAttributes(importmap, {
|
|
16026
15693
|
"src": undefined,
|
|
16027
15694
|
"jsenv-inlined-by": "jsenv:importmap",
|
|
@@ -17796,7 +17463,9 @@ const injectSupervisorIntoHTML = async ({
|
|
|
17796
17463
|
src: inlineScriptSrc
|
|
17797
17464
|
});
|
|
17798
17465
|
mutations.push(() => {
|
|
17799
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised
|
|
17466
|
+
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
17467
|
+
indentation: "auto"
|
|
17468
|
+
});
|
|
17800
17469
|
setHtmlNodeAttributes(scriptNode, {
|
|
17801
17470
|
"jsenv-cooked-by": "jsenv:supervisor",
|
|
17802
17471
|
"src": undefined,
|
|
@@ -17819,7 +17488,9 @@ const injectSupervisorIntoHTML = async ({
|
|
|
17819
17488
|
inlineSrc: inlineScriptSrc
|
|
17820
17489
|
});
|
|
17821
17490
|
mutations.push(() => {
|
|
17822
|
-
setHtmlNodeText(scriptNode, inlineJsSupervised
|
|
17491
|
+
setHtmlNodeText(scriptNode, inlineJsSupervised, {
|
|
17492
|
+
indentation: "auto"
|
|
17493
|
+
});
|
|
17823
17494
|
setHtmlNodeAttributes(scriptNode, {
|
|
17824
17495
|
"jsenv-cooked-by": "jsenv:supervisor"
|
|
17825
17496
|
});
|
|
@@ -17852,7 +17523,9 @@ const injectSupervisorIntoHTML = async ({
|
|
|
17852
17523
|
src
|
|
17853
17524
|
});
|
|
17854
17525
|
mutations.push(() => {
|
|
17855
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised
|
|
17526
|
+
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
17527
|
+
indentation: "auto"
|
|
17528
|
+
});
|
|
17856
17529
|
setHtmlNodeAttributes(scriptNode, {
|
|
17857
17530
|
"jsenv-cooked-by": "jsenv:supervisor",
|
|
17858
17531
|
"src": undefined,
|
|
@@ -17887,6 +17560,10 @@ const injectSupervisorIntoHTML = async ({
|
|
|
17887
17560
|
}
|
|
17888
17561
|
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
17889
17562
|
if (src) {
|
|
17563
|
+
const urlObject = new URL(src, "http://example.com");
|
|
17564
|
+
if (urlObject.searchParams.has("inline")) {
|
|
17565
|
+
return;
|
|
17566
|
+
}
|
|
17890
17567
|
handleScriptWithSrc(scriptNode, {
|
|
17891
17568
|
type,
|
|
17892
17569
|
src
|
|
@@ -17903,20 +17580,15 @@ const injectSupervisorIntoHTML = async ({
|
|
|
17903
17580
|
serverIsJsenvDevServer: webServer.isJsenvDevServer,
|
|
17904
17581
|
rootDirectoryUrl: webServer.rootDirectoryUrl,
|
|
17905
17582
|
scriptInfos
|
|
17906
|
-
}, "
|
|
17907
|
-
|
|
17583
|
+
}, " ");
|
|
17584
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
17908
17585
|
tagName: "script",
|
|
17909
|
-
textContent: `
|
|
17910
|
-
window.__supervisor__.setup({
|
|
17911
|
-
${setupParamsSource}
|
|
17912
|
-
})
|
|
17913
|
-
`
|
|
17586
|
+
textContent: `window.__supervisor__.setup({${setupParamsSource}})`
|
|
17914
17587
|
}), "jsenv:supervisor");
|
|
17915
|
-
|
|
17588
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
17916
17589
|
tagName: "script",
|
|
17917
17590
|
src: supervisorScriptSrc
|
|
17918
|
-
});
|
|
17919
|
-
injectScriptNodeAsEarlyAsPossible(htmlAst, supervisorScript, "jsenv:supervisor");
|
|
17591
|
+
}), "jsenv:supervisor");
|
|
17920
17592
|
}
|
|
17921
17593
|
// 3. Perform actions (transforming inline script content) and html mutations
|
|
17922
17594
|
if (actions.length > 0) {
|
|
@@ -17944,14 +17616,11 @@ const generateCodeToSuperviseScriptWithSrc = ({
|
|
|
17944
17616
|
type,
|
|
17945
17617
|
src
|
|
17946
17618
|
}) => {
|
|
17619
|
+
const srcEncoded = JSON.stringify(src);
|
|
17947
17620
|
if (type === "js_module") {
|
|
17948
|
-
return `
|
|
17949
|
-
window.__supervisor__.superviseScriptTypeModule(${JSON.stringify(src)}, (url) => import(url));
|
|
17950
|
-
`;
|
|
17621
|
+
return `window.__supervisor__.superviseScriptTypeModule(${srcEncoded}, (url) => import(url));`;
|
|
17951
17622
|
}
|
|
17952
|
-
return `
|
|
17953
|
-
window.__supervisor__.superviseScript(${JSON.stringify(src)});
|
|
17954
|
-
`;
|
|
17623
|
+
return `window.__supervisor__.superviseScript(${srcEncoded});`;
|
|
17955
17624
|
};
|
|
17956
17625
|
|
|
17957
17626
|
/*
|
|
@@ -18556,10 +18225,23 @@ const jsenvPluginImportAssertions = ({
|
|
|
18556
18225
|
};
|
|
18557
18226
|
const turnIntoJsModuleProxy = (reference, type) => {
|
|
18558
18227
|
reference.mutation = magicSource => {
|
|
18559
|
-
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
18228
|
+
const {
|
|
18229
|
+
assertNode
|
|
18230
|
+
} = reference;
|
|
18231
|
+
if (reference.subtype === "import_dynamic") {
|
|
18232
|
+
const assertPropertyNode = assertNode.properties.find(prop => prop.key.name === "assert");
|
|
18233
|
+
const assertPropertyValue = assertPropertyNode.value;
|
|
18234
|
+
const typePropertyNode = assertPropertyValue.properties.find(prop => prop.key.name === "type");
|
|
18235
|
+
magicSource.remove({
|
|
18236
|
+
start: typePropertyNode.start,
|
|
18237
|
+
end: typePropertyNode.end
|
|
18238
|
+
});
|
|
18239
|
+
} else {
|
|
18240
|
+
magicSource.remove({
|
|
18241
|
+
start: assertNode.start,
|
|
18242
|
+
end: assertNode.end
|
|
18243
|
+
});
|
|
18244
|
+
}
|
|
18563
18245
|
};
|
|
18564
18246
|
const newUrl = injectQueryParams(reference.url, {
|
|
18565
18247
|
[`as_${type}_module`]: ""
|
|
@@ -20300,7 +19982,7 @@ const jsenvPluginAutoreloadClient = () => {
|
|
|
20300
19982
|
expectedType: "js_module",
|
|
20301
19983
|
specifier: autoreloadClientFileUrl
|
|
20302
19984
|
});
|
|
20303
|
-
|
|
19985
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
20304
19986
|
tagName: "script",
|
|
20305
19987
|
type: "module",
|
|
20306
19988
|
src: autoreloadClientReference.generatedSpecifier
|
|
@@ -20668,16 +20350,13 @@ const jsenvPluginRibbon = ({
|
|
|
20668
20350
|
const paramsJson = JSON.stringify({
|
|
20669
20351
|
text: context.dev ? "DEV" : "BUILD"
|
|
20670
20352
|
}, null, " ");
|
|
20671
|
-
|
|
20353
|
+
injectHtmlNode(htmlAst, createHtmlNode({
|
|
20672
20354
|
tagName: "script",
|
|
20673
20355
|
type: "module",
|
|
20674
|
-
textContent: `
|
|
20675
|
-
|
|
20676
|
-
|
|
20677
|
-
|
|
20678
|
-
`
|
|
20679
|
-
});
|
|
20680
|
-
injectHtmlNode(htmlAst, scriptNode, "jsenv:ribbon");
|
|
20356
|
+
textContent: `import { injectRibbon } from "${ribbonClientFileReference.generatedSpecifier}"
|
|
20357
|
+
|
|
20358
|
+
injectRibbon(${paramsJson});`
|
|
20359
|
+
}), "jsenv:ribbon");
|
|
20681
20360
|
return stringifyHtmlAst(htmlAst);
|
|
20682
20361
|
}
|
|
20683
20362
|
}
|
|
@@ -20694,6 +20373,7 @@ const getCorePlugins = ({
|
|
|
20694
20373
|
directoryReferenceAllowed,
|
|
20695
20374
|
supervisor,
|
|
20696
20375
|
transpilation = true,
|
|
20376
|
+
inlining = true,
|
|
20697
20377
|
clientAutoreload = false,
|
|
20698
20378
|
clientFileChangeCallbackList,
|
|
20699
20379
|
clientFilesPruneCallbackList,
|
|
@@ -20726,9 +20406,9 @@ const getCorePlugins = ({
|
|
|
20726
20406
|
}), jsenvPluginTranspilation(transpilation), jsenvPluginImportmap(),
|
|
20727
20407
|
// before node esm to handle bare specifiers
|
|
20728
20408
|
// + before node esm to handle importmap before inline content
|
|
20729
|
-
|
|
20409
|
+
jsenvPluginInlineContentAnalysis(),
|
|
20730
20410
|
// before "file urls" to resolve and load inline urls
|
|
20731
|
-
...(supervisor ? [jsenvPluginSupervisor(supervisor)] : []),
|
|
20411
|
+
...(inlining ? [jsenvPluginInlining()] : []), ...(supervisor ? [jsenvPluginSupervisor(supervisor)] : []),
|
|
20732
20412
|
// after inline as it needs inline script to be cooked
|
|
20733
20413
|
jsenvPluginFileUrls({
|
|
20734
20414
|
directoryReferenceAllowed,
|
|
@@ -20983,7 +20663,7 @@ const injectors = {
|
|
|
20983
20663
|
const htmlAst = parseHtmlString(urlInfo.content, {
|
|
20984
20664
|
storeOriginalPositions: false
|
|
20985
20665
|
});
|
|
20986
|
-
|
|
20666
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
20987
20667
|
tagName: "script",
|
|
20988
20668
|
textContent: generateClientCodeForVersionMappings(versionMappings, {
|
|
20989
20669
|
globalName: "window",
|
|
@@ -21002,10 +20682,11 @@ const jsInjector = (urlInfo, {
|
|
|
21002
20682
|
minification
|
|
21003
20683
|
}) => {
|
|
21004
20684
|
const magicSource = createMagicSource(urlInfo.content);
|
|
21005
|
-
|
|
20685
|
+
const code = generateClientCodeForVersionMappings(versionMappings, {
|
|
21006
20686
|
globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
|
|
21007
20687
|
minification
|
|
21008
|
-
})
|
|
20688
|
+
});
|
|
20689
|
+
magicSource.prepend(`${code}\n\n`);
|
|
21009
20690
|
return magicSource.toContentAndSourcemap();
|
|
21010
20691
|
};
|
|
21011
20692
|
const generateClientCodeForVersionMappings = (versionMappings, {
|
|
@@ -21015,14 +20696,12 @@ const generateClientCodeForVersionMappings = (versionMappings, {
|
|
|
21015
20696
|
if (minification) {
|
|
21016
20697
|
return `;(function(){var m = ${JSON.stringify(versionMappings)}; ${globalName}.__v__ = function (s) { return m[s] || s }; })();`;
|
|
21017
20698
|
}
|
|
21018
|
-
return
|
|
21019
|
-
;(function() {
|
|
20699
|
+
return `;(function() {
|
|
21020
20700
|
var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")};
|
|
21021
20701
|
${globalName}.__v__ = function (specifier) {
|
|
21022
20702
|
return __versionMappings__[specifier] || specifier
|
|
21023
20703
|
};
|
|
21024
|
-
})()
|
|
21025
|
-
`;
|
|
20704
|
+
})();`;
|
|
21026
20705
|
};
|
|
21027
20706
|
const injectVersionMappingsAsImportmap = async ({
|
|
21028
20707
|
urlInfo,
|
|
@@ -21035,18 +20714,15 @@ const injectVersionMappingsAsImportmap = async ({
|
|
|
21035
20714
|
// jsenv_plugin_importmap.js is removing importmap during build
|
|
21036
20715
|
// it means at this point we know HTML has no importmap in it
|
|
21037
20716
|
// we can safely inject one
|
|
21038
|
-
|
|
20717
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
21039
20718
|
tagName: "script",
|
|
21040
20719
|
type: "importmap",
|
|
21041
20720
|
textContent: kitchen.kitchenContext.minification ? JSON.stringify({
|
|
21042
20721
|
imports: versionMappings
|
|
21043
|
-
}) :
|
|
21044
|
-
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
`
|
|
21048
|
-
});
|
|
21049
|
-
injectScriptNodeAsEarlyAsPossible(htmlAst, importmapNode, "jsenv:versioning");
|
|
20722
|
+
}) : JSON.stringify({
|
|
20723
|
+
imports: versionMappings
|
|
20724
|
+
}, null, " ")
|
|
20725
|
+
}), "jsenv:versioning");
|
|
21050
20726
|
kitchen.urlInfoTransformer.applyFinalTransformations(urlInfo, {
|
|
21051
20727
|
content: stringifyHtmlAst(htmlAst)
|
|
21052
20728
|
});
|
|
@@ -21121,7 +20797,7 @@ const defaultRuntimeCompat = {
|
|
|
21121
20797
|
* Controls if url in build file contents are versioned
|
|
21122
20798
|
* @param {('search_param'|'filename')} [buildParameters.versioningMethod="search_param"]
|
|
21123
20799
|
* Controls how url are versioned
|
|
21124
|
-
* @param {
|
|
20800
|
+
* @param {('none'|'inline'|'file'|'programmatic'} [buildParameters.sourcemaps="none"]
|
|
21125
20801
|
* Generate sourcemaps in the build directory
|
|
21126
20802
|
* @return {Object} buildReturnValue
|
|
21127
20803
|
* @return {Object} buildReturnValue.buildFileContents
|
|
@@ -21142,7 +20818,7 @@ const build = async ({
|
|
|
21142
20818
|
runtimeCompat = defaultRuntimeCompat,
|
|
21143
20819
|
base = runtimeCompat.node ? "./" : "/",
|
|
21144
20820
|
plugins = [],
|
|
21145
|
-
sourcemaps =
|
|
20821
|
+
sourcemaps = "none",
|
|
21146
20822
|
sourcemapsSourcesContent,
|
|
21147
20823
|
urlAnalysis = {},
|
|
21148
20824
|
urlResolution,
|
|
@@ -21305,6 +20981,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
21305
20981
|
babelHelpersAsImport: !explicitJsModuleFallback,
|
|
21306
20982
|
jsModuleFallbackOnJsClassic: false
|
|
21307
20983
|
},
|
|
20984
|
+
inlining: false,
|
|
21308
20985
|
scenarioPlaceholders
|
|
21309
20986
|
})],
|
|
21310
20987
|
sourcemaps,
|
|
@@ -21343,9 +21020,9 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21343
21020
|
...contextSharedDuringBuild,
|
|
21344
21021
|
plugins: [urlAnalysisPlugin, ...(lineBreakNormalization ? [jsenvPluginLineBreakNormalization()] : []), jsenvPluginJsModuleFallback({
|
|
21345
21022
|
systemJsInjection: true
|
|
21346
|
-
}),
|
|
21023
|
+
}), jsenvPluginInlineContentAnalysis({
|
|
21347
21024
|
fetchInlineUrls: false
|
|
21348
|
-
}), {
|
|
21025
|
+
}), jsenvPluginInlining(), {
|
|
21349
21026
|
name: "jsenv:build",
|
|
21350
21027
|
appliesDuring: "build",
|
|
21351
21028
|
resolveUrl: reference => {
|
|
@@ -21382,16 +21059,25 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21382
21059
|
return reference.url;
|
|
21383
21060
|
}
|
|
21384
21061
|
if (reference.isInline) {
|
|
21062
|
+
const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl);
|
|
21063
|
+
const parentRawUrl = parentUrlInfo.originalUrl;
|
|
21385
21064
|
const rawUrlInfo = GRAPH.find(rawGraph, rawUrlInfo => {
|
|
21386
|
-
|
|
21387
|
-
|
|
21065
|
+
const {
|
|
21066
|
+
inlineUrlSite
|
|
21067
|
+
} = rawUrlInfo;
|
|
21068
|
+
// not inline
|
|
21069
|
+
if (!inlineUrlSite) return false;
|
|
21070
|
+
if (inlineUrlSite.url === parentRawUrl && inlineUrlSite.line === reference.specifierLine && inlineUrlSite.column === reference.specifierColumn) {
|
|
21071
|
+
return true;
|
|
21388
21072
|
}
|
|
21389
21073
|
if (rawUrlInfo.content === reference.content) {
|
|
21390
21074
|
return true;
|
|
21391
21075
|
}
|
|
21392
|
-
|
|
21076
|
+
if (rawUrlInfo.originalContent === reference.content) {
|
|
21077
|
+
return true;
|
|
21078
|
+
}
|
|
21079
|
+
return false;
|
|
21393
21080
|
});
|
|
21394
|
-
const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl);
|
|
21395
21081
|
if (!rawUrlInfo) {
|
|
21396
21082
|
// generated during final graph
|
|
21397
21083
|
// (happens for JSON.parse injected for import assertions for instance)
|
|
@@ -21521,7 +21207,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21521
21207
|
const rawUrl = buildDirectoryRedirections.get(url) || url;
|
|
21522
21208
|
const rawUrlInfo = rawGraph.getUrlInfo(rawUrl);
|
|
21523
21209
|
if (!rawUrlInfo) {
|
|
21524
|
-
throw new Error(createDetailedMessage
|
|
21210
|
+
throw new Error(createDetailedMessage(`Cannot find url`, {
|
|
21525
21211
|
url,
|
|
21526
21212
|
"raw urls": Array.from(buildDirectoryRedirections.values()),
|
|
21527
21213
|
"build urls": Array.from(buildDirectoryRedirections.keys())
|
|
@@ -21559,6 +21245,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21559
21245
|
return rawUrlInfo;
|
|
21560
21246
|
}
|
|
21561
21247
|
if (reference.isInline) {
|
|
21248
|
+
if (reference.prev && !reference.prev.isInline) {
|
|
21249
|
+
const urlBeforeRedirect = findKey(finalRedirections, reference.prev.url);
|
|
21250
|
+
return fromBundleOrRawGraph(urlBeforeRedirect);
|
|
21251
|
+
}
|
|
21562
21252
|
return fromBundleOrRawGraph(reference.url);
|
|
21563
21253
|
}
|
|
21564
21254
|
// reference updated during "postbuild":
|
|
@@ -22007,7 +21697,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22007
21697
|
build: true,
|
|
22008
21698
|
runtimeCompat,
|
|
22009
21699
|
...contextSharedDuringBuild,
|
|
22010
|
-
plugins: [urlAnalysisPlugin,
|
|
21700
|
+
plugins: [urlAnalysisPlugin, jsenvPluginInlineContentAnalysis({
|
|
22011
21701
|
fetchInlineUrls: false,
|
|
22012
21702
|
analyzeConvertedScripts: true,
|
|
22013
21703
|
// to be able to version their urls
|
|
@@ -22280,7 +21970,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22280
21970
|
type: getHtmlNodeAttribute(hintNode, "type"),
|
|
22281
21971
|
crossorigin: getHtmlNodeAttribute(hintNode, "crossorigin")
|
|
22282
21972
|
});
|
|
22283
|
-
insertHtmlNodeAfter(nodeToInsert, hintNode
|
|
21973
|
+
insertHtmlNodeAfter(nodeToInsert, hintNode);
|
|
22284
21974
|
});
|
|
22285
21975
|
}
|
|
22286
21976
|
});
|
|
@@ -22591,7 +22281,7 @@ const jsenvPluginServerEventsClientInjection = () => {
|
|
|
22591
22281
|
expectedType: "js_module",
|
|
22592
22282
|
specifier: serverEventsClientFileUrl
|
|
22593
22283
|
});
|
|
22594
|
-
|
|
22284
|
+
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
22595
22285
|
tagName: "script",
|
|
22596
22286
|
type: "module",
|
|
22597
22287
|
src: serverEventsClientFileReference.generatedSpecifier
|
|
@@ -22953,7 +22643,7 @@ const createFileService = ({
|
|
|
22953
22643
|
if (code === "PARSE_ERROR") {
|
|
22954
22644
|
// when possible let browser re-throw the syntax error
|
|
22955
22645
|
// it's not possible to do that when url info content is not available
|
|
22956
|
-
// (happens for
|
|
22646
|
+
// (happens for js_module_fallback for instance)
|
|
22957
22647
|
if (urlInfo.content !== undefined) {
|
|
22958
22648
|
return {
|
|
22959
22649
|
url: reference.url,
|
|
@@ -23523,7 +23213,7 @@ const generateFileExecutionSteps = ({
|
|
|
23523
23213
|
return;
|
|
23524
23214
|
}
|
|
23525
23215
|
if (typeof stepConfig !== "object") {
|
|
23526
|
-
throw new TypeError(createDetailedMessage
|
|
23216
|
+
throw new TypeError(createDetailedMessage(`found unexpected value in plan, they must be object`, {
|
|
23527
23217
|
["file relative path"]: fileRelativeUrl,
|
|
23528
23218
|
["execution name"]: executionName,
|
|
23529
23219
|
["value"]: stepConfig
|
|
@@ -23590,7 +23280,7 @@ const readNodeV8CoverageDirectory = async ({
|
|
|
23590
23280
|
timeSpentTrying += 200;
|
|
23591
23281
|
return tryReadJsonFile();
|
|
23592
23282
|
}
|
|
23593
|
-
console.warn(createDetailedMessage
|
|
23283
|
+
console.warn(createDetailedMessage(`Error while reading coverage file`, {
|
|
23594
23284
|
"error stack": e.stack,
|
|
23595
23285
|
"file": dirEntryUrl
|
|
23596
23286
|
}));
|
|
@@ -23751,7 +23441,7 @@ const composeV8AndIstanbul = (v8FileByFileCoverage, istanbulFileByFileCoverage,
|
|
|
23751
23441
|
const v8Coverage = v8FileByFileCoverage[key];
|
|
23752
23442
|
if (v8Coverage) {
|
|
23753
23443
|
if (coverageV8ConflictWarning) {
|
|
23754
|
-
console.warn(createDetailedMessage
|
|
23444
|
+
console.warn(createDetailedMessage(`Coverage conflict on "${key}", found two coverage that cannot be merged together: v8 and istanbul. The istanbul coverage will be ignored.`, {
|
|
23755
23445
|
details: `This happens when a file is executed on a runtime using v8 coverage (node or chromium) and on runtime using istanbul coverage (firefox or webkit)`,
|
|
23756
23446
|
suggestion: "You can disable this warning with coverageV8ConflictWarning: false"
|
|
23757
23447
|
}));
|
|
@@ -23856,7 +23546,7 @@ const relativeUrlToEmptyCoverage = async (relativeUrl, {
|
|
|
23856
23546
|
const operation = Abort.startOperation();
|
|
23857
23547
|
operation.addAbortSignal(signal);
|
|
23858
23548
|
try {
|
|
23859
|
-
const fileUrl = resolveUrl
|
|
23549
|
+
const fileUrl = resolveUrl(relativeUrl, rootDirectoryUrl);
|
|
23860
23550
|
const content = await readFile(fileUrl, {
|
|
23861
23551
|
as: "string"
|
|
23862
23552
|
});
|
|
@@ -25137,7 +24827,7 @@ const executeTestPlan = async ({
|
|
|
25137
24827
|
});
|
|
25138
24828
|
if (patternsMatchingCoverAndExecute.length) {
|
|
25139
24829
|
// It would be strange, for a given file to be both covered and executed
|
|
25140
|
-
throw new Error(createDetailedMessage
|
|
24830
|
+
throw new Error(createDetailedMessage(`some file will be both covered and executed`, {
|
|
25141
24831
|
patterns: patternsMatchingCoverAndExecute
|
|
25142
24832
|
}));
|
|
25143
24833
|
}
|
|
@@ -25166,7 +24856,7 @@ const executeTestPlan = async ({
|
|
|
25166
24856
|
const logger = createLogger({
|
|
25167
24857
|
logLevel
|
|
25168
24858
|
});
|
|
25169
|
-
logger.debug(createDetailedMessage
|
|
24859
|
+
logger.debug(createDetailedMessage(`Prepare executing plan`, {
|
|
25170
24860
|
runtimes: JSON.stringify(runtimes, null, " ")
|
|
25171
24861
|
}));
|
|
25172
24862
|
|
|
@@ -25182,7 +24872,7 @@ const executeTestPlan = async ({
|
|
|
25182
24872
|
await ensureEmptyDirectory(process.env.NODE_V8_COVERAGE);
|
|
25183
24873
|
} else {
|
|
25184
24874
|
coverageMethodForNodeJs = "Profiler";
|
|
25185
|
-
logger.warn(createDetailedMessage
|
|
24875
|
+
logger.warn(createDetailedMessage(`process.env.NODE_V8_COVERAGE is required to generate coverage for Node.js subprocesses`, {
|
|
25186
24876
|
"suggestion": `set process.env.NODE_V8_COVERAGE`,
|
|
25187
24877
|
"suggestion 2": `use coverageMethodForNodeJs: "Profiler". But it means coverage for child_process and worker_thread cannot be collected`
|
|
25188
24878
|
}));
|
|
@@ -25899,7 +25589,7 @@ const importPlaywright = async ({
|
|
|
25899
25589
|
return namespace;
|
|
25900
25590
|
} catch (e) {
|
|
25901
25591
|
if (e.code === "ERR_MODULE_NOT_FOUND") {
|
|
25902
|
-
throw new Error(createDetailedMessage
|
|
25592
|
+
throw new Error(createDetailedMessage(`"playwright" not found. You need playwright in your dependencies to use "${browserName}"`, {
|
|
25903
25593
|
suggestion: `npm install --save-dev playwright`
|
|
25904
25594
|
}), {
|
|
25905
25595
|
cause: e
|
|
@@ -26010,7 +25700,12 @@ const ExecOptions = {
|
|
|
26010
25700
|
while (i < execArgv.length) {
|
|
26011
25701
|
const execArg = execArgv[i];
|
|
26012
25702
|
const option = execOptionFromExecArg(execArg);
|
|
26013
|
-
execOptions[option.name]
|
|
25703
|
+
const existing = execOptions[option.name];
|
|
25704
|
+
if (existing) {
|
|
25705
|
+
execOptions[option.name] = Array.isArray(existing) ? [...existing, option.value] : [existing, option.value];
|
|
25706
|
+
} else {
|
|
25707
|
+
execOptions[option.name] = option.value;
|
|
25708
|
+
}
|
|
26014
25709
|
i++;
|
|
26015
25710
|
}
|
|
26016
25711
|
return execOptions;
|
|
@@ -26026,7 +25721,13 @@ const ExecOptions = {
|
|
|
26026
25721
|
execArgv.push(optionName);
|
|
26027
25722
|
return;
|
|
26028
25723
|
}
|
|
26029
|
-
|
|
25724
|
+
if (Array.isArray(optionValue)) {
|
|
25725
|
+
optionValue.forEach(subValue => {
|
|
25726
|
+
execArgv.push(`${optionName}=${subValue}`);
|
|
25727
|
+
});
|
|
25728
|
+
} else {
|
|
25729
|
+
execArgv.push(`${optionName}=${optionValue}`);
|
|
25730
|
+
}
|
|
26030
25731
|
});
|
|
26031
25732
|
return execArgv;
|
|
26032
25733
|
}
|
|
@@ -26057,7 +25758,7 @@ const createChildExecOptions = async ({
|
|
|
26057
25758
|
debugModeInheritBreak = true
|
|
26058
25759
|
} = {}) => {
|
|
26059
25760
|
if (typeof debugMode === "string" && AVAILABLE_DEBUG_MODE.indexOf(debugMode) === -1) {
|
|
26060
|
-
throw new TypeError(createDetailedMessage
|
|
25761
|
+
throw new TypeError(createDetailedMessage(`unexpected debug mode.`, {
|
|
26061
25762
|
["debug mode"]: debugMode,
|
|
26062
25763
|
["allowed debug mode"]: AVAILABLE_DEBUG_MODE
|
|
26063
25764
|
}));
|
|
@@ -26254,6 +25955,10 @@ const EXIT_CODES = {
|
|
|
26254
25955
|
SIGTERM: 128 + SIGTERM_SIGNAL_NUMBER
|
|
26255
25956
|
};
|
|
26256
25957
|
|
|
25958
|
+
const IMPORTMAP_NODE_LOADER_FILE_URL = new URL("./importmap_node_loader.mjs?entry_point=", import.meta.url).href;
|
|
25959
|
+
|
|
25960
|
+
const NO_EXPERIMENTAL_WARNING_FILE_URL = new URL("./no_experimental_warnings.cjs?entry_point=", import.meta.url).href;
|
|
25961
|
+
|
|
26257
25962
|
const CONTROLLABLE_CHILD_PROCESS_URL = new URL("./controllable_child_process.mjs?entry_point=", import.meta.url).href;
|
|
26258
25963
|
const nodeChildProcess = {
|
|
26259
25964
|
type: "node",
|
|
@@ -26266,6 +25971,7 @@ nodeChildProcess.run = async ({
|
|
|
26266
25971
|
logProcessCommand = false,
|
|
26267
25972
|
rootDirectoryUrl,
|
|
26268
25973
|
fileRelativeUrl,
|
|
25974
|
+
importMap,
|
|
26269
25975
|
keepRunning,
|
|
26270
25976
|
gracefulStopAllocatedMs = 4000,
|
|
26271
25977
|
stopSignal,
|
|
@@ -26296,6 +26002,12 @@ nodeChildProcess.run = async ({
|
|
|
26296
26002
|
env.NODE_V8_COVERAGE = "";
|
|
26297
26003
|
}
|
|
26298
26004
|
commandLineOptions = ["--experimental-import-meta-resolve", ...commandLineOptions];
|
|
26005
|
+
if (importMap) {
|
|
26006
|
+
env.IMPORT_MAP = JSON.stringify(importMap);
|
|
26007
|
+
env.IMPORT_MAP_BASE_URL = rootDirectoryUrl;
|
|
26008
|
+
commandLineOptions.push(`--experimental-loader=${fileURLToPath(IMPORTMAP_NODE_LOADER_FILE_URL)}`);
|
|
26009
|
+
commandLineOptions.push(`--require=${fileURLToPath(NO_EXPERIMENTAL_WARNING_FILE_URL)}`);
|
|
26010
|
+
}
|
|
26299
26011
|
const cleanupCallbackList = createCallbackListNotifiedOnce();
|
|
26300
26012
|
const cleanup = async reason => {
|
|
26301
26013
|
await cleanupCallbackList.notify({
|
|
@@ -26321,9 +26033,10 @@ nodeChildProcess.run = async ({
|
|
|
26321
26033
|
execArgv,
|
|
26322
26034
|
// silent: true
|
|
26323
26035
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
26324
|
-
env: envForChildProcess
|
|
26036
|
+
env: envForChildProcess,
|
|
26037
|
+
cwd: new URL(rootDirectoryUrl)
|
|
26325
26038
|
});
|
|
26326
|
-
logger.debug(createDetailedMessage
|
|
26039
|
+
logger.debug(createDetailedMessage(`child process forked (pid ${childProcess.pid})`, {
|
|
26327
26040
|
"custom env": JSON.stringify(env, null, " ")
|
|
26328
26041
|
}));
|
|
26329
26042
|
// if we pass stream, pipe them https://github.com/sindresorhus/execa/issues/81
|
|
@@ -26584,6 +26297,7 @@ nodeWorkerThread.run = async ({
|
|
|
26584
26297
|
// logger,
|
|
26585
26298
|
rootDirectoryUrl,
|
|
26586
26299
|
fileRelativeUrl,
|
|
26300
|
+
importMap,
|
|
26587
26301
|
keepRunning,
|
|
26588
26302
|
stopSignal,
|
|
26589
26303
|
onConsole,
|
|
@@ -26610,6 +26324,12 @@ nodeWorkerThread.run = async ({
|
|
|
26610
26324
|
if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
|
|
26611
26325
|
env.NODE_V8_COVERAGE = "";
|
|
26612
26326
|
}
|
|
26327
|
+
if (importMap) {
|
|
26328
|
+
env.IMPORT_MAP = JSON.stringify(importMap);
|
|
26329
|
+
env.IMPORT_MAP_BASE_URL = rootDirectoryUrl;
|
|
26330
|
+
commandLineOptions.push(`--experimental-loader=${fileURLToPath(IMPORTMAP_NODE_LOADER_FILE_URL)}`);
|
|
26331
|
+
commandLineOptions.push(`--require=${fileURLToPath(NO_EXPERIMENTAL_WARNING_FILE_URL)}`);
|
|
26332
|
+
}
|
|
26613
26333
|
const workerThreadExecOptions = await createChildExecOptions({
|
|
26614
26334
|
signal,
|
|
26615
26335
|
debugPort,
|
|
@@ -26995,6 +26715,7 @@ const execute = async ({
|
|
|
26995
26715
|
logLevel,
|
|
26996
26716
|
rootDirectoryUrl,
|
|
26997
26717
|
webServer,
|
|
26718
|
+
importMap,
|
|
26998
26719
|
fileRelativeUrl,
|
|
26999
26720
|
allocatedMs,
|
|
27000
26721
|
mirrorConsole = true,
|
|
@@ -27028,6 +26749,7 @@ const execute = async ({
|
|
|
27028
26749
|
rootDirectoryUrl,
|
|
27029
26750
|
webServer,
|
|
27030
26751
|
fileRelativeUrl,
|
|
26752
|
+
importMap,
|
|
27031
26753
|
...runtimeParams
|
|
27032
26754
|
};
|
|
27033
26755
|
let result = await run({
|