@jsenv/core 36.0.1 → 36.1.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/ribbon.js +4 -0
- package/dist/jsenv_core.js +188 -912
- package/package.json +4 -4
- package/src/build/build.js +33 -36
- package/src/dev/file_service.js +6 -4
- package/src/dev/start_dev_server.js +6 -4
- package/src/kitchen/kitchen.js +71 -13
- package/src/kitchen/url_graph/url_graph_report.js +9 -5
- package/src/kitchen/url_graph.js +0 -1
- package/src/plugins/plugin_controller.js +15 -7
- package/src/plugins/plugins.js +11 -12
- package/src/plugins/{file_urls/jsenv_plugin_file_urls.js → protocol_file/jsenv_plugin_protocol_file.js} +50 -45
- package/src/plugins/{http_urls/jsenv_plugin_http_urls.js → protocol_http/jsenv_plugin_protocol_http.js} +6 -5
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +0 -69
- package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +3 -3
- package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +15 -38
- package/src/plugins/ribbon/client/ribbon.js +9 -0
- package/dist/js/supervisor.js +0 -1175
- package/src/helpers/basic_fetch.js +0 -53
- package/src/helpers/ping_server.js +0 -30
- package/src/plugins/supervisor/client/supervisor.js +0 -1153
- package/src/plugins/supervisor/html_supervisor_injection.js +0 -281
- package/src/plugins/supervisor/js_supervisor_injection.js +0 -283
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +0 -218
- /package/src/plugins/{url_type_from_reference.js → resolution_node_esm/url_type_from_reference.js} +0 -0
package/dist/jsenv_core.js
CHANGED
|
@@ -13,10 +13,11 @@ import http from "node:http";
|
|
|
13
13
|
import { Readable, Stream, Writable } from "node:stream";
|
|
14
14
|
import { Http2ServerResponse } from "node:http2";
|
|
15
15
|
import { lookup } from "node:dns";
|
|
16
|
-
import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource
|
|
16
|
+
import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource } from "@jsenv/sourcemap";
|
|
17
17
|
import { parseHtmlString, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, stringifyHtmlAst, parseSrcSet, getHtmlNodeText, setHtmlNodeAttributes, getHtmlNodePosition, getHtmlNodeAttributePosition, removeHtmlNodeText, setHtmlNodeText, parseCssUrls, parseJsUrls, applyBabelPlugins, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
19
19
|
import babelParser from "@babel/parser";
|
|
20
|
+
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
20
21
|
|
|
21
22
|
/*
|
|
22
23
|
* data:[<mediatype>][;base64],<data>
|
|
@@ -7290,8 +7291,6 @@ const generateAccessControlHeaders = ({
|
|
|
7290
7291
|
};
|
|
7291
7292
|
};
|
|
7292
7293
|
|
|
7293
|
-
new Map();
|
|
7294
|
-
|
|
7295
7294
|
const lookupPackageDirectory = currentUrl => {
|
|
7296
7295
|
if (currentUrl === "file:///") {
|
|
7297
7296
|
return null;
|
|
@@ -7806,7 +7805,6 @@ const createUrlInfo = url => {
|
|
|
7806
7805
|
originalUrl: undefined,
|
|
7807
7806
|
filename: "",
|
|
7808
7807
|
isEntryPoint: false,
|
|
7809
|
-
shouldHandle: undefined,
|
|
7810
7808
|
originalContent: undefined,
|
|
7811
7809
|
content: undefined,
|
|
7812
7810
|
sourcemap: null,
|
|
@@ -7972,7 +7970,7 @@ const createPluginController = kitchenContext => {
|
|
|
7972
7970
|
if (info.timing) {
|
|
7973
7971
|
info.timing[`${hook.name}-${hook.plugin.name.replace("jsenv:", "")}`] = performance$1.now() - startTimestamp;
|
|
7974
7972
|
}
|
|
7975
|
-
valueReturned = assertAndNormalizeReturnValue(hook.name, valueReturned);
|
|
7973
|
+
valueReturned = assertAndNormalizeReturnValue(hook.name, valueReturned, info);
|
|
7976
7974
|
return valueReturned;
|
|
7977
7975
|
};
|
|
7978
7976
|
const callAsyncHook = async (hook, info, context) => {
|
|
@@ -7993,7 +7991,7 @@ const createPluginController = kitchenContext => {
|
|
|
7993
7991
|
if (info.timing) {
|
|
7994
7992
|
info.timing[`${hook.name}-${hook.plugin.name.replace("jsenv:", "")}`] = performance$1.now() - startTimestamp;
|
|
7995
7993
|
}
|
|
7996
|
-
valueReturned = assertAndNormalizeReturnValue(hook.name, valueReturned);
|
|
7994
|
+
valueReturned = assertAndNormalizeReturnValue(hook.name, valueReturned, info);
|
|
7997
7995
|
return valueReturned;
|
|
7998
7996
|
};
|
|
7999
7997
|
const callHooks = (hookName, info, context, callback) => {
|
|
@@ -8085,7 +8083,7 @@ info = {}) => {
|
|
|
8085
8083
|
}
|
|
8086
8084
|
return hookValue;
|
|
8087
8085
|
};
|
|
8088
|
-
const assertAndNormalizeReturnValue = (hookName, returnValue) => {
|
|
8086
|
+
const assertAndNormalizeReturnValue = (hookName, returnValue, info) => {
|
|
8089
8087
|
// all hooks are allowed to return null/undefined as a signal of "I don't do anything"
|
|
8090
8088
|
if (returnValue === null || returnValue === undefined) {
|
|
8091
8089
|
return returnValue;
|
|
@@ -8094,7 +8092,7 @@ const assertAndNormalizeReturnValue = (hookName, returnValue) => {
|
|
|
8094
8092
|
if (!returnValueAssertion.appliesTo.includes(hookName)) {
|
|
8095
8093
|
continue;
|
|
8096
8094
|
}
|
|
8097
|
-
const assertionResult = returnValueAssertion.assertion(returnValue);
|
|
8095
|
+
const assertionResult = returnValueAssertion.assertion(returnValue, info);
|
|
8098
8096
|
if (assertionResult !== undefined) {
|
|
8099
8097
|
// normalization
|
|
8100
8098
|
returnValue = assertionResult;
|
|
@@ -8118,7 +8116,7 @@ const returnValueAssertions = [{
|
|
|
8118
8116
|
}, {
|
|
8119
8117
|
name: "content_assertion",
|
|
8120
8118
|
appliesTo: ["fetchUrlContent", "transformUrlContent", "finalizeUrlContent", "optimizeUrlContent"],
|
|
8121
|
-
assertion: valueReturned => {
|
|
8119
|
+
assertion: (valueReturned, urlInfo) => {
|
|
8122
8120
|
if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
|
|
8123
8121
|
return {
|
|
8124
8122
|
content: valueReturned
|
|
@@ -8126,11 +8124,10 @@ const returnValueAssertions = [{
|
|
|
8126
8124
|
}
|
|
8127
8125
|
if (typeof valueReturned === "object") {
|
|
8128
8126
|
const {
|
|
8129
|
-
shouldHandle,
|
|
8130
8127
|
content,
|
|
8131
8128
|
body
|
|
8132
8129
|
} = valueReturned;
|
|
8133
|
-
if (
|
|
8130
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
8134
8131
|
return undefined;
|
|
8135
8132
|
}
|
|
8136
8133
|
if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
|
|
@@ -9102,6 +9099,9 @@ const createKitchen = ({
|
|
|
9102
9099
|
logLevel,
|
|
9103
9100
|
rootDirectoryUrl,
|
|
9104
9101
|
mainFilePath,
|
|
9102
|
+
ignore,
|
|
9103
|
+
ignoreProtocol = "remove",
|
|
9104
|
+
supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
|
|
9105
9105
|
urlGraph,
|
|
9106
9106
|
dev = false,
|
|
9107
9107
|
build = false,
|
|
@@ -9147,6 +9147,35 @@ const createKitchen = ({
|
|
|
9147
9147
|
plugins.forEach(pluginEntry => {
|
|
9148
9148
|
pluginController.pushPlugin(pluginEntry);
|
|
9149
9149
|
});
|
|
9150
|
+
const isIgnoredByProtocol = url => {
|
|
9151
|
+
const {
|
|
9152
|
+
protocol
|
|
9153
|
+
} = new URL(url);
|
|
9154
|
+
const protocolIsSupported = supportedProtocols.some(supportedProtocol => protocol === supportedProtocol);
|
|
9155
|
+
return !protocolIsSupported;
|
|
9156
|
+
};
|
|
9157
|
+
let isIgnoredByParam = () => false;
|
|
9158
|
+
if (ignore) {
|
|
9159
|
+
const associations = URL_META.resolveAssociations({
|
|
9160
|
+
ignore
|
|
9161
|
+
}, rootDirectoryUrl);
|
|
9162
|
+
const cache = new Map();
|
|
9163
|
+
isIgnoredByParam = url => {
|
|
9164
|
+
const fromCache = cache.get(url);
|
|
9165
|
+
if (fromCache) return fromCache;
|
|
9166
|
+
const {
|
|
9167
|
+
ignore
|
|
9168
|
+
} = URL_META.applyAssociations({
|
|
9169
|
+
url,
|
|
9170
|
+
associations
|
|
9171
|
+
});
|
|
9172
|
+
cache.set(url, ignore);
|
|
9173
|
+
return ignore;
|
|
9174
|
+
};
|
|
9175
|
+
}
|
|
9176
|
+
const isIgnored = url => {
|
|
9177
|
+
return isIgnoredByProtocol(url) || isIgnoredByParam(url);
|
|
9178
|
+
};
|
|
9150
9179
|
|
|
9151
9180
|
/*
|
|
9152
9181
|
* - "http_request"
|
|
@@ -9192,7 +9221,6 @@ const createKitchen = ({
|
|
|
9192
9221
|
specifierColumn,
|
|
9193
9222
|
baseUrl,
|
|
9194
9223
|
isOriginalPosition,
|
|
9195
|
-
shouldHandle,
|
|
9196
9224
|
isEntryPoint = false,
|
|
9197
9225
|
isResourceHint = false,
|
|
9198
9226
|
isImplicit = false,
|
|
@@ -9241,7 +9269,6 @@ const createKitchen = ({
|
|
|
9241
9269
|
specifierColumn,
|
|
9242
9270
|
isOriginalPosition,
|
|
9243
9271
|
baseUrl,
|
|
9244
|
-
shouldHandle,
|
|
9245
9272
|
isEntryPoint,
|
|
9246
9273
|
isResourceHint,
|
|
9247
9274
|
isImplicit,
|
|
@@ -9286,13 +9313,29 @@ const createKitchen = ({
|
|
|
9286
9313
|
url = normalizeUrl(url);
|
|
9287
9314
|
let referencedUrlObject;
|
|
9288
9315
|
let searchParams;
|
|
9289
|
-
const
|
|
9316
|
+
const setReferenceUrl = referenceUrl => {
|
|
9317
|
+
// ignored urls are prefixed with "ignore:" so that reference are associated
|
|
9318
|
+
// to a dedicated urlInfo that is ignored.
|
|
9319
|
+
// this way it's only once a resource is referenced by reference that is not ignored
|
|
9320
|
+
// that the resource is cooked
|
|
9321
|
+
if (reference.specifier[0] === "#" &&
|
|
9322
|
+
// For Html, css and "#" refer to a resource in the page, reference must be preserved
|
|
9323
|
+
// However for js import specifiers they have a different meaning and we want
|
|
9324
|
+
// to resolve them (https://nodejs.org/api/packages.html#imports for instance)
|
|
9325
|
+
reference.type !== "js_import") {
|
|
9326
|
+
referenceUrl = `ignore:${referenceUrl}`;
|
|
9327
|
+
} else if (isIgnored(referenceUrl)) {
|
|
9328
|
+
referenceUrl = `ignore:${referenceUrl}`;
|
|
9329
|
+
}
|
|
9330
|
+
if (referenceUrl.startsWith("ignore:") && !reference.specifier.startsWith("ignore:")) {
|
|
9331
|
+
reference.specifier = `ignore:${reference.specifier}`;
|
|
9332
|
+
}
|
|
9290
9333
|
referencedUrlObject = new URL(referenceUrl);
|
|
9291
9334
|
searchParams = referencedUrlObject.searchParams;
|
|
9292
9335
|
reference.url = referenceUrl;
|
|
9293
9336
|
reference.searchParams = searchParams;
|
|
9294
9337
|
};
|
|
9295
|
-
|
|
9338
|
+
setReferenceUrl(url);
|
|
9296
9339
|
if (reference.debug) {
|
|
9297
9340
|
logger.debug(`url resolved by "${pluginController.getLastPluginUsed().name}"
|
|
9298
9341
|
${ANSI.color(reference.specifier, ANSI.GREY)} ->
|
|
@@ -9314,7 +9357,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9314
9357
|
...reference
|
|
9315
9358
|
};
|
|
9316
9359
|
updateReference(prevReference, reference);
|
|
9317
|
-
|
|
9360
|
+
setReferenceUrl(normalizedReturnValue);
|
|
9318
9361
|
});
|
|
9319
9362
|
reference.generatedUrl = reference.url;
|
|
9320
9363
|
const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url);
|
|
@@ -9333,8 +9376,16 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9333
9376
|
reference.generatedUrl = normalizeUrl(referencedUrlObject.href);
|
|
9334
9377
|
});
|
|
9335
9378
|
const returnValue = pluginController.callHooksUntil("formatReference", reference, referenceContext);
|
|
9336
|
-
reference.
|
|
9337
|
-
|
|
9379
|
+
if (reference.url.startsWith("ignore:")) {
|
|
9380
|
+
if (ignoreProtocol === "remove") {
|
|
9381
|
+
reference.specifier = reference.specifier.slice("ignore:".length);
|
|
9382
|
+
}
|
|
9383
|
+
reference.generatedSpecifier = reference.specifier;
|
|
9384
|
+
reference.generatedSpecifier = urlSpecifierEncoding.encode(reference);
|
|
9385
|
+
} else {
|
|
9386
|
+
reference.generatedSpecifier = returnValue || reference.generatedUrl;
|
|
9387
|
+
reference.generatedSpecifier = urlSpecifierEncoding.encode(reference);
|
|
9388
|
+
}
|
|
9338
9389
|
return [reference, urlInfo];
|
|
9339
9390
|
} catch (error) {
|
|
9340
9391
|
throw createResolveUrlError({
|
|
@@ -9504,7 +9555,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9504
9555
|
contextDuringFetch: context
|
|
9505
9556
|
});
|
|
9506
9557
|
};
|
|
9507
|
-
if (urlInfo.
|
|
9558
|
+
if (!urlInfo.url.startsWith("ignore:")) {
|
|
9508
9559
|
// references
|
|
9509
9560
|
const references = [];
|
|
9510
9561
|
context.referenceUtils = {
|
|
@@ -9834,11 +9885,6 @@ const traceFromUrlSite = urlSite => {
|
|
|
9834
9885
|
};
|
|
9835
9886
|
};
|
|
9836
9887
|
const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
9837
|
-
if (reference.shouldHandle) {
|
|
9838
|
-
urlInfo.shouldHandle = true;
|
|
9839
|
-
} else {
|
|
9840
|
-
urlInfo.shouldHandle = false;
|
|
9841
|
-
}
|
|
9842
9888
|
urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
|
|
9843
9889
|
if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
|
|
9844
9890
|
urlInfo.isEntryPoint = true;
|
|
@@ -10070,15 +10116,19 @@ const createUrlGraphReport = urlGraph => {
|
|
|
10070
10116
|
total: 0
|
|
10071
10117
|
};
|
|
10072
10118
|
urlGraph.urlInfoMap.forEach(urlInfo => {
|
|
10073
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
10074
|
-
return;
|
|
10075
|
-
}
|
|
10076
10119
|
// ignore:
|
|
10077
|
-
// - inline files: they are already taken into account in the file where they appear
|
|
10078
10120
|
// - ignored files: we don't know their content
|
|
10079
|
-
|
|
10121
|
+
// - inline files and data files: they are already taken into account in the file where they appear
|
|
10122
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
10123
|
+
return;
|
|
10124
|
+
}
|
|
10125
|
+
if (urlInfo.isInline) {
|
|
10126
|
+
return;
|
|
10127
|
+
}
|
|
10128
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
10080
10129
|
return;
|
|
10081
10130
|
}
|
|
10131
|
+
|
|
10082
10132
|
// file loaded via import assertion are already inside the graph
|
|
10083
10133
|
// their js module equivalent are ignored to avoid counting it twice
|
|
10084
10134
|
// in the build graph the file targeted by import assertion will likely be gone
|
|
@@ -11106,17 +11156,12 @@ const parseAndTransformJsReferences = async (urlInfo, context, {
|
|
|
11106
11156
|
};
|
|
11107
11157
|
|
|
11108
11158
|
const jsenvPluginReferenceAnalysis = ({
|
|
11109
|
-
include,
|
|
11110
|
-
supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
|
|
11111
11159
|
inlineContent = true,
|
|
11112
11160
|
inlineConvertedScript = false,
|
|
11113
11161
|
fetchInlineUrls = true,
|
|
11114
11162
|
allowEscapeForVersioning = false
|
|
11115
11163
|
}) => {
|
|
11116
|
-
return [
|
|
11117
|
-
include,
|
|
11118
|
-
supportedProtocols
|
|
11119
|
-
}), jsenvPluginDirectoryReferenceAnalysis(), jsenvPluginHtmlReferenceAnalysis({
|
|
11164
|
+
return [jsenvPluginDirectoryReferenceAnalysis(), jsenvPluginHtmlReferenceAnalysis({
|
|
11120
11165
|
inlineContent,
|
|
11121
11166
|
inlineConvertedScript
|
|
11122
11167
|
}), jsenvPluginWebmanifestReferenceAnalysis(), jsenvPluginCssReferenceAnalysis(), jsenvPluginJsReferenceAnalysis({
|
|
@@ -11124,65 +11169,6 @@ const jsenvPluginReferenceAnalysis = ({
|
|
|
11124
11169
|
allowEscapeForVersioning
|
|
11125
11170
|
}), ...(inlineContent ? [jsenvPluginDataUrlsAnalysis()] : []), ...(inlineContent && fetchInlineUrls ? [jsenvPluginInlineContentFetcher()] : []), jsenvPluginReferenceExpectedTypes()];
|
|
11126
11171
|
};
|
|
11127
|
-
const jsenvPluginReferenceAnalysisInclude = ({
|
|
11128
|
-
include,
|
|
11129
|
-
supportedProtocols
|
|
11130
|
-
}) => {
|
|
11131
|
-
// eslint-disable-next-line no-unused-vars
|
|
11132
|
-
let getIncludeInfo = url => undefined;
|
|
11133
|
-
return {
|
|
11134
|
-
name: "jsenv:reference_analysis_include",
|
|
11135
|
-
appliesDuring: "*",
|
|
11136
|
-
init: ({
|
|
11137
|
-
rootDirectoryUrl
|
|
11138
|
-
}) => {
|
|
11139
|
-
if (include) {
|
|
11140
|
-
const associations = URL_META.resolveAssociations({
|
|
11141
|
-
include
|
|
11142
|
-
}, rootDirectoryUrl);
|
|
11143
|
-
getIncludeInfo = url => {
|
|
11144
|
-
const {
|
|
11145
|
-
include
|
|
11146
|
-
} = URL_META.applyAssociations({
|
|
11147
|
-
url,
|
|
11148
|
-
associations
|
|
11149
|
-
});
|
|
11150
|
-
return include;
|
|
11151
|
-
};
|
|
11152
|
-
}
|
|
11153
|
-
},
|
|
11154
|
-
redirectReference: reference => {
|
|
11155
|
-
if (reference.shouldHandle !== undefined) {
|
|
11156
|
-
return;
|
|
11157
|
-
}
|
|
11158
|
-
if (reference.specifier[0] === "#" &&
|
|
11159
|
-
// For Html, css and in general "#" refer to a resource in the page
|
|
11160
|
-
// so that urls must be kept intact
|
|
11161
|
-
// However for js import specifiers they have a different meaning and we want
|
|
11162
|
-
// to resolve them (https://nodejs.org/api/packages.html#imports for instance)
|
|
11163
|
-
reference.type !== "js_import") {
|
|
11164
|
-
reference.shouldHandle = false;
|
|
11165
|
-
return;
|
|
11166
|
-
}
|
|
11167
|
-
const includeInfo = getIncludeInfo(reference.url);
|
|
11168
|
-
if (includeInfo === true) {
|
|
11169
|
-
reference.shouldHandle = true;
|
|
11170
|
-
return;
|
|
11171
|
-
}
|
|
11172
|
-
if (includeInfo === false) {
|
|
11173
|
-
reference.shouldHandle = false;
|
|
11174
|
-
return;
|
|
11175
|
-
}
|
|
11176
|
-
const {
|
|
11177
|
-
protocol
|
|
11178
|
-
} = new URL(reference.url);
|
|
11179
|
-
const protocolIsSupported = supportedProtocols.some(supportedProtocol => protocol === supportedProtocol);
|
|
11180
|
-
if (protocolIsSupported) {
|
|
11181
|
-
reference.shouldHandle = true;
|
|
11182
|
-
}
|
|
11183
|
-
}
|
|
11184
|
-
};
|
|
11185
|
-
};
|
|
11186
11172
|
const jsenvPluginInlineContentFetcher = () => {
|
|
11187
11173
|
return {
|
|
11188
11174
|
name: "jsenv:inline_content_fetcher",
|
|
@@ -17435,10 +17421,10 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
|
|
|
17435
17421
|
runtimeCompat,
|
|
17436
17422
|
preservesSymlink: true
|
|
17437
17423
|
});
|
|
17438
|
-
if (
|
|
17424
|
+
if (resolvers.js_module === undefined) {
|
|
17439
17425
|
resolvers.js_module = nodeEsmResolverDefault;
|
|
17440
17426
|
}
|
|
17441
|
-
if (
|
|
17427
|
+
if (resolvers.js_classic === undefined) {
|
|
17442
17428
|
resolvers.js_classic = (reference, context) => {
|
|
17443
17429
|
if (reference.subtype === "self_import_scripts_arg") {
|
|
17444
17430
|
return nodeEsmResolverDefault(reference, context);
|
|
@@ -17467,41 +17453,25 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
|
|
|
17467
17453
|
};
|
|
17468
17454
|
};
|
|
17469
17455
|
|
|
17470
|
-
const jsenvPluginWebResolution = (
|
|
17471
|
-
const resolvers = {};
|
|
17472
|
-
const resolveUsingWebResolution = (reference, context) => {
|
|
17473
|
-
if (reference.specifier === "/") {
|
|
17474
|
-
const {
|
|
17475
|
-
mainFilePath,
|
|
17476
|
-
rootDirectoryUrl
|
|
17477
|
-
} = context;
|
|
17478
|
-
return String(new URL(mainFilePath, rootDirectoryUrl));
|
|
17479
|
-
}
|
|
17480
|
-
if (reference.specifier[0] === "/") {
|
|
17481
|
-
return new URL(reference.specifier.slice(1), context.rootDirectoryUrl).href;
|
|
17482
|
-
}
|
|
17483
|
-
return new URL(reference.specifier,
|
|
17484
|
-
// baseUrl happens second argument to new URL() is different from
|
|
17485
|
-
// import.meta.url or document.currentScript.src
|
|
17486
|
-
reference.baseUrl || reference.parentUrl).href;
|
|
17487
|
-
};
|
|
17488
|
-
Object.keys(resolutionConfig).forEach(urlType => {
|
|
17489
|
-
const config = resolutionConfig[urlType];
|
|
17490
|
-
if (config === true) {
|
|
17491
|
-
resolvers[urlType] = resolveUsingWebResolution;
|
|
17492
|
-
} else if (config === false) {
|
|
17493
|
-
resolvers[urlType] = () => null;
|
|
17494
|
-
} else {
|
|
17495
|
-
throw new TypeError(`config must be true or false, got ${config} on "${urlType}"`);
|
|
17496
|
-
}
|
|
17497
|
-
});
|
|
17456
|
+
const jsenvPluginWebResolution = () => {
|
|
17498
17457
|
return {
|
|
17499
17458
|
name: "jsenv:web_resolution",
|
|
17500
17459
|
appliesDuring: "*",
|
|
17501
17460
|
resolveReference: (reference, context) => {
|
|
17502
|
-
|
|
17503
|
-
|
|
17504
|
-
|
|
17461
|
+
if (reference.specifier === "/") {
|
|
17462
|
+
const {
|
|
17463
|
+
mainFilePath,
|
|
17464
|
+
rootDirectoryUrl
|
|
17465
|
+
} = context;
|
|
17466
|
+
return String(new URL(mainFilePath, rootDirectoryUrl));
|
|
17467
|
+
}
|
|
17468
|
+
if (reference.specifier[0] === "/") {
|
|
17469
|
+
return new URL(reference.specifier.slice(1), context.rootDirectoryUrl).href;
|
|
17470
|
+
}
|
|
17471
|
+
return new URL(reference.specifier,
|
|
17472
|
+
// baseUrl happens second argument to new URL() is different from
|
|
17473
|
+
// import.meta.url or document.currentScript.src
|
|
17474
|
+
reference.baseUrl || reference.parentUrl).href;
|
|
17505
17475
|
}
|
|
17506
17476
|
};
|
|
17507
17477
|
};
|
|
@@ -17540,14 +17510,14 @@ const jsenvPluginVersionSearchParam = () => {
|
|
|
17540
17510
|
};
|
|
17541
17511
|
};
|
|
17542
17512
|
|
|
17543
|
-
const
|
|
17513
|
+
const jsenvPluginProtocolFile = ({
|
|
17544
17514
|
magicExtensions = ["inherit", ".js"],
|
|
17545
17515
|
magicDirectoryIndex = true,
|
|
17546
17516
|
preserveSymlinks = false,
|
|
17547
17517
|
directoryReferenceAllowed = false
|
|
17548
17518
|
}) => {
|
|
17549
17519
|
return [{
|
|
17550
|
-
name: "jsenv:
|
|
17520
|
+
name: "jsenv:fs_redirection",
|
|
17551
17521
|
appliesDuring: "*",
|
|
17552
17522
|
redirectReference: reference => {
|
|
17553
17523
|
// http, https, data, about, ...
|
|
@@ -17557,6 +17527,19 @@ const jsenvPluginFileUrls = ({
|
|
|
17557
17527
|
if (reference.isInline) {
|
|
17558
17528
|
return null;
|
|
17559
17529
|
}
|
|
17530
|
+
// ignore root file url
|
|
17531
|
+
if (reference.url === "file:///" || reference.url === "file://") {
|
|
17532
|
+
reference.leadsToADirectory = true;
|
|
17533
|
+
return `ignore:file:///`;
|
|
17534
|
+
}
|
|
17535
|
+
// ignore "./" on new URL("./")
|
|
17536
|
+
if (reference.subtype === "new_url_first_arg" && reference.specifier === "./") {
|
|
17537
|
+
return `ignore:${reference.url}`;
|
|
17538
|
+
}
|
|
17539
|
+
// ignore all new URL second arg
|
|
17540
|
+
if (reference.subtype === "new_url_second_arg") {
|
|
17541
|
+
return `ignore:${reference.url}`;
|
|
17542
|
+
}
|
|
17560
17543
|
const urlObject = new URL(reference.url);
|
|
17561
17544
|
let stat;
|
|
17562
17545
|
try {
|
|
@@ -17578,6 +17561,7 @@ const jsenvPluginFileUrls = ({
|
|
|
17578
17561
|
const pathnameUsesTrailingSlash = pathname.endsWith("/");
|
|
17579
17562
|
urlObject.search = "";
|
|
17580
17563
|
urlObject.hash = "";
|
|
17564
|
+
|
|
17581
17565
|
// force trailing slash on directories
|
|
17582
17566
|
if (stat && stat.isDirectory() && !pathnameUsesTrailingSlash) {
|
|
17583
17567
|
urlObject.pathname = `${pathname}/`;
|
|
@@ -17588,33 +17572,24 @@ const jsenvPluginFileUrls = ({
|
|
|
17588
17572
|
urlObject.pathname = pathname.slice(0, -1);
|
|
17589
17573
|
}
|
|
17590
17574
|
let url = urlObject.href;
|
|
17591
|
-
const
|
|
17592
|
-
|
|
17593
|
-
|
|
17594
|
-
|
|
17595
|
-
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
const filesystemResolution = applyFileSystemMagicResolution(url, {
|
|
17602
|
-
fileStat: stat,
|
|
17603
|
-
magicDirectoryIndex,
|
|
17604
|
-
magicExtensions: getExtensionsToTry(magicExtensions, reference.parentUrl)
|
|
17605
|
-
});
|
|
17606
|
-
if (filesystemResolution.stat) {
|
|
17607
|
-
stat = filesystemResolution.stat;
|
|
17608
|
-
url = filesystemResolution.url;
|
|
17609
|
-
}
|
|
17575
|
+
const shouldApplyDilesystemMagicResolution = reference.type === "js_import";
|
|
17576
|
+
if (shouldApplyDilesystemMagicResolution) {
|
|
17577
|
+
const filesystemResolution = applyFileSystemMagicResolution(url, {
|
|
17578
|
+
fileStat: stat,
|
|
17579
|
+
magicDirectoryIndex,
|
|
17580
|
+
magicExtensions: getExtensionsToTry(magicExtensions, reference.parentUrl)
|
|
17581
|
+
});
|
|
17582
|
+
if (filesystemResolution.stat) {
|
|
17583
|
+
stat = filesystemResolution.stat;
|
|
17584
|
+
url = filesystemResolution.url;
|
|
17610
17585
|
}
|
|
17611
|
-
|
|
17612
|
-
|
|
17613
|
-
|
|
17614
|
-
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
|
|
17586
|
+
}
|
|
17587
|
+
if (stat && stat.isDirectory()) {
|
|
17588
|
+
const directoryAllowed = reference.type === "filesystem" || typeof directoryReferenceAllowed === "function" && directoryReferenceAllowed(reference) || directoryReferenceAllowed;
|
|
17589
|
+
if (!directoryAllowed) {
|
|
17590
|
+
const error = new Error("Reference leads to a directory");
|
|
17591
|
+
error.code = "DIRECTORY_REFERENCE_NOT_ALLOWED";
|
|
17592
|
+
throw error;
|
|
17618
17593
|
}
|
|
17619
17594
|
}
|
|
17620
17595
|
reference.leadsToADirectory = stat && stat.isDirectory();
|
|
@@ -17626,7 +17601,7 @@ const jsenvPluginFileUrls = ({
|
|
|
17626
17601
|
return null;
|
|
17627
17602
|
}
|
|
17628
17603
|
}, {
|
|
17629
|
-
name: "jsenv:
|
|
17604
|
+
name: "jsenv:fs_resolution",
|
|
17630
17605
|
appliesDuring: "*",
|
|
17631
17606
|
resolveReference: {
|
|
17632
17607
|
filesystem: (reference, context) => {
|
|
@@ -17639,10 +17614,10 @@ const jsenvPluginFileUrls = ({
|
|
|
17639
17614
|
}
|
|
17640
17615
|
}
|
|
17641
17616
|
}, {
|
|
17642
|
-
name: "jsenv:@
|
|
17643
|
-
// during
|
|
17617
|
+
name: "jsenv:@fs",
|
|
17618
|
+
// during build it's fine to use "file://"" urls
|
|
17619
|
+
// but during dev it's a browser running the code
|
|
17644
17620
|
// so absolute file urls needs to be relativized
|
|
17645
|
-
// during build it's fine to use file:// urls
|
|
17646
17621
|
appliesDuring: "dev",
|
|
17647
17622
|
resolveReference: reference => {
|
|
17648
17623
|
if (reference.specifier.startsWith("/@fs/")) {
|
|
@@ -17697,715 +17672,17 @@ const resolveSymlink = fileUrl => {
|
|
|
17697
17672
|
return pathToFileURL(realpathSync(new URL(fileUrl))).href;
|
|
17698
17673
|
};
|
|
17699
17674
|
|
|
17700
|
-
const
|
|
17675
|
+
const jsenvPluginProtocolHttp = () => {
|
|
17701
17676
|
return {
|
|
17702
|
-
name: "jsenv:
|
|
17677
|
+
name: "jsenv:protocol_http",
|
|
17703
17678
|
appliesDuring: "*",
|
|
17704
17679
|
redirectReference: reference => {
|
|
17705
|
-
if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
|
|
17706
|
-
reference.shouldHandle = false;
|
|
17707
|
-
}
|
|
17708
17680
|
// TODO: according to some pattern matching jsenv could be allowed
|
|
17709
17681
|
// to fetch and transform http urls
|
|
17710
|
-
|
|
17711
|
-
|
|
17712
|
-
};
|
|
17713
|
-
|
|
17714
|
-
/*
|
|
17715
|
-
* ```js
|
|
17716
|
-
* console.log(42)
|
|
17717
|
-
* ```
|
|
17718
|
-
* becomes
|
|
17719
|
-
* ```js
|
|
17720
|
-
* window.__supervisor__.jsClassicStart('main.html@L10-L13.js')
|
|
17721
|
-
* try {
|
|
17722
|
-
* console.log(42)
|
|
17723
|
-
* window.__supervisor__.jsClassicEnd('main.html@L10-L13.js')
|
|
17724
|
-
* } catch(e) {
|
|
17725
|
-
* window.__supervisor__.jsClassicError('main.html@L10-L13.js', e)
|
|
17726
|
-
* }
|
|
17727
|
-
* ```
|
|
17728
|
-
*
|
|
17729
|
-
* ```js
|
|
17730
|
-
* import value from "./file.js"
|
|
17731
|
-
* console.log(value)
|
|
17732
|
-
* ```
|
|
17733
|
-
* becomes
|
|
17734
|
-
* ```js
|
|
17735
|
-
* window.__supervisor__.jsModuleStart('main.html@L10-L13.js')
|
|
17736
|
-
* try {
|
|
17737
|
-
* const value = await import("./file.js")
|
|
17738
|
-
* console.log(value)
|
|
17739
|
-
* window.__supervisor__.jsModuleEnd('main.html@L10-L13.js')
|
|
17740
|
-
* } catch(e) {
|
|
17741
|
-
* window.__supervisor__.jsModuleError('main.html@L10-L13.js', e)
|
|
17742
|
-
* }
|
|
17743
|
-
* ```
|
|
17744
|
-
*
|
|
17745
|
-
* -> TO KEEP IN MIND:
|
|
17746
|
-
* Static import can throw errors like
|
|
17747
|
-
* The requested module '/js_module_export_not_found/foo.js' does not provide an export named 'answerr'
|
|
17748
|
-
* While dynamic import will work just fine
|
|
17749
|
-
* and create a variable named "undefined"
|
|
17750
|
-
*/
|
|
17751
|
-
|
|
17752
|
-
const injectSupervisorIntoJs = async ({
|
|
17753
|
-
webServer,
|
|
17754
|
-
content,
|
|
17755
|
-
url,
|
|
17756
|
-
type,
|
|
17757
|
-
inlineSrc
|
|
17758
|
-
}) => {
|
|
17759
|
-
const babelPluginJsSupervisor = type === "js_module" ? babelPluginJsModuleSupervisor : babelPluginJsClassicSupervisor;
|
|
17760
|
-
const result = await applyBabelPlugins({
|
|
17761
|
-
urlInfo: {
|
|
17762
|
-
content,
|
|
17763
|
-
originalUrl: url,
|
|
17764
|
-
type
|
|
17765
|
-
},
|
|
17766
|
-
babelPlugins: [[babelPluginJsSupervisor, {
|
|
17767
|
-
inlineSrc
|
|
17768
|
-
}]]
|
|
17769
|
-
});
|
|
17770
|
-
let code = result.code;
|
|
17771
|
-
let map = result.map;
|
|
17772
|
-
const sourcemapDataUrl = generateSourcemapDataUrl(map);
|
|
17773
|
-
code = SOURCEMAP.writeComment({
|
|
17774
|
-
contentType: "text/javascript",
|
|
17775
|
-
content: code,
|
|
17776
|
-
specifier: sourcemapDataUrl
|
|
17777
|
-
});
|
|
17778
|
-
code = `${code}
|
|
17779
|
-
//# sourceURL=${urlToRelativeUrl(url, webServer.rootDirectoryUrl)}`;
|
|
17780
|
-
return code;
|
|
17781
|
-
};
|
|
17782
|
-
const babelPluginJsModuleSupervisor = babel => {
|
|
17783
|
-
const t = babel.types;
|
|
17784
|
-
return {
|
|
17785
|
-
name: "js-module-supervisor",
|
|
17786
|
-
visitor: {
|
|
17787
|
-
Program: (programPath, state) => {
|
|
17788
|
-
const {
|
|
17789
|
-
inlineSrc
|
|
17790
|
-
} = state.opts;
|
|
17791
|
-
if (state.file.metadata.jsExecutionInstrumented) return;
|
|
17792
|
-
state.file.metadata.jsExecutionInstrumented = true;
|
|
17793
|
-
const urlNode = t.stringLiteral(inlineSrc);
|
|
17794
|
-
const startCallNode = createSupervisionCall({
|
|
17795
|
-
t,
|
|
17796
|
-
urlNode,
|
|
17797
|
-
methodName: "jsModuleStart"
|
|
17798
|
-
});
|
|
17799
|
-
const endCallNode = createSupervisionCall({
|
|
17800
|
-
t,
|
|
17801
|
-
urlNode,
|
|
17802
|
-
methodName: "jsModuleEnd"
|
|
17803
|
-
});
|
|
17804
|
-
const errorCallNode = createSupervisionCall({
|
|
17805
|
-
t,
|
|
17806
|
-
urlNode,
|
|
17807
|
-
methodName: "jsModuleError",
|
|
17808
|
-
args: [t.identifier("e")]
|
|
17809
|
-
});
|
|
17810
|
-
const bodyPath = programPath.get("body");
|
|
17811
|
-
const importNodes = [];
|
|
17812
|
-
const topLevelNodes = [];
|
|
17813
|
-
for (const topLevelNodePath of bodyPath) {
|
|
17814
|
-
const topLevelNode = topLevelNodePath.node;
|
|
17815
|
-
if (t.isImportDeclaration(topLevelNode)) {
|
|
17816
|
-
importNodes.push(topLevelNode);
|
|
17817
|
-
} else {
|
|
17818
|
-
topLevelNodes.push(topLevelNode);
|
|
17819
|
-
}
|
|
17820
|
-
}
|
|
17821
|
-
|
|
17822
|
-
// replace all import nodes with dynamic imports
|
|
17823
|
-
const dynamicImports = [];
|
|
17824
|
-
importNodes.forEach(importNode => {
|
|
17825
|
-
const dynamicImportConversion = convertStaticImportIntoDynamicImport(importNode, t);
|
|
17826
|
-
if (Array.isArray(dynamicImportConversion)) {
|
|
17827
|
-
dynamicImports.push(...dynamicImportConversion);
|
|
17828
|
-
} else {
|
|
17829
|
-
dynamicImports.push(dynamicImportConversion);
|
|
17830
|
-
}
|
|
17831
|
-
});
|
|
17832
|
-
const tryCatchNode = t.tryStatement(t.blockStatement([...dynamicImports, ...topLevelNodes, endCallNode]), t.catchClause(t.identifier("e"), t.blockStatement([errorCallNode])));
|
|
17833
|
-
programPath.replaceWith(t.program([startCallNode, tryCatchNode]));
|
|
17834
|
-
}
|
|
17835
|
-
}
|
|
17836
|
-
};
|
|
17837
|
-
};
|
|
17838
|
-
const convertStaticImportIntoDynamicImport = (staticImportNode, t) => {
|
|
17839
|
-
const awaitExpression = t.awaitExpression(t.callExpression(t.import(), [t.stringLiteral(staticImportNode.source.value)]));
|
|
17840
|
-
|
|
17841
|
-
// import "./file.js" -> await import("./file.js")
|
|
17842
|
-
if (staticImportNode.specifiers.length === 0) {
|
|
17843
|
-
return t.expressionStatement(awaitExpression);
|
|
17844
|
-
}
|
|
17845
|
-
if (staticImportNode.specifiers.length === 1) {
|
|
17846
|
-
const [firstSpecifier] = staticImportNode.specifiers;
|
|
17847
|
-
if (firstSpecifier.type === "ImportNamespaceSpecifier") {
|
|
17848
|
-
return t.variableDeclaration("const", [t.variableDeclarator(t.identifier(firstSpecifier.local.name), awaitExpression)]);
|
|
17849
|
-
}
|
|
17850
|
-
}
|
|
17851
|
-
if (staticImportNode.specifiers.length === 2) {
|
|
17852
|
-
const [first, second] = staticImportNode.specifiers;
|
|
17853
|
-
if (first.type === "ImportDefaultSpecifier" && second.type === "ImportNamespaceSpecifier") {
|
|
17854
|
-
const namespaceDeclaration = t.variableDeclaration("const", [t.variableDeclarator(t.identifier(second.local.name), awaitExpression)]);
|
|
17855
|
-
const defaultDeclaration = t.variableDeclaration("const", [t.variableDeclarator(t.identifier(first.local.name), t.memberExpression(t.identifier(second.local.name), t.identifier("default")))]);
|
|
17856
|
-
return [namespaceDeclaration, defaultDeclaration];
|
|
17857
|
-
}
|
|
17858
|
-
}
|
|
17859
|
-
|
|
17860
|
-
// import { name } from "./file.js" -> const { name } = await import("./file.js")
|
|
17861
|
-
// import toto, { name } from "./file.js" -> const { name, default as toto } = await import("./file.js")
|
|
17862
|
-
const objectPattern = t.objectPattern(staticImportNode.specifiers.map(specifier => {
|
|
17863
|
-
if (specifier.type === "ImportDefaultSpecifier") {
|
|
17864
|
-
return t.objectProperty(t.identifier("default"), t.identifier(specifier.local.name), false,
|
|
17865
|
-
// computed
|
|
17866
|
-
false // shorthand
|
|
17867
|
-
);
|
|
17868
|
-
}
|
|
17869
|
-
// if (specifier.type === "ImportNamespaceSpecifier") {
|
|
17870
|
-
// return t.restElement(t.identifier(specifier.local.name))
|
|
17871
|
-
// }
|
|
17872
|
-
const isRenamed = specifier.imported.name !== specifier.local.name;
|
|
17873
|
-
if (isRenamed) {
|
|
17874
|
-
return t.objectProperty(t.identifier(specifier.imported.name), t.identifier(specifier.local.name), false,
|
|
17875
|
-
// computed
|
|
17876
|
-
false // shorthand
|
|
17877
|
-
);
|
|
17878
|
-
}
|
|
17879
|
-
// shorthand must be true
|
|
17880
|
-
return t.objectProperty(t.identifier(specifier.local.name), t.identifier(specifier.local.name), false,
|
|
17881
|
-
// computed
|
|
17882
|
-
true // shorthand
|
|
17883
|
-
);
|
|
17884
|
-
}));
|
|
17885
|
-
|
|
17886
|
-
const variableDeclarator = t.variableDeclarator(objectPattern, awaitExpression);
|
|
17887
|
-
const variableDeclaration = t.variableDeclaration("const", [variableDeclarator]);
|
|
17888
|
-
return variableDeclaration;
|
|
17889
|
-
};
|
|
17890
|
-
const babelPluginJsClassicSupervisor = babel => {
|
|
17891
|
-
const t = babel.types;
|
|
17892
|
-
return {
|
|
17893
|
-
name: "js-classic-supervisor",
|
|
17894
|
-
visitor: {
|
|
17895
|
-
Program: (programPath, state) => {
|
|
17896
|
-
const {
|
|
17897
|
-
inlineSrc
|
|
17898
|
-
} = state.opts;
|
|
17899
|
-
if (state.file.metadata.jsExecutionInstrumented) return;
|
|
17900
|
-
state.file.metadata.jsExecutionInstrumented = true;
|
|
17901
|
-
const urlNode = t.stringLiteral(inlineSrc);
|
|
17902
|
-
const startCallNode = createSupervisionCall({
|
|
17903
|
-
t,
|
|
17904
|
-
urlNode,
|
|
17905
|
-
methodName: "jsClassicStart"
|
|
17906
|
-
});
|
|
17907
|
-
const endCallNode = createSupervisionCall({
|
|
17908
|
-
t,
|
|
17909
|
-
urlNode,
|
|
17910
|
-
methodName: "jsClassicEnd"
|
|
17911
|
-
});
|
|
17912
|
-
const errorCallNode = createSupervisionCall({
|
|
17913
|
-
t,
|
|
17914
|
-
urlNode,
|
|
17915
|
-
methodName: "jsClassicError",
|
|
17916
|
-
args: [t.identifier("e")]
|
|
17917
|
-
});
|
|
17918
|
-
const topLevelNodes = programPath.node.body;
|
|
17919
|
-
const tryCatchNode = t.tryStatement(t.blockStatement([...topLevelNodes, endCallNode]), t.catchClause(t.identifier("e"), t.blockStatement([errorCallNode])));
|
|
17920
|
-
programPath.replaceWith(t.program([startCallNode, tryCatchNode]));
|
|
17921
|
-
}
|
|
17922
|
-
}
|
|
17923
|
-
};
|
|
17924
|
-
};
|
|
17925
|
-
const createSupervisionCall = ({
|
|
17926
|
-
t,
|
|
17927
|
-
methodName,
|
|
17928
|
-
urlNode,
|
|
17929
|
-
args = []
|
|
17930
|
-
}) => {
|
|
17931
|
-
return t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier("window"), t.identifier("__supervisor__")), t.identifier(methodName)), [urlNode, ...args]), [], null);
|
|
17932
|
-
};
|
|
17933
|
-
|
|
17934
|
-
/*
|
|
17935
|
-
* Jsenv needs to track js execution in order to:
|
|
17936
|
-
* 1. report errors
|
|
17937
|
-
* 2. wait for all js execution inside an HTML page before killing the browser
|
|
17938
|
-
*
|
|
17939
|
-
* A naive approach would rely on "load" events on window but:
|
|
17940
|
-
* scenario | covered by window "load"
|
|
17941
|
-
* ------------------------------------------- | -------------------------
|
|
17942
|
-
* js referenced by <script src> | yes
|
|
17943
|
-
* js inlined into <script> | yes
|
|
17944
|
-
* js referenced by <script type="module" src> | partially (not for import and top level await)
|
|
17945
|
-
* js inlined into <script type="module"> | not at all
|
|
17946
|
-
* Same for "error" event on window who is not enough
|
|
17947
|
-
*
|
|
17948
|
-
* <script src="file.js">
|
|
17949
|
-
* becomes
|
|
17950
|
-
* <script>
|
|
17951
|
-
* window.__supervisor__.superviseScript('file.js')
|
|
17952
|
-
* </script>
|
|
17953
|
-
*
|
|
17954
|
-
* <script>
|
|
17955
|
-
* console.log(42)
|
|
17956
|
-
* </script>
|
|
17957
|
-
* becomes
|
|
17958
|
-
* <script inlined-from-src="main.html@L10-C5.js">
|
|
17959
|
-
* window.__supervisor.__superviseScript("main.html@L10-C5.js")
|
|
17960
|
-
* </script>
|
|
17961
|
-
*
|
|
17962
|
-
* <script type="module" src="module.js"></script>
|
|
17963
|
-
* becomes
|
|
17964
|
-
* <script type="module">
|
|
17965
|
-
* window.__supervisor__.superviseScriptTypeModule('module.js')
|
|
17966
|
-
* </script>
|
|
17967
|
-
*
|
|
17968
|
-
* <script type="module">
|
|
17969
|
-
* console.log(42)
|
|
17970
|
-
* </script>
|
|
17971
|
-
* becomes
|
|
17972
|
-
* <script type="module" inlined-from-src="main.html@L10-C5.js">
|
|
17973
|
-
* window.__supervisor__.superviseScriptTypeModule('main.html@L10-C5.js')
|
|
17974
|
-
* </script>
|
|
17975
|
-
*
|
|
17976
|
-
* Why Inline scripts are converted to files dynamically?
|
|
17977
|
-
* -> No changes required on js source code, it's only the HTML that is modified
|
|
17978
|
-
* - Also allow to catch syntax errors and export missing
|
|
17979
|
-
*/
|
|
17980
|
-
|
|
17981
|
-
const supervisorFileUrl$1 = new URL("./js/supervisor.js", import.meta.url).href;
|
|
17982
|
-
const injectSupervisorIntoHTML = async ({
|
|
17983
|
-
content,
|
|
17984
|
-
url
|
|
17985
|
-
}, {
|
|
17986
|
-
supervisorScriptSrc = supervisorFileUrl$1,
|
|
17987
|
-
supervisorOptions,
|
|
17988
|
-
webServer,
|
|
17989
|
-
onInlineScript = () => {},
|
|
17990
|
-
generateInlineScriptSrc = ({
|
|
17991
|
-
inlineScriptUrl
|
|
17992
|
-
}) => urlToRelativeUrl(inlineScriptUrl, webServer.rootDirectoryUrl),
|
|
17993
|
-
inlineAsRemote
|
|
17994
|
-
}) => {
|
|
17995
|
-
const htmlAst = parseHtmlString(content);
|
|
17996
|
-
const mutations = [];
|
|
17997
|
-
const actions = [];
|
|
17998
|
-
const scriptInfos = [];
|
|
17999
|
-
// 1. Find inline and remote scripts
|
|
18000
|
-
{
|
|
18001
|
-
const handleInlineScript = (scriptNode, {
|
|
18002
|
-
type,
|
|
18003
|
-
extension,
|
|
18004
|
-
textContent
|
|
18005
|
-
}) => {
|
|
18006
|
-
const {
|
|
18007
|
-
line,
|
|
18008
|
-
column,
|
|
18009
|
-
lineEnd,
|
|
18010
|
-
columnEnd,
|
|
18011
|
-
isOriginal
|
|
18012
|
-
} = getHtmlNodePosition(scriptNode, {
|
|
18013
|
-
preferOriginal: true
|
|
18014
|
-
});
|
|
18015
|
-
const inlineScriptUrl = generateInlineContentUrl({
|
|
18016
|
-
url,
|
|
18017
|
-
extension: extension || ".js",
|
|
18018
|
-
line,
|
|
18019
|
-
column,
|
|
18020
|
-
lineEnd,
|
|
18021
|
-
columnEnd
|
|
18022
|
-
});
|
|
18023
|
-
const inlineScriptSrc = generateInlineScriptSrc({
|
|
18024
|
-
type,
|
|
18025
|
-
textContent,
|
|
18026
|
-
inlineScriptUrl,
|
|
18027
|
-
isOriginal,
|
|
18028
|
-
line,
|
|
18029
|
-
column
|
|
18030
|
-
});
|
|
18031
|
-
onInlineScript({
|
|
18032
|
-
type,
|
|
18033
|
-
textContent,
|
|
18034
|
-
url: inlineScriptUrl,
|
|
18035
|
-
isOriginal,
|
|
18036
|
-
line,
|
|
18037
|
-
column,
|
|
18038
|
-
src: inlineScriptSrc
|
|
18039
|
-
});
|
|
18040
|
-
if (inlineAsRemote) {
|
|
18041
|
-
// prefere la version src
|
|
18042
|
-
scriptInfos.push({
|
|
18043
|
-
type,
|
|
18044
|
-
src: inlineScriptSrc
|
|
18045
|
-
});
|
|
18046
|
-
const remoteJsSupervised = generateCodeToSuperviseScriptWithSrc({
|
|
18047
|
-
type,
|
|
18048
|
-
src: inlineScriptSrc
|
|
18049
|
-
});
|
|
18050
|
-
mutations.push(() => {
|
|
18051
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
18052
|
-
indentation: "auto"
|
|
18053
|
-
});
|
|
18054
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18055
|
-
"jsenv-cooked-by": "jsenv:supervisor",
|
|
18056
|
-
"src": undefined,
|
|
18057
|
-
"inlined-from-src": inlineScriptSrc
|
|
18058
|
-
});
|
|
18059
|
-
});
|
|
18060
|
-
} else {
|
|
18061
|
-
scriptInfos.push({
|
|
18062
|
-
type,
|
|
18063
|
-
src: inlineScriptSrc,
|
|
18064
|
-
isInline: true
|
|
18065
|
-
});
|
|
18066
|
-
actions.push(async () => {
|
|
18067
|
-
try {
|
|
18068
|
-
const inlineJsSupervised = await injectSupervisorIntoJs({
|
|
18069
|
-
webServer,
|
|
18070
|
-
content: textContent,
|
|
18071
|
-
url: inlineScriptUrl,
|
|
18072
|
-
type,
|
|
18073
|
-
inlineSrc: inlineScriptSrc
|
|
18074
|
-
});
|
|
18075
|
-
mutations.push(() => {
|
|
18076
|
-
setHtmlNodeText(scriptNode, inlineJsSupervised, {
|
|
18077
|
-
indentation: "auto"
|
|
18078
|
-
});
|
|
18079
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18080
|
-
"jsenv-cooked-by": "jsenv:supervisor"
|
|
18081
|
-
});
|
|
18082
|
-
});
|
|
18083
|
-
} catch (e) {
|
|
18084
|
-
if (e.code === "PARSE_ERROR") {
|
|
18085
|
-
// mutations.push(() => {
|
|
18086
|
-
// setHtmlNodeAttributes(scriptNode, {
|
|
18087
|
-
// "jsenv-cooked-by": "jsenv:supervisor",
|
|
18088
|
-
// })
|
|
18089
|
-
// })
|
|
18090
|
-
// on touche a rien
|
|
18091
|
-
return;
|
|
18092
|
-
}
|
|
18093
|
-
throw e;
|
|
18094
|
-
}
|
|
18095
|
-
});
|
|
18096
|
-
}
|
|
18097
|
-
};
|
|
18098
|
-
const handleScriptWithSrc = (scriptNode, {
|
|
18099
|
-
type,
|
|
18100
|
-
src
|
|
18101
|
-
}) => {
|
|
18102
|
-
scriptInfos.push({
|
|
18103
|
-
type,
|
|
18104
|
-
src
|
|
18105
|
-
});
|
|
18106
|
-
const remoteJsSupervised = generateCodeToSuperviseScriptWithSrc({
|
|
18107
|
-
type,
|
|
18108
|
-
src
|
|
18109
|
-
});
|
|
18110
|
-
mutations.push(() => {
|
|
18111
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
18112
|
-
indentation: "auto"
|
|
18113
|
-
});
|
|
18114
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18115
|
-
"jsenv-cooked-by": "jsenv:supervisor",
|
|
18116
|
-
"src": undefined,
|
|
18117
|
-
"inlined-from-src": src
|
|
18118
|
-
});
|
|
18119
|
-
});
|
|
18120
|
-
};
|
|
18121
|
-
visitHtmlNodes(htmlAst, {
|
|
18122
|
-
script: scriptNode => {
|
|
18123
|
-
const {
|
|
18124
|
-
type,
|
|
18125
|
-
extension
|
|
18126
|
-
} = analyzeScriptNode(scriptNode);
|
|
18127
|
-
if (type !== "js_classic" && type !== "js_module") {
|
|
18128
|
-
return;
|
|
18129
|
-
}
|
|
18130
|
-
if (getHtmlNodeAttribute(scriptNode, "jsenv-injected-by")) {
|
|
18131
|
-
return;
|
|
18132
|
-
}
|
|
18133
|
-
const noSupervisor = getHtmlNodeAttribute(scriptNode, "no-supervisor");
|
|
18134
|
-
if (noSupervisor !== undefined) {
|
|
18135
|
-
return;
|
|
18136
|
-
}
|
|
18137
|
-
const scriptNodeText = getHtmlNodeText(scriptNode);
|
|
18138
|
-
if (scriptNodeText) {
|
|
18139
|
-
handleInlineScript(scriptNode, {
|
|
18140
|
-
type,
|
|
18141
|
-
extension,
|
|
18142
|
-
textContent: scriptNodeText
|
|
18143
|
-
});
|
|
18144
|
-
return;
|
|
18145
|
-
}
|
|
18146
|
-
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
18147
|
-
if (src) {
|
|
18148
|
-
const urlObject = new URL(src, "http://example.com");
|
|
18149
|
-
if (urlObject.searchParams.has("inline")) {
|
|
18150
|
-
return;
|
|
18151
|
-
}
|
|
18152
|
-
handleScriptWithSrc(scriptNode, {
|
|
18153
|
-
type,
|
|
18154
|
-
src
|
|
18155
|
-
});
|
|
18156
|
-
return;
|
|
18157
|
-
}
|
|
18158
|
-
}
|
|
18159
|
-
});
|
|
18160
|
-
}
|
|
18161
|
-
// 2. Inject supervisor js file + setup call
|
|
18162
|
-
{
|
|
18163
|
-
const setupParamsSource = stringifyParams({
|
|
18164
|
-
...supervisorOptions,
|
|
18165
|
-
serverIsJsenvDevServer: webServer.isJsenvDevServer,
|
|
18166
|
-
rootDirectoryUrl: webServer.rootDirectoryUrl,
|
|
18167
|
-
scriptInfos
|
|
18168
|
-
}, " ");
|
|
18169
|
-
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
18170
|
-
tagName: "script",
|
|
18171
|
-
textContent: `window.__supervisor__.setup({${setupParamsSource}})`
|
|
18172
|
-
}), "jsenv:supervisor");
|
|
18173
|
-
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
18174
|
-
tagName: "script",
|
|
18175
|
-
src: supervisorScriptSrc
|
|
18176
|
-
}), "jsenv:supervisor");
|
|
18177
|
-
}
|
|
18178
|
-
// 3. Perform actions (transforming inline script content) and html mutations
|
|
18179
|
-
if (actions.length > 0) {
|
|
18180
|
-
await Promise.all(actions.map(action => action()));
|
|
18181
|
-
}
|
|
18182
|
-
mutations.forEach(mutation => mutation());
|
|
18183
|
-
const htmlModified = stringifyHtmlAst(htmlAst);
|
|
18184
|
-
return {
|
|
18185
|
-
content: htmlModified
|
|
18186
|
-
};
|
|
18187
|
-
};
|
|
18188
|
-
const stringifyParams = (params, prefix = "") => {
|
|
18189
|
-
const source = JSON.stringify(params, null, prefix);
|
|
18190
|
-
if (prefix.length) {
|
|
18191
|
-
// remove leading "{\n"
|
|
18192
|
-
// remove leading prefix
|
|
18193
|
-
// remove trailing "\n}"
|
|
18194
|
-
return source.slice(2 + prefix.length, -2);
|
|
18195
|
-
}
|
|
18196
|
-
// remove leading "{"
|
|
18197
|
-
// remove trailing "}"
|
|
18198
|
-
return source.slice(1, -1);
|
|
18199
|
-
};
|
|
18200
|
-
const generateCodeToSuperviseScriptWithSrc = ({
|
|
18201
|
-
type,
|
|
18202
|
-
src
|
|
18203
|
-
}) => {
|
|
18204
|
-
const srcEncoded = JSON.stringify(src);
|
|
18205
|
-
if (type === "js_module") {
|
|
18206
|
-
return `window.__supervisor__.superviseScriptTypeModule(${srcEncoded}, (url) => import(url));`;
|
|
18207
|
-
}
|
|
18208
|
-
return `window.__supervisor__.superviseScript(${srcEncoded});`;
|
|
18209
|
-
};
|
|
18210
|
-
|
|
18211
|
-
/*
|
|
18212
|
-
* This plugin provides a way for jsenv to know when js execution is done
|
|
18213
|
-
*/
|
|
18214
|
-
|
|
18215
|
-
const supervisorFileUrl = new URL("./js/supervisor.js", import.meta.url).href;
|
|
18216
|
-
const jsenvPluginSupervisor = ({
|
|
18217
|
-
logs = false,
|
|
18218
|
-
measurePerf = false,
|
|
18219
|
-
errorOverlay = true,
|
|
18220
|
-
openInEditor = true,
|
|
18221
|
-
errorBaseUrl
|
|
18222
|
-
}) => {
|
|
18223
|
-
return {
|
|
18224
|
-
name: "jsenv:supervisor",
|
|
18225
|
-
appliesDuring: "dev",
|
|
18226
|
-
serve: async (request, context) => {
|
|
18227
|
-
if (request.pathname.startsWith("/__get_code_frame__/")) {
|
|
18228
|
-
const {
|
|
18229
|
-
pathname,
|
|
18230
|
-
searchParams
|
|
18231
|
-
} = new URL(request.url);
|
|
18232
|
-
let urlWithLineAndColumn = pathname.slice("/__get_code_frame__/".length);
|
|
18233
|
-
urlWithLineAndColumn = decodeURIComponent(urlWithLineAndColumn);
|
|
18234
|
-
const match = urlWithLineAndColumn.match(/:([0-9]+):([0-9]+)$/);
|
|
18235
|
-
if (!match) {
|
|
18236
|
-
return {
|
|
18237
|
-
status: 400,
|
|
18238
|
-
body: "Missing line and column in url"
|
|
18239
|
-
};
|
|
18240
|
-
}
|
|
18241
|
-
const file = urlWithLineAndColumn.slice(0, match.index);
|
|
18242
|
-
let line = parseInt(match[1]);
|
|
18243
|
-
let column = parseInt(match[2]);
|
|
18244
|
-
const urlInfo = context.urlGraph.getUrlInfo(file);
|
|
18245
|
-
if (!urlInfo) {
|
|
18246
|
-
return {
|
|
18247
|
-
status: 204,
|
|
18248
|
-
headers: {
|
|
18249
|
-
"cache-control": "no-store"
|
|
18250
|
-
}
|
|
18251
|
-
};
|
|
18252
|
-
}
|
|
18253
|
-
const remap = searchParams.has("remap");
|
|
18254
|
-
if (remap) {
|
|
18255
|
-
const sourcemap = urlInfo.sourcemap;
|
|
18256
|
-
if (sourcemap) {
|
|
18257
|
-
const original = getOriginalPosition({
|
|
18258
|
-
sourcemap,
|
|
18259
|
-
url: file,
|
|
18260
|
-
line,
|
|
18261
|
-
column
|
|
18262
|
-
});
|
|
18263
|
-
if (original.line !== null) {
|
|
18264
|
-
line = original.line;
|
|
18265
|
-
if (original.column !== null) {
|
|
18266
|
-
column = original.column;
|
|
18267
|
-
}
|
|
18268
|
-
}
|
|
18269
|
-
}
|
|
18270
|
-
}
|
|
18271
|
-
const codeFrame = stringifyUrlSite({
|
|
18272
|
-
url: file,
|
|
18273
|
-
line,
|
|
18274
|
-
column,
|
|
18275
|
-
content: urlInfo.originalContent
|
|
18276
|
-
});
|
|
18277
|
-
return {
|
|
18278
|
-
status: 200,
|
|
18279
|
-
headers: {
|
|
18280
|
-
"cache-control": "no-store",
|
|
18281
|
-
"content-type": "text/plain",
|
|
18282
|
-
"content-length": Buffer.byteLength(codeFrame)
|
|
18283
|
-
},
|
|
18284
|
-
body: codeFrame
|
|
18285
|
-
};
|
|
18286
|
-
}
|
|
18287
|
-
if (request.pathname.startsWith("/__get_error_cause__/")) {
|
|
18288
|
-
let file = request.pathname.slice("/__get_error_cause__/".length);
|
|
18289
|
-
file = decodeURIComponent(file);
|
|
18290
|
-
if (!file) {
|
|
18291
|
-
return {
|
|
18292
|
-
status: 400,
|
|
18293
|
-
body: "Missing file in url"
|
|
18294
|
-
};
|
|
18295
|
-
}
|
|
18296
|
-
const getErrorCauseInfo = () => {
|
|
18297
|
-
const urlInfo = context.urlGraph.getUrlInfo(file);
|
|
18298
|
-
if (!urlInfo) {
|
|
18299
|
-
return null;
|
|
18300
|
-
}
|
|
18301
|
-
const {
|
|
18302
|
-
error
|
|
18303
|
-
} = urlInfo;
|
|
18304
|
-
if (error) {
|
|
18305
|
-
return error;
|
|
18306
|
-
}
|
|
18307
|
-
// search in direct dependencies (404 or 500)
|
|
18308
|
-
const {
|
|
18309
|
-
dependencies
|
|
18310
|
-
} = urlInfo;
|
|
18311
|
-
for (const dependencyUrl of dependencies) {
|
|
18312
|
-
const dependencyUrlInfo = context.urlGraph.getUrlInfo(dependencyUrl);
|
|
18313
|
-
if (dependencyUrlInfo.error) {
|
|
18314
|
-
return dependencyUrlInfo.error;
|
|
18315
|
-
}
|
|
18316
|
-
}
|
|
18317
|
-
return null;
|
|
18318
|
-
};
|
|
18319
|
-
const causeInfo = getErrorCauseInfo();
|
|
18320
|
-
const body = JSON.stringify(causeInfo ? {
|
|
18321
|
-
code: causeInfo.code,
|
|
18322
|
-
message: causeInfo.message,
|
|
18323
|
-
reason: causeInfo.reason,
|
|
18324
|
-
stack: errorBaseUrl ? `stack mocked for snapshot` : causeInfo.stack,
|
|
18325
|
-
codeFrame: causeInfo.traceMessage
|
|
18326
|
-
} : null, null, " ");
|
|
18327
|
-
return {
|
|
18328
|
-
status: 200,
|
|
18329
|
-
headers: {
|
|
18330
|
-
"cache-control": "no-store",
|
|
18331
|
-
"content-type": "application/json",
|
|
18332
|
-
"content-length": Buffer.byteLength(body)
|
|
18333
|
-
},
|
|
18334
|
-
body
|
|
18335
|
-
};
|
|
18336
|
-
}
|
|
18337
|
-
if (request.pathname.startsWith("/__open_in_editor__/")) {
|
|
18338
|
-
let file = request.pathname.slice("/__open_in_editor__/".length);
|
|
18339
|
-
file = decodeURIComponent(file);
|
|
18340
|
-
if (!file) {
|
|
18341
|
-
return {
|
|
18342
|
-
status: 400,
|
|
18343
|
-
body: "Missing file in url"
|
|
18344
|
-
};
|
|
18345
|
-
}
|
|
18346
|
-
const launch = requireFromJsenv("launch-editor");
|
|
18347
|
-
launch(fileURLToPath(file), () => {
|
|
18348
|
-
// ignore error for now
|
|
18349
|
-
});
|
|
18350
|
-
return {
|
|
18351
|
-
status: 200,
|
|
18352
|
-
headers: {
|
|
18353
|
-
"cache-control": "no-store"
|
|
18354
|
-
}
|
|
18355
|
-
};
|
|
17682
|
+
if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
|
|
17683
|
+
return `ignore:${reference.url}`;
|
|
18356
17684
|
}
|
|
18357
17685
|
return null;
|
|
18358
|
-
},
|
|
18359
|
-
transformUrlContent: {
|
|
18360
|
-
html: ({
|
|
18361
|
-
url,
|
|
18362
|
-
content
|
|
18363
|
-
}, context) => {
|
|
18364
|
-
const [supervisorFileReference] = context.referenceUtils.inject({
|
|
18365
|
-
type: "script",
|
|
18366
|
-
expectedType: "js_classic",
|
|
18367
|
-
specifier: supervisorFileUrl
|
|
18368
|
-
});
|
|
18369
|
-
return injectSupervisorIntoHTML({
|
|
18370
|
-
content,
|
|
18371
|
-
url
|
|
18372
|
-
}, {
|
|
18373
|
-
supervisorScriptSrc: supervisorFileReference.generatedSpecifier,
|
|
18374
|
-
supervisorOptions: {
|
|
18375
|
-
errorBaseUrl,
|
|
18376
|
-
logs,
|
|
18377
|
-
measurePerf,
|
|
18378
|
-
errorOverlay,
|
|
18379
|
-
openInEditor
|
|
18380
|
-
},
|
|
18381
|
-
webServer: {
|
|
18382
|
-
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
18383
|
-
isJsenvDevServer: true
|
|
18384
|
-
},
|
|
18385
|
-
inlineAsRemote: true,
|
|
18386
|
-
generateInlineScriptSrc: ({
|
|
18387
|
-
type,
|
|
18388
|
-
textContent,
|
|
18389
|
-
inlineScriptUrl,
|
|
18390
|
-
isOriginal,
|
|
18391
|
-
line,
|
|
18392
|
-
column
|
|
18393
|
-
}) => {
|
|
18394
|
-
const [inlineScriptReference] = context.referenceUtils.foundInline({
|
|
18395
|
-
type: "script",
|
|
18396
|
-
subtype: "inline",
|
|
18397
|
-
expectedType: type,
|
|
18398
|
-
isOriginalPosition: isOriginal,
|
|
18399
|
-
specifierLine: line - 1,
|
|
18400
|
-
specifierColumn: column,
|
|
18401
|
-
specifier: inlineScriptUrl,
|
|
18402
|
-
contentType: "text/javascript",
|
|
18403
|
-
content: textContent
|
|
18404
|
-
});
|
|
18405
|
-
return inlineScriptReference.generatedSpecifier;
|
|
18406
|
-
}
|
|
18407
|
-
});
|
|
18408
|
-
}
|
|
18409
17686
|
}
|
|
18410
17687
|
};
|
|
18411
17688
|
};
|
|
@@ -20893,8 +20170,8 @@ const getCorePlugins = ({
|
|
|
20893
20170
|
runtimeCompat,
|
|
20894
20171
|
referenceAnalysis = {},
|
|
20895
20172
|
nodeEsmResolution = {},
|
|
20896
|
-
|
|
20897
|
-
|
|
20173
|
+
magicExtensions,
|
|
20174
|
+
magicDirectoryIndex,
|
|
20898
20175
|
directoryReferenceAllowed,
|
|
20899
20176
|
supervisor,
|
|
20900
20177
|
transpilation = true,
|
|
@@ -20912,9 +20189,6 @@ const getCorePlugins = ({
|
|
|
20912
20189
|
if (supervisor === true) {
|
|
20913
20190
|
supervisor = {};
|
|
20914
20191
|
}
|
|
20915
|
-
if (fileSystemMagicRedirection === true) {
|
|
20916
|
-
fileSystemMagicRedirection = {};
|
|
20917
|
-
}
|
|
20918
20192
|
if (clientAutoreload === true) {
|
|
20919
20193
|
clientAutoreload = {};
|
|
20920
20194
|
}
|
|
@@ -20930,10 +20204,11 @@ const getCorePlugins = ({
|
|
|
20930
20204
|
- reference inside a js module -> resolved by node esm
|
|
20931
20205
|
- All the rest uses web standard url resolution
|
|
20932
20206
|
*/
|
|
20933
|
-
|
|
20207
|
+
jsenvPluginProtocolFile({
|
|
20934
20208
|
directoryReferenceAllowed,
|
|
20935
|
-
|
|
20936
|
-
|
|
20209
|
+
magicExtensions,
|
|
20210
|
+
magicDirectoryIndex
|
|
20211
|
+
}), jsenvPluginProtocolHttp(), ...(nodeEsmResolution ? [jsenvPluginNodeEsmResolution(nodeEsmResolution)] : []), jsenvPluginWebResolution(), jsenvPluginVersionSearchParam(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), ...(scenarioPlaceholders ? [jsenvPluginGlobalScenarios()] : []), jsenvPluginNodeRuntime({
|
|
20937
20212
|
runtimeCompat
|
|
20938
20213
|
}), jsenvPluginImportMetaHot(), ...(clientAutoreload ? [jsenvPluginAutoreload({
|
|
20939
20214
|
...clientAutoreload,
|
|
@@ -21330,13 +20605,14 @@ const build = async ({
|
|
|
21330
20605
|
buildDirectoryUrl,
|
|
21331
20606
|
entryPoints = {},
|
|
21332
20607
|
assetsDirectory = "",
|
|
20608
|
+
ignore,
|
|
21333
20609
|
runtimeCompat = defaultRuntimeCompat,
|
|
21334
20610
|
base = runtimeCompat.node ? "./" : "/",
|
|
21335
20611
|
plugins = [],
|
|
21336
20612
|
referenceAnalysis = {},
|
|
21337
20613
|
nodeEsmResolution,
|
|
21338
|
-
|
|
21339
|
-
|
|
20614
|
+
magicExtensions,
|
|
20615
|
+
magicDirectoryIndex,
|
|
21340
20616
|
directoryReferenceAllowed,
|
|
21341
20617
|
scenarioPlaceholders,
|
|
21342
20618
|
transpilation = {},
|
|
@@ -21467,18 +20743,16 @@ build ${entryPointKeys.length} entry points`);
|
|
|
21467
20743
|
signal,
|
|
21468
20744
|
logLevel,
|
|
21469
20745
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
20746
|
+
ignore,
|
|
20747
|
+
// during first pass (craft) we keep "ignore:" when a reference is ignored
|
|
20748
|
+
// so that the second pass (shape) properly ignore those urls
|
|
20749
|
+
ignoreProtocol: "keep",
|
|
21470
20750
|
urlGraph: rawGraph,
|
|
21471
20751
|
build: true,
|
|
21472
20752
|
runtimeCompat,
|
|
21473
20753
|
...contextSharedDuringBuild,
|
|
21474
20754
|
plugins: [...plugins, {
|
|
21475
20755
|
appliesDuring: "build",
|
|
21476
|
-
formatReference: reference => {
|
|
21477
|
-
if (!reference.shouldHandle) {
|
|
21478
|
-
return `ignore:${reference.specifier}`;
|
|
21479
|
-
}
|
|
21480
|
-
return null;
|
|
21481
|
-
},
|
|
21482
20756
|
fetchUrlContent: (urlInfo, context) => {
|
|
21483
20757
|
if (context.reference.original) {
|
|
21484
20758
|
rawRedirections.set(context.reference.original.url, context.reference.url);
|
|
@@ -21490,8 +20764,8 @@ build ${entryPointKeys.length} entry points`);
|
|
|
21490
20764
|
runtimeCompat,
|
|
21491
20765
|
referenceAnalysis,
|
|
21492
20766
|
nodeEsmResolution,
|
|
21493
|
-
|
|
21494
|
-
|
|
20767
|
+
magicExtensions,
|
|
20768
|
+
magicDirectoryIndex,
|
|
21495
20769
|
directoryReferenceAllowed,
|
|
21496
20770
|
transpilation: {
|
|
21497
20771
|
...transpilation,
|
|
@@ -21527,6 +20801,14 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21527
20801
|
const finalGraphKitchen = createKitchen({
|
|
21528
20802
|
logLevel,
|
|
21529
20803
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
20804
|
+
// here most plugins are not there
|
|
20805
|
+
// - no external plugin
|
|
20806
|
+
// - no plugin putting reference.mustIgnore on https urls
|
|
20807
|
+
// At this stage it's only about redirecting urls to the build directory
|
|
20808
|
+
// consequently only a subset or urls are supported
|
|
20809
|
+
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
20810
|
+
ignore,
|
|
20811
|
+
ignoreProtocol: versioning ? "keep" : "remove",
|
|
21530
20812
|
urlGraph: finalGraph,
|
|
21531
20813
|
build: true,
|
|
21532
20814
|
runtimeCompat,
|
|
@@ -21685,9 +20967,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21685
20967
|
},
|
|
21686
20968
|
formatReference: reference => {
|
|
21687
20969
|
if (!reference.generatedUrl.startsWith("file:")) {
|
|
21688
|
-
if (!versioning && reference.generatedUrl.startsWith("ignore:")) {
|
|
21689
|
-
return reference.generatedUrl.slice("ignore:".length);
|
|
21690
|
-
}
|
|
21691
20970
|
return null;
|
|
21692
20971
|
}
|
|
21693
20972
|
if (reference.isResourceHint) {
|
|
@@ -22104,14 +21383,11 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22104
21383
|
const contentVersionMap = new Map();
|
|
22105
21384
|
const hashCallbacks = [];
|
|
22106
21385
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22107
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
22108
|
-
return;
|
|
22109
|
-
}
|
|
22110
21386
|
if (urlInfo.type === "sourcemap") {
|
|
22111
21387
|
return;
|
|
22112
21388
|
}
|
|
22113
21389
|
// ignore:
|
|
22114
|
-
// - inline files:
|
|
21390
|
+
// - inline files and data files:
|
|
22115
21391
|
// they are already taken into account in the file where they appear
|
|
22116
21392
|
// - ignored files:
|
|
22117
21393
|
// we don't know their content
|
|
@@ -22123,7 +21399,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22123
21399
|
if (urlInfo.isInline) {
|
|
22124
21400
|
return;
|
|
22125
21401
|
}
|
|
22126
|
-
if (
|
|
21402
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
21403
|
+
return;
|
|
21404
|
+
}
|
|
21405
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
22127
21406
|
return;
|
|
22128
21407
|
}
|
|
22129
21408
|
if (urlInfo.dependents.size === 0 && !urlInfo.isEntryPoint) {
|
|
@@ -22149,7 +21428,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22149
21428
|
const dependencyContentVersion = contentVersionMap.get(reference.url);
|
|
22150
21429
|
if (!dependencyContentVersion) {
|
|
22151
21430
|
// no content generated for this dependency
|
|
22152
|
-
// (inline, data:, sourcemap,
|
|
21431
|
+
// (inline, data:, ignore:, sourcemap, ...)
|
|
22153
21432
|
return null;
|
|
22154
21433
|
}
|
|
22155
21434
|
if (preferWithoutVersioning(reference)) {
|
|
@@ -22208,6 +21487,8 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22208
21487
|
const versioningKitchen = createKitchen({
|
|
22209
21488
|
logLevel: logger.level,
|
|
22210
21489
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
21490
|
+
ignore,
|
|
21491
|
+
ignoreProtocol: "remove",
|
|
22211
21492
|
urlGraph: finalGraph,
|
|
22212
21493
|
build: true,
|
|
22213
21494
|
runtimeCompat,
|
|
@@ -22247,13 +21528,13 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22247
21528
|
return url;
|
|
22248
21529
|
},
|
|
22249
21530
|
formatReference: reference => {
|
|
22250
|
-
if (
|
|
22251
|
-
|
|
22252
|
-
|
|
22253
|
-
|
|
21531
|
+
if (reference.url.startsWith("ignore:")) {
|
|
21532
|
+
return null;
|
|
21533
|
+
}
|
|
21534
|
+
if (reference.isInline) {
|
|
22254
21535
|
return null;
|
|
22255
21536
|
}
|
|
22256
|
-
if (reference.
|
|
21537
|
+
if (reference.url.startsWith("data:")) {
|
|
22257
21538
|
return null;
|
|
22258
21539
|
}
|
|
22259
21540
|
if (reference.isResourceHint) {
|
|
@@ -22265,9 +21546,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22265
21546
|
if (!canUseVersionedUrl(referencedUrlInfo)) {
|
|
22266
21547
|
return reference.specifier;
|
|
22267
21548
|
}
|
|
22268
|
-
if (!referencedUrlInfo.shouldHandle) {
|
|
22269
|
-
return null;
|
|
22270
|
-
}
|
|
22271
21549
|
const versionedUrl = versionedUrlMap.get(reference.url);
|
|
22272
21550
|
if (!versionedUrl) {
|
|
22273
21551
|
// happens for sourcemap
|
|
@@ -22375,9 +21653,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22375
21653
|
}
|
|
22376
21654
|
{
|
|
22377
21655
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22378
|
-
if (!urlInfo.shouldHandle) {
|
|
22379
|
-
return;
|
|
22380
|
-
}
|
|
22381
21656
|
if (!urlInfo.url.startsWith("file:")) {
|
|
22382
21657
|
return;
|
|
22383
21658
|
}
|
|
@@ -22524,10 +21799,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22524
21799
|
if (serviceWorkerEntryUrlInfos.length > 0) {
|
|
22525
21800
|
const serviceWorkerResources = {};
|
|
22526
21801
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22527
|
-
if (
|
|
21802
|
+
if (!urlInfo.url.startsWith("file:")) {
|
|
22528
21803
|
return;
|
|
22529
21804
|
}
|
|
22530
|
-
if (
|
|
21805
|
+
if (urlInfo.isInline) {
|
|
22531
21806
|
return;
|
|
22532
21807
|
}
|
|
22533
21808
|
if (!canUseVersionedUrl(urlInfo)) {
|
|
@@ -22583,9 +21858,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22583
21858
|
return buildRelativeUrl;
|
|
22584
21859
|
};
|
|
22585
21860
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22586
|
-
if (!urlInfo.shouldHandle) {
|
|
22587
|
-
return;
|
|
22588
|
-
}
|
|
22589
21861
|
if (!urlInfo.url.startsWith("file:")) {
|
|
22590
21862
|
return;
|
|
22591
21863
|
}
|
|
@@ -22850,13 +22122,14 @@ const createFileService = ({
|
|
|
22850
22122
|
contextCache,
|
|
22851
22123
|
sourceDirectoryUrl,
|
|
22852
22124
|
sourceMainFilePath,
|
|
22125
|
+
ignore,
|
|
22853
22126
|
sourceFilesConfig,
|
|
22854
22127
|
runtimeCompat,
|
|
22855
22128
|
plugins,
|
|
22856
22129
|
referenceAnalysis,
|
|
22857
22130
|
nodeEsmResolution,
|
|
22858
|
-
|
|
22859
|
-
|
|
22131
|
+
magicExtensions,
|
|
22132
|
+
magicDirectoryIndex,
|
|
22860
22133
|
supervisor,
|
|
22861
22134
|
transpilation,
|
|
22862
22135
|
clientAutoreload,
|
|
@@ -22922,6 +22195,7 @@ const createFileService = ({
|
|
|
22922
22195
|
logLevel,
|
|
22923
22196
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
22924
22197
|
mainFilePath: sourceMainFilePath,
|
|
22198
|
+
ignore,
|
|
22925
22199
|
urlGraph,
|
|
22926
22200
|
dev: true,
|
|
22927
22201
|
runtimeCompat,
|
|
@@ -22932,8 +22206,8 @@ const createFileService = ({
|
|
|
22932
22206
|
runtimeCompat,
|
|
22933
22207
|
referenceAnalysis,
|
|
22934
22208
|
nodeEsmResolution,
|
|
22935
|
-
|
|
22936
|
-
|
|
22209
|
+
magicExtensions,
|
|
22210
|
+
magicDirectoryIndex,
|
|
22937
22211
|
supervisor,
|
|
22938
22212
|
transpilation,
|
|
22939
22213
|
clientAutoreload,
|
|
@@ -23247,6 +22521,7 @@ const inferParentFromRequest = (request, sourceDirectoryUrl) => {
|
|
|
23247
22521
|
const startDevServer = async ({
|
|
23248
22522
|
sourceDirectoryUrl,
|
|
23249
22523
|
sourceMainFilePath = "./index.html",
|
|
22524
|
+
ignore,
|
|
23250
22525
|
port = 3456,
|
|
23251
22526
|
hostname,
|
|
23252
22527
|
acceptAnyIp,
|
|
@@ -23271,9 +22546,9 @@ const startDevServer = async ({
|
|
|
23271
22546
|
plugins = [],
|
|
23272
22547
|
referenceAnalysis = {},
|
|
23273
22548
|
nodeEsmResolution,
|
|
23274
|
-
webResolution,
|
|
23275
22549
|
supervisor = true,
|
|
23276
|
-
|
|
22550
|
+
magicExtensions,
|
|
22551
|
+
magicDirectoryIndex,
|
|
23277
22552
|
transpilation,
|
|
23278
22553
|
cacheControl = true,
|
|
23279
22554
|
ribbon = true,
|
|
@@ -23385,13 +22660,14 @@ const startDevServer = async ({
|
|
|
23385
22660
|
contextCache,
|
|
23386
22661
|
sourceDirectoryUrl,
|
|
23387
22662
|
sourceMainFilePath,
|
|
22663
|
+
ignore,
|
|
23388
22664
|
sourceFilesConfig,
|
|
23389
22665
|
runtimeCompat,
|
|
23390
22666
|
plugins,
|
|
23391
22667
|
referenceAnalysis,
|
|
23392
22668
|
nodeEsmResolution,
|
|
23393
|
-
|
|
23394
|
-
|
|
22669
|
+
magicExtensions,
|
|
22670
|
+
magicDirectoryIndex,
|
|
23395
22671
|
supervisor,
|
|
23396
22672
|
transpilation,
|
|
23397
22673
|
clientAutoreload,
|