@jsenv/core 39.7.7 → 39.8.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "39.
|
|
3
|
+
"version": "39.8.1",
|
|
4
4
|
"description": "Tool to develop, test and build js projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -70,19 +70,19 @@
|
|
|
70
70
|
"@financial-times/polyfill-useragent-normaliser": "1.10.2",
|
|
71
71
|
"@jsenv/abort": "4.3.0",
|
|
72
72
|
"@jsenv/ast": "6.4.1",
|
|
73
|
-
"@jsenv/filesystem": "4.
|
|
73
|
+
"@jsenv/filesystem": "4.12.0",
|
|
74
74
|
"@jsenv/humanize": "1.2.8",
|
|
75
75
|
"@jsenv/importmap": "1.2.1",
|
|
76
76
|
"@jsenv/integrity": "0.0.2",
|
|
77
|
-
"@jsenv/js-module-fallback": "1.3.
|
|
77
|
+
"@jsenv/js-module-fallback": "1.3.54",
|
|
78
78
|
"@jsenv/node-esm-resolution": "1.0.6",
|
|
79
|
-
"@jsenv/plugin-bundling": "2.7.
|
|
79
|
+
"@jsenv/plugin-bundling": "2.7.21",
|
|
80
80
|
"@jsenv/plugin-minification": "1.5.12",
|
|
81
|
-
"@jsenv/plugin-supervisor": "1.6.
|
|
82
|
-
"@jsenv/plugin-transpilation": "1.4.
|
|
81
|
+
"@jsenv/plugin-supervisor": "1.6.1",
|
|
82
|
+
"@jsenv/plugin-transpilation": "1.4.89",
|
|
83
83
|
"@jsenv/runtime-compat": "1.3.1",
|
|
84
84
|
"@jsenv/server": "15.3.3",
|
|
85
|
-
"@jsenv/sourcemap": "1.2.
|
|
85
|
+
"@jsenv/sourcemap": "1.2.29",
|
|
86
86
|
"@jsenv/url-meta": "8.5.2",
|
|
87
87
|
"@jsenv/urls": "2.5.4",
|
|
88
88
|
"@jsenv/utils": "2.1.2",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"@playwright/browser-firefox": "1.49.1",
|
|
109
109
|
"@playwright/browser-webkit": "1.49.1",
|
|
110
110
|
"babel-plugin-transform-async-to-promises": "0.8.18",
|
|
111
|
-
"eslint": "9.
|
|
111
|
+
"eslint": "9.17.0",
|
|
112
112
|
"open": "10.1.0",
|
|
113
113
|
"playwright": "1.49.1",
|
|
114
114
|
"prettier": "3.4.2",
|
|
@@ -1,37 +1,9 @@
|
|
|
1
|
+
import { findAncestorDirectoryUrl } from "@jsenv/filesystem";
|
|
1
2
|
import { existsSync } from "node:fs";
|
|
2
3
|
|
|
3
4
|
export const lookupPackageDirectory = (currentUrl) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (existsSync(new URL(packageJsonFileUrl))) {
|
|
9
|
-
return currentUrl;
|
|
10
|
-
}
|
|
11
|
-
return lookupPackageDirectory(getParentUrl(currentUrl));
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const getParentUrl = (url) => {
|
|
15
|
-
if (url.startsWith("file://")) {
|
|
16
|
-
// With node.js new URL('../', 'file:///C:/').href
|
|
17
|
-
// returns "file:///C:/" instead of "file:///"
|
|
18
|
-
const resource = url.slice("file://".length);
|
|
19
|
-
const slashLastIndex = resource.lastIndexOf("/");
|
|
20
|
-
if (slashLastIndex === -1) {
|
|
21
|
-
return url;
|
|
22
|
-
}
|
|
23
|
-
const lastCharIndex = resource.length - 1;
|
|
24
|
-
if (slashLastIndex === lastCharIndex) {
|
|
25
|
-
const slashBeforeLastIndex = resource.lastIndexOf(
|
|
26
|
-
"/",
|
|
27
|
-
slashLastIndex - 1,
|
|
28
|
-
);
|
|
29
|
-
if (slashBeforeLastIndex === -1) {
|
|
30
|
-
return url;
|
|
31
|
-
}
|
|
32
|
-
return `file://${resource.slice(0, slashBeforeLastIndex + 1)}`;
|
|
33
|
-
}
|
|
34
|
-
return `file://${resource.slice(0, slashLastIndex + 1)}`;
|
|
35
|
-
}
|
|
36
|
-
return new URL(url.endsWith("/") ? "../" : "./", url).href;
|
|
5
|
+
return findAncestorDirectoryUrl(currentUrl, (ancestorDirectoryUrl) => {
|
|
6
|
+
const potentialPackageJsonFileUrl = `${ancestorDirectoryUrl}package.json`;
|
|
7
|
+
return existsSync(new URL(potentialPackageJsonFileUrl));
|
|
8
|
+
});
|
|
37
9
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { writeFileSync } from "@jsenv/filesystem";
|
|
2
2
|
import {
|
|
3
3
|
composeTwoSourcemaps,
|
|
4
4
|
generateSourcemapDataUrl,
|
|
@@ -275,18 +275,7 @@ export const createUrlInfoTransformer = ({
|
|
|
275
275
|
contentIsInlined = false;
|
|
276
276
|
}
|
|
277
277
|
if (!contentIsInlined) {
|
|
278
|
-
|
|
279
|
-
writeFileSync(new URL(generatedUrl), urlInfo.content);
|
|
280
|
-
} catch (e) {
|
|
281
|
-
if (e.code === "EISDIR") {
|
|
282
|
-
// happens when directory existed but got delete
|
|
283
|
-
// we can safely remove that directory and write the new file
|
|
284
|
-
removeDirectorySync(new URL(generatedUrl));
|
|
285
|
-
writeFileSync(new URL(generatedUrl), urlInfo.content);
|
|
286
|
-
} else {
|
|
287
|
-
throw e;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
278
|
+
writeFileSync(new URL(generatedUrl), urlInfo.content, { force: true });
|
|
290
279
|
}
|
|
291
280
|
const { sourcemapGeneratedUrl, sourcemapReference } = urlInfo;
|
|
292
281
|
if (sourcemapGeneratedUrl && sourcemapReference) {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "@jsenv/urls";
|
|
12
12
|
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
13
13
|
import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
14
|
+
import { lookupPackageDirectory } from "../../helpers/lookup_package_directory.js";
|
|
14
15
|
import { jsenvCoreDirectoryUrl } from "../../jsenv_core_directory_url.js";
|
|
15
16
|
import { jsenvPluginFsRedirection } from "./jsenv_plugin_fs_redirection.js";
|
|
16
17
|
|
|
@@ -83,6 +84,7 @@ export const jsenvPluginProtocolFile = ({
|
|
|
83
84
|
if (!urlInfo.url.startsWith("file:")) {
|
|
84
85
|
return null;
|
|
85
86
|
}
|
|
87
|
+
const { rootDirectoryUrl } = urlInfo.context;
|
|
86
88
|
const generateContent = () => {
|
|
87
89
|
const urlObject = new URL(urlInfo.url);
|
|
88
90
|
const { firstReference } = urlInfo;
|
|
@@ -101,11 +103,12 @@ export const jsenvPluginProtocolFile = ({
|
|
|
101
103
|
: false;
|
|
102
104
|
if (acceptsHtml) {
|
|
103
105
|
firstReference.expectedType = "html";
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const directoryUrl = urlObject.href;
|
|
107
|
+
const directoryContentItems = generateDirectoryContentItems(
|
|
108
|
+
directoryUrl,
|
|
109
|
+
rootDirectoryUrl,
|
|
108
110
|
);
|
|
111
|
+
const html = generateHtmlForDirectory(directoryContentItems);
|
|
109
112
|
return {
|
|
110
113
|
type: "html",
|
|
111
114
|
contentType: "text/html",
|
|
@@ -138,32 +141,13 @@ export const jsenvPluginProtocolFile = ({
|
|
|
138
141
|
if (e.code !== "ENOENT") {
|
|
139
142
|
throw e;
|
|
140
143
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
firstExistingAncestorDirectoryUrl = new URL(
|
|
145
|
-
"../",
|
|
146
|
-
firstExistingAncestorDirectoryUrl,
|
|
147
|
-
);
|
|
148
|
-
if (
|
|
149
|
-
!urlIsInsideOf(
|
|
150
|
-
firstExistingAncestorDirectoryUrl,
|
|
151
|
-
rootDirectoryUrl,
|
|
152
|
-
)
|
|
153
|
-
) {
|
|
154
|
-
firstExistingAncestorDirectoryUrl = rootDirectoryUrl;
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const firstExistingAncestorDirectoryContent = readdirSync(
|
|
160
|
-
new URL(firstExistingAncestorDirectoryUrl),
|
|
144
|
+
const directoryContentItems = generateDirectoryContentItems(
|
|
145
|
+
urlInfo.url,
|
|
146
|
+
rootDirectoryUrl,
|
|
161
147
|
);
|
|
162
148
|
const html = generateHtmlForENOENT(
|
|
163
149
|
urlInfo.url,
|
|
164
|
-
|
|
165
|
-
firstExistingAncestorDirectoryUrl,
|
|
166
|
-
urlInfo.context.rootDirectoryUrl,
|
|
150
|
+
directoryContentItems,
|
|
167
151
|
directoryListingUrlMocks,
|
|
168
152
|
);
|
|
169
153
|
return {
|
|
@@ -182,11 +166,9 @@ export const jsenvPluginProtocolFile = ({
|
|
|
182
166
|
];
|
|
183
167
|
};
|
|
184
168
|
|
|
185
|
-
const generateHtmlForDirectory = (
|
|
186
|
-
directoryUrl
|
|
187
|
-
|
|
188
|
-
rootDirectoryUrl,
|
|
189
|
-
) => {
|
|
169
|
+
const generateHtmlForDirectory = (directoryContentItems) => {
|
|
170
|
+
let directoryUrl = directoryContentItems.firstExistingDirectoryUrl;
|
|
171
|
+
const rootDirectoryUrl = directoryContentItems.rootDirectoryUrl;
|
|
190
172
|
directoryUrl = assertAndNormalizeDirectoryUrl(directoryUrl);
|
|
191
173
|
|
|
192
174
|
const htmlForDirectory = String(readFileSync(htmlFileUrlForDirectory));
|
|
@@ -195,23 +177,19 @@ const generateHtmlForDirectory = (
|
|
|
195
177
|
directoryUrl,
|
|
196
178
|
directoryNav: () =>
|
|
197
179
|
generateDirectoryNav(directoryRelativeUrl, rootDirectoryUrl),
|
|
198
|
-
directoryContent: () =>
|
|
199
|
-
generateDirectoryContent(
|
|
200
|
-
directoryContentArray,
|
|
201
|
-
directoryUrl,
|
|
202
|
-
rootDirectoryUrl,
|
|
203
|
-
),
|
|
180
|
+
directoryContent: () => generateDirectoryContent(directoryContentItems),
|
|
204
181
|
};
|
|
205
182
|
const html = replacePlaceholders(htmlForDirectory, replacers);
|
|
206
183
|
return html;
|
|
207
184
|
};
|
|
208
185
|
const generateHtmlForENOENT = (
|
|
209
186
|
url,
|
|
210
|
-
|
|
211
|
-
ancestorDirectoryUrl,
|
|
212
|
-
rootDirectoryUrl,
|
|
187
|
+
directoryContentItems,
|
|
213
188
|
directoryListingUrlMocks,
|
|
214
189
|
) => {
|
|
190
|
+
const ancestorDirectoryUrl = directoryContentItems.firstExistingDirectoryUrl;
|
|
191
|
+
const rootDirectoryUrl = directoryContentItems.rootDirectoryUrl;
|
|
192
|
+
|
|
215
193
|
const htmlFor404AndAncestorDir = String(
|
|
216
194
|
readFileSync(html404AndAncestorDirFileUrl),
|
|
217
195
|
);
|
|
@@ -230,11 +208,7 @@ const generateHtmlForENOENT = (
|
|
|
230
208
|
ancestorDirectoryNav: () =>
|
|
231
209
|
generateDirectoryNav(ancestorDirectoryRelativeUrl, rootDirectoryUrl),
|
|
232
210
|
ancestorDirectoryContent: () =>
|
|
233
|
-
generateDirectoryContent(
|
|
234
|
-
ancestorDirectoryContentArray,
|
|
235
|
-
ancestorDirectoryUrl,
|
|
236
|
-
rootDirectoryUrl,
|
|
237
|
-
),
|
|
211
|
+
generateDirectoryContent(directoryContentItems),
|
|
238
212
|
};
|
|
239
213
|
const html = replacePlaceholders(htmlFor404AndAncestorDir, replacers);
|
|
240
214
|
return html;
|
|
@@ -276,31 +250,95 @@ const generateDirectoryNav = (relativeUrl, rootDirectoryUrl) => {
|
|
|
276
250
|
}
|
|
277
251
|
return dirPartsHtml;
|
|
278
252
|
};
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
|
|
253
|
+
const generateDirectoryContentItems = (directoryUrl, rootDirectoryUrl) => {
|
|
254
|
+
let firstExistingDirectoryUrl = new URL("./", directoryUrl);
|
|
255
|
+
while (!existsSync(firstExistingDirectoryUrl)) {
|
|
256
|
+
firstExistingDirectoryUrl = new URL("../", firstExistingDirectoryUrl);
|
|
257
|
+
if (!urlIsInsideOf(firstExistingDirectoryUrl, rootDirectoryUrl)) {
|
|
258
|
+
firstExistingDirectoryUrl = new URL(rootDirectoryUrl);
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
286
261
|
}
|
|
287
|
-
const
|
|
262
|
+
const directoryContentArray = readdirSync(firstExistingDirectoryUrl);
|
|
263
|
+
const fileUrls = [];
|
|
288
264
|
for (const filename of directoryContentArray) {
|
|
289
|
-
const fileUrlObject = new URL(filename,
|
|
290
|
-
|
|
291
|
-
|
|
265
|
+
const fileUrlObject = new URL(filename, firstExistingDirectoryUrl);
|
|
266
|
+
fileUrls.push(fileUrlObject);
|
|
267
|
+
}
|
|
268
|
+
package_workspaces: {
|
|
269
|
+
if (String(firstExistingDirectoryUrl) !== String(rootDirectoryUrl)) {
|
|
270
|
+
break package_workspaces;
|
|
271
|
+
}
|
|
272
|
+
const packageDirectoryUrl = lookupPackageDirectory(rootDirectoryUrl);
|
|
273
|
+
if (!packageDirectoryUrl) {
|
|
274
|
+
break package_workspaces;
|
|
275
|
+
}
|
|
276
|
+
if (String(packageDirectoryUrl) === String(rootDirectoryUrl)) {
|
|
277
|
+
break package_workspaces;
|
|
278
|
+
}
|
|
279
|
+
let packageContent;
|
|
280
|
+
try {
|
|
281
|
+
packageContent = JSON.parse(
|
|
282
|
+
readFileSync(new URL("package.json", packageDirectoryUrl), "utf8"),
|
|
283
|
+
);
|
|
284
|
+
} catch {
|
|
285
|
+
break package_workspaces;
|
|
286
|
+
}
|
|
287
|
+
const { workspaces } = packageContent;
|
|
288
|
+
if (Array.isArray(workspaces)) {
|
|
289
|
+
for (const workspace of workspaces) {
|
|
290
|
+
const workspaceUrlObject = new URL(workspace, packageDirectoryUrl);
|
|
291
|
+
const workspaceUrl = workspaceUrlObject.href;
|
|
292
|
+
if (workspaceUrl.endsWith("*")) {
|
|
293
|
+
const directoryUrl = ensurePathnameTrailingSlash(
|
|
294
|
+
workspaceUrl.slice(0, -1),
|
|
295
|
+
);
|
|
296
|
+
fileUrls.push(new URL(directoryUrl));
|
|
297
|
+
} else {
|
|
298
|
+
fileUrls.push(ensurePathnameTrailingSlash(workspaceUrlObject));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const sortedUrls = [];
|
|
305
|
+
for (let fileUrl of fileUrls) {
|
|
306
|
+
if (lstatSync(fileUrl).isDirectory()) {
|
|
307
|
+
sortedUrls.push(ensurePathnameTrailingSlash(fileUrl));
|
|
292
308
|
} else {
|
|
293
|
-
|
|
309
|
+
sortedUrls.push(fileUrl);
|
|
294
310
|
}
|
|
295
311
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
312
|
+
sortedUrls.sort((a, b) => {
|
|
313
|
+
return comparePathnames(a.pathname, b.pathname);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const items = [];
|
|
317
|
+
for (const sortedUrl of sortedUrls) {
|
|
318
|
+
const fileUrlRelativeToParent = urlToRelativeUrl(
|
|
319
|
+
sortedUrl,
|
|
320
|
+
firstExistingDirectoryUrl,
|
|
321
|
+
);
|
|
322
|
+
const fileUrlRelativeToRoot = urlToRelativeUrl(sortedUrl, rootDirectoryUrl);
|
|
303
323
|
const type = fileUrlRelativeToParent.endsWith("/") ? "dir" : "file";
|
|
324
|
+
items.push({
|
|
325
|
+
type,
|
|
326
|
+
fileUrlRelativeToParent,
|
|
327
|
+
fileUrlRelativeToRoot,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
items.rootDirectoryUrl = rootDirectoryUrl;
|
|
331
|
+
items.firstExistingDirectoryUrl = firstExistingDirectoryUrl;
|
|
332
|
+
return items;
|
|
333
|
+
};
|
|
334
|
+
const generateDirectoryContent = (directoryContentItems) => {
|
|
335
|
+
if (directoryContentItems.length === 0) {
|
|
336
|
+
return `<p>Directory is empty</p>`;
|
|
337
|
+
}
|
|
338
|
+
let html = `<ul class="directory_content">`;
|
|
339
|
+
for (const directoryContentItem of directoryContentItems) {
|
|
340
|
+
const { type, fileUrlRelativeToParent, fileUrlRelativeToRoot } =
|
|
341
|
+
directoryContentItem;
|
|
304
342
|
html += `
|
|
305
343
|
<li class="directory_child" data-type="${type}">
|
|
306
344
|
<a href="/${fileUrlRelativeToRoot}">${fileUrlRelativeToParent}</a>
|