@jsenv/core 40.5.3 → 40.6.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.
@@ -183,6 +183,12 @@ ${reason}`,
183
183
  });
184
184
  return error;
185
185
  }
186
+ if (error.code === "PROTOCOL_NOT_SUPPORTED") {
187
+ const notSupportedError = createFailedToResolveUrlError({
188
+ reason: error.message,
189
+ });
190
+ return notSupportedError;
191
+ }
186
192
  return createFailedToResolveUrlError({
187
193
  reason: `An error occured during specifier resolution`,
188
194
  ...detailsFromValueThrown(error),
@@ -223,7 +229,6 @@ ${reason}`,
223
229
  });
224
230
  return fetchError;
225
231
  };
226
-
227
232
  if (error.code === "EPERM") {
228
233
  return createFailedToFetchUrlContentError({
229
234
  code: "NOT_ALLOWED",
@@ -270,6 +275,9 @@ const createTransformUrlContentError = ({
270
275
  if (error.code === "MODULE_NOT_FOUND") {
271
276
  return error;
272
277
  }
278
+ if (error.code === "PROTOCOL_NOT_SUPPORTED") {
279
+ return error;
280
+ }
273
281
  if (error.code === "DIRECTORY_REFERENCE_NOT_ALLOWED") {
274
282
  return error;
275
283
  }
@@ -277,47 +285,8 @@ const createTransformUrlContentError = ({
277
285
  if (error.isJsenvCookingError) {
278
286
  return error;
279
287
  }
288
+ const trace = getErrorTrace(error, urlInfo.firstReference);
280
289
  const reference = urlInfo.firstReference;
281
- let trace = reference.trace;
282
- let line = error.line;
283
- let column = error.column;
284
- if (urlInfo.isInline) {
285
- line = trace.line + line;
286
- line = line - 1;
287
- trace = {
288
- ...trace,
289
- line,
290
- column,
291
- codeFrame: generateContentFrame({
292
- line,
293
- column,
294
- content: urlInfo.inlineUrlSite.content,
295
- }),
296
- message: stringifyUrlSite({
297
- url: urlInfo.inlineUrlSite.url,
298
- line,
299
- column,
300
- content: urlInfo.inlineUrlSite.content,
301
- }),
302
- };
303
- } else {
304
- trace = {
305
- url: urlInfo.url,
306
- line,
307
- column: error.column,
308
- codeFrame: generateContentFrame({
309
- line,
310
- column: error.column,
311
- content: urlInfo.content,
312
- }),
313
- message: stringifyUrlSite({
314
- url: urlInfo.url,
315
- line,
316
- column: error.column,
317
- content: urlInfo.content,
318
- }),
319
- };
320
- }
321
290
  const transformError = new Error(
322
291
  createDetailedMessage(
323
292
  `parse error on "${urlInfo.type}"
@@ -408,9 +377,55 @@ ${reference.trace.message}`,
408
377
  return finalizeError;
409
378
  };
410
379
 
380
+ const getErrorTrace = (error, reference) => {
381
+ const urlInfo = reference.urlInfo;
382
+ let trace = reference.trace;
383
+ let line = error.line;
384
+ let column = error.column;
385
+ if (urlInfo.isInline) {
386
+ line = trace.line + line;
387
+ line = line - 1;
388
+ return {
389
+ ...trace,
390
+ line,
391
+ column,
392
+ codeFrame: generateContentFrame({
393
+ line,
394
+ column,
395
+ content: urlInfo.inlineUrlSite.content,
396
+ }),
397
+ message: stringifyUrlSite({
398
+ url: urlInfo.inlineUrlSite.url,
399
+ line,
400
+ column,
401
+ content: urlInfo.inlineUrlSite.content,
402
+ }),
403
+ };
404
+ }
405
+ return {
406
+ url: urlInfo.url,
407
+ line,
408
+ column: error.column,
409
+ codeFrame: generateContentFrame({
410
+ line,
411
+ column: error.column,
412
+ content: urlInfo.content,
413
+ }),
414
+ message: stringifyUrlSite({
415
+ url: urlInfo.url,
416
+ line,
417
+ column: error.column,
418
+ content: urlInfo.content,
419
+ }),
420
+ };
421
+ };
422
+
411
423
  const detailsFromFirstReference = (reference) => {
412
424
  const referenceInProject = getFirstReferenceInProject(reference);
413
- if (referenceInProject === reference) {
425
+ if (
426
+ referenceInProject === reference ||
427
+ referenceInProject.type === "http_request"
428
+ ) {
414
429
  return {};
415
430
  }
416
431
  return {
@@ -419,6 +434,9 @@ const detailsFromFirstReference = (reference) => {
419
434
  };
420
435
  const getFirstReferenceInProject = (reference) => {
421
436
  const ownerUrlInfo = reference.ownerUrlInfo;
437
+ if (ownerUrlInfo.isRoot) {
438
+ return reference;
439
+ }
422
440
  if (
423
441
  !ownerUrlInfo.url.includes("/node_modules/") &&
424
442
  ownerUrlInfo.packageDirectoryUrl ===
@@ -426,7 +444,8 @@ const getFirstReferenceInProject = (reference) => {
426
444
  ) {
427
445
  return reference;
428
446
  }
429
- return getFirstReferenceInProject(ownerUrlInfo.firstReference);
447
+ const { firstReference } = ownerUrlInfo;
448
+ return getFirstReferenceInProject(firstReference);
430
449
  };
431
450
 
432
451
  const detailsFromPluginController = (pluginController) => {
@@ -2668,7 +2687,28 @@ const createKitchen = ({
2668
2687
 
2669
2688
  ignore,
2670
2689
  ignoreProtocol = "remove",
2671
- supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
2690
+ supportedProtocols = [
2691
+ "file:",
2692
+ "data:",
2693
+ // eslint-disable-next-line no-script-url
2694
+ "javascript:",
2695
+ "virtual:",
2696
+ "ignore:",
2697
+ "http:",
2698
+ "https:",
2699
+ "chrome:",
2700
+ "chrome-extension:",
2701
+ "chrome-untrusted:",
2702
+ "isolated-app:",
2703
+ ],
2704
+ includedProtocols = [
2705
+ "file:",
2706
+ "data:",
2707
+ "virtual:",
2708
+ "ignore:",
2709
+ "http:",
2710
+ "https:",
2711
+ ],
2672
2712
 
2673
2713
  // during dev/test clientRuntimeCompat is a single runtime
2674
2714
  // during build clientRuntimeCompat is runtimeCompat
@@ -2688,6 +2728,9 @@ const createKitchen = ({
2688
2728
 
2689
2729
  const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
2690
2730
  const packageConditions = [nodeRuntimeEnabled ? "node" : "browser", "import"];
2731
+ if (nodeRuntimeEnabled) {
2732
+ supportedProtocols.push("node:");
2733
+ }
2691
2734
 
2692
2735
  if (packageDependencies === "auto") {
2693
2736
  packageDependencies = build && nodeRuntimeEnabled ? "ignore" : "include";
@@ -2759,8 +2802,11 @@ const createKitchen = ({
2759
2802
 
2760
2803
  const isIgnoredByProtocol = (url) => {
2761
2804
  const { protocol } = new URL(url);
2762
- const protocolIsSupported = supportedProtocols.includes(protocol);
2763
- return !protocolIsSupported;
2805
+ const protocolIsIncluded = includedProtocols.includes(protocol);
2806
+ if (protocolIsIncluded) {
2807
+ return false;
2808
+ }
2809
+ return true;
2764
2810
  };
2765
2811
  const isIgnoredBecauseInPackageDependencies = (() => {
2766
2812
  if (packageDependencies === undefined) {
@@ -2967,6 +3013,21 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
2967
3013
  }
2968
3014
  reference.generatedUrl = reference.url;
2969
3015
  reference.generatedSearchParams = reference.searchParams;
3016
+ if (dev) {
3017
+ let url = reference.url;
3018
+ let { protocol } = new URL(url);
3019
+ if (protocol === "ignore:") {
3020
+ url = url.slice("ignore:".length);
3021
+ protocol = new URL(url, "http://example.com").protocol;
3022
+ }
3023
+ if (!supportedProtocols.includes(protocol)) {
3024
+ const protocolNotSupportedError = new Error(
3025
+ `Unsupported protocol "${protocol}" for url "${url}"`,
3026
+ );
3027
+ protocolNotSupportedError.code = "PROTOCOL_NOT_SUPPORTED";
3028
+ throw protocolNotSupportedError;
3029
+ }
3030
+ }
2970
3031
  return reference;
2971
3032
  } catch (error) {
2972
3033
  throw createResolveUrlError({
@@ -5594,13 +5655,32 @@ const createNodeEsmResolver = ({
5594
5655
  return null; // let it to jsenv_web_resolution
5595
5656
  }
5596
5657
  const { specifier } = reference;
5597
- const conditions = buildPackageConditions(specifier, parentUrl);
5598
- const { url, type, isMain, packageDirectoryUrl } = applyNodeEsmResolution({
5658
+ // specifiers like "#something" have a special meaning for Node.js
5659
+ // but can also be used in .css and .html files for example and should not be modified
5660
+ // by node esm resolution
5661
+ const webResolutionFallback =
5662
+ ownerUrlInfo.type !== "js_module" ||
5663
+ reference.type === "sourcemap_comment";
5664
+ const conditions = buildPackageConditions(specifier, parentUrl, {
5665
+ webResolutionFallback,
5666
+ });
5667
+ let resolution;
5668
+ const nodeEsmResolutionParams = {
5599
5669
  conditions,
5600
5670
  parentUrl,
5601
5671
  specifier,
5602
5672
  preservesSymlink,
5603
- });
5673
+ };
5674
+ if (webResolutionFallback) {
5675
+ try {
5676
+ resolution = applyNodeEsmResolution(nodeEsmResolutionParams);
5677
+ } catch {
5678
+ return null; // delegate to web_resolution plugin
5679
+ }
5680
+ } else {
5681
+ resolution = applyNodeEsmResolution(nodeEsmResolutionParams);
5682
+ }
5683
+ const { url, type, isMain, packageDirectoryUrl } = resolution;
5604
5684
  // try to give a more meaningful filename after build
5605
5685
  if (isMain && packageDirectoryUrl) {
5606
5686
  const basename = urlToBasename(url);
@@ -5669,12 +5749,26 @@ const createBuildPackageConditions = (
5669
5749
  const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
5670
5750
  // https://nodejs.org/api/esm.html#resolver-algorithm-specification
5671
5751
  const processArgConditions = readCustomConditionsFromProcessArgs();
5672
- const devResolver = (specifier, importer) => {
5752
+ const devResolver = (specifier, importer, { webResolutionFallback }) => {
5673
5753
  if (isBareSpecifier$1(specifier)) {
5674
- const { url } = applyNodeEsmResolution({
5675
- specifier,
5676
- parentUrl: importer,
5677
- });
5754
+ let url;
5755
+ if (webResolutionFallback) {
5756
+ try {
5757
+ const resolution = applyNodeEsmResolution({
5758
+ specifier,
5759
+ parentUrl: importer,
5760
+ });
5761
+ url = resolution.url;
5762
+ } catch {
5763
+ url = new URL(specifier, importer).href;
5764
+ }
5765
+ } else {
5766
+ const resolution = applyNodeEsmResolution({
5767
+ specifier,
5768
+ parentUrl: importer,
5769
+ });
5770
+ url = resolution.url;
5771
+ }
5678
5772
  return !url.includes("/node_modules/");
5679
5773
  }
5680
5774
  return !importer.includes("/node_modules/");
@@ -5778,12 +5872,12 @@ const createBuildPackageConditions = (
5778
5872
  }
5779
5873
 
5780
5874
  const conditionCandidateArray = Object.keys(conditionResolvers);
5781
- return (specifier, importer) => {
5875
+ return (specifier, importer, params) => {
5782
5876
  const conditions = [];
5783
5877
  for (const conditionCandidate of conditionCandidateArray) {
5784
5878
  const conditionResolver = conditionResolvers[conditionCandidate];
5785
5879
  if (typeof conditionResolver === "function") {
5786
- if (conditionResolver(specifier, importer)) {
5880
+ if (conditionResolver(specifier, importer, params)) {
5787
5881
  conditions.push(conditionCandidate);
5788
5882
  }
5789
5883
  } else if (conditionResolver) {
@@ -5907,8 +6001,7 @@ const jsenvPluginNodeEsmResolution = (
5907
6001
  if (config === true) {
5908
6002
  resolver = nodeEsmResolverDefault;
5909
6003
  } else if (config === false) {
5910
- // resolverMap.set(urlType, () => null);
5911
- continue;
6004
+ resolver = null;
5912
6005
  } else if (typeof config === "object") {
5913
6006
  resolver = resolverFromObject(config, { kitchenContext, urlType });
5914
6007
  } else {
@@ -5923,6 +6016,9 @@ const jsenvPluginNodeEsmResolution = (
5923
6016
  resolverMap.set(urlType, resolver);
5924
6017
  }
5925
6018
  }
6019
+ if (!anyTypeResolver) {
6020
+ anyTypeResolver = nodeEsmResolverDefault;
6021
+ }
5926
6022
 
5927
6023
  if (!resolverMap.has("js_module")) {
5928
6024
  resolverMap.set("js_module", nodeEsmResolverDefault);
@@ -5948,8 +6044,11 @@ const jsenvPluginNodeEsmResolution = (
5948
6044
  }
5949
6045
  const urlType = urlTypeFromReference(reference);
5950
6046
  const resolver = resolverMap.get(urlType);
5951
- if (resolver) {
5952
- return resolver(reference);
6047
+ if (resolver !== undefined) {
6048
+ if (typeof resolver === "function") {
6049
+ return resolver(reference);
6050
+ }
6051
+ return resolver;
5953
6052
  }
5954
6053
  if (anyTypeResolver) {
5955
6054
  return anyTypeResolver(reference);
@@ -6805,6 +6904,9 @@ const jsenvPluginProtocolFile = ({
6805
6904
  name: "jsenv:directory_as_json",
6806
6905
  appliesDuring: "*",
6807
6906
  fetchUrlContent: (urlInfo) => {
6907
+ if (!urlInfo.url.startsWith("file:")) {
6908
+ return null;
6909
+ }
6808
6910
  const { firstReference } = urlInfo;
6809
6911
  let { fsStat } = firstReference;
6810
6912
  if (!fsStat) {
@@ -11744,7 +11846,7 @@ const prepareEntryPointBuild = async (
11744
11846
  // - no plugin putting reference.mustIgnore on https urls
11745
11847
  // At this stage it's only about redirecting urls to the build directory
11746
11848
  // consequently only a subset or urls are supported
11747
- supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
11849
+ includedProtocols: ["file:", "data:", "virtual:", "ignore:"],
11748
11850
  ignore,
11749
11851
  ignoreProtocol: "remove",
11750
11852
  build: true,