@jsenv/core 39.5.22 → 39.5.24

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.
@@ -10875,7 +10875,7 @@ const jsenvPluginImportAttributes = ({
10875
10875
  const originalUrlInfo = urlInfo.getWithoutSearchParam(
10876
10876
  `as_${type}_module`,
10877
10877
  {
10878
- expectedType: "json",
10878
+ expectedType: type,
10879
10879
  },
10880
10880
  );
10881
10881
  if (!originalUrlInfo) {
@@ -11172,6 +11172,10 @@ const generateHtmlForSyntaxError = (
11172
11172
  const htmlForSyntaxError = String(readFileSync(htmlSyntaxErrorFileUrl));
11173
11173
  const htmlRelativeUrl = urlToRelativeUrl(htmlUrl, rootDirectoryUrl);
11174
11174
  const { line, column } = htmlSyntaxError;
11175
+ if (htmlUrl.startsWith(jsenvCoreDirectoryUrl.href)) {
11176
+ htmlUrl = urlToRelativeUrl(htmlUrl, jsenvCoreDirectoryUrl);
11177
+ htmlUrl = `@jsenv/core/${htmlUrl}`;
11178
+ }
11175
11179
  const urlWithLineAndColumn = `${htmlUrl}:${line}:${column}`;
11176
11180
  const replacers = {
11177
11181
  fileRelativeUrl: htmlRelativeUrl,
@@ -11530,7 +11534,9 @@ const assertAndNormalizeReturnValue = (hook, returnValue, info) => {
11530
11534
  if (!returnValueAssertion.appliesTo.includes(hook.name)) {
11531
11535
  continue;
11532
11536
  }
11533
- const assertionResult = returnValueAssertion.assertion(returnValue, info);
11537
+ const assertionResult = returnValueAssertion.assertion(returnValue, info, {
11538
+ hook,
11539
+ });
11534
11540
  if (assertionResult !== undefined) {
11535
11541
  // normalization
11536
11542
  returnValue = assertionResult;
@@ -11544,7 +11550,7 @@ const returnValueAssertions = [
11544
11550
  {
11545
11551
  name: "url_assertion",
11546
11552
  appliesTo: ["resolveReference", "redirectReference"],
11547
- assertion: (valueReturned) => {
11553
+ assertion: (valueReturned, urlInfo, { hook }) => {
11548
11554
  if (valueReturned instanceof URL) {
11549
11555
  return valueReturned.href;
11550
11556
  }
@@ -11552,7 +11558,7 @@ const returnValueAssertions = [
11552
11558
  return undefined;
11553
11559
  }
11554
11560
  throw new Error(
11555
- `Unexpected value returned by plugin: it must be a string; got ${valueReturned}`,
11561
+ `Unexpected value returned by "${hook.plugin.name}" plugin: it must be a string; got ${valueReturned}`,
11556
11562
  );
11557
11563
  },
11558
11564
  },
@@ -11564,7 +11570,7 @@ const returnValueAssertions = [
11564
11570
  "finalizeUrlContent",
11565
11571
  "optimizeUrlContent",
11566
11572
  ],
11567
- assertion: (valueReturned, urlInfo) => {
11573
+ assertion: (valueReturned, urlInfo, { hook }) => {
11568
11574
  if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
11569
11575
  return { content: valueReturned };
11570
11576
  }
@@ -11575,13 +11581,13 @@ const returnValueAssertions = [
11575
11581
  }
11576
11582
  if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
11577
11583
  throw new Error(
11578
- `Unexpected "content" returned by plugin: it must be a string or a buffer; got ${content}`,
11584
+ `Unexpected "content" returned by "${hook.plugin.name}" ${hook.name} hook: it must be a string or a buffer; got ${content}`,
11579
11585
  );
11580
11586
  }
11581
11587
  return undefined;
11582
11588
  }
11583
11589
  throw new Error(
11584
- `Unexpected value returned by plugin: it must be a string, a buffer or an object; got ${valueReturned}`,
11590
+ `Unexpected value returned by "${hook.plugin.name}" ${hook.name} hook: it must be a string, a buffer or an object; got ${valueReturned}`,
11585
11591
  );
11586
11592
  },
11587
11593
  },
@@ -12044,17 +12050,18 @@ const isResponseEligibleForIntegrityValidation = (response) => {
12044
12050
  };
12045
12051
 
12046
12052
  const assertFetchedContentCompliance = ({ urlInfo, content }) => {
12053
+ if (urlInfo.status === 404) {
12054
+ return;
12055
+ }
12047
12056
  const { expectedContentType } = urlInfo.firstReference;
12048
12057
  if (expectedContentType && urlInfo.contentType !== expectedContentType) {
12049
12058
  throw new Error(
12050
- `Unexpected content-type on url: "${expectedContentType}" was expect but got "${urlInfo.contentType}`,
12059
+ `content-type must be "${expectedContentType}", got "${urlInfo.contentType}`,
12051
12060
  );
12052
12061
  }
12053
12062
  const { expectedType } = urlInfo.firstReference;
12054
12063
  if (expectedType && urlInfo.type !== expectedType) {
12055
- throw new Error(
12056
- `Unexpected type on url: "${expectedType}" was expect but got "${urlInfo.type}"`,
12057
- );
12064
+ throw new Error(`type must be "${expectedType}", got "${urlInfo.type}"`);
12058
12065
  }
12059
12066
  const { integrity } = urlInfo.firstReference;
12060
12067
  if (integrity) {
@@ -13431,6 +13438,7 @@ const createUrlInfo = (url, context) => {
13431
13438
  jsQuote: null, // maybe move to inlineUrlSite?
13432
13439
 
13433
13440
  timing: {},
13441
+ status: 200,
13434
13442
  headers: {},
13435
13443
  debug: false,
13436
13444
  };
@@ -14498,21 +14506,16 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
14498
14506
  body,
14499
14507
  isEntryPoint,
14500
14508
  } = fetchUrlContentReturnValue;
14501
- if (status !== 200) {
14502
- throw new Error(`unexpected status, ${status}`);
14503
- }
14504
14509
  if (content === undefined) {
14505
14510
  content = body;
14506
14511
  }
14507
14512
  if (contentType === undefined) {
14508
14513
  contentType = headers["content-type"] || "application/octet-stream";
14509
14514
  }
14515
+ urlInfo.status = status;
14510
14516
  urlInfo.contentType = contentType;
14511
14517
  urlInfo.headers = headers;
14512
- urlInfo.type =
14513
- type ||
14514
- urlInfo.firstReference.expectedType ||
14515
- inferUrlInfoType(urlInfo);
14518
+ urlInfo.type = type || inferUrlInfoType(urlInfo);
14516
14519
  urlInfo.subtype =
14517
14520
  subtype ||
14518
14521
  urlInfo.firstReference.expectedSubtype ||
@@ -14836,10 +14839,11 @@ const memoizeIsSupported = (runtimeCompat) => {
14836
14839
 
14837
14840
  const inferUrlInfoType = (urlInfo) => {
14838
14841
  const { type, typeHint } = urlInfo;
14842
+ const { contentType } = urlInfo;
14843
+ const { expectedType } = urlInfo.firstReference;
14839
14844
  if (type === "sourcemap" || typeHint === "sourcemap") {
14840
14845
  return "sourcemap";
14841
14846
  }
14842
- const { contentType } = urlInfo;
14843
14847
  if (contentType === "text/html") {
14844
14848
  return "html";
14845
14849
  }
@@ -14847,7 +14851,12 @@ const inferUrlInfoType = (urlInfo) => {
14847
14851
  return "css";
14848
14852
  }
14849
14853
  if (contentType === "text/javascript") {
14850
- if (urlInfo.typeHint === "js_classic") return "js_classic";
14854
+ if (expectedType === "js_classic") {
14855
+ return "js_classic";
14856
+ }
14857
+ if (typeHint === "js_classic") {
14858
+ return "js_classic";
14859
+ }
14851
14860
  return "js_module";
14852
14861
  }
14853
14862
  if (contentType === "application/importmap+json") {
@@ -14865,7 +14874,7 @@ const inferUrlInfoType = (urlInfo) => {
14865
14874
  if (CONTENT_TYPE.isTextual(contentType)) {
14866
14875
  return "text";
14867
14876
  }
14868
- return "other";
14877
+ return expectedType || "other";
14869
14878
  };
14870
14879
 
14871
14880
  const createUrlGraphSummary = (
@@ -18850,10 +18859,13 @@ const jsenvPluginProtocolFile = ({
18850
18859
  };
18851
18860
  }
18852
18861
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
18853
- if (contentType === "text/html") {
18862
+ const request = urlInfo.context.request;
18863
+ if (request && request.headers["sec-fetch-dest"] === "document") {
18854
18864
  try {
18855
18865
  const fileBuffer = readFileSync(urlObject);
18856
- const content = String(fileBuffer);
18866
+ const content = CONTENT_TYPE.isTextual(contentType)
18867
+ ? String(fileBuffer)
18868
+ : fileBuffer;
18857
18869
  return {
18858
18870
  content,
18859
18871
  contentType,
@@ -18870,7 +18882,7 @@ const jsenvPluginProtocolFile = ({
18870
18882
  const parentDirectoryContentArray = readdirSync(
18871
18883
  new URL(parentDirectoryUrl),
18872
18884
  );
18873
- const html = generateHtmlForENOENTOnHtmlFile(
18885
+ const html = generateHtmlForENOENT(
18874
18886
  urlInfo.url,
18875
18887
  parentDirectoryContentArray,
18876
18888
  parentDirectoryUrl,
@@ -18878,6 +18890,7 @@ const jsenvPluginProtocolFile = ({
18878
18890
  directoryListingUrlMocks,
18879
18891
  );
18880
18892
  return {
18893
+ status: 404,
18881
18894
  contentType: "text/html",
18882
18895
  content: html,
18883
18896
  headers: {
@@ -18923,7 +18936,7 @@ const generateHtmlForDirectory = (
18923
18936
  const html = replacePlaceholders$1(htmlForDirectory, replacers);
18924
18937
  return html;
18925
18938
  };
18926
- const generateHtmlForENOENTOnHtmlFile = (
18939
+ const generateHtmlForENOENT = (
18927
18940
  url,
18928
18941
  parentDirectoryContentArray,
18929
18942
  parentDirectoryUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "39.5.22",
3
+ "version": "39.5.24",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -78,7 +78,7 @@
78
78
  "@jsenv/node-esm-resolution": "1.0.6",
79
79
  "@jsenv/plugin-bundling": "2.7.16",
80
80
  "@jsenv/plugin-minification": "1.5.10",
81
- "@jsenv/plugin-supervisor": "1.5.27",
81
+ "@jsenv/plugin-supervisor": "1.5.28",
82
82
  "@jsenv/plugin-transpilation": "1.4.84",
83
83
  "@jsenv/runtime-compat": "1.3.1",
84
84
  "@jsenv/server": "15.3.3",
@@ -1,17 +1,18 @@
1
1
  import { validateResponseIntegrity } from "@jsenv/integrity";
2
2
 
3
3
  export const assertFetchedContentCompliance = ({ urlInfo, content }) => {
4
+ if (urlInfo.status === 404) {
5
+ return;
6
+ }
4
7
  const { expectedContentType } = urlInfo.firstReference;
5
8
  if (expectedContentType && urlInfo.contentType !== expectedContentType) {
6
9
  throw new Error(
7
- `Unexpected content-type on url: "${expectedContentType}" was expect but got "${urlInfo.contentType}`,
10
+ `content-type must be "${expectedContentType}", got "${urlInfo.contentType}`,
8
11
  );
9
12
  }
10
13
  const { expectedType } = urlInfo.firstReference;
11
14
  if (expectedType && urlInfo.type !== expectedType) {
12
- throw new Error(
13
- `Unexpected type on url: "${expectedType}" was expect but got "${urlInfo.type}"`,
14
- );
15
+ throw new Error(`type must be "${expectedType}", got "${urlInfo.type}"`);
15
16
  }
16
17
  const { integrity } = urlInfo.firstReference;
17
18
  if (integrity) {
@@ -342,21 +342,16 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
342
342
  body,
343
343
  isEntryPoint,
344
344
  } = fetchUrlContentReturnValue;
345
- if (status !== 200) {
346
- throw new Error(`unexpected status, ${status}`);
347
- }
348
345
  if (content === undefined) {
349
346
  content = body;
350
347
  }
351
348
  if (contentType === undefined) {
352
349
  contentType = headers["content-type"] || "application/octet-stream";
353
350
  }
351
+ urlInfo.status = status;
354
352
  urlInfo.contentType = contentType;
355
353
  urlInfo.headers = headers;
356
- urlInfo.type =
357
- type ||
358
- urlInfo.firstReference.expectedType ||
359
- inferUrlInfoType(urlInfo);
354
+ urlInfo.type = type || inferUrlInfoType(urlInfo);
360
355
  urlInfo.subtype =
361
356
  subtype ||
362
357
  urlInfo.firstReference.expectedSubtype ||
@@ -680,10 +675,11 @@ const memoizeIsSupported = (runtimeCompat) => {
680
675
 
681
676
  const inferUrlInfoType = (urlInfo) => {
682
677
  const { type, typeHint } = urlInfo;
678
+ const { contentType } = urlInfo;
679
+ const { expectedType } = urlInfo.firstReference;
683
680
  if (type === "sourcemap" || typeHint === "sourcemap") {
684
681
  return "sourcemap";
685
682
  }
686
- const { contentType } = urlInfo;
687
683
  if (contentType === "text/html") {
688
684
  return "html";
689
685
  }
@@ -691,7 +687,12 @@ const inferUrlInfoType = (urlInfo) => {
691
687
  return "css";
692
688
  }
693
689
  if (contentType === "text/javascript") {
694
- if (urlInfo.typeHint === "js_classic") return "js_classic";
690
+ if (expectedType === "js_classic") {
691
+ return "js_classic";
692
+ }
693
+ if (typeHint === "js_classic") {
694
+ return "js_classic";
695
+ }
695
696
  return "js_module";
696
697
  }
697
698
  if (contentType === "application/importmap+json") {
@@ -709,5 +710,5 @@ const inferUrlInfoType = (urlInfo) => {
709
710
  if (CONTENT_TYPE.isTextual(contentType)) {
710
711
  return "text";
711
712
  }
712
- return "other";
713
+ return expectedType || "other";
713
714
  };
@@ -226,6 +226,7 @@ const createUrlInfo = (url, context) => {
226
226
  jsQuote: null, // maybe move to inlineUrlSite?
227
227
 
228
228
  timing: {},
229
+ status: 200,
229
230
  headers: {},
230
231
  debug: false,
231
232
  };
@@ -1,8 +1,8 @@
1
1
  import { parseHtml } from "@jsenv/ast";
2
+ import { generateContentFrame } from "@jsenv/humanize";
2
3
  import { urlToRelativeUrl } from "@jsenv/urls";
3
4
  import { readFileSync } from "node:fs";
4
-
5
- import { generateContentFrame } from "@jsenv/humanize";
5
+ import { jsenvCoreDirectoryUrl } from "../../jsenv_core_directory_url.js";
6
6
 
7
7
  export const jsenvPluginHtmlSyntaxErrorFallback = () => {
8
8
  const htmlSyntaxErrorFileUrl = new URL(
@@ -58,6 +58,10 @@ const generateHtmlForSyntaxError = (
58
58
  const htmlForSyntaxError = String(readFileSync(htmlSyntaxErrorFileUrl));
59
59
  const htmlRelativeUrl = urlToRelativeUrl(htmlUrl, rootDirectoryUrl);
60
60
  const { line, column } = htmlSyntaxError;
61
+ if (htmlUrl.startsWith(jsenvCoreDirectoryUrl.href)) {
62
+ htmlUrl = urlToRelativeUrl(htmlUrl, jsenvCoreDirectoryUrl);
63
+ htmlUrl = `@jsenv/core/${htmlUrl}`;
64
+ }
61
65
  const urlWithLineAndColumn = `${htmlUrl}:${line}:${column}`;
62
66
  const replacers = {
63
67
  fileRelativeUrl: htmlRelativeUrl,
@@ -324,7 +324,9 @@ const assertAndNormalizeReturnValue = (hook, returnValue, info) => {
324
324
  if (!returnValueAssertion.appliesTo.includes(hook.name)) {
325
325
  continue;
326
326
  }
327
- const assertionResult = returnValueAssertion.assertion(returnValue, info);
327
+ const assertionResult = returnValueAssertion.assertion(returnValue, info, {
328
+ hook,
329
+ });
328
330
  if (assertionResult !== undefined) {
329
331
  // normalization
330
332
  returnValue = assertionResult;
@@ -338,7 +340,7 @@ const returnValueAssertions = [
338
340
  {
339
341
  name: "url_assertion",
340
342
  appliesTo: ["resolveReference", "redirectReference"],
341
- assertion: (valueReturned) => {
343
+ assertion: (valueReturned, urlInfo, { hook }) => {
342
344
  if (valueReturned instanceof URL) {
343
345
  return valueReturned.href;
344
346
  }
@@ -346,7 +348,7 @@ const returnValueAssertions = [
346
348
  return undefined;
347
349
  }
348
350
  throw new Error(
349
- `Unexpected value returned by plugin: it must be a string; got ${valueReturned}`,
351
+ `Unexpected value returned by "${hook.plugin.name}" plugin: it must be a string; got ${valueReturned}`,
350
352
  );
351
353
  },
352
354
  },
@@ -358,7 +360,7 @@ const returnValueAssertions = [
358
360
  "finalizeUrlContent",
359
361
  "optimizeUrlContent",
360
362
  ],
361
- assertion: (valueReturned, urlInfo) => {
363
+ assertion: (valueReturned, urlInfo, { hook }) => {
362
364
  if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
363
365
  return { content: valueReturned };
364
366
  }
@@ -369,13 +371,13 @@ const returnValueAssertions = [
369
371
  }
370
372
  if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
371
373
  throw new Error(
372
- `Unexpected "content" returned by plugin: it must be a string or a buffer; got ${content}`,
374
+ `Unexpected "content" returned by "${hook.plugin.name}" ${hook.name} hook: it must be a string or a buffer; got ${content}`,
373
375
  );
374
376
  }
375
377
  return undefined;
376
378
  }
377
379
  throw new Error(
378
- `Unexpected value returned by plugin: it must be a string, a buffer or an object; got ${valueReturned}`,
380
+ `Unexpected value returned by "${hook.plugin.name}" ${hook.name} hook: it must be a string, a buffer or an object; got ${valueReturned}`,
379
381
  );
380
382
  },
381
383
  },
@@ -118,10 +118,13 @@ export const jsenvPluginProtocolFile = ({
118
118
  };
119
119
  }
120
120
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
121
- if (contentType === "text/html") {
121
+ const request = urlInfo.context.request;
122
+ if (request && request.headers["sec-fetch-dest"] === "document") {
122
123
  try {
123
124
  const fileBuffer = readFileSync(urlObject);
124
- const content = String(fileBuffer);
125
+ const content = CONTENT_TYPE.isTextual(contentType)
126
+ ? String(fileBuffer)
127
+ : fileBuffer;
125
128
  return {
126
129
  content,
127
130
  contentType,
@@ -138,7 +141,7 @@ export const jsenvPluginProtocolFile = ({
138
141
  const parentDirectoryContentArray = readdirSync(
139
142
  new URL(parentDirectoryUrl),
140
143
  );
141
- const html = generateHtmlForENOENTOnHtmlFile(
144
+ const html = generateHtmlForENOENT(
142
145
  urlInfo.url,
143
146
  parentDirectoryContentArray,
144
147
  parentDirectoryUrl,
@@ -146,6 +149,7 @@ export const jsenvPluginProtocolFile = ({
146
149
  directoryListingUrlMocks,
147
150
  );
148
151
  return {
152
+ status: 404,
149
153
  contentType: "text/html",
150
154
  content: html,
151
155
  headers: {
@@ -191,7 +195,7 @@ const generateHtmlForDirectory = (
191
195
  const html = replacePlaceholders(htmlForDirectory, replacers);
192
196
  return html;
193
197
  };
194
- const generateHtmlForENOENTOnHtmlFile = (
198
+ const generateHtmlForENOENT = (
195
199
  url,
196
200
  parentDirectoryContentArray,
197
201
  parentDirectoryUrl,