@jsenv/core 39.7.5 → 39.7.6

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.
@@ -195,10 +195,10 @@
195
195
  No entry on the filesystem for <code>/${fileRelativeUrl}</code> (at
196
196
  ${fileUrl})
197
197
  <br>
198
- Content of the parent directory is listed below:
198
+ Content of the ancestor directory is listed below:
199
199
  </span>
200
200
  </p>
201
- <h1 class="directory_nav">${parentDirectoryNav}</h1>
202
- ${parentDirectoryContent}
201
+ <h1 class="directory_nav">${ancestorDirectoryNav}</h1>
202
+ ${ancestorDirectoryContent}
203
203
  </body>
204
204
  </html>
@@ -18890,8 +18890,8 @@ const resolveSymlink = (fileUrl) => {
18890
18890
  return realUrlObject.href;
18891
18891
  };
18892
18892
 
18893
- const html404AndParentDirFileUrl = new URL(
18894
- "./html/html_404_and_parent_dir.html",
18893
+ const html404AndAncestorDirFileUrl = new URL(
18894
+ "./html/html_404_and_ancestor_dir.html",
18895
18895
  import.meta.url,
18896
18896
  );
18897
18897
  const htmlFileUrlForDirectory = new URL(
@@ -18959,68 +18959,86 @@ const jsenvPluginProtocolFile = ({
18959
18959
  if (!urlInfo.url.startsWith("file:")) {
18960
18960
  return null;
18961
18961
  }
18962
- const urlObject = new URL(urlInfo.url);
18963
- const { firstReference } = urlInfo;
18964
- if (firstReference.leadsToADirectory) {
18965
- const directoryContentArray = readdirSync(urlObject);
18966
- if (firstReference.type === "filesystem") {
18967
- const content = JSON.stringify(directoryContentArray, null, " ");
18962
+ const generateContent = () => {
18963
+ const urlObject = new URL(urlInfo.url);
18964
+ const { firstReference } = urlInfo;
18965
+ if (firstReference.leadsToADirectory) {
18966
+ const directoryContentArray = readdirSync(urlObject);
18967
+ if (firstReference.type === "filesystem") {
18968
+ const content = JSON.stringify(directoryContentArray, null, " ");
18969
+ return {
18970
+ type: "directory",
18971
+ contentType: "application/json",
18972
+ content,
18973
+ };
18974
+ }
18975
+ const acceptsHtml = urlInfo.context.request
18976
+ ? pickContentType(urlInfo.context.request, ["text/html"])
18977
+ : false;
18978
+ if (acceptsHtml) {
18979
+ firstReference.expectedType = "html";
18980
+ const html = generateHtmlForDirectory(
18981
+ urlObject.href,
18982
+ directoryContentArray,
18983
+ urlInfo.context.rootDirectoryUrl,
18984
+ );
18985
+ return {
18986
+ type: "html",
18987
+ contentType: "text/html",
18988
+ content: html,
18989
+ };
18990
+ }
18968
18991
  return {
18969
18992
  type: "directory",
18970
18993
  contentType: "application/json",
18971
- content,
18972
- };
18973
- }
18974
- const acceptsHtml = urlInfo.context.request
18975
- ? pickContentType(urlInfo.context.request, ["text/html"])
18976
- : false;
18977
- if (acceptsHtml) {
18978
- firstReference.expectedType = "html";
18979
- const html = generateHtmlForDirectory(
18980
- urlObject.href,
18981
- directoryContentArray,
18982
- urlInfo.context.rootDirectoryUrl,
18983
- );
18984
- return {
18985
- type: "html",
18986
- contentType: "text/html",
18987
- content: html,
18994
+ content: JSON.stringify(directoryContentArray, null, " "),
18988
18995
  };
18989
18996
  }
18997
+ const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
18998
+ const fileBuffer = readFileSync(urlObject);
18999
+ const content = CONTENT_TYPE.isTextual(contentType)
19000
+ ? String(fileBuffer)
19001
+ : fileBuffer;
18990
19002
  return {
18991
- type: "directory",
18992
- contentType: "application/json",
18993
- content: JSON.stringify(directoryContentArray, null, " "),
19003
+ content,
19004
+ contentType,
19005
+ contentLength: fileBuffer.length,
18994
19006
  };
18995
- }
18996
- const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
19007
+ };
19008
+
18997
19009
  const request = urlInfo.context.request;
18998
19010
  if (request && request.headers["sec-fetch-dest"] === "document") {
18999
19011
  try {
19000
- const fileBuffer = readFileSync(urlObject);
19001
- const content = CONTENT_TYPE.isTextual(contentType)
19002
- ? String(fileBuffer)
19003
- : fileBuffer;
19004
- return {
19005
- content,
19006
- contentType,
19007
- contentLength: fileBuffer.length,
19008
- };
19012
+ return generateContent();
19009
19013
  } catch (e) {
19010
19014
  if (e.code !== "ENOENT") {
19011
19015
  throw e;
19012
19016
  }
19013
- const parentDirectoryUrl = new URL("./", urlInfo.url);
19014
- if (!existsSync(parentDirectoryUrl)) {
19015
- throw e;
19017
+ const rootDirectoryUrl = urlInfo.context.rootDirectoryUrl;
19018
+ let firstExistingAncestorDirectoryUrl = new URL("./", urlInfo.url);
19019
+ while (!existsSync(firstExistingAncestorDirectoryUrl)) {
19020
+ firstExistingAncestorDirectoryUrl = new URL(
19021
+ "../",
19022
+ firstExistingAncestorDirectoryUrl,
19023
+ );
19024
+ if (
19025
+ !urlIsInsideOf(
19026
+ firstExistingAncestorDirectoryUrl,
19027
+ rootDirectoryUrl,
19028
+ )
19029
+ ) {
19030
+ firstExistingAncestorDirectoryUrl = rootDirectoryUrl;
19031
+ break;
19032
+ }
19016
19033
  }
19017
- const parentDirectoryContentArray = readdirSync(
19018
- new URL(parentDirectoryUrl),
19034
+
19035
+ const firstExistingAncestorDirectoryContent = readdirSync(
19036
+ new URL(firstExistingAncestorDirectoryUrl),
19019
19037
  );
19020
19038
  const html = generateHtmlForENOENT(
19021
19039
  urlInfo.url,
19022
- parentDirectoryContentArray,
19023
- parentDirectoryUrl,
19040
+ firstExistingAncestorDirectoryContent,
19041
+ firstExistingAncestorDirectoryUrl,
19024
19042
  urlInfo.context.rootDirectoryUrl,
19025
19043
  directoryListingUrlMocks,
19026
19044
  );
@@ -19034,15 +19052,7 @@ const jsenvPluginProtocolFile = ({
19034
19052
  };
19035
19053
  }
19036
19054
  }
19037
- const fileBuffer = readFileSync(urlObject);
19038
- const content = CONTENT_TYPE.isTextual(contentType)
19039
- ? String(fileBuffer)
19040
- : fileBuffer;
19041
- return {
19042
- content,
19043
- contentType,
19044
- contentLength: fileBuffer.length,
19045
- };
19055
+ return generateContent();
19046
19056
  },
19047
19057
  },
19048
19058
  ];
@@ -19073,17 +19083,17 @@ const generateHtmlForDirectory = (
19073
19083
  };
19074
19084
  const generateHtmlForENOENT = (
19075
19085
  url,
19076
- parentDirectoryContentArray,
19077
- parentDirectoryUrl,
19086
+ ancestorDirectoryContentArray,
19087
+ ancestorDirectoryUrl,
19078
19088
  rootDirectoryUrl,
19079
19089
  directoryListingUrlMocks,
19080
19090
  ) => {
19081
- const htmlFor404AndParentDir = String(
19082
- readFileSync(html404AndParentDirFileUrl),
19091
+ const htmlFor404AndAncestorDir = String(
19092
+ readFileSync(html404AndAncestorDirFileUrl),
19083
19093
  );
19084
19094
  const fileRelativeUrl = urlToRelativeUrl(url, rootDirectoryUrl);
19085
- const parentDirectoryRelativeUrl = urlToRelativeUrl(
19086
- parentDirectoryUrl,
19095
+ const ancestorDirectoryRelativeUrl = urlToRelativeUrl(
19096
+ ancestorDirectoryUrl,
19087
19097
  rootDirectoryUrl,
19088
19098
  );
19089
19099
  const replacers = {
@@ -19091,18 +19101,18 @@ const generateHtmlForENOENT = (
19091
19101
  ? `@jsenv/core/${urlToRelativeUrl(url, jsenvCoreDirectoryUrl)}`
19092
19102
  : url,
19093
19103
  fileRelativeUrl,
19094
- parentDirectoryUrl,
19095
- parentDirectoryRelativeUrl,
19096
- parentDirectoryNav: () =>
19097
- generateDirectoryNav(parentDirectoryRelativeUrl, rootDirectoryUrl),
19098
- parentDirectoryContent: () =>
19104
+ ancestorDirectoryUrl,
19105
+ ancestorDirectoryRelativeUrl,
19106
+ ancestorDirectoryNav: () =>
19107
+ generateDirectoryNav(ancestorDirectoryRelativeUrl, rootDirectoryUrl),
19108
+ ancestorDirectoryContent: () =>
19099
19109
  generateDirectoryContent(
19100
- parentDirectoryContentArray,
19101
- parentDirectoryUrl,
19110
+ ancestorDirectoryContentArray,
19111
+ ancestorDirectoryUrl,
19102
19112
  rootDirectoryUrl,
19103
19113
  ),
19104
19114
  };
19105
- const html = replacePlaceholders$1(htmlFor404AndParentDir, replacers);
19115
+ const html = replacePlaceholders$1(htmlFor404AndAncestorDir, replacers);
19106
19116
  return html;
19107
19117
  };
19108
19118
  const generateDirectoryNav = (relativeUrl, rootDirectoryUrl) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "39.7.5",
3
+ "version": "39.7.6",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -45,10 +45,10 @@
45
45
  No entry on the filesystem for <code>/${fileRelativeUrl}</code> (at
46
46
  ${fileUrl})
47
47
  <br />
48
- Content of the parent directory is listed below:
48
+ Content of the ancestor directory is listed below:
49
49
  </span>
50
50
  </p>
51
- <h1 class="directory_nav">${parentDirectoryNav}</h1>
52
- ${parentDirectoryContent}
51
+ <h1 class="directory_nav">${ancestorDirectoryNav}</h1>
52
+ ${ancestorDirectoryContent}
53
53
  </body>
54
54
  </html>
@@ -14,8 +14,8 @@ import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
14
14
  import { jsenvCoreDirectoryUrl } from "../../jsenv_core_directory_url.js";
15
15
  import { jsenvPluginFsRedirection } from "./jsenv_plugin_fs_redirection.js";
16
16
 
17
- const html404AndParentDirFileUrl = new URL(
18
- "./client/html_404_and_parent_dir.html",
17
+ const html404AndAncestorDirFileUrl = new URL(
18
+ "./client/html_404_and_ancestor_dir.html",
19
19
  import.meta.url,
20
20
  );
21
21
  const htmlFileUrlForDirectory = new URL(
@@ -83,68 +83,86 @@ export const jsenvPluginProtocolFile = ({
83
83
  if (!urlInfo.url.startsWith("file:")) {
84
84
  return null;
85
85
  }
86
- const urlObject = new URL(urlInfo.url);
87
- const { firstReference } = urlInfo;
88
- if (firstReference.leadsToADirectory) {
89
- const directoryContentArray = readdirSync(urlObject);
90
- if (firstReference.type === "filesystem") {
91
- const content = JSON.stringify(directoryContentArray, null, " ");
86
+ const generateContent = () => {
87
+ const urlObject = new URL(urlInfo.url);
88
+ const { firstReference } = urlInfo;
89
+ if (firstReference.leadsToADirectory) {
90
+ const directoryContentArray = readdirSync(urlObject);
91
+ if (firstReference.type === "filesystem") {
92
+ const content = JSON.stringify(directoryContentArray, null, " ");
93
+ return {
94
+ type: "directory",
95
+ contentType: "application/json",
96
+ content,
97
+ };
98
+ }
99
+ const acceptsHtml = urlInfo.context.request
100
+ ? pickContentType(urlInfo.context.request, ["text/html"])
101
+ : false;
102
+ if (acceptsHtml) {
103
+ firstReference.expectedType = "html";
104
+ const html = generateHtmlForDirectory(
105
+ urlObject.href,
106
+ directoryContentArray,
107
+ urlInfo.context.rootDirectoryUrl,
108
+ );
109
+ return {
110
+ type: "html",
111
+ contentType: "text/html",
112
+ content: html,
113
+ };
114
+ }
92
115
  return {
93
116
  type: "directory",
94
117
  contentType: "application/json",
95
- content,
96
- };
97
- }
98
- const acceptsHtml = urlInfo.context.request
99
- ? pickContentType(urlInfo.context.request, ["text/html"])
100
- : false;
101
- if (acceptsHtml) {
102
- firstReference.expectedType = "html";
103
- const html = generateHtmlForDirectory(
104
- urlObject.href,
105
- directoryContentArray,
106
- urlInfo.context.rootDirectoryUrl,
107
- );
108
- return {
109
- type: "html",
110
- contentType: "text/html",
111
- content: html,
118
+ content: JSON.stringify(directoryContentArray, null, " "),
112
119
  };
113
120
  }
121
+ const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
122
+ const fileBuffer = readFileSync(urlObject);
123
+ const content = CONTENT_TYPE.isTextual(contentType)
124
+ ? String(fileBuffer)
125
+ : fileBuffer;
114
126
  return {
115
- type: "directory",
116
- contentType: "application/json",
117
- content: JSON.stringify(directoryContentArray, null, " "),
127
+ content,
128
+ contentType,
129
+ contentLength: fileBuffer.length,
118
130
  };
119
- }
120
- const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
131
+ };
132
+
121
133
  const request = urlInfo.context.request;
122
134
  if (request && request.headers["sec-fetch-dest"] === "document") {
123
135
  try {
124
- const fileBuffer = readFileSync(urlObject);
125
- const content = CONTENT_TYPE.isTextual(contentType)
126
- ? String(fileBuffer)
127
- : fileBuffer;
128
- return {
129
- content,
130
- contentType,
131
- contentLength: fileBuffer.length,
132
- };
136
+ return generateContent();
133
137
  } catch (e) {
134
138
  if (e.code !== "ENOENT") {
135
139
  throw e;
136
140
  }
137
- const parentDirectoryUrl = new URL("./", urlInfo.url);
138
- if (!existsSync(parentDirectoryUrl)) {
139
- throw e;
141
+ const rootDirectoryUrl = urlInfo.context.rootDirectoryUrl;
142
+ let firstExistingAncestorDirectoryUrl = new URL("./", urlInfo.url);
143
+ while (!existsSync(firstExistingAncestorDirectoryUrl)) {
144
+ firstExistingAncestorDirectoryUrl = new URL(
145
+ "../",
146
+ firstExistingAncestorDirectoryUrl,
147
+ );
148
+ if (
149
+ !urlIsInsideOf(
150
+ firstExistingAncestorDirectoryUrl,
151
+ rootDirectoryUrl,
152
+ )
153
+ ) {
154
+ firstExistingAncestorDirectoryUrl = rootDirectoryUrl;
155
+ break;
156
+ }
140
157
  }
141
- const parentDirectoryContentArray = readdirSync(
142
- new URL(parentDirectoryUrl),
158
+
159
+ const firstExistingAncestorDirectoryContent = readdirSync(
160
+ new URL(firstExistingAncestorDirectoryUrl),
143
161
  );
144
162
  const html = generateHtmlForENOENT(
145
163
  urlInfo.url,
146
- parentDirectoryContentArray,
147
- parentDirectoryUrl,
164
+ firstExistingAncestorDirectoryContent,
165
+ firstExistingAncestorDirectoryUrl,
148
166
  urlInfo.context.rootDirectoryUrl,
149
167
  directoryListingUrlMocks,
150
168
  );
@@ -158,15 +176,7 @@ export const jsenvPluginProtocolFile = ({
158
176
  };
159
177
  }
160
178
  }
161
- const fileBuffer = readFileSync(urlObject);
162
- const content = CONTENT_TYPE.isTextual(contentType)
163
- ? String(fileBuffer)
164
- : fileBuffer;
165
- return {
166
- content,
167
- contentType,
168
- contentLength: fileBuffer.length,
169
- };
179
+ return generateContent();
170
180
  },
171
181
  },
172
182
  ];
@@ -197,17 +207,17 @@ const generateHtmlForDirectory = (
197
207
  };
198
208
  const generateHtmlForENOENT = (
199
209
  url,
200
- parentDirectoryContentArray,
201
- parentDirectoryUrl,
210
+ ancestorDirectoryContentArray,
211
+ ancestorDirectoryUrl,
202
212
  rootDirectoryUrl,
203
213
  directoryListingUrlMocks,
204
214
  ) => {
205
- const htmlFor404AndParentDir = String(
206
- readFileSync(html404AndParentDirFileUrl),
215
+ const htmlFor404AndAncestorDir = String(
216
+ readFileSync(html404AndAncestorDirFileUrl),
207
217
  );
208
218
  const fileRelativeUrl = urlToRelativeUrl(url, rootDirectoryUrl);
209
- const parentDirectoryRelativeUrl = urlToRelativeUrl(
210
- parentDirectoryUrl,
219
+ const ancestorDirectoryRelativeUrl = urlToRelativeUrl(
220
+ ancestorDirectoryUrl,
211
221
  rootDirectoryUrl,
212
222
  );
213
223
  const replacers = {
@@ -215,18 +225,18 @@ const generateHtmlForENOENT = (
215
225
  ? `@jsenv/core/${urlToRelativeUrl(url, jsenvCoreDirectoryUrl)}`
216
226
  : url,
217
227
  fileRelativeUrl,
218
- parentDirectoryUrl,
219
- parentDirectoryRelativeUrl,
220
- parentDirectoryNav: () =>
221
- generateDirectoryNav(parentDirectoryRelativeUrl, rootDirectoryUrl),
222
- parentDirectoryContent: () =>
228
+ ancestorDirectoryUrl,
229
+ ancestorDirectoryRelativeUrl,
230
+ ancestorDirectoryNav: () =>
231
+ generateDirectoryNav(ancestorDirectoryRelativeUrl, rootDirectoryUrl),
232
+ ancestorDirectoryContent: () =>
223
233
  generateDirectoryContent(
224
- parentDirectoryContentArray,
225
- parentDirectoryUrl,
234
+ ancestorDirectoryContentArray,
235
+ ancestorDirectoryUrl,
226
236
  rootDirectoryUrl,
227
237
  ),
228
238
  };
229
- const html = replacePlaceholders(htmlFor404AndParentDir, replacers);
239
+ const html = replacePlaceholders(htmlFor404AndAncestorDir, replacers);
230
240
  return html;
231
241
  };
232
242
  const generateDirectoryNav = (relativeUrl, rootDirectoryUrl) => {