@jsenv/core 36.0.2 → 36.1.1
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/jsenv_core.js +149 -879
- package/package.json +4 -4
- package/src/build/build.js +29 -40
- package/src/dev/file_service.js +18 -3
- package/src/dev/start_dev_server.js +2 -0
- package/src/kitchen/kitchen.js +65 -12
- 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 +2 -1
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +44 -39
- package/src/plugins/protocol_http/jsenv_plugin_protocol_http.js +4 -3
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +0 -88
- 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/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
|
-
mustIgnore: 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
|
-
mustIgnore,
|
|
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
|
-
mustIgnore,
|
|
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
|
-
mustIgnore,
|
|
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,7 +9376,10 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9333
9376
|
reference.generatedUrl = normalizeUrl(referencedUrlObject.href);
|
|
9334
9377
|
});
|
|
9335
9378
|
const returnValue = pluginController.callHooksUntil("formatReference", reference, referenceContext);
|
|
9336
|
-
if (reference.
|
|
9379
|
+
if (reference.url.startsWith("ignore:")) {
|
|
9380
|
+
if (ignoreProtocol === "remove") {
|
|
9381
|
+
reference.specifier = reference.specifier.slice("ignore:".length);
|
|
9382
|
+
}
|
|
9337
9383
|
reference.generatedSpecifier = reference.specifier;
|
|
9338
9384
|
reference.generatedSpecifier = urlSpecifierEncoding.encode(reference);
|
|
9339
9385
|
} else {
|
|
@@ -9509,7 +9555,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
9509
9555
|
contextDuringFetch: context
|
|
9510
9556
|
});
|
|
9511
9557
|
};
|
|
9512
|
-
if (!urlInfo.
|
|
9558
|
+
if (!urlInfo.url.startsWith("ignore:")) {
|
|
9513
9559
|
// references
|
|
9514
9560
|
const references = [];
|
|
9515
9561
|
context.referenceUtils = {
|
|
@@ -9839,11 +9885,6 @@ const traceFromUrlSite = urlSite => {
|
|
|
9839
9885
|
};
|
|
9840
9886
|
};
|
|
9841
9887
|
const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
9842
|
-
if (reference.mustIgnore) {
|
|
9843
|
-
urlInfo.mustIgnore = true;
|
|
9844
|
-
} else {
|
|
9845
|
-
urlInfo.mustIgnore = false;
|
|
9846
|
-
}
|
|
9847
9888
|
urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
|
|
9848
9889
|
if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
|
|
9849
9890
|
urlInfo.isEntryPoint = true;
|
|
@@ -10075,15 +10116,19 @@ const createUrlGraphReport = urlGraph => {
|
|
|
10075
10116
|
total: 0
|
|
10076
10117
|
};
|
|
10077
10118
|
urlGraph.urlInfoMap.forEach(urlInfo => {
|
|
10078
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
10079
|
-
return;
|
|
10080
|
-
}
|
|
10081
10119
|
// ignore:
|
|
10082
|
-
// - inline files: they are already taken into account in the file where they appear
|
|
10083
10120
|
// - ignored files: we don't know their content
|
|
10084
|
-
|
|
10121
|
+
// - inline files and data files: they are already taken into account in the file where they appear
|
|
10122
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
10085
10123
|
return;
|
|
10086
10124
|
}
|
|
10125
|
+
if (urlInfo.isInline) {
|
|
10126
|
+
return;
|
|
10127
|
+
}
|
|
10128
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
10129
|
+
return;
|
|
10130
|
+
}
|
|
10131
|
+
|
|
10087
10132
|
// file loaded via import assertion are already inside the graph
|
|
10088
10133
|
// their js module equivalent are ignored to avoid counting it twice
|
|
10089
10134
|
// in the build graph the file targeted by import assertion will likely be gone
|
|
@@ -11111,19 +11156,12 @@ const parseAndTransformJsReferences = async (urlInfo, context, {
|
|
|
11111
11156
|
};
|
|
11112
11157
|
|
|
11113
11158
|
const jsenvPluginReferenceAnalysis = ({
|
|
11114
|
-
include,
|
|
11115
|
-
supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
|
|
11116
|
-
ignoreProtocol = "remove",
|
|
11117
11159
|
inlineContent = true,
|
|
11118
11160
|
inlineConvertedScript = false,
|
|
11119
11161
|
fetchInlineUrls = true,
|
|
11120
11162
|
allowEscapeForVersioning = false
|
|
11121
11163
|
}) => {
|
|
11122
|
-
return [
|
|
11123
|
-
include,
|
|
11124
|
-
supportedProtocols,
|
|
11125
|
-
ignoreProtocol
|
|
11126
|
-
}), jsenvPluginDirectoryReferenceAnalysis(), jsenvPluginHtmlReferenceAnalysis({
|
|
11164
|
+
return [jsenvPluginDirectoryReferenceAnalysis(), jsenvPluginHtmlReferenceAnalysis({
|
|
11127
11165
|
inlineContent,
|
|
11128
11166
|
inlineConvertedScript
|
|
11129
11167
|
}), jsenvPluginWebmanifestReferenceAnalysis(), jsenvPluginCssReferenceAnalysis(), jsenvPluginJsReferenceAnalysis({
|
|
@@ -11131,78 +11169,6 @@ const jsenvPluginReferenceAnalysis = ({
|
|
|
11131
11169
|
allowEscapeForVersioning
|
|
11132
11170
|
}), ...(inlineContent ? [jsenvPluginDataUrlsAnalysis()] : []), ...(inlineContent && fetchInlineUrls ? [jsenvPluginInlineContentFetcher()] : []), jsenvPluginReferenceExpectedTypes()];
|
|
11133
11171
|
};
|
|
11134
|
-
const jsenvPluginReferenceAnalysisInclude = ({
|
|
11135
|
-
include,
|
|
11136
|
-
supportedProtocols,
|
|
11137
|
-
ignoreProtocol
|
|
11138
|
-
}) => {
|
|
11139
|
-
// eslint-disable-next-line no-unused-vars
|
|
11140
|
-
let getIncludeInfo = url => undefined;
|
|
11141
|
-
return {
|
|
11142
|
-
name: "jsenv:reference_analysis_include",
|
|
11143
|
-
appliesDuring: "*",
|
|
11144
|
-
init: ({
|
|
11145
|
-
rootDirectoryUrl
|
|
11146
|
-
}) => {
|
|
11147
|
-
if (include) {
|
|
11148
|
-
const associations = URL_META.resolveAssociations({
|
|
11149
|
-
include
|
|
11150
|
-
}, rootDirectoryUrl);
|
|
11151
|
-
getIncludeInfo = url => {
|
|
11152
|
-
const {
|
|
11153
|
-
include
|
|
11154
|
-
} = URL_META.applyAssociations({
|
|
11155
|
-
url,
|
|
11156
|
-
associations
|
|
11157
|
-
});
|
|
11158
|
-
return include;
|
|
11159
|
-
};
|
|
11160
|
-
}
|
|
11161
|
-
},
|
|
11162
|
-
redirectReference: reference => {
|
|
11163
|
-
if (reference.mustIgnore !== undefined) {
|
|
11164
|
-
return;
|
|
11165
|
-
}
|
|
11166
|
-
if (reference.specifier[0] === "#" &&
|
|
11167
|
-
// For Html, css and in general "#" refer to a resource in the page
|
|
11168
|
-
// so that urls must be kept intact
|
|
11169
|
-
// However for js import specifiers they have a different meaning and we want
|
|
11170
|
-
// to resolve them (https://nodejs.org/api/packages.html#imports for instance)
|
|
11171
|
-
reference.type !== "js_import") {
|
|
11172
|
-
reference.mustIgnore = true;
|
|
11173
|
-
return;
|
|
11174
|
-
}
|
|
11175
|
-
if (reference.url.startsWith("ignore:")) {
|
|
11176
|
-
reference.mustIgnore = true;
|
|
11177
|
-
if (ignoreProtocol === "remove") {
|
|
11178
|
-
reference.specifier = reference.specifier.slice("ignore:".length);
|
|
11179
|
-
}
|
|
11180
|
-
return;
|
|
11181
|
-
}
|
|
11182
|
-
const includeInfo = getIncludeInfo(reference.url);
|
|
11183
|
-
if (includeInfo === true) {
|
|
11184
|
-
reference.mustIgnore = false;
|
|
11185
|
-
return;
|
|
11186
|
-
}
|
|
11187
|
-
if (includeInfo === false) {
|
|
11188
|
-
reference.mustIgnore = true;
|
|
11189
|
-
return;
|
|
11190
|
-
}
|
|
11191
|
-
const {
|
|
11192
|
-
protocol
|
|
11193
|
-
} = new URL(reference.url);
|
|
11194
|
-
const protocolIsSupported = supportedProtocols.some(supportedProtocol => protocol === supportedProtocol);
|
|
11195
|
-
if (!protocolIsSupported) {
|
|
11196
|
-
reference.mustIgnore = true;
|
|
11197
|
-
}
|
|
11198
|
-
},
|
|
11199
|
-
formatReference: reference => {
|
|
11200
|
-
if (ignoreProtocol === "inject" && reference.mustIgnore && !reference.url.startsWith("ignore:")) {
|
|
11201
|
-
reference.specifier = `ignore:${reference.specifier}`;
|
|
11202
|
-
}
|
|
11203
|
-
}
|
|
11204
|
-
};
|
|
11205
|
-
};
|
|
11206
11172
|
const jsenvPluginInlineContentFetcher = () => {
|
|
11207
11173
|
return {
|
|
11208
11174
|
name: "jsenv:inline_content_fetcher",
|
|
@@ -17561,6 +17527,19 @@ const jsenvPluginProtocolFile = ({
|
|
|
17561
17527
|
if (reference.isInline) {
|
|
17562
17528
|
return null;
|
|
17563
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
|
+
}
|
|
17564
17543
|
const urlObject = new URL(reference.url);
|
|
17565
17544
|
let stat;
|
|
17566
17545
|
try {
|
|
@@ -17582,6 +17561,7 @@ const jsenvPluginProtocolFile = ({
|
|
|
17582
17561
|
const pathnameUsesTrailingSlash = pathname.endsWith("/");
|
|
17583
17562
|
urlObject.search = "";
|
|
17584
17563
|
urlObject.hash = "";
|
|
17564
|
+
|
|
17585
17565
|
// force trailing slash on directories
|
|
17586
17566
|
if (stat && stat.isDirectory() && !pathnameUsesTrailingSlash) {
|
|
17587
17567
|
urlObject.pathname = `${pathname}/`;
|
|
@@ -17592,33 +17572,24 @@ const jsenvPluginProtocolFile = ({
|
|
|
17592
17572
|
urlObject.pathname = pathname.slice(0, -1);
|
|
17593
17573
|
}
|
|
17594
17574
|
let url = urlObject.href;
|
|
17595
|
-
const
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
const filesystemResolution = applyFileSystemMagicResolution(url, {
|
|
17606
|
-
fileStat: stat,
|
|
17607
|
-
magicDirectoryIndex,
|
|
17608
|
-
magicExtensions: getExtensionsToTry(magicExtensions, reference.parentUrl)
|
|
17609
|
-
});
|
|
17610
|
-
if (filesystemResolution.stat) {
|
|
17611
|
-
stat = filesystemResolution.stat;
|
|
17612
|
-
url = filesystemResolution.url;
|
|
17613
|
-
}
|
|
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;
|
|
17614
17585
|
}
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
|
|
17618
|
-
|
|
17619
|
-
|
|
17620
|
-
|
|
17621
|
-
|
|
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;
|
|
17622
17593
|
}
|
|
17623
17594
|
}
|
|
17624
17595
|
reference.leadsToADirectory = stat && stat.isDirectory();
|
|
@@ -17706,710 +17677,12 @@ const jsenvPluginProtocolHttp = () => {
|
|
|
17706
17677
|
name: "jsenv:protocol_http",
|
|
17707
17678
|
appliesDuring: "*",
|
|
17708
17679
|
redirectReference: reference => {
|
|
17709
|
-
if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
|
|
17710
|
-
reference.mustIgnore = true;
|
|
17711
|
-
}
|
|
17712
17680
|
// TODO: according to some pattern matching jsenv could be allowed
|
|
17713
17681
|
// to fetch and transform http urls
|
|
17714
|
-
|
|
17715
|
-
|
|
17716
|
-
};
|
|
17717
|
-
|
|
17718
|
-
/*
|
|
17719
|
-
* ```js
|
|
17720
|
-
* console.log(42)
|
|
17721
|
-
* ```
|
|
17722
|
-
* becomes
|
|
17723
|
-
* ```js
|
|
17724
|
-
* window.__supervisor__.jsClassicStart('main.html@L10-L13.js')
|
|
17725
|
-
* try {
|
|
17726
|
-
* console.log(42)
|
|
17727
|
-
* window.__supervisor__.jsClassicEnd('main.html@L10-L13.js')
|
|
17728
|
-
* } catch(e) {
|
|
17729
|
-
* window.__supervisor__.jsClassicError('main.html@L10-L13.js', e)
|
|
17730
|
-
* }
|
|
17731
|
-
* ```
|
|
17732
|
-
*
|
|
17733
|
-
* ```js
|
|
17734
|
-
* import value from "./file.js"
|
|
17735
|
-
* console.log(value)
|
|
17736
|
-
* ```
|
|
17737
|
-
* becomes
|
|
17738
|
-
* ```js
|
|
17739
|
-
* window.__supervisor__.jsModuleStart('main.html@L10-L13.js')
|
|
17740
|
-
* try {
|
|
17741
|
-
* const value = await import("./file.js")
|
|
17742
|
-
* console.log(value)
|
|
17743
|
-
* window.__supervisor__.jsModuleEnd('main.html@L10-L13.js')
|
|
17744
|
-
* } catch(e) {
|
|
17745
|
-
* window.__supervisor__.jsModuleError('main.html@L10-L13.js', e)
|
|
17746
|
-
* }
|
|
17747
|
-
* ```
|
|
17748
|
-
*
|
|
17749
|
-
* -> TO KEEP IN MIND:
|
|
17750
|
-
* Static import can throw errors like
|
|
17751
|
-
* The requested module '/js_module_export_not_found/foo.js' does not provide an export named 'answerr'
|
|
17752
|
-
* While dynamic import will work just fine
|
|
17753
|
-
* and create a variable named "undefined"
|
|
17754
|
-
*/
|
|
17755
|
-
|
|
17756
|
-
const injectSupervisorIntoJs = async ({
|
|
17757
|
-
webServer,
|
|
17758
|
-
content,
|
|
17759
|
-
url,
|
|
17760
|
-
type,
|
|
17761
|
-
inlineSrc
|
|
17762
|
-
}) => {
|
|
17763
|
-
const babelPluginJsSupervisor = type === "js_module" ? babelPluginJsModuleSupervisor : babelPluginJsClassicSupervisor;
|
|
17764
|
-
const result = await applyBabelPlugins({
|
|
17765
|
-
urlInfo: {
|
|
17766
|
-
content,
|
|
17767
|
-
originalUrl: url,
|
|
17768
|
-
type
|
|
17769
|
-
},
|
|
17770
|
-
babelPlugins: [[babelPluginJsSupervisor, {
|
|
17771
|
-
inlineSrc
|
|
17772
|
-
}]]
|
|
17773
|
-
});
|
|
17774
|
-
let code = result.code;
|
|
17775
|
-
let map = result.map;
|
|
17776
|
-
const sourcemapDataUrl = generateSourcemapDataUrl(map);
|
|
17777
|
-
code = SOURCEMAP.writeComment({
|
|
17778
|
-
contentType: "text/javascript",
|
|
17779
|
-
content: code,
|
|
17780
|
-
specifier: sourcemapDataUrl
|
|
17781
|
-
});
|
|
17782
|
-
code = `${code}
|
|
17783
|
-
//# sourceURL=${urlToRelativeUrl(url, webServer.rootDirectoryUrl)}`;
|
|
17784
|
-
return code;
|
|
17785
|
-
};
|
|
17786
|
-
const babelPluginJsModuleSupervisor = babel => {
|
|
17787
|
-
const t = babel.types;
|
|
17788
|
-
return {
|
|
17789
|
-
name: "js-module-supervisor",
|
|
17790
|
-
visitor: {
|
|
17791
|
-
Program: (programPath, state) => {
|
|
17792
|
-
const {
|
|
17793
|
-
inlineSrc
|
|
17794
|
-
} = state.opts;
|
|
17795
|
-
if (state.file.metadata.jsExecutionInstrumented) return;
|
|
17796
|
-
state.file.metadata.jsExecutionInstrumented = true;
|
|
17797
|
-
const urlNode = t.stringLiteral(inlineSrc);
|
|
17798
|
-
const startCallNode = createSupervisionCall({
|
|
17799
|
-
t,
|
|
17800
|
-
urlNode,
|
|
17801
|
-
methodName: "jsModuleStart"
|
|
17802
|
-
});
|
|
17803
|
-
const endCallNode = createSupervisionCall({
|
|
17804
|
-
t,
|
|
17805
|
-
urlNode,
|
|
17806
|
-
methodName: "jsModuleEnd"
|
|
17807
|
-
});
|
|
17808
|
-
const errorCallNode = createSupervisionCall({
|
|
17809
|
-
t,
|
|
17810
|
-
urlNode,
|
|
17811
|
-
methodName: "jsModuleError",
|
|
17812
|
-
args: [t.identifier("e")]
|
|
17813
|
-
});
|
|
17814
|
-
const bodyPath = programPath.get("body");
|
|
17815
|
-
const importNodes = [];
|
|
17816
|
-
const topLevelNodes = [];
|
|
17817
|
-
for (const topLevelNodePath of bodyPath) {
|
|
17818
|
-
const topLevelNode = topLevelNodePath.node;
|
|
17819
|
-
if (t.isImportDeclaration(topLevelNode)) {
|
|
17820
|
-
importNodes.push(topLevelNode);
|
|
17821
|
-
} else {
|
|
17822
|
-
topLevelNodes.push(topLevelNode);
|
|
17823
|
-
}
|
|
17824
|
-
}
|
|
17825
|
-
|
|
17826
|
-
// replace all import nodes with dynamic imports
|
|
17827
|
-
const dynamicImports = [];
|
|
17828
|
-
importNodes.forEach(importNode => {
|
|
17829
|
-
const dynamicImportConversion = convertStaticImportIntoDynamicImport(importNode, t);
|
|
17830
|
-
if (Array.isArray(dynamicImportConversion)) {
|
|
17831
|
-
dynamicImports.push(...dynamicImportConversion);
|
|
17832
|
-
} else {
|
|
17833
|
-
dynamicImports.push(dynamicImportConversion);
|
|
17834
|
-
}
|
|
17835
|
-
});
|
|
17836
|
-
const tryCatchNode = t.tryStatement(t.blockStatement([...dynamicImports, ...topLevelNodes, endCallNode]), t.catchClause(t.identifier("e"), t.blockStatement([errorCallNode])));
|
|
17837
|
-
programPath.replaceWith(t.program([startCallNode, tryCatchNode]));
|
|
17838
|
-
}
|
|
17839
|
-
}
|
|
17840
|
-
};
|
|
17841
|
-
};
|
|
17842
|
-
const convertStaticImportIntoDynamicImport = (staticImportNode, t) => {
|
|
17843
|
-
const awaitExpression = t.awaitExpression(t.callExpression(t.import(), [t.stringLiteral(staticImportNode.source.value)]));
|
|
17844
|
-
|
|
17845
|
-
// import "./file.js" -> await import("./file.js")
|
|
17846
|
-
if (staticImportNode.specifiers.length === 0) {
|
|
17847
|
-
return t.expressionStatement(awaitExpression);
|
|
17848
|
-
}
|
|
17849
|
-
if (staticImportNode.specifiers.length === 1) {
|
|
17850
|
-
const [firstSpecifier] = staticImportNode.specifiers;
|
|
17851
|
-
if (firstSpecifier.type === "ImportNamespaceSpecifier") {
|
|
17852
|
-
return t.variableDeclaration("const", [t.variableDeclarator(t.identifier(firstSpecifier.local.name), awaitExpression)]);
|
|
17853
|
-
}
|
|
17854
|
-
}
|
|
17855
|
-
if (staticImportNode.specifiers.length === 2) {
|
|
17856
|
-
const [first, second] = staticImportNode.specifiers;
|
|
17857
|
-
if (first.type === "ImportDefaultSpecifier" && second.type === "ImportNamespaceSpecifier") {
|
|
17858
|
-
const namespaceDeclaration = t.variableDeclaration("const", [t.variableDeclarator(t.identifier(second.local.name), awaitExpression)]);
|
|
17859
|
-
const defaultDeclaration = t.variableDeclaration("const", [t.variableDeclarator(t.identifier(first.local.name), t.memberExpression(t.identifier(second.local.name), t.identifier("default")))]);
|
|
17860
|
-
return [namespaceDeclaration, defaultDeclaration];
|
|
17861
|
-
}
|
|
17862
|
-
}
|
|
17863
|
-
|
|
17864
|
-
// import { name } from "./file.js" -> const { name } = await import("./file.js")
|
|
17865
|
-
// import toto, { name } from "./file.js" -> const { name, default as toto } = await import("./file.js")
|
|
17866
|
-
const objectPattern = t.objectPattern(staticImportNode.specifiers.map(specifier => {
|
|
17867
|
-
if (specifier.type === "ImportDefaultSpecifier") {
|
|
17868
|
-
return t.objectProperty(t.identifier("default"), t.identifier(specifier.local.name), false,
|
|
17869
|
-
// computed
|
|
17870
|
-
false // shorthand
|
|
17871
|
-
);
|
|
17872
|
-
}
|
|
17873
|
-
// if (specifier.type === "ImportNamespaceSpecifier") {
|
|
17874
|
-
// return t.restElement(t.identifier(specifier.local.name))
|
|
17875
|
-
// }
|
|
17876
|
-
const isRenamed = specifier.imported.name !== specifier.local.name;
|
|
17877
|
-
if (isRenamed) {
|
|
17878
|
-
return t.objectProperty(t.identifier(specifier.imported.name), t.identifier(specifier.local.name), false,
|
|
17879
|
-
// computed
|
|
17880
|
-
false // shorthand
|
|
17881
|
-
);
|
|
17882
|
-
}
|
|
17883
|
-
// shorthand must be true
|
|
17884
|
-
return t.objectProperty(t.identifier(specifier.local.name), t.identifier(specifier.local.name), false,
|
|
17885
|
-
// computed
|
|
17886
|
-
true // shorthand
|
|
17887
|
-
);
|
|
17888
|
-
}));
|
|
17889
|
-
|
|
17890
|
-
const variableDeclarator = t.variableDeclarator(objectPattern, awaitExpression);
|
|
17891
|
-
const variableDeclaration = t.variableDeclaration("const", [variableDeclarator]);
|
|
17892
|
-
return variableDeclaration;
|
|
17893
|
-
};
|
|
17894
|
-
const babelPluginJsClassicSupervisor = babel => {
|
|
17895
|
-
const t = babel.types;
|
|
17896
|
-
return {
|
|
17897
|
-
name: "js-classic-supervisor",
|
|
17898
|
-
visitor: {
|
|
17899
|
-
Program: (programPath, state) => {
|
|
17900
|
-
const {
|
|
17901
|
-
inlineSrc
|
|
17902
|
-
} = state.opts;
|
|
17903
|
-
if (state.file.metadata.jsExecutionInstrumented) return;
|
|
17904
|
-
state.file.metadata.jsExecutionInstrumented = true;
|
|
17905
|
-
const urlNode = t.stringLiteral(inlineSrc);
|
|
17906
|
-
const startCallNode = createSupervisionCall({
|
|
17907
|
-
t,
|
|
17908
|
-
urlNode,
|
|
17909
|
-
methodName: "jsClassicStart"
|
|
17910
|
-
});
|
|
17911
|
-
const endCallNode = createSupervisionCall({
|
|
17912
|
-
t,
|
|
17913
|
-
urlNode,
|
|
17914
|
-
methodName: "jsClassicEnd"
|
|
17915
|
-
});
|
|
17916
|
-
const errorCallNode = createSupervisionCall({
|
|
17917
|
-
t,
|
|
17918
|
-
urlNode,
|
|
17919
|
-
methodName: "jsClassicError",
|
|
17920
|
-
args: [t.identifier("e")]
|
|
17921
|
-
});
|
|
17922
|
-
const topLevelNodes = programPath.node.body;
|
|
17923
|
-
const tryCatchNode = t.tryStatement(t.blockStatement([...topLevelNodes, endCallNode]), t.catchClause(t.identifier("e"), t.blockStatement([errorCallNode])));
|
|
17924
|
-
programPath.replaceWith(t.program([startCallNode, tryCatchNode]));
|
|
17925
|
-
}
|
|
17926
|
-
}
|
|
17927
|
-
};
|
|
17928
|
-
};
|
|
17929
|
-
const createSupervisionCall = ({
|
|
17930
|
-
t,
|
|
17931
|
-
methodName,
|
|
17932
|
-
urlNode,
|
|
17933
|
-
args = []
|
|
17934
|
-
}) => {
|
|
17935
|
-
return t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier("window"), t.identifier("__supervisor__")), t.identifier(methodName)), [urlNode, ...args]), [], null);
|
|
17936
|
-
};
|
|
17937
|
-
|
|
17938
|
-
/*
|
|
17939
|
-
* Jsenv needs to track js execution in order to:
|
|
17940
|
-
* 1. report errors
|
|
17941
|
-
* 2. wait for all js execution inside an HTML page before killing the browser
|
|
17942
|
-
*
|
|
17943
|
-
* A naive approach would rely on "load" events on window but:
|
|
17944
|
-
* scenario | covered by window "load"
|
|
17945
|
-
* ------------------------------------------- | -------------------------
|
|
17946
|
-
* js referenced by <script src> | yes
|
|
17947
|
-
* js inlined into <script> | yes
|
|
17948
|
-
* js referenced by <script type="module" src> | partially (not for import and top level await)
|
|
17949
|
-
* js inlined into <script type="module"> | not at all
|
|
17950
|
-
* Same for "error" event on window who is not enough
|
|
17951
|
-
*
|
|
17952
|
-
* <script src="file.js">
|
|
17953
|
-
* becomes
|
|
17954
|
-
* <script>
|
|
17955
|
-
* window.__supervisor__.superviseScript('file.js')
|
|
17956
|
-
* </script>
|
|
17957
|
-
*
|
|
17958
|
-
* <script>
|
|
17959
|
-
* console.log(42)
|
|
17960
|
-
* </script>
|
|
17961
|
-
* becomes
|
|
17962
|
-
* <script inlined-from-src="main.html@L10-C5.js">
|
|
17963
|
-
* window.__supervisor.__superviseScript("main.html@L10-C5.js")
|
|
17964
|
-
* </script>
|
|
17965
|
-
*
|
|
17966
|
-
* <script type="module" src="module.js"></script>
|
|
17967
|
-
* becomes
|
|
17968
|
-
* <script type="module">
|
|
17969
|
-
* window.__supervisor__.superviseScriptTypeModule('module.js')
|
|
17970
|
-
* </script>
|
|
17971
|
-
*
|
|
17972
|
-
* <script type="module">
|
|
17973
|
-
* console.log(42)
|
|
17974
|
-
* </script>
|
|
17975
|
-
* becomes
|
|
17976
|
-
* <script type="module" inlined-from-src="main.html@L10-C5.js">
|
|
17977
|
-
* window.__supervisor__.superviseScriptTypeModule('main.html@L10-C5.js')
|
|
17978
|
-
* </script>
|
|
17979
|
-
*
|
|
17980
|
-
* Why Inline scripts are converted to files dynamically?
|
|
17981
|
-
* -> No changes required on js source code, it's only the HTML that is modified
|
|
17982
|
-
* - Also allow to catch syntax errors and export missing
|
|
17983
|
-
*/
|
|
17984
|
-
|
|
17985
|
-
const supervisorFileUrl$1 = new URL("./js/supervisor.js", import.meta.url).href;
|
|
17986
|
-
const injectSupervisorIntoHTML = async ({
|
|
17987
|
-
content,
|
|
17988
|
-
url
|
|
17989
|
-
}, {
|
|
17990
|
-
supervisorScriptSrc = supervisorFileUrl$1,
|
|
17991
|
-
supervisorOptions,
|
|
17992
|
-
webServer,
|
|
17993
|
-
onInlineScript = () => {},
|
|
17994
|
-
generateInlineScriptSrc = ({
|
|
17995
|
-
inlineScriptUrl
|
|
17996
|
-
}) => urlToRelativeUrl(inlineScriptUrl, webServer.rootDirectoryUrl),
|
|
17997
|
-
inlineAsRemote
|
|
17998
|
-
}) => {
|
|
17999
|
-
const htmlAst = parseHtmlString(content);
|
|
18000
|
-
const mutations = [];
|
|
18001
|
-
const actions = [];
|
|
18002
|
-
const scriptInfos = [];
|
|
18003
|
-
// 1. Find inline and remote scripts
|
|
18004
|
-
{
|
|
18005
|
-
const handleInlineScript = (scriptNode, {
|
|
18006
|
-
type,
|
|
18007
|
-
extension,
|
|
18008
|
-
textContent
|
|
18009
|
-
}) => {
|
|
18010
|
-
const {
|
|
18011
|
-
line,
|
|
18012
|
-
column,
|
|
18013
|
-
lineEnd,
|
|
18014
|
-
columnEnd,
|
|
18015
|
-
isOriginal
|
|
18016
|
-
} = getHtmlNodePosition(scriptNode, {
|
|
18017
|
-
preferOriginal: true
|
|
18018
|
-
});
|
|
18019
|
-
const inlineScriptUrl = generateInlineContentUrl({
|
|
18020
|
-
url,
|
|
18021
|
-
extension: extension || ".js",
|
|
18022
|
-
line,
|
|
18023
|
-
column,
|
|
18024
|
-
lineEnd,
|
|
18025
|
-
columnEnd
|
|
18026
|
-
});
|
|
18027
|
-
const inlineScriptSrc = generateInlineScriptSrc({
|
|
18028
|
-
type,
|
|
18029
|
-
textContent,
|
|
18030
|
-
inlineScriptUrl,
|
|
18031
|
-
isOriginal,
|
|
18032
|
-
line,
|
|
18033
|
-
column
|
|
18034
|
-
});
|
|
18035
|
-
onInlineScript({
|
|
18036
|
-
type,
|
|
18037
|
-
textContent,
|
|
18038
|
-
url: inlineScriptUrl,
|
|
18039
|
-
isOriginal,
|
|
18040
|
-
line,
|
|
18041
|
-
column,
|
|
18042
|
-
src: inlineScriptSrc
|
|
18043
|
-
});
|
|
18044
|
-
if (inlineAsRemote) {
|
|
18045
|
-
// prefere la version src
|
|
18046
|
-
scriptInfos.push({
|
|
18047
|
-
type,
|
|
18048
|
-
src: inlineScriptSrc
|
|
18049
|
-
});
|
|
18050
|
-
const remoteJsSupervised = generateCodeToSuperviseScriptWithSrc({
|
|
18051
|
-
type,
|
|
18052
|
-
src: inlineScriptSrc
|
|
18053
|
-
});
|
|
18054
|
-
mutations.push(() => {
|
|
18055
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
18056
|
-
indentation: "auto"
|
|
18057
|
-
});
|
|
18058
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18059
|
-
"jsenv-cooked-by": "jsenv:supervisor",
|
|
18060
|
-
"src": undefined,
|
|
18061
|
-
"inlined-from-src": inlineScriptSrc
|
|
18062
|
-
});
|
|
18063
|
-
});
|
|
18064
|
-
} else {
|
|
18065
|
-
scriptInfos.push({
|
|
18066
|
-
type,
|
|
18067
|
-
src: inlineScriptSrc,
|
|
18068
|
-
isInline: true
|
|
18069
|
-
});
|
|
18070
|
-
actions.push(async () => {
|
|
18071
|
-
try {
|
|
18072
|
-
const inlineJsSupervised = await injectSupervisorIntoJs({
|
|
18073
|
-
webServer,
|
|
18074
|
-
content: textContent,
|
|
18075
|
-
url: inlineScriptUrl,
|
|
18076
|
-
type,
|
|
18077
|
-
inlineSrc: inlineScriptSrc
|
|
18078
|
-
});
|
|
18079
|
-
mutations.push(() => {
|
|
18080
|
-
setHtmlNodeText(scriptNode, inlineJsSupervised, {
|
|
18081
|
-
indentation: "auto"
|
|
18082
|
-
});
|
|
18083
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18084
|
-
"jsenv-cooked-by": "jsenv:supervisor"
|
|
18085
|
-
});
|
|
18086
|
-
});
|
|
18087
|
-
} catch (e) {
|
|
18088
|
-
if (e.code === "PARSE_ERROR") {
|
|
18089
|
-
// mutations.push(() => {
|
|
18090
|
-
// setHtmlNodeAttributes(scriptNode, {
|
|
18091
|
-
// "jsenv-cooked-by": "jsenv:supervisor",
|
|
18092
|
-
// })
|
|
18093
|
-
// })
|
|
18094
|
-
// on touche a rien
|
|
18095
|
-
return;
|
|
18096
|
-
}
|
|
18097
|
-
throw e;
|
|
18098
|
-
}
|
|
18099
|
-
});
|
|
18100
|
-
}
|
|
18101
|
-
};
|
|
18102
|
-
const handleScriptWithSrc = (scriptNode, {
|
|
18103
|
-
type,
|
|
18104
|
-
src
|
|
18105
|
-
}) => {
|
|
18106
|
-
scriptInfos.push({
|
|
18107
|
-
type,
|
|
18108
|
-
src
|
|
18109
|
-
});
|
|
18110
|
-
const remoteJsSupervised = generateCodeToSuperviseScriptWithSrc({
|
|
18111
|
-
type,
|
|
18112
|
-
src
|
|
18113
|
-
});
|
|
18114
|
-
mutations.push(() => {
|
|
18115
|
-
setHtmlNodeText(scriptNode, remoteJsSupervised, {
|
|
18116
|
-
indentation: "auto"
|
|
18117
|
-
});
|
|
18118
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
18119
|
-
"jsenv-cooked-by": "jsenv:supervisor",
|
|
18120
|
-
"src": undefined,
|
|
18121
|
-
"inlined-from-src": src
|
|
18122
|
-
});
|
|
18123
|
-
});
|
|
18124
|
-
};
|
|
18125
|
-
visitHtmlNodes(htmlAst, {
|
|
18126
|
-
script: scriptNode => {
|
|
18127
|
-
const {
|
|
18128
|
-
type,
|
|
18129
|
-
extension
|
|
18130
|
-
} = analyzeScriptNode(scriptNode);
|
|
18131
|
-
if (type !== "js_classic" && type !== "js_module") {
|
|
18132
|
-
return;
|
|
18133
|
-
}
|
|
18134
|
-
if (getHtmlNodeAttribute(scriptNode, "jsenv-injected-by")) {
|
|
18135
|
-
return;
|
|
18136
|
-
}
|
|
18137
|
-
const noSupervisor = getHtmlNodeAttribute(scriptNode, "no-supervisor");
|
|
18138
|
-
if (noSupervisor !== undefined) {
|
|
18139
|
-
return;
|
|
18140
|
-
}
|
|
18141
|
-
const scriptNodeText = getHtmlNodeText(scriptNode);
|
|
18142
|
-
if (scriptNodeText) {
|
|
18143
|
-
handleInlineScript(scriptNode, {
|
|
18144
|
-
type,
|
|
18145
|
-
extension,
|
|
18146
|
-
textContent: scriptNodeText
|
|
18147
|
-
});
|
|
18148
|
-
return;
|
|
18149
|
-
}
|
|
18150
|
-
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
18151
|
-
if (src) {
|
|
18152
|
-
const urlObject = new URL(src, "http://example.com");
|
|
18153
|
-
if (urlObject.searchParams.has("inline")) {
|
|
18154
|
-
return;
|
|
18155
|
-
}
|
|
18156
|
-
handleScriptWithSrc(scriptNode, {
|
|
18157
|
-
type,
|
|
18158
|
-
src
|
|
18159
|
-
});
|
|
18160
|
-
return;
|
|
18161
|
-
}
|
|
18162
|
-
}
|
|
18163
|
-
});
|
|
18164
|
-
}
|
|
18165
|
-
// 2. Inject supervisor js file + setup call
|
|
18166
|
-
{
|
|
18167
|
-
const setupParamsSource = stringifyParams({
|
|
18168
|
-
...supervisorOptions,
|
|
18169
|
-
serverIsJsenvDevServer: webServer.isJsenvDevServer,
|
|
18170
|
-
rootDirectoryUrl: webServer.rootDirectoryUrl,
|
|
18171
|
-
scriptInfos
|
|
18172
|
-
}, " ");
|
|
18173
|
-
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
18174
|
-
tagName: "script",
|
|
18175
|
-
textContent: `window.__supervisor__.setup({${setupParamsSource}})`
|
|
18176
|
-
}), "jsenv:supervisor");
|
|
18177
|
-
injectHtmlNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
18178
|
-
tagName: "script",
|
|
18179
|
-
src: supervisorScriptSrc
|
|
18180
|
-
}), "jsenv:supervisor");
|
|
18181
|
-
}
|
|
18182
|
-
// 3. Perform actions (transforming inline script content) and html mutations
|
|
18183
|
-
if (actions.length > 0) {
|
|
18184
|
-
await Promise.all(actions.map(action => action()));
|
|
18185
|
-
}
|
|
18186
|
-
mutations.forEach(mutation => mutation());
|
|
18187
|
-
const htmlModified = stringifyHtmlAst(htmlAst);
|
|
18188
|
-
return {
|
|
18189
|
-
content: htmlModified
|
|
18190
|
-
};
|
|
18191
|
-
};
|
|
18192
|
-
const stringifyParams = (params, prefix = "") => {
|
|
18193
|
-
const source = JSON.stringify(params, null, prefix);
|
|
18194
|
-
if (prefix.length) {
|
|
18195
|
-
// remove leading "{\n"
|
|
18196
|
-
// remove leading prefix
|
|
18197
|
-
// remove trailing "\n}"
|
|
18198
|
-
return source.slice(2 + prefix.length, -2);
|
|
18199
|
-
}
|
|
18200
|
-
// remove leading "{"
|
|
18201
|
-
// remove trailing "}"
|
|
18202
|
-
return source.slice(1, -1);
|
|
18203
|
-
};
|
|
18204
|
-
const generateCodeToSuperviseScriptWithSrc = ({
|
|
18205
|
-
type,
|
|
18206
|
-
src
|
|
18207
|
-
}) => {
|
|
18208
|
-
const srcEncoded = JSON.stringify(src);
|
|
18209
|
-
if (type === "js_module") {
|
|
18210
|
-
return `window.__supervisor__.superviseScriptTypeModule(${srcEncoded}, (url) => import(url));`;
|
|
18211
|
-
}
|
|
18212
|
-
return `window.__supervisor__.superviseScript(${srcEncoded});`;
|
|
18213
|
-
};
|
|
18214
|
-
|
|
18215
|
-
/*
|
|
18216
|
-
* This plugin provides a way for jsenv to know when js execution is done
|
|
18217
|
-
*/
|
|
18218
|
-
|
|
18219
|
-
const supervisorFileUrl = new URL("./js/supervisor.js", import.meta.url).href;
|
|
18220
|
-
const jsenvPluginSupervisor = ({
|
|
18221
|
-
logs = false,
|
|
18222
|
-
measurePerf = false,
|
|
18223
|
-
errorOverlay = true,
|
|
18224
|
-
openInEditor = true,
|
|
18225
|
-
errorBaseUrl
|
|
18226
|
-
}) => {
|
|
18227
|
-
return {
|
|
18228
|
-
name: "jsenv:supervisor",
|
|
18229
|
-
appliesDuring: "dev",
|
|
18230
|
-
serve: async (request, context) => {
|
|
18231
|
-
if (request.pathname.startsWith("/__get_code_frame__/")) {
|
|
18232
|
-
const {
|
|
18233
|
-
pathname,
|
|
18234
|
-
searchParams
|
|
18235
|
-
} = new URL(request.url);
|
|
18236
|
-
let urlWithLineAndColumn = pathname.slice("/__get_code_frame__/".length);
|
|
18237
|
-
urlWithLineAndColumn = decodeURIComponent(urlWithLineAndColumn);
|
|
18238
|
-
const match = urlWithLineAndColumn.match(/:([0-9]+):([0-9]+)$/);
|
|
18239
|
-
if (!match) {
|
|
18240
|
-
return {
|
|
18241
|
-
status: 400,
|
|
18242
|
-
body: "Missing line and column in url"
|
|
18243
|
-
};
|
|
18244
|
-
}
|
|
18245
|
-
const file = urlWithLineAndColumn.slice(0, match.index);
|
|
18246
|
-
let line = parseInt(match[1]);
|
|
18247
|
-
let column = parseInt(match[2]);
|
|
18248
|
-
const urlInfo = context.urlGraph.getUrlInfo(file);
|
|
18249
|
-
if (!urlInfo) {
|
|
18250
|
-
return {
|
|
18251
|
-
status: 204,
|
|
18252
|
-
headers: {
|
|
18253
|
-
"cache-control": "no-store"
|
|
18254
|
-
}
|
|
18255
|
-
};
|
|
18256
|
-
}
|
|
18257
|
-
const remap = searchParams.has("remap");
|
|
18258
|
-
if (remap) {
|
|
18259
|
-
const sourcemap = urlInfo.sourcemap;
|
|
18260
|
-
if (sourcemap) {
|
|
18261
|
-
const original = getOriginalPosition({
|
|
18262
|
-
sourcemap,
|
|
18263
|
-
url: file,
|
|
18264
|
-
line,
|
|
18265
|
-
column
|
|
18266
|
-
});
|
|
18267
|
-
if (original.line !== null) {
|
|
18268
|
-
line = original.line;
|
|
18269
|
-
if (original.column !== null) {
|
|
18270
|
-
column = original.column;
|
|
18271
|
-
}
|
|
18272
|
-
}
|
|
18273
|
-
}
|
|
18274
|
-
}
|
|
18275
|
-
const codeFrame = stringifyUrlSite({
|
|
18276
|
-
url: file,
|
|
18277
|
-
line,
|
|
18278
|
-
column,
|
|
18279
|
-
content: urlInfo.originalContent
|
|
18280
|
-
});
|
|
18281
|
-
return {
|
|
18282
|
-
status: 200,
|
|
18283
|
-
headers: {
|
|
18284
|
-
"cache-control": "no-store",
|
|
18285
|
-
"content-type": "text/plain",
|
|
18286
|
-
"content-length": Buffer.byteLength(codeFrame)
|
|
18287
|
-
},
|
|
18288
|
-
body: codeFrame
|
|
18289
|
-
};
|
|
18290
|
-
}
|
|
18291
|
-
if (request.pathname.startsWith("/__get_error_cause__/")) {
|
|
18292
|
-
let file = request.pathname.slice("/__get_error_cause__/".length);
|
|
18293
|
-
file = decodeURIComponent(file);
|
|
18294
|
-
if (!file) {
|
|
18295
|
-
return {
|
|
18296
|
-
status: 400,
|
|
18297
|
-
body: "Missing file in url"
|
|
18298
|
-
};
|
|
18299
|
-
}
|
|
18300
|
-
const getErrorCauseInfo = () => {
|
|
18301
|
-
const urlInfo = context.urlGraph.getUrlInfo(file);
|
|
18302
|
-
if (!urlInfo) {
|
|
18303
|
-
return null;
|
|
18304
|
-
}
|
|
18305
|
-
const {
|
|
18306
|
-
error
|
|
18307
|
-
} = urlInfo;
|
|
18308
|
-
if (error) {
|
|
18309
|
-
return error;
|
|
18310
|
-
}
|
|
18311
|
-
// search in direct dependencies (404 or 500)
|
|
18312
|
-
const {
|
|
18313
|
-
dependencies
|
|
18314
|
-
} = urlInfo;
|
|
18315
|
-
for (const dependencyUrl of dependencies) {
|
|
18316
|
-
const dependencyUrlInfo = context.urlGraph.getUrlInfo(dependencyUrl);
|
|
18317
|
-
if (dependencyUrlInfo.error) {
|
|
18318
|
-
return dependencyUrlInfo.error;
|
|
18319
|
-
}
|
|
18320
|
-
}
|
|
18321
|
-
return null;
|
|
18322
|
-
};
|
|
18323
|
-
const causeInfo = getErrorCauseInfo();
|
|
18324
|
-
const body = JSON.stringify(causeInfo ? {
|
|
18325
|
-
code: causeInfo.code,
|
|
18326
|
-
message: causeInfo.message,
|
|
18327
|
-
reason: causeInfo.reason,
|
|
18328
|
-
stack: errorBaseUrl ? `stack mocked for snapshot` : causeInfo.stack,
|
|
18329
|
-
codeFrame: causeInfo.traceMessage
|
|
18330
|
-
} : null, null, " ");
|
|
18331
|
-
return {
|
|
18332
|
-
status: 200,
|
|
18333
|
-
headers: {
|
|
18334
|
-
"cache-control": "no-store",
|
|
18335
|
-
"content-type": "application/json",
|
|
18336
|
-
"content-length": Buffer.byteLength(body)
|
|
18337
|
-
},
|
|
18338
|
-
body
|
|
18339
|
-
};
|
|
18340
|
-
}
|
|
18341
|
-
if (request.pathname.startsWith("/__open_in_editor__/")) {
|
|
18342
|
-
let file = request.pathname.slice("/__open_in_editor__/".length);
|
|
18343
|
-
file = decodeURIComponent(file);
|
|
18344
|
-
if (!file) {
|
|
18345
|
-
return {
|
|
18346
|
-
status: 400,
|
|
18347
|
-
body: "Missing file in url"
|
|
18348
|
-
};
|
|
18349
|
-
}
|
|
18350
|
-
const launch = requireFromJsenv("launch-editor");
|
|
18351
|
-
launch(fileURLToPath(file), () => {
|
|
18352
|
-
// ignore error for now
|
|
18353
|
-
});
|
|
18354
|
-
return {
|
|
18355
|
-
status: 200,
|
|
18356
|
-
headers: {
|
|
18357
|
-
"cache-control": "no-store"
|
|
18358
|
-
}
|
|
18359
|
-
};
|
|
17682
|
+
if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
|
|
17683
|
+
return `ignore:${reference.url}`;
|
|
18360
17684
|
}
|
|
18361
17685
|
return null;
|
|
18362
|
-
},
|
|
18363
|
-
transformUrlContent: {
|
|
18364
|
-
html: ({
|
|
18365
|
-
url,
|
|
18366
|
-
content
|
|
18367
|
-
}, context) => {
|
|
18368
|
-
const [supervisorFileReference] = context.referenceUtils.inject({
|
|
18369
|
-
type: "script",
|
|
18370
|
-
expectedType: "js_classic",
|
|
18371
|
-
specifier: supervisorFileUrl
|
|
18372
|
-
});
|
|
18373
|
-
return injectSupervisorIntoHTML({
|
|
18374
|
-
content,
|
|
18375
|
-
url
|
|
18376
|
-
}, {
|
|
18377
|
-
supervisorScriptSrc: supervisorFileReference.generatedSpecifier,
|
|
18378
|
-
supervisorOptions: {
|
|
18379
|
-
errorBaseUrl,
|
|
18380
|
-
logs,
|
|
18381
|
-
measurePerf,
|
|
18382
|
-
errorOverlay,
|
|
18383
|
-
openInEditor
|
|
18384
|
-
},
|
|
18385
|
-
webServer: {
|
|
18386
|
-
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
18387
|
-
isJsenvDevServer: true
|
|
18388
|
-
},
|
|
18389
|
-
inlineAsRemote: true,
|
|
18390
|
-
generateInlineScriptSrc: ({
|
|
18391
|
-
type,
|
|
18392
|
-
textContent,
|
|
18393
|
-
inlineScriptUrl,
|
|
18394
|
-
isOriginal,
|
|
18395
|
-
line,
|
|
18396
|
-
column
|
|
18397
|
-
}) => {
|
|
18398
|
-
const [inlineScriptReference] = context.referenceUtils.foundInline({
|
|
18399
|
-
type: "script",
|
|
18400
|
-
subtype: "inline",
|
|
18401
|
-
expectedType: type,
|
|
18402
|
-
isOriginalPosition: isOriginal,
|
|
18403
|
-
specifierLine: line - 1,
|
|
18404
|
-
specifierColumn: column,
|
|
18405
|
-
specifier: inlineScriptUrl,
|
|
18406
|
-
contentType: "text/javascript",
|
|
18407
|
-
content: textContent
|
|
18408
|
-
});
|
|
18409
|
-
return inlineScriptReference.generatedSpecifier;
|
|
18410
|
-
}
|
|
18411
|
-
});
|
|
18412
|
-
}
|
|
18413
17686
|
}
|
|
18414
17687
|
};
|
|
18415
17688
|
};
|
|
@@ -21332,6 +20605,7 @@ const build = async ({
|
|
|
21332
20605
|
buildDirectoryUrl,
|
|
21333
20606
|
entryPoints = {},
|
|
21334
20607
|
assetsDirectory = "",
|
|
20608
|
+
ignore,
|
|
21335
20609
|
runtimeCompat = defaultRuntimeCompat,
|
|
21336
20610
|
base = runtimeCompat.node ? "./" : "/",
|
|
21337
20611
|
plugins = [],
|
|
@@ -21469,6 +20743,10 @@ build ${entryPointKeys.length} entry points`);
|
|
|
21469
20743
|
signal,
|
|
21470
20744
|
logLevel,
|
|
21471
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",
|
|
21472
20750
|
urlGraph: rawGraph,
|
|
21473
20751
|
build: true,
|
|
21474
20752
|
runtimeCompat,
|
|
@@ -21484,12 +20762,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
21484
20762
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
21485
20763
|
urlGraph: rawGraph,
|
|
21486
20764
|
runtimeCompat,
|
|
21487
|
-
referenceAnalysis
|
|
21488
|
-
...referenceAnalysis,
|
|
21489
|
-
// during first pass (craft) we inject "ignore:" when a reference must be ignored
|
|
21490
|
-
// so that the second pass (shape) properly ignore those urls
|
|
21491
|
-
ignoreProtocol: "inject"
|
|
21492
|
-
},
|
|
20765
|
+
referenceAnalysis,
|
|
21493
20766
|
nodeEsmResolution,
|
|
21494
20767
|
magicExtensions,
|
|
21495
20768
|
magicDirectoryIndex,
|
|
@@ -21528,20 +20801,21 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
21528
20801
|
const finalGraphKitchen = createKitchen({
|
|
21529
20802
|
logLevel,
|
|
21530
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",
|
|
21531
20812
|
urlGraph: finalGraph,
|
|
21532
20813
|
build: true,
|
|
21533
20814
|
runtimeCompat,
|
|
21534
20815
|
...contextSharedDuringBuild,
|
|
21535
20816
|
plugins: [jsenvPluginReferenceAnalysis({
|
|
21536
20817
|
...referenceAnalysis,
|
|
21537
|
-
|
|
21538
|
-
// - no external plugin
|
|
21539
|
-
// - no plugin putting reference.mustIgnore on https urls
|
|
21540
|
-
// At this stage it's only about redirecting urls to the build directory
|
|
21541
|
-
// consequently only a subset or urls are supported
|
|
21542
|
-
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
21543
|
-
fetchInlineUrls: false,
|
|
21544
|
-
ignoreProtocol: versioning ? "keep" : "remove"
|
|
20818
|
+
fetchInlineUrls: false
|
|
21545
20819
|
}), ...(lineBreakNormalization ? [jsenvPluginLineBreakNormalization()] : []), jsenvPluginJsModuleFallback({
|
|
21546
20820
|
systemJsInjection: true
|
|
21547
20821
|
}), jsenvPluginInlining(), {
|
|
@@ -22109,14 +21383,11 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22109
21383
|
const contentVersionMap = new Map();
|
|
22110
21384
|
const hashCallbacks = [];
|
|
22111
21385
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22112
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
22113
|
-
return;
|
|
22114
|
-
}
|
|
22115
21386
|
if (urlInfo.type === "sourcemap") {
|
|
22116
21387
|
return;
|
|
22117
21388
|
}
|
|
22118
21389
|
// ignore:
|
|
22119
|
-
// - inline files:
|
|
21390
|
+
// - inline files and data files:
|
|
22120
21391
|
// they are already taken into account in the file where they appear
|
|
22121
21392
|
// - ignored files:
|
|
22122
21393
|
// we don't know their content
|
|
@@ -22128,7 +21399,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22128
21399
|
if (urlInfo.isInline) {
|
|
22129
21400
|
return;
|
|
22130
21401
|
}
|
|
22131
|
-
if (urlInfo.
|
|
21402
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
21403
|
+
return;
|
|
21404
|
+
}
|
|
21405
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
22132
21406
|
return;
|
|
22133
21407
|
}
|
|
22134
21408
|
if (urlInfo.dependents.size === 0 && !urlInfo.isEntryPoint) {
|
|
@@ -22154,7 +21428,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22154
21428
|
const dependencyContentVersion = contentVersionMap.get(reference.url);
|
|
22155
21429
|
if (!dependencyContentVersion) {
|
|
22156
21430
|
// no content generated for this dependency
|
|
22157
|
-
// (inline, data:, sourcemap,
|
|
21431
|
+
// (inline, data:, ignore:, sourcemap, ...)
|
|
22158
21432
|
return null;
|
|
22159
21433
|
}
|
|
22160
21434
|
if (preferWithoutVersioning(reference)) {
|
|
@@ -22213,20 +21487,14 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22213
21487
|
const versioningKitchen = createKitchen({
|
|
22214
21488
|
logLevel: logger.level,
|
|
22215
21489
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
21490
|
+
ignore,
|
|
21491
|
+
ignoreProtocol: "remove",
|
|
22216
21492
|
urlGraph: finalGraph,
|
|
22217
21493
|
build: true,
|
|
22218
21494
|
runtimeCompat,
|
|
22219
21495
|
...contextSharedDuringBuild,
|
|
22220
|
-
plugins: [
|
|
22221
|
-
// here most plugins are not there
|
|
22222
|
-
// - no external plugin
|
|
22223
|
-
// - no plugin putting reference.mustIgnore on https urls
|
|
22224
|
-
// At this stage it's only about versioning urls
|
|
22225
|
-
// consequently only a subset or urls are supported
|
|
22226
|
-
jsenvPluginReferenceAnalysis({
|
|
21496
|
+
plugins: [jsenvPluginReferenceAnalysis({
|
|
22227
21497
|
...referenceAnalysis,
|
|
22228
|
-
supportedProtocols: ["file:", "data:", "virtual:"],
|
|
22229
|
-
ignoreProtocol: "remove",
|
|
22230
21498
|
fetchInlineUrls: false,
|
|
22231
21499
|
inlineConvertedScript: true,
|
|
22232
21500
|
// to be able to version their urls
|
|
@@ -22260,10 +21528,13 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22260
21528
|
return url;
|
|
22261
21529
|
},
|
|
22262
21530
|
formatReference: reference => {
|
|
22263
|
-
if (reference.
|
|
21531
|
+
if (reference.url.startsWith("ignore:")) {
|
|
22264
21532
|
return null;
|
|
22265
21533
|
}
|
|
22266
|
-
if (reference.isInline
|
|
21534
|
+
if (reference.isInline) {
|
|
21535
|
+
return null;
|
|
21536
|
+
}
|
|
21537
|
+
if (reference.url.startsWith("data:")) {
|
|
22267
21538
|
return null;
|
|
22268
21539
|
}
|
|
22269
21540
|
if (reference.isResourceHint) {
|
|
@@ -22275,9 +21546,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22275
21546
|
if (!canUseVersionedUrl(referencedUrlInfo)) {
|
|
22276
21547
|
return reference.specifier;
|
|
22277
21548
|
}
|
|
22278
|
-
if (referencedUrlInfo.mustIgnore) {
|
|
22279
|
-
return null;
|
|
22280
|
-
}
|
|
22281
21549
|
const versionedUrl = versionedUrlMap.get(reference.url);
|
|
22282
21550
|
if (!versionedUrl) {
|
|
22283
21551
|
// happens for sourcemap
|
|
@@ -22385,9 +21653,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22385
21653
|
}
|
|
22386
21654
|
{
|
|
22387
21655
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22388
|
-
if (urlInfo.mustIgnore) {
|
|
22389
|
-
return;
|
|
22390
|
-
}
|
|
22391
21656
|
if (!urlInfo.url.startsWith("file:")) {
|
|
22392
21657
|
return;
|
|
22393
21658
|
}
|
|
@@ -22534,10 +21799,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22534
21799
|
if (serviceWorkerEntryUrlInfos.length > 0) {
|
|
22535
21800
|
const serviceWorkerResources = {};
|
|
22536
21801
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22537
|
-
if (urlInfo.
|
|
21802
|
+
if (!urlInfo.url.startsWith("file:")) {
|
|
22538
21803
|
return;
|
|
22539
21804
|
}
|
|
22540
|
-
if (
|
|
21805
|
+
if (urlInfo.isInline) {
|
|
22541
21806
|
return;
|
|
22542
21807
|
}
|
|
22543
21808
|
if (!canUseVersionedUrl(urlInfo)) {
|
|
@@ -22593,9 +21858,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
22593
21858
|
return buildRelativeUrl;
|
|
22594
21859
|
};
|
|
22595
21860
|
GRAPH.forEach(finalGraph, urlInfo => {
|
|
22596
|
-
if (urlInfo.mustIgnore) {
|
|
22597
|
-
return;
|
|
22598
|
-
}
|
|
22599
21861
|
if (!urlInfo.url.startsWith("file:")) {
|
|
22600
21862
|
return;
|
|
22601
21863
|
}
|
|
@@ -22860,6 +22122,7 @@ const createFileService = ({
|
|
|
22860
22122
|
contextCache,
|
|
22861
22123
|
sourceDirectoryUrl,
|
|
22862
22124
|
sourceMainFilePath,
|
|
22125
|
+
ignore,
|
|
22863
22126
|
sourceFilesConfig,
|
|
22864
22127
|
runtimeCompat,
|
|
22865
22128
|
plugins,
|
|
@@ -22932,6 +22195,7 @@ const createFileService = ({
|
|
|
22932
22195
|
logLevel,
|
|
22933
22196
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
22934
22197
|
mainFilePath: sourceMainFilePath,
|
|
22198
|
+
ignore,
|
|
22935
22199
|
urlGraph,
|
|
22936
22200
|
dev: true,
|
|
22937
22201
|
runtimeCompat,
|
|
@@ -23072,7 +22336,7 @@ const createFileService = ({
|
|
|
23072
22336
|
return responseFromPlugin;
|
|
23073
22337
|
}
|
|
23074
22338
|
let reference;
|
|
23075
|
-
const parentUrl = inferParentFromRequest(request, sourceDirectoryUrl);
|
|
22339
|
+
const parentUrl = inferParentFromRequest(request, sourceDirectoryUrl, sourceMainFilePath);
|
|
23076
22340
|
if (parentUrl) {
|
|
23077
22341
|
reference = urlGraph.inferReference(request.resource, parentUrl);
|
|
23078
22342
|
}
|
|
@@ -23230,7 +22494,7 @@ const createFileService = ({
|
|
|
23230
22494
|
}
|
|
23231
22495
|
};
|
|
23232
22496
|
};
|
|
23233
|
-
const inferParentFromRequest = (request, sourceDirectoryUrl) => {
|
|
22497
|
+
const inferParentFromRequest = (request, sourceDirectoryUrl, sourceMainFilePath) => {
|
|
23234
22498
|
const {
|
|
23235
22499
|
referer
|
|
23236
22500
|
} = request.headers;
|
|
@@ -23240,7 +22504,11 @@ const inferParentFromRequest = (request, sourceDirectoryUrl) => {
|
|
|
23240
22504
|
const refererUrlObject = new URL(referer);
|
|
23241
22505
|
refererUrlObject.searchParams.delete("hmr");
|
|
23242
22506
|
refererUrlObject.searchParams.delete("v");
|
|
23243
|
-
|
|
22507
|
+
let refererUrl = refererUrlObject.href;
|
|
22508
|
+
if (refererUrl === `${request.origin}/`) {
|
|
22509
|
+
refererUrl = new URL(sourceMainFilePath, request.origin).href;
|
|
22510
|
+
}
|
|
22511
|
+
return WEB_URL_CONVERTER.asFileUrl(refererUrl, {
|
|
23244
22512
|
origin: request.origin,
|
|
23245
22513
|
rootDirectoryUrl: sourceDirectoryUrl
|
|
23246
22514
|
});
|
|
@@ -23257,6 +22525,7 @@ const inferParentFromRequest = (request, sourceDirectoryUrl) => {
|
|
|
23257
22525
|
const startDevServer = async ({
|
|
23258
22526
|
sourceDirectoryUrl,
|
|
23259
22527
|
sourceMainFilePath = "./index.html",
|
|
22528
|
+
ignore,
|
|
23260
22529
|
port = 3456,
|
|
23261
22530
|
hostname,
|
|
23262
22531
|
acceptAnyIp,
|
|
@@ -23395,6 +22664,7 @@ const startDevServer = async ({
|
|
|
23395
22664
|
contextCache,
|
|
23396
22665
|
sourceDirectoryUrl,
|
|
23397
22666
|
sourceMainFilePath,
|
|
22667
|
+
ignore,
|
|
23398
22668
|
sourceFilesConfig,
|
|
23399
22669
|
runtimeCompat,
|
|
23400
22670
|
plugins,
|