@jsenv/core 38.4.15 → 38.4.17

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.
@@ -13,7 +13,7 @@ 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 { injectJsImport, visitJsAstUntil, applyBabelPlugins, parseHtml, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, getHtmlNodeText, stringifyHtmlAst, setHtmlNodeAttributes, parseJsUrls, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn, getHtmlNodePosition, getUrlForContentInsideHtml, getHtmlNodeAttributePosition, parseSrcSet, removeHtmlNodeText, setHtmlNodeText, removeHtmlNode, parseCssUrls, getUrlForContentInsideJs, analyzeLinkNode, findHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
16
+ import { injectJsImport, visitJsAstUntil, applyBabelPlugins, parseHtml, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, getHtmlNodeText, stringifyHtmlAst, setHtmlNodeAttributes, parseJsUrls, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn, getHtmlNodePosition, getHtmlNodeAttributePosition, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, removeHtmlNode, parseCssUrls, getUrlForContentInsideJs, analyzeLinkNode, findHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
17
17
  import { sourcemapConverter, createMagicSource, composeTwoSourcemaps, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
18
18
  import { createRequire } from "node:module";
19
19
  import { systemJsClientFileUrlDefault, convertJsModuleToJsClassic } from "@jsenv/js-module-fallback";
@@ -897,7 +897,7 @@ const createUnicode = ({ supported, ANSI }) => {
897
897
  };
898
898
 
899
899
  const UNICODE = createUnicode({
900
- supported: isUnicodeSupported(),
900
+ supported: isUnicodeSupported() || process.env.FORCE_UNICODE === "1",
901
901
  ANSI,
902
902
  });
903
903
 
@@ -11528,13 +11528,14 @@ const createDependencies = (ownerUrlInfo) => {
11528
11528
  const parentContent = isOriginalPosition
11529
11529
  ? ownerUrlInfo.originalContent
11530
11530
  : ownerUrlInfo.content;
11531
+ const trace = traceFromUrlSite({
11532
+ url: parentUrl,
11533
+ content: parentContent,
11534
+ line: specifierLine,
11535
+ column: specifierColumn,
11536
+ });
11531
11537
  const reference = createResolveAndFinalize({
11532
- trace: traceFromUrlSite({
11533
- url: parentUrl,
11534
- content: parentContent,
11535
- line: specifierLine,
11536
- column: specifierColumn,
11537
- }),
11538
+ trace,
11538
11539
  isOriginalPosition,
11539
11540
  specifierLine,
11540
11541
  specifierColumn,
@@ -13747,9 +13748,12 @@ const createTransformUrlContentError = ({
13747
13748
  if (code === "PARSE_ERROR") {
13748
13749
  transformError.reason = `parse error on ${urlInfo.type}`;
13749
13750
  transformError.cause = error;
13751
+ let line = error.line;
13752
+ if (urlInfo.type === "js_module") {
13753
+ line = line - 1;
13754
+ }
13750
13755
  if (urlInfo.isInline) {
13751
- transformError.trace.line =
13752
- urlInfo.firstReference.trace.line + error.line - 1;
13756
+ transformError.trace.line = urlInfo.firstReference.trace.line + line;
13753
13757
  transformError.trace.column =
13754
13758
  urlInfo.firstReference.trace.column + error.column;
13755
13759
  transformError.trace.codeFrame = generateContentFrame({
@@ -13766,16 +13770,16 @@ const createTransformUrlContentError = ({
13766
13770
  } else {
13767
13771
  transformError.trace = {
13768
13772
  url: urlInfo.url,
13769
- line: error.line,
13773
+ line,
13770
13774
  column: error.column,
13771
13775
  codeFrame: generateContentFrame({
13772
- line: error.line - 1,
13776
+ line,
13773
13777
  column: error.column,
13774
13778
  content: urlInfo.content,
13775
13779
  }),
13776
13780
  message: stringifyUrlSite({
13777
13781
  url: urlInfo.url,
13778
- line: error.line - 1,
13782
+ line,
13779
13783
  column: error.column,
13780
13784
  content: urlInfo.content,
13781
13785
  }),
@@ -15888,420 +15892,441 @@ const jsenvPluginHtmlReferenceAnalysis = ({
15888
15892
  let importmapFound = false;
15889
15893
  const importmapLoaded = startLoadingImportmap(urlInfo);
15890
15894
 
15891
- const htmlAst = parseHtml({
15892
- html: urlInfo.content,
15893
- url: urlInfo.url,
15894
- });
15895
+ try {
15896
+ const htmlAst = parseHtml({
15897
+ html: urlInfo.content,
15898
+ url: urlInfo.url,
15899
+ });
15895
15900
 
15896
- const mutations = [];
15897
- const actions = [];
15898
- const finalizeCallbacks = [];
15901
+ const mutations = [];
15902
+ const actions = [];
15903
+ const finalizeCallbacks = [];
15899
15904
 
15900
- const createExternalReference = (
15901
- node,
15902
- attributeName,
15903
- attributeValue,
15904
- { type, subtype, expectedType, ...rest },
15905
- ) => {
15906
- let position;
15907
- if (getHtmlNodeAttribute(node, "jsenv-cooked-by")) {
15908
- // when generated from inline content,
15909
- // line, column is not "src" nor "inlined-from-src" but "original-position"
15910
- position = getHtmlNodePosition(node);
15911
- } else {
15912
- position = getHtmlNodeAttributePosition(node, attributeName);
15913
- }
15914
- const {
15915
- line,
15916
- column,
15917
- // originalLine, originalColumn
15918
- } = position;
15919
- const debug = getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
15920
-
15921
- const { crossorigin, integrity } = readFetchMetas(node);
15922
- const isResourceHint = [
15923
- "preconnect",
15924
- "dns-prefetch",
15925
- "prefetch",
15926
- "preload",
15927
- "modulepreload",
15928
- ].includes(subtype);
15929
- let attributeLocation = node.sourceCodeLocation.attrs[attributeName];
15930
- if (
15931
- !attributeLocation &&
15932
- attributeName === "href" &&
15933
- (node.tagName === "use" || node.tagName === "image")
15934
- ) {
15935
- attributeLocation = node.sourceCodeLocation.attrs["xlink:href"];
15936
- }
15937
- const attributeStart = attributeLocation.startOffset;
15938
- const attributeValueStart = urlInfo.content.indexOf(
15905
+ const createExternalReference = (
15906
+ node,
15907
+ attributeName,
15939
15908
  attributeValue,
15940
- attributeStart + `${attributeName}=`.length,
15941
- );
15942
- const attributeValueEnd = attributeValueStart + attributeValue.length;
15943
- const reference = urlInfo.dependencies.found({
15944
- type,
15945
- subtype,
15946
- expectedType,
15947
- specifier: attributeValue,
15948
- specifierLine: line,
15949
- specifierColumn: column,
15950
- specifierStart: attributeValueStart,
15951
- specifierEnd: attributeValueEnd,
15952
- isResourceHint,
15953
- isWeak: isResourceHint,
15954
- crossorigin,
15955
- integrity,
15956
- debug,
15957
- astInfo: { node, attributeName },
15958
- ...rest,
15959
- });
15960
- actions.push(async () => {
15961
- await reference.readGeneratedSpecifier();
15962
- mutations.push(() => {
15963
- setHtmlNodeAttributes(node, {
15964
- [attributeName]: reference.generatedSpecifier,
15909
+ { type, subtype, expectedType, ...rest },
15910
+ ) => {
15911
+ let position;
15912
+ if (getHtmlNodeAttribute(node, "jsenv-cooked-by")) {
15913
+ // when generated from inline content,
15914
+ // line, column is not "src" nor "inlined-from-src" but "original-position"
15915
+ position = getHtmlNodePosition(node);
15916
+ } else {
15917
+ position = getHtmlNodeAttributePosition(node, attributeName);
15918
+ }
15919
+ const {
15920
+ line,
15921
+ column,
15922
+ // originalLine, originalColumn
15923
+ } = position;
15924
+ const debug =
15925
+ getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
15926
+
15927
+ const { crossorigin, integrity } = readFetchMetas(node);
15928
+ const isResourceHint = [
15929
+ "preconnect",
15930
+ "dns-prefetch",
15931
+ "prefetch",
15932
+ "preload",
15933
+ "modulepreload",
15934
+ ].includes(subtype);
15935
+ let attributeLocation =
15936
+ node.sourceCodeLocation.attrs[attributeName];
15937
+ if (
15938
+ !attributeLocation &&
15939
+ attributeName === "href" &&
15940
+ (node.tagName === "use" || node.tagName === "image")
15941
+ ) {
15942
+ attributeLocation = node.sourceCodeLocation.attrs["xlink:href"];
15943
+ }
15944
+ const attributeStart = attributeLocation.startOffset;
15945
+ const attributeValueStart = urlInfo.content.indexOf(
15946
+ attributeValue,
15947
+ attributeStart + `${attributeName}=`.length,
15948
+ );
15949
+ const attributeValueEnd =
15950
+ attributeValueStart + attributeValue.length;
15951
+ const reference = urlInfo.dependencies.found({
15952
+ type,
15953
+ subtype,
15954
+ expectedType,
15955
+ specifier: attributeValue,
15956
+ specifierLine: line,
15957
+ specifierColumn: column,
15958
+ specifierStart: attributeValueStart,
15959
+ specifierEnd: attributeValueEnd,
15960
+ isResourceHint,
15961
+ isWeak: isResourceHint,
15962
+ crossorigin,
15963
+ integrity,
15964
+ debug,
15965
+ astInfo: { node, attributeName },
15966
+ ...rest,
15967
+ });
15968
+ actions.push(async () => {
15969
+ await reference.readGeneratedSpecifier();
15970
+ mutations.push(() => {
15971
+ setHtmlNodeAttributes(node, {
15972
+ [attributeName]: reference.generatedSpecifier,
15973
+ });
15965
15974
  });
15966
15975
  });
15967
- });
15968
- return reference;
15969
- };
15970
- const visitHref = (node, referenceProps) => {
15971
- const href = getHtmlNodeAttribute(node, "href");
15972
- if (href) {
15973
- return createExternalReference(node, "href", href, referenceProps);
15974
- }
15975
- return null;
15976
- };
15977
- const visitSrc = (node, referenceProps) => {
15978
- const src = getHtmlNodeAttribute(node, "src");
15979
- if (src) {
15980
- return createExternalReference(node, "src", src, referenceProps);
15981
- }
15982
- return null;
15983
- };
15984
- const visitSrcset = (node, referenceProps) => {
15985
- const srcset = getHtmlNodeAttribute(node, "srcset");
15986
- if (srcset) {
15987
- const srcCandidates = parseSrcSet(srcset);
15988
- return srcCandidates.map((srcCandidate) => {
15976
+ return reference;
15977
+ };
15978
+ const visitHref = (node, referenceProps) => {
15979
+ const href = getHtmlNodeAttribute(node, "href");
15980
+ if (href) {
15989
15981
  return createExternalReference(
15990
15982
  node,
15991
- "srcset",
15992
- srcCandidate.specifier,
15983
+ "href",
15984
+ href,
15993
15985
  referenceProps,
15994
15986
  );
15987
+ }
15988
+ return null;
15989
+ };
15990
+ const visitSrc = (node, referenceProps) => {
15991
+ const src = getHtmlNodeAttribute(node, "src");
15992
+ if (src) {
15993
+ return createExternalReference(node, "src", src, referenceProps);
15994
+ }
15995
+ return null;
15996
+ };
15997
+ const visitSrcset = (node, referenceProps) => {
15998
+ const srcset = getHtmlNodeAttribute(node, "srcset");
15999
+ if (srcset) {
16000
+ const srcCandidates = parseSrcSet(srcset);
16001
+ return srcCandidates.map((srcCandidate) => {
16002
+ return createExternalReference(
16003
+ node,
16004
+ "srcset",
16005
+ srcCandidate.specifier,
16006
+ referenceProps,
16007
+ );
16008
+ });
16009
+ }
16010
+ return null;
16011
+ };
16012
+ const createInlineReference = (
16013
+ node,
16014
+ inlineContent,
16015
+ { type, expectedType, contentType },
16016
+ ) => {
16017
+ const hotAccept =
16018
+ getHtmlNodeAttribute(node, "hot-accept") !== undefined;
16019
+ const { line, column, isOriginal } = getHtmlNodePosition(node, {
16020
+ preferOriginal: true,
15995
16021
  });
15996
- }
15997
- return null;
15998
- };
15999
-
16000
- const createInlineReference = (
16001
- node,
16002
- inlineContent,
16003
- { type, expectedType, contentType },
16004
- ) => {
16005
- const hotAccept =
16006
- getHtmlNodeAttribute(node, "hot-accept") !== undefined;
16007
- const { line, column, isOriginal } = getHtmlNodePosition(node, {
16008
- preferOriginal: true,
16009
- });
16010
- const inlineContentUrl = getUrlForContentInsideHtml(node, {
16011
- htmlUrl: urlInfo.url,
16012
- });
16013
- const debug = getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
16014
- const inlineReference = urlInfo.dependencies.foundInline({
16015
- type,
16016
- expectedType,
16017
- isOriginalPosition: isOriginal,
16018
- // we remove 1 to the line because imagine the following html:
16019
- // <style>body { color: red; }</style>
16020
- // -> content starts same line as <style> (same for <script>)
16021
- specifierLine: line - 1,
16022
- specifierColumn: column,
16023
- specifier: inlineContentUrl,
16024
- contentType,
16025
- content: inlineContent,
16026
- debug,
16027
- astInfo: { node },
16028
- });
16029
-
16030
- actions.push(async () => {
16031
- await inlineReference.urlInfo.cook();
16032
- mutations.push(() => {
16033
- if (hotAccept) {
16034
- removeHtmlNodeText(node);
16035
- setHtmlNodeAttributes(node, {
16036
- "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
16037
- });
16038
- } else {
16039
- setHtmlNodeText(node, inlineReference.urlInfo.content, {
16040
- indentation: false, // indentation would decrease stack trace precision
16041
- });
16042
- setHtmlNodeAttributes(node, {
16043
- "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
16044
- });
16045
- }
16022
+ const inlineContentUrl = getUrlForContentInsideHtml(node, {
16023
+ htmlUrl: urlInfo.url,
16046
16024
  });
16047
- });
16048
- return inlineReference;
16049
- };
16050
- const visitTextContent = (
16051
- node,
16052
- { type, subtype, expectedType, contentType },
16053
- ) => {
16054
- const inlineContent = getHtmlNodeText(node);
16055
- if (!inlineContent) {
16056
- return null;
16057
- }
16058
- return createInlineReference(node, inlineContent, {
16059
- type,
16060
- subtype,
16061
- expectedType,
16062
- contentType,
16063
- });
16064
- };
16065
-
16066
- visitHtmlNodes(htmlAst, {
16067
- link: (linkNode) => {
16068
- const rel = getHtmlNodeAttribute(linkNode, "rel");
16069
- const type = getHtmlNodeAttribute(linkNode, "type");
16070
- const ref = visitHref(linkNode, {
16071
- type: "link_href",
16072
- subtype: rel,
16073
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#including_a_mime_type
16074
- expectedContentType: type,
16025
+ const debug =
16026
+ getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
16027
+ const inlineReference = urlInfo.dependencies.foundInline({
16028
+ type,
16029
+ expectedType,
16030
+ isOriginalPosition: isOriginal,
16031
+ // we remove 1 to the line because imagine the following html:
16032
+ // <style>body { color: red; }</style>
16033
+ // -> content starts same line as <style> (same for <script>)
16034
+ specifierLine: line - 1,
16035
+ specifierColumn: column,
16036
+ specifier: inlineContentUrl,
16037
+ contentType,
16038
+ content: inlineContent,
16039
+ debug,
16040
+ astInfo: { node },
16075
16041
  });
16076
- if (ref) {
16077
- finalizeCallbacks.push(() => {
16078
- if (ref.expectedType) ; else {
16079
- ref.expectedType = decideLinkExpectedType(ref, urlInfo);
16042
+
16043
+ actions.push(async () => {
16044
+ await inlineReference.urlInfo.cook();
16045
+ mutations.push(() => {
16046
+ if (hotAccept) {
16047
+ removeHtmlNodeText(node);
16048
+ setHtmlNodeAttributes(node, {
16049
+ "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
16050
+ });
16051
+ } else {
16052
+ setHtmlNodeText(node, inlineReference.urlInfo.content, {
16053
+ indentation: false, // indentation would decrease stack trace precision
16054
+ });
16055
+ setHtmlNodeAttributes(node, {
16056
+ "jsenv-cooked-by": "jsenv:html_inline_content_analysis",
16057
+ });
16080
16058
  }
16081
16059
  });
16060
+ });
16061
+ return inlineReference;
16062
+ };
16063
+ const visitTextContent = (
16064
+ node,
16065
+ { type, subtype, expectedType, contentType },
16066
+ ) => {
16067
+ const inlineContent = getHtmlNodeText(node);
16068
+ if (!inlineContent) {
16069
+ return null;
16082
16070
  }
16083
- },
16084
- style: inlineContent
16085
- ? (styleNode) => {
16086
- visitTextContent(styleNode, {
16087
- type: "style",
16088
- expectedType: "css",
16089
- contentType: "text/css",
16071
+ return createInlineReference(node, inlineContent, {
16072
+ type,
16073
+ subtype,
16074
+ expectedType,
16075
+ contentType,
16076
+ });
16077
+ };
16078
+
16079
+ visitHtmlNodes(htmlAst, {
16080
+ link: (linkNode) => {
16081
+ const rel = getHtmlNodeAttribute(linkNode, "rel");
16082
+ const type = getHtmlNodeAttribute(linkNode, "type");
16083
+ const ref = visitHref(linkNode, {
16084
+ type: "link_href",
16085
+ subtype: rel,
16086
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#including_a_mime_type
16087
+ expectedContentType: type,
16088
+ });
16089
+ if (ref) {
16090
+ finalizeCallbacks.push(() => {
16091
+ if (ref.expectedType) {
16092
+ // might be set by other plugins, in that case respect it
16093
+ } else {
16094
+ ref.expectedType = decideLinkExpectedType(ref, urlInfo);
16095
+ }
16090
16096
  });
16091
16097
  }
16092
- : null,
16093
- script: (scriptNode) => {
16094
- const { type, subtype, contentType, extension } =
16095
- analyzeScriptNode(scriptNode);
16096
- if (type === "text") {
16097
- // ignore <script type="whatever">foobar</script>
16098
- // per HTML spec https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
16099
- return;
16100
- }
16101
- if (type === "importmap") {
16102
- importmapFound = true;
16103
-
16104
- const src = getHtmlNodeAttribute(scriptNode, "src");
16105
- if (src) {
16106
- // Browser would throw on remote importmap
16107
- // and won't sent a request to the server for it
16108
- // We must precook the importmap to know its content and inline it into the HTML
16109
- const importmapReference = createExternalReference(
16110
- scriptNode,
16111
- "src",
16112
- src,
16113
- {
16114
- type: "script",
16115
- subtype: "importmap",
16116
- expectedType: "importmap",
16117
- },
16118
- );
16119
- const { line, column, isOriginal } = getHtmlNodePosition(
16120
- scriptNode,
16121
- {
16122
- preferOriginal: true,
16123
- },
16124
- );
16125
- const importmapInlineUrl = getUrlForContentInsideHtml(
16126
- scriptNode,
16127
- {
16128
- htmlUrl: urlInfo.url,
16129
- },
16130
- );
16131
- const importmapReferenceInlined = importmapReference.inline({
16132
- line: line - 1,
16133
- column,
16134
- isOriginal,
16135
- specifier: importmapInlineUrl,
16136
- contentType: "application/importmap+json",
16137
- });
16138
- const importmapInlineUrlInfo =
16139
- importmapReferenceInlined.urlInfo;
16140
- actions.push(async () => {
16141
- await importmapInlineUrlInfo.cook();
16142
- importmapLoaded(importmapInlineUrlInfo);
16143
- mutations.push(() => {
16144
- setHtmlNodeText(
16145
- scriptNode,
16146
- importmapInlineUrlInfo.content,
16147
- {
16148
- indentation: "auto",
16149
- },
16150
- );
16151
- setHtmlNodeAttributes(scriptNode, {
16152
- "src": undefined,
16153
- "jsenv-inlined-by": "jsenv:html_reference_analysis",
16154
- "inlined-from-src": src,
16155
- });
16098
+ },
16099
+ style: inlineContent
16100
+ ? (styleNode) => {
16101
+ visitTextContent(styleNode, {
16102
+ type: "style",
16103
+ expectedType: "css",
16104
+ contentType: "text/css",
16156
16105
  });
16157
- });
16158
- } else {
16159
- const htmlNodeText = getHtmlNodeText(scriptNode);
16160
- if (htmlNodeText) {
16161
- const importmapReference = createInlineReference(
16106
+ }
16107
+ : null,
16108
+ script: (scriptNode) => {
16109
+ const { type, subtype, contentType, extension } =
16110
+ analyzeScriptNode(scriptNode);
16111
+ if (type === "text") {
16112
+ // ignore <script type="whatever">foobar</script>
16113
+ // per HTML spec https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
16114
+ return;
16115
+ }
16116
+ if (type === "importmap") {
16117
+ importmapFound = true;
16118
+
16119
+ const src = getHtmlNodeAttribute(scriptNode, "src");
16120
+ if (src) {
16121
+ // Browser would throw on remote importmap
16122
+ // and won't sent a request to the server for it
16123
+ // We must precook the importmap to know its content and inline it into the HTML
16124
+ const importmapReference = createExternalReference(
16162
16125
  scriptNode,
16163
- htmlNodeText,
16126
+ "src",
16127
+ src,
16164
16128
  {
16165
16129
  type: "script",
16130
+ subtype: "importmap",
16166
16131
  expectedType: "importmap",
16167
- contentType: "application/importmap+json",
16168
16132
  },
16169
16133
  );
16170
- const inlineImportmapUrlInfo = importmapReference.urlInfo;
16134
+ const { line, column, isOriginal } = getHtmlNodePosition(
16135
+ scriptNode,
16136
+ {
16137
+ preferOriginal: true,
16138
+ },
16139
+ );
16140
+ const importmapInlineUrl = getUrlForContentInsideHtml(
16141
+ scriptNode,
16142
+ {
16143
+ htmlUrl: urlInfo.url,
16144
+ },
16145
+ );
16146
+ const importmapReferenceInlined = importmapReference.inline({
16147
+ line: line - 1,
16148
+ column,
16149
+ isOriginal,
16150
+ specifier: importmapInlineUrl,
16151
+ contentType: "application/importmap+json",
16152
+ });
16153
+ const importmapInlineUrlInfo =
16154
+ importmapReferenceInlined.urlInfo;
16171
16155
  actions.push(async () => {
16172
- await inlineImportmapUrlInfo.cook();
16173
- importmapLoaded(inlineImportmapUrlInfo);
16156
+ try {
16157
+ await importmapInlineUrlInfo.cook();
16158
+ } finally {
16159
+ importmapLoaded(importmapInlineUrlInfo);
16160
+ }
16174
16161
  mutations.push(() => {
16175
16162
  setHtmlNodeText(
16176
16163
  scriptNode,
16177
- inlineImportmapUrlInfo.content,
16164
+ importmapInlineUrlInfo.content,
16178
16165
  {
16179
16166
  indentation: "auto",
16180
16167
  },
16181
16168
  );
16182
16169
  setHtmlNodeAttributes(scriptNode, {
16183
- "jsenv-cooked-by": "jsenv:html_reference_analysis",
16170
+ "src": undefined,
16171
+ "jsenv-inlined-by": "jsenv:html_reference_analysis",
16172
+ "inlined-from-src": src,
16173
+ });
16174
+ });
16175
+ });
16176
+ } else {
16177
+ const htmlNodeText = getHtmlNodeText(scriptNode);
16178
+ if (htmlNodeText) {
16179
+ const importmapReference = createInlineReference(
16180
+ scriptNode,
16181
+ htmlNodeText,
16182
+ {
16183
+ type: "script",
16184
+ expectedType: "importmap",
16185
+ contentType: "application/importmap+json",
16186
+ },
16187
+ );
16188
+ const inlineImportmapUrlInfo = importmapReference.urlInfo;
16189
+ actions.push(async () => {
16190
+ try {
16191
+ await inlineImportmapUrlInfo.cook();
16192
+ } finally {
16193
+ importmapLoaded(inlineImportmapUrlInfo);
16194
+ }
16195
+ mutations.push(() => {
16196
+ setHtmlNodeText(
16197
+ scriptNode,
16198
+ inlineImportmapUrlInfo.content,
16199
+ {
16200
+ indentation: "auto",
16201
+ },
16202
+ );
16203
+ setHtmlNodeAttributes(scriptNode, {
16204
+ "jsenv-cooked-by": "jsenv:html_reference_analysis",
16205
+ });
16184
16206
  });
16185
16207
  });
16208
+ }
16209
+ }
16210
+ // once this plugin knows the importmap, it will use it
16211
+ // to map imports. These import specifiers will be normalized
16212
+ // by "formatReference" making the importmap presence useless.
16213
+ // In dev/test we keep importmap into the HTML to see it even if useless
16214
+ // Duing build we get rid of it
16215
+ if (urlInfo.context.build) {
16216
+ mutations.push(() => {
16217
+ removeHtmlNode(scriptNode);
16186
16218
  });
16187
16219
  }
16220
+ return;
16188
16221
  }
16189
- // once this plugin knows the importmap, it will use it
16190
- // to map imports. These import specifiers will be normalized
16191
- // by "formatReference" making the importmap presence useless.
16192
- // In dev/test we keep importmap into the HTML to see it even if useless
16193
- // Duing build we get rid of it
16194
- if (urlInfo.context.build) {
16195
- mutations.push(() => {
16196
- removeHtmlNode(scriptNode);
16197
- });
16222
+ const externalRef = visitSrc(scriptNode, {
16223
+ type: "script",
16224
+ subtype: type,
16225
+ expectedType: type,
16226
+ });
16227
+ if (externalRef) {
16228
+ return;
16198
16229
  }
16199
- return;
16200
- }
16201
- const externalRef = visitSrc(scriptNode, {
16202
- type: "script",
16203
- subtype: type,
16204
- expectedType: type,
16205
- });
16206
- if (externalRef) {
16207
- return;
16208
- }
16209
16230
 
16210
- // now visit the content, if any
16211
- if (!inlineContent) {
16212
- return;
16213
- }
16214
- // If the inline script was already handled by an other plugin, ignore it
16215
- // - we want to preserve inline scripts generated by html supervisor during dev
16216
- // - we want to avoid cooking twice a script during build
16217
- if (
16218
- !inlineConvertedScript &&
16219
- getHtmlNodeAttribute(scriptNode, "jsenv-injected-by") ===
16220
- "jsenv:js_module_fallback"
16221
- ) {
16222
- return;
16223
- }
16231
+ // now visit the content, if any
16232
+ if (!inlineContent) {
16233
+ return;
16234
+ }
16235
+ // If the inline script was already handled by an other plugin, ignore it
16236
+ // - we want to preserve inline scripts generated by html supervisor during dev
16237
+ // - we want to avoid cooking twice a script during build
16238
+ if (
16239
+ !inlineConvertedScript &&
16240
+ getHtmlNodeAttribute(scriptNode, "jsenv-injected-by") ===
16241
+ "jsenv:js_module_fallback"
16242
+ ) {
16243
+ return;
16244
+ }
16224
16245
 
16225
- const inlineRef = visitTextContent(scriptNode, {
16226
- type: "script",
16227
- subtype,
16228
- expectedType: type,
16229
- contentType,
16230
- });
16231
- if (inlineRef) {
16232
- // 1. <script type="jsx"> becomes <script>
16233
- if (type === "js_classic" && extension !== ".js") {
16234
- mutations.push(() => {
16235
- setHtmlNodeAttributes(scriptNode, {
16236
- type: undefined,
16246
+ const inlineRef = visitTextContent(scriptNode, {
16247
+ type: "script",
16248
+ subtype,
16249
+ expectedType: type,
16250
+ contentType,
16251
+ });
16252
+ if (inlineRef) {
16253
+ // 1. <script type="jsx"> becomes <script>
16254
+ if (type === "js_classic" && extension !== ".js") {
16255
+ mutations.push(() => {
16256
+ setHtmlNodeAttributes(scriptNode, {
16257
+ type: undefined,
16258
+ });
16237
16259
  });
16238
- });
16239
- }
16240
- // 2. <script type="module/jsx"> becomes <script type="module">
16241
- if (type === "js_module" && extension !== ".js") {
16242
- mutations.push(() => {
16243
- setHtmlNodeAttributes(scriptNode, {
16244
- type: "module",
16260
+ }
16261
+ // 2. <script type="module/jsx"> becomes <script type="module">
16262
+ if (type === "js_module" && extension !== ".js") {
16263
+ mutations.push(() => {
16264
+ setHtmlNodeAttributes(scriptNode, {
16265
+ type: "module",
16266
+ });
16245
16267
  });
16246
- });
16268
+ }
16247
16269
  }
16248
- }
16249
- },
16250
- a: (aNode) => {
16251
- visitHref(aNode, {
16252
- type: "a_href",
16253
- });
16254
- },
16255
- iframe: (iframeNode) => {
16256
- visitSrc(iframeNode, {
16257
- type: "iframe_src",
16258
- });
16259
- },
16260
- img: (imgNode) => {
16261
- visitSrc(imgNode, {
16262
- type: "img_src",
16263
- });
16264
- visitSrcset(imgNode, {
16265
- type: "img_srcset",
16266
- });
16267
- },
16268
- source: (sourceNode) => {
16269
- visitSrc(sourceNode, {
16270
- type: "source_src",
16271
- });
16272
- visitSrcset(sourceNode, {
16273
- type: "source_srcset",
16274
- });
16275
- },
16276
- // svg <image> tag
16277
- image: (imageNode) => {
16278
- visitHref(imageNode, {
16279
- type: "image_href",
16280
- });
16281
- },
16282
- use: (useNode) => {
16283
- visitHref(useNode, {
16284
- type: "use_href",
16285
- });
16286
- },
16287
- });
16288
- if (!importmapFound) {
16289
- importmapLoaded();
16290
- }
16291
- finalizeCallbacks.forEach((finalizeCallback) => {
16292
- finalizeCallback();
16293
- });
16270
+ },
16271
+ a: (aNode) => {
16272
+ visitHref(aNode, {
16273
+ type: "a_href",
16274
+ });
16275
+ },
16276
+ iframe: (iframeNode) => {
16277
+ visitSrc(iframeNode, {
16278
+ type: "iframe_src",
16279
+ });
16280
+ },
16281
+ img: (imgNode) => {
16282
+ visitSrc(imgNode, {
16283
+ type: "img_src",
16284
+ });
16285
+ visitSrcset(imgNode, {
16286
+ type: "img_srcset",
16287
+ });
16288
+ },
16289
+ source: (sourceNode) => {
16290
+ visitSrc(sourceNode, {
16291
+ type: "source_src",
16292
+ });
16293
+ visitSrcset(sourceNode, {
16294
+ type: "source_srcset",
16295
+ });
16296
+ },
16297
+ // svg <image> tag
16298
+ image: (imageNode) => {
16299
+ visitHref(imageNode, {
16300
+ type: "image_href",
16301
+ });
16302
+ },
16303
+ use: (useNode) => {
16304
+ visitHref(useNode, {
16305
+ type: "use_href",
16306
+ });
16307
+ },
16308
+ });
16309
+ if (!importmapFound) {
16310
+ importmapLoaded();
16311
+ }
16312
+ finalizeCallbacks.forEach((finalizeCallback) => {
16313
+ finalizeCallback();
16314
+ });
16294
16315
 
16295
- if (actions.length > 0) {
16296
- await Promise.all(actions.map((action) => action()));
16297
- actions.length = 0;
16298
- }
16299
- if (mutations.length === 0) {
16300
- return null;
16316
+ if (actions.length > 0) {
16317
+ await Promise.all(actions.map((action) => action()));
16318
+ actions.length = 0;
16319
+ }
16320
+ if (mutations.length === 0) {
16321
+ return null;
16322
+ }
16323
+ mutations.forEach((mutation) => mutation());
16324
+ mutations.length = 0;
16325
+ return stringifyHtmlAst(htmlAst);
16326
+ } catch (e) {
16327
+ importmapLoaded();
16328
+ throw e;
16301
16329
  }
16302
- mutations.forEach((mutation) => mutation());
16303
- mutations.length = 0;
16304
- return stringifyHtmlAst(htmlAst);
16305
16330
  },
16306
16331
  },
16307
16332
  };
@@ -22302,6 +22327,9 @@ const startDevServer = async ({
22302
22327
  sourceDirectoryUrl,
22303
22328
  "sourceDirectoryUrl",
22304
22329
  );
22330
+ if (!existsSync(new URL(sourceDirectoryUrl))) {
22331
+ throw new Error(`ENOENT on sourceDirectoryUrl at ${sourceDirectoryUrl}`);
22332
+ }
22305
22333
  if (typeof sourceMainFilePath !== "string") {
22306
22334
  throw new TypeError(
22307
22335
  `sourceMainFilePath must be a string, got ${sourceMainFilePath}`,