@jsenv/core 39.3.11 → 39.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,92 @@
1
- export const jsenvPluginProtocolHttp = () => {
1
+ import { URL_META } from "@jsenv/url-meta";
2
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
3
+
4
+ export const jsenvPluginProtocolHttp = ({ include }) => {
5
+ if (include === false) {
6
+ return {
7
+ name: "jsenv:protocol_http",
8
+ appliesDuring: "*",
9
+ redirectReference: (reference) => {
10
+ if (!reference.url.startsWith("http")) {
11
+ return null;
12
+ }
13
+ return `ignore:${reference.url}`;
14
+ },
15
+ };
16
+ }
17
+ const shouldInclude =
18
+ include === true
19
+ ? () => true
20
+ : URL_META.createFilter(include, "http://jsenv.com");
21
+
2
22
  return {
3
23
  name: "jsenv:protocol_http",
4
- appliesDuring: "*",
24
+ appliesDuring: "build",
25
+ // resolveReference: (reference) => {
26
+ // if (reference.original && reference.original.url.startsWith("http")) {
27
+ // return new URL(reference.specifier, reference.original.url);
28
+ // }
29
+ // return null;
30
+ // },
5
31
  redirectReference: (reference) => {
6
- // TODO: according to some pattern matching jsenv could be allowed
7
- // to fetch and transform http urls
8
- if (
9
- reference.url.startsWith("http:") ||
10
- reference.url.startsWith("https:")
11
- ) {
32
+ if (!reference.url.startsWith("http")) {
33
+ return null;
34
+ }
35
+ if (!shouldInclude(reference.url)) {
12
36
  return `ignore:${reference.url}`;
13
37
  }
14
- return null;
38
+ const outDirectoryUrl = reference.ownerUrlInfo.context.outDirectoryUrl;
39
+ const urlObject = new URL(reference.url);
40
+ const { host, pathname, search } = urlObject;
41
+ let fileUrl = String(outDirectoryUrl);
42
+ if (reference.url.startsWith("http:")) {
43
+ fileUrl += "@http/";
44
+ } else {
45
+ fileUrl += "@https/";
46
+ }
47
+ fileUrl += asValidFilename(host);
48
+ if (pathname) {
49
+ fileUrl += "/";
50
+ fileUrl += asValidFilename(pathname);
51
+ }
52
+ if (search) {
53
+ fileUrl += search;
54
+ }
55
+ return fileUrl;
56
+ },
57
+ fetchUrlContent: async (urlInfo) => {
58
+ if (!urlInfo.originalUrl.startsWith("http")) {
59
+ return null;
60
+ }
61
+ const response = await fetch(urlInfo.originalUrl);
62
+ const responseStatus = response.status;
63
+ if (responseStatus < 200 || responseStatus > 299) {
64
+ throw new Error(`unexpected response status ${responseStatus}`);
65
+ }
66
+ const responseHeaders = response.headers;
67
+ const responseContentType = responseHeaders.get("content-type");
68
+ const contentType = responseContentType || "application/octet-stream";
69
+ const isTextual = CONTENT_TYPE.isTextual(contentType);
70
+ let content;
71
+ if (isTextual) {
72
+ content = await response.text();
73
+ } else {
74
+ content = await response.buffer;
75
+ }
76
+ return {
77
+ content,
78
+ contentType,
79
+ contentLength: responseHeaders.get("content-length") || undefined,
80
+ };
15
81
  },
16
82
  };
17
83
  };
84
+
85
+ // see https://github.com/parshap/node-sanitize-filename/blob/master/index.js
86
+ const asValidFilename = (string) => {
87
+ string = string.trim().toLowerCase();
88
+ if (string === ".") return "_";
89
+ if (string === "..") return "__";
90
+ string = string.replace(/[ ,]/g, "_").replace(/["/?<>\\:*|]/g, "");
91
+ return string;
92
+ };
@@ -35,17 +35,27 @@ export const createNodeEsmResolver = ({
35
35
  const { ownerUrlInfo } = reference;
36
36
  if (reference.specifier === "/") {
37
37
  const { mainFilePath, rootDirectoryUrl } = ownerUrlInfo.context;
38
- return String(new URL(mainFilePath, rootDirectoryUrl));
38
+ const url = new URL(mainFilePath, rootDirectoryUrl);
39
+ return url;
39
40
  }
40
41
  if (reference.specifier[0] === "/") {
41
- return new URL(
42
+ const url = new URL(
42
43
  reference.specifier.slice(1),
43
44
  ownerUrlInfo.context.rootDirectoryUrl,
44
- ).href;
45
+ );
46
+ return url;
47
+ }
48
+ let parentUrl;
49
+ if (reference.baseUrl) {
50
+ parentUrl = reference.baseUrl;
51
+ } else if (ownerUrlInfo.originalUrl?.startsWith("http")) {
52
+ parentUrl = ownerUrlInfo.originalUrl;
53
+ } else {
54
+ parentUrl = ownerUrlInfo.url;
45
55
  }
46
- const parentUrl = reference.baseUrl || ownerUrlInfo.url;
47
56
  if (!parentUrl.startsWith("file:")) {
48
- return new URL(reference.specifier, parentUrl).href;
57
+ const url = new URL(reference.specifier, parentUrl);
58
+ return url;
49
59
  }
50
60
  const { url, type, packageDirectoryUrl } = applyNodeEsmResolution({
51
61
  conditions: packageConditions,
@@ -6,20 +6,22 @@ export const jsenvPluginWebResolution = () => {
6
6
  const { ownerUrlInfo } = reference;
7
7
  if (reference.specifier === "/") {
8
8
  const { mainFilePath, rootDirectoryUrl } = ownerUrlInfo.context;
9
- return String(new URL(mainFilePath, rootDirectoryUrl));
9
+ const url = new URL(mainFilePath, rootDirectoryUrl);
10
+ return url;
10
11
  }
11
12
  if (reference.specifier[0] === "/") {
12
- return new URL(
13
+ const url = new URL(
13
14
  reference.specifier.slice(1),
14
15
  ownerUrlInfo.context.rootDirectoryUrl,
15
- ).href;
16
+ );
17
+ return url;
16
18
  }
17
- return new URL(
18
- reference.specifier,
19
- // baseUrl happens second argument to new URL() is different from
20
- // import.meta.url or document.currentScript.src
21
- reference.baseUrl || ownerUrlInfo.url,
22
- ).href;
19
+ // baseUrl happens second argument to new URL() is different from
20
+ // import.meta.url or document.currentScript.src
21
+ const parentUrl =
22
+ reference.baseUrl || ownerUrlInfo.originalUrl || ownerUrlInfo.url;
23
+ const url = new URL(reference.specifier, parentUrl);
24
+ return url;
23
25
  },
24
26
  };
25
27
  };