@jsenv/core 39.2.19 → 39.3.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.
@@ -2,27 +2,15 @@ import {
2
2
  assertAndNormalizeDirectoryUrl,
3
3
  comparePathnames,
4
4
  } from "@jsenv/filesystem";
5
- import {
6
- applyFileSystemMagicResolution,
7
- getExtensionsToTry,
8
- } from "@jsenv/node-esm-resolution";
9
5
  import { pickContentType } from "@jsenv/server";
10
6
  import {
11
7
  ensurePathnameTrailingSlash,
12
8
  urlIsInsideOf,
13
- urlToFilename,
14
9
  urlToRelativeUrl,
15
10
  } from "@jsenv/urls";
16
11
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
17
- import {
18
- existsSync,
19
- lstatSync,
20
- readdirSync,
21
- readFileSync,
22
- realpathSync,
23
- statSync,
24
- } from "node:fs";
25
- import { pathToFileURL } from "node:url";
12
+ import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
13
+ import { jsenvPluginFsRedirection } from "./jsenv_plugin_fs_redirection.js";
26
14
 
27
15
  const html404AndParentDirIsEmptyFileUrl = new URL(
28
16
  "./html_404_and_parent_dir_is_empty.html",
@@ -35,119 +23,16 @@ const html404AndParentDirFileUrl = new URL(
35
23
  const htmlFileUrlForDirectory = new URL("./directory.html", import.meta.url);
36
24
 
37
25
  export const jsenvPluginProtocolFile = ({
38
- magicExtensions = ["inherit", ".js"],
39
- magicDirectoryIndex = true,
40
- preserveSymlinks = false,
41
- directoryReferenceEffect = "error",
26
+ magicExtensions,
27
+ magicDirectoryIndex,
28
+ preserveSymlinks,
42
29
  }) => {
43
30
  return [
44
- {
45
- name: "jsenv:fs_redirection",
46
- appliesDuring: "*",
47
- redirectReference: (reference) => {
48
- // http, https, data, about, ...
49
- if (!reference.url.startsWith("file:")) {
50
- return null;
51
- }
52
- if (reference.isInline) {
53
- return null;
54
- }
55
- // ignore root file url
56
- if (reference.url === "file:///" || reference.url === "file://") {
57
- reference.leadsToADirectory = true;
58
- return `ignore:file:///`;
59
- }
60
- // ignore "./" on new URL("./")
61
- if (
62
- reference.subtype === "new_url_first_arg" &&
63
- reference.specifier === "./"
64
- ) {
65
- return `ignore:${reference.url}`;
66
- }
67
- // ignore all new URL second arg
68
- if (reference.subtype === "new_url_second_arg") {
69
- return `ignore:${reference.url}`;
70
- }
71
-
72
- const urlObject = new URL(reference.url);
73
- let stat;
74
- try {
75
- stat = statSync(urlObject);
76
- } catch (e) {
77
- if (e.code === "ENOENT") {
78
- stat = null;
79
- } else {
80
- throw e;
81
- }
82
- }
83
-
84
- const { search, hash } = urlObject;
85
- let { pathname } = urlObject;
86
- const pathnameUsesTrailingSlash = pathname.endsWith("/");
87
- urlObject.search = "";
88
- urlObject.hash = "";
89
-
90
- // force trailing slash on directories
91
- if (stat && stat.isDirectory() && !pathnameUsesTrailingSlash) {
92
- urlObject.pathname = `${pathname}/`;
93
- }
94
- // otherwise remove trailing slash if any
95
- if (stat && !stat.isDirectory() && pathnameUsesTrailingSlash) {
96
- // a warning here? (because it's strange to reference a file with a trailing slash)
97
- urlObject.pathname = pathname.slice(0, -1);
98
- }
99
-
100
- let url = urlObject.href;
101
- const shouldApplyDilesystemMagicResolution =
102
- reference.type === "js_import";
103
- if (shouldApplyDilesystemMagicResolution) {
104
- const filesystemResolution = applyFileSystemMagicResolution(url, {
105
- fileStat: stat,
106
- magicDirectoryIndex,
107
- magicExtensions: getExtensionsToTry(
108
- magicExtensions,
109
- reference.ownerUrlInfo.url,
110
- ),
111
- });
112
- if (filesystemResolution.stat) {
113
- stat = filesystemResolution.stat;
114
- url = filesystemResolution.url;
115
- }
116
- }
117
- if (!stat) {
118
- return null;
119
- }
120
- reference.leadsToADirectory = stat && stat.isDirectory();
121
- if (reference.leadsToADirectory) {
122
- let actionForDirectory;
123
- if (reference.type === "a_href") {
124
- actionForDirectory = "ignore";
125
- } else if (
126
- reference.type === "http_request" ||
127
- reference.type === "filesystem"
128
- ) {
129
- actionForDirectory = "copy";
130
- } else if (typeof directoryReferenceEffect === "string") {
131
- actionForDirectory = directoryReferenceEffect;
132
- } else if (typeof directoryReferenceEffect === "function") {
133
- actionForDirectory = directoryReferenceEffect(reference);
134
- } else {
135
- actionForDirectory = "error";
136
- }
137
- if (actionForDirectory === "error") {
138
- const error = new Error("Reference leads to a directory");
139
- error.code = "DIRECTORY_REFERENCE_NOT_ALLOWED";
140
- throw error;
141
- }
142
- if (actionForDirectory === "preserve") {
143
- return `ignore:${url}${search}${hash}`;
144
- }
145
- }
146
- const urlRaw = preserveSymlinks ? url : resolveSymlink(url);
147
- const resolvedUrl = `${urlRaw}${search}${hash}`;
148
- return resolvedUrl;
149
- },
150
- },
31
+ jsenvPluginFsRedirection({
32
+ magicExtensions,
33
+ magicDirectoryIndex,
34
+ preserveSymlinks,
35
+ }),
151
36
  {
152
37
  name: "jsenv:fs_resolution",
153
38
  appliesDuring: "*",
@@ -197,18 +82,10 @@ export const jsenvPluginProtocolFile = ({
197
82
  return null;
198
83
  }
199
84
  const urlObject = new URL(urlInfo.url);
200
- if (urlInfo.firstReference.leadsToADirectory) {
201
- if (!urlInfo.filenameHint) {
202
- if (urlInfo.firstReference.type === "filesystem") {
203
- urlInfo.filenameHint = `${
204
- urlInfo.firstReference.ownerUrlInfo.filenameHint
205
- }${urlToFilename(urlInfo.url)}/`;
206
- } else {
207
- urlInfo.filenameHint = `${urlToFilename(urlInfo.url)}/`;
208
- }
209
- }
85
+ const { firstReference } = urlInfo;
86
+ if (firstReference.leadsToADirectory) {
210
87
  const directoryContentArray = readdirSync(urlObject);
211
- if (urlInfo.firstReference.type === "filesystem") {
88
+ if (firstReference.type === "filesystem") {
212
89
  const content = JSON.stringify(directoryContentArray, null, " ");
213
90
  return {
214
91
  type: "directory",
@@ -236,13 +113,6 @@ export const jsenvPluginProtocolFile = ({
236
113
  content: JSON.stringify(directoryContentArray, null, " "),
237
114
  };
238
115
  }
239
- if (
240
- !urlInfo.dirnameHint &&
241
- urlInfo.firstReference.ownerUrlInfo.type === "directory"
242
- ) {
243
- urlInfo.dirnameHint =
244
- urlInfo.firstReference.ownerUrlInfo.filenameHint;
245
- }
246
116
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
247
117
  if (contentType === "text/html") {
248
118
  try {
@@ -387,13 +257,3 @@ const replacePlaceholders = (html, replacers) => {
387
257
  return replacer;
388
258
  });
389
259
  };
390
-
391
- const resolveSymlink = (fileUrl) => {
392
- const urlObject = new URL(fileUrl);
393
- const realpath = realpathSync(urlObject);
394
- const realUrlObject = pathToFileURL(realpath);
395
- if (urlObject.pathname.endsWith("/")) {
396
- realUrlObject.pathname += `/`;
397
- }
398
- return realUrlObject.href;
399
- };
@@ -5,15 +5,17 @@ export const jsenvPluginDirectoryReferenceAnalysis = () => {
5
5
  name: "jsenv:directory_reference_analysis",
6
6
  transformUrlContent: {
7
7
  directory: async (urlInfo) => {
8
- const originalDirectoryReference =
9
- findOriginalDirectoryReference(urlInfo);
8
+ if (urlInfo.contentType !== "application/json") {
9
+ return null;
10
+ }
11
+ // const isShapeBuildStep = urlInfo.kitchen.context.buildStep === "shape";
12
+ const originalDirectoryReference = findOriginalDirectoryReference(
13
+ urlInfo.firstReference,
14
+ );
10
15
  const directoryRelativeUrl = urlToRelativeUrl(
11
16
  urlInfo.url,
12
17
  urlInfo.context.rootDirectoryUrl,
13
18
  );
14
- if (urlInfo.contentType !== "application/json") {
15
- return null;
16
- }
17
19
  const entryNames = JSON.parse(urlInfo.content);
18
20
  const newEntryNames = [];
19
21
  for (const entryName of entryNames) {
@@ -35,19 +37,18 @@ export const jsenvPluginDirectoryReferenceAnalysis = () => {
35
37
  };
36
38
  };
37
39
 
38
- const findOriginalDirectoryReference = (urlInfo) => {
40
+ const findOriginalDirectoryReference = (firstReference) => {
39
41
  const findNonFileSystemAncestor = (urlInfo) => {
40
42
  for (const referenceFromOther of urlInfo.referenceFromOthersSet) {
41
- const urlInfoReferencingThisOne = referenceFromOther.ownerUrlInfo;
42
- if (urlInfoReferencingThisOne.type !== "directory") {
43
+ if (referenceFromOther.type !== "filesystem") {
43
44
  return referenceFromOther;
44
45
  }
45
- const found = findNonFileSystemAncestor(urlInfoReferencingThisOne);
46
- if (found) {
47
- return found;
48
- }
46
+ return findNonFileSystemAncestor(referenceFromOther.ownerUrlInfo);
49
47
  }
50
48
  return null;
51
49
  };
52
- return findNonFileSystemAncestor(urlInfo);
50
+ if (firstReference.type !== "filesystem") {
51
+ return firstReference;
52
+ }
53
+ return findNonFileSystemAncestor(firstReference.ownerUrlInfo);
53
54
  };
@@ -10,9 +10,12 @@ export const jsenvPluginReferenceAnalysis = ({
10
10
  inlineContent = true,
11
11
  inlineConvertedScript = false,
12
12
  fetchInlineUrls = true,
13
+ directoryReferenceEffect,
13
14
  }) => {
14
15
  return [
15
- jsenvPluginDirectoryReferenceAnalysis(),
16
+ jsenvPluginDirectoryReferenceAnalysis({
17
+ directoryReferenceEffect,
18
+ }),
16
19
  jsenvPluginHtmlReferenceAnalysis({
17
20
  inlineContent,
18
21
  inlineConvertedScript,