@jsenv/core 40.6.0 → 40.6.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/dist/build/build.js +111 -47
- package/dist/build/jsenv_core_packages.js +149 -149
- package/dist/start_build_server/jsenv_core_packages.js +29 -29
- package/dist/start_dev_server/jsenv_core_packages.js +202 -150
- package/dist/start_dev_server/start_dev_server.js +112 -48
- package/package.json +10 -9
- package/src/build/build.js +1 -1
- package/src/dev/start_dev_server.js +2 -2
- package/src/kitchen/errors.js +62 -43
- package/src/kitchen/kitchen.js +45 -3
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +3 -0
|
@@ -5,6 +5,79 @@ import { extname } from "node:path";
|
|
|
5
5
|
import crypto, { createHash } from "node:crypto";
|
|
6
6
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
+
const isFileSystemPath = (value) => {
|
|
9
|
+
if (typeof value !== "string") {
|
|
10
|
+
throw new TypeError(
|
|
11
|
+
`isFileSystemPath first arg must be a string, got ${value}`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
if (value[0] === "/") {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return startsWithWindowsDriveLetter(value);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const startsWithWindowsDriveLetter = (string) => {
|
|
21
|
+
const firstChar = string[0];
|
|
22
|
+
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
23
|
+
|
|
24
|
+
const secondChar = string[1];
|
|
25
|
+
if (secondChar !== ":") return false;
|
|
26
|
+
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const fileSystemPathToUrl = (value) => {
|
|
31
|
+
if (!isFileSystemPath(value)) {
|
|
32
|
+
throw new Error(`value must be a filesystem path, got ${value}`);
|
|
33
|
+
}
|
|
34
|
+
return String(pathToFileURL(value));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const getCallerPosition = () => {
|
|
38
|
+
const { prepareStackTrace } = Error;
|
|
39
|
+
Error.prepareStackTrace = (error, stack) => {
|
|
40
|
+
Error.prepareStackTrace = prepareStackTrace;
|
|
41
|
+
return stack;
|
|
42
|
+
};
|
|
43
|
+
const { stack } = new Error();
|
|
44
|
+
const callerCallsite = stack[2];
|
|
45
|
+
const fileName = callerCallsite.getFileName();
|
|
46
|
+
return {
|
|
47
|
+
url:
|
|
48
|
+
fileName && isFileSystemPath(fileName)
|
|
49
|
+
? fileSystemPathToUrl(fileName)
|
|
50
|
+
: fileName,
|
|
51
|
+
line: callerCallsite.getLineNumber(),
|
|
52
|
+
column: callerCallsite.getColumnNumber(),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const urlToFileSystemPath = (url) => {
|
|
57
|
+
const urlObject = new URL(url);
|
|
58
|
+
let { origin, pathname, hash } = urlObject;
|
|
59
|
+
if (urlObject.protocol === "file:") {
|
|
60
|
+
origin = "file://";
|
|
61
|
+
}
|
|
62
|
+
pathname = pathname
|
|
63
|
+
.split("/")
|
|
64
|
+
.map((part) => {
|
|
65
|
+
return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
|
|
66
|
+
})
|
|
67
|
+
.join("/");
|
|
68
|
+
if (hash) {
|
|
69
|
+
pathname += `%23${encodeURIComponent(hash.slice(1))}`;
|
|
70
|
+
}
|
|
71
|
+
const urlString = `${origin}${pathname}`;
|
|
72
|
+
const fileSystemPath = fileURLToPath(urlString);
|
|
73
|
+
if (fileSystemPath[fileSystemPath.length - 1] === "/") {
|
|
74
|
+
// remove trailing / so that nodejs path becomes predictable otherwise it logs
|
|
75
|
+
// the trailing slash on linux but does not on windows
|
|
76
|
+
return fileSystemPath.slice(0, -1);
|
|
77
|
+
}
|
|
78
|
+
return fileSystemPath;
|
|
79
|
+
};
|
|
80
|
+
|
|
8
81
|
/*
|
|
9
82
|
* data:[<mediatype>][;base64],<data>
|
|
10
83
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs#syntax
|
|
@@ -637,6 +710,58 @@ const escapeHtml = (string) => {
|
|
|
637
710
|
.replace(/'/g, "'");
|
|
638
711
|
};
|
|
639
712
|
|
|
713
|
+
const formatError = (error) => {
|
|
714
|
+
let text = "";
|
|
715
|
+
text += error.stack;
|
|
716
|
+
const { cause } = error;
|
|
717
|
+
if (cause) {
|
|
718
|
+
const formatCause = (cause, depth) => {
|
|
719
|
+
let causeText = prefixFirstAndIndentRemainingLines({
|
|
720
|
+
prefix: " [cause]:",
|
|
721
|
+
indentation: " ".repeat(depth + 1),
|
|
722
|
+
text: cause.stack,
|
|
723
|
+
});
|
|
724
|
+
const nestedCause = cause.cause;
|
|
725
|
+
if (nestedCause) {
|
|
726
|
+
const nestedCauseText = formatCause(nestedCause, depth + 1);
|
|
727
|
+
causeText += `\n${nestedCauseText}`;
|
|
728
|
+
}
|
|
729
|
+
return causeText;
|
|
730
|
+
};
|
|
731
|
+
const causeText = formatCause(cause, 0);
|
|
732
|
+
text += `\n${causeText}`;
|
|
733
|
+
}
|
|
734
|
+
return text;
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
const prefixFirstAndIndentRemainingLines = ({
|
|
738
|
+
prefix,
|
|
739
|
+
indentation,
|
|
740
|
+
text,
|
|
741
|
+
trimLines,
|
|
742
|
+
trimLastLine,
|
|
743
|
+
}) => {
|
|
744
|
+
const lines = text.split(/\r?\n/);
|
|
745
|
+
const firstLine = lines.shift();
|
|
746
|
+
if (indentation === undefined) {
|
|
747
|
+
{
|
|
748
|
+
indentation = " "; // prefix + space
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
let result = `${prefix} ${firstLine}` ;
|
|
752
|
+
let i = 0;
|
|
753
|
+
while (i < lines.length) {
|
|
754
|
+
const line = trimLines ? lines[i].trim() : lines[i];
|
|
755
|
+
i++;
|
|
756
|
+
result += line.length
|
|
757
|
+
? `\n${indentation}${line}`
|
|
758
|
+
: trimLastLine && i === lines.length
|
|
759
|
+
? ""
|
|
760
|
+
: `\n`;
|
|
761
|
+
}
|
|
762
|
+
return result;
|
|
763
|
+
};
|
|
764
|
+
|
|
640
765
|
const LOG_LEVEL_OFF = "off";
|
|
641
766
|
|
|
642
767
|
const LOG_LEVEL_DEBUG = "debug";
|
|
@@ -1262,6 +1387,75 @@ const urlToOrigin$1 = (url) => {
|
|
|
1262
1387
|
return new URL(urlString).origin;
|
|
1263
1388
|
};
|
|
1264
1389
|
|
|
1390
|
+
const setUrlExtension = (url, extension) => {
|
|
1391
|
+
const origin = urlToOrigin$1(url);
|
|
1392
|
+
const currentExtension = urlToExtension$1(url);
|
|
1393
|
+
if (typeof extension === "function") {
|
|
1394
|
+
extension = extension(currentExtension);
|
|
1395
|
+
}
|
|
1396
|
+
const resource = urlToResource(url);
|
|
1397
|
+
const [pathname, search] = resource.split("?");
|
|
1398
|
+
const pathnameWithoutExtension = currentExtension
|
|
1399
|
+
? pathname.slice(0, -currentExtension.length)
|
|
1400
|
+
: pathname;
|
|
1401
|
+
let newPathname;
|
|
1402
|
+
if (pathnameWithoutExtension.endsWith("/")) {
|
|
1403
|
+
newPathname = pathnameWithoutExtension.slice(0, -1);
|
|
1404
|
+
newPathname += extension;
|
|
1405
|
+
newPathname += "/";
|
|
1406
|
+
} else {
|
|
1407
|
+
newPathname = pathnameWithoutExtension;
|
|
1408
|
+
newPathname += extension;
|
|
1409
|
+
}
|
|
1410
|
+
return `${origin}${newPathname}${search ? `?${search}` : ""}`;
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
const setUrlFilename = (url, filename) => {
|
|
1414
|
+
const parentPathname = new URL("./", url).pathname;
|
|
1415
|
+
return transformUrlPathname(url, (pathname) => {
|
|
1416
|
+
if (typeof filename === "function") {
|
|
1417
|
+
filename = filename(pathnameToFilename(pathname));
|
|
1418
|
+
}
|
|
1419
|
+
return `${parentPathname}${filename}`;
|
|
1420
|
+
});
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
const setUrlBasename = (url, basename) => {
|
|
1424
|
+
return setUrlFilename(url, (filename) => {
|
|
1425
|
+
if (typeof basename === "function") {
|
|
1426
|
+
basename = basename(filenameToBasename(filename));
|
|
1427
|
+
}
|
|
1428
|
+
return `${basename}${urlToExtension$1(url)}`;
|
|
1429
|
+
});
|
|
1430
|
+
};
|
|
1431
|
+
|
|
1432
|
+
const transformUrlPathname = (url, transformer) => {
|
|
1433
|
+
if (typeof url === "string") {
|
|
1434
|
+
const urlObject = new URL(url);
|
|
1435
|
+
const { pathname } = urlObject;
|
|
1436
|
+
const pathnameTransformed = transformer(pathname);
|
|
1437
|
+
if (pathnameTransformed === pathname) {
|
|
1438
|
+
return url;
|
|
1439
|
+
}
|
|
1440
|
+
let { origin } = urlObject;
|
|
1441
|
+
// origin is "null" for "file://" urls with Node.js
|
|
1442
|
+
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
1443
|
+
origin = "file://";
|
|
1444
|
+
}
|
|
1445
|
+
const { search, hash } = urlObject;
|
|
1446
|
+
const urlWithPathnameTransformed = `${origin}${pathnameTransformed}${search}${hash}`;
|
|
1447
|
+
return urlWithPathnameTransformed;
|
|
1448
|
+
}
|
|
1449
|
+
const pathnameTransformed = transformer(url.pathname);
|
|
1450
|
+
url.pathname = pathnameTransformed;
|
|
1451
|
+
return url;
|
|
1452
|
+
};
|
|
1453
|
+
const ensurePathnameTrailingSlash = (url) => {
|
|
1454
|
+
return transformUrlPathname(url, (pathname) => {
|
|
1455
|
+
return pathname.endsWith("/") ? pathname : `${pathname}/`;
|
|
1456
|
+
});
|
|
1457
|
+
};
|
|
1458
|
+
|
|
1265
1459
|
const asUrlWithoutSearch = (url) => {
|
|
1266
1460
|
url = String(url);
|
|
1267
1461
|
if (url.includes("?")) {
|
|
@@ -1352,130 +1546,6 @@ const injectQueryParams = (url, params) => {
|
|
|
1352
1546
|
return normalizeUrl(calledWithString ? urlObject.href : urlObject);
|
|
1353
1547
|
};
|
|
1354
1548
|
|
|
1355
|
-
const setUrlExtension = (url, extension) => {
|
|
1356
|
-
const origin = urlToOrigin$1(url);
|
|
1357
|
-
const currentExtension = urlToExtension$1(url);
|
|
1358
|
-
if (typeof extension === "function") {
|
|
1359
|
-
extension = extension(currentExtension);
|
|
1360
|
-
}
|
|
1361
|
-
const resource = urlToResource(url);
|
|
1362
|
-
const [pathname, search] = resource.split("?");
|
|
1363
|
-
const pathnameWithoutExtension = currentExtension
|
|
1364
|
-
? pathname.slice(0, -currentExtension.length)
|
|
1365
|
-
: pathname;
|
|
1366
|
-
let newPathname;
|
|
1367
|
-
if (pathnameWithoutExtension.endsWith("/")) {
|
|
1368
|
-
newPathname = pathnameWithoutExtension.slice(0, -1);
|
|
1369
|
-
newPathname += extension;
|
|
1370
|
-
newPathname += "/";
|
|
1371
|
-
} else {
|
|
1372
|
-
newPathname = pathnameWithoutExtension;
|
|
1373
|
-
newPathname += extension;
|
|
1374
|
-
}
|
|
1375
|
-
return `${origin}${newPathname}${search ? `?${search}` : ""}`;
|
|
1376
|
-
};
|
|
1377
|
-
|
|
1378
|
-
const setUrlFilename = (url, filename) => {
|
|
1379
|
-
const parentPathname = new URL("./", url).pathname;
|
|
1380
|
-
return transformUrlPathname(url, (pathname) => {
|
|
1381
|
-
if (typeof filename === "function") {
|
|
1382
|
-
filename = filename(pathnameToFilename(pathname));
|
|
1383
|
-
}
|
|
1384
|
-
return `${parentPathname}${filename}`;
|
|
1385
|
-
});
|
|
1386
|
-
};
|
|
1387
|
-
|
|
1388
|
-
const setUrlBasename = (url, basename) => {
|
|
1389
|
-
return setUrlFilename(url, (filename) => {
|
|
1390
|
-
if (typeof basename === "function") {
|
|
1391
|
-
basename = basename(filenameToBasename(filename));
|
|
1392
|
-
}
|
|
1393
|
-
return `${basename}${urlToExtension$1(url)}`;
|
|
1394
|
-
});
|
|
1395
|
-
};
|
|
1396
|
-
|
|
1397
|
-
const transformUrlPathname = (url, transformer) => {
|
|
1398
|
-
if (typeof url === "string") {
|
|
1399
|
-
const urlObject = new URL(url);
|
|
1400
|
-
const { pathname } = urlObject;
|
|
1401
|
-
const pathnameTransformed = transformer(pathname);
|
|
1402
|
-
if (pathnameTransformed === pathname) {
|
|
1403
|
-
return url;
|
|
1404
|
-
}
|
|
1405
|
-
let { origin } = urlObject;
|
|
1406
|
-
// origin is "null" for "file://" urls with Node.js
|
|
1407
|
-
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
1408
|
-
origin = "file://";
|
|
1409
|
-
}
|
|
1410
|
-
const { search, hash } = urlObject;
|
|
1411
|
-
const urlWithPathnameTransformed = `${origin}${pathnameTransformed}${search}${hash}`;
|
|
1412
|
-
return urlWithPathnameTransformed;
|
|
1413
|
-
}
|
|
1414
|
-
const pathnameTransformed = transformer(url.pathname);
|
|
1415
|
-
url.pathname = pathnameTransformed;
|
|
1416
|
-
return url;
|
|
1417
|
-
};
|
|
1418
|
-
const ensurePathnameTrailingSlash = (url) => {
|
|
1419
|
-
return transformUrlPathname(url, (pathname) => {
|
|
1420
|
-
return pathname.endsWith("/") ? pathname : `${pathname}/`;
|
|
1421
|
-
});
|
|
1422
|
-
};
|
|
1423
|
-
|
|
1424
|
-
const isFileSystemPath = (value) => {
|
|
1425
|
-
if (typeof value !== "string") {
|
|
1426
|
-
throw new TypeError(
|
|
1427
|
-
`isFileSystemPath first arg must be a string, got ${value}`,
|
|
1428
|
-
);
|
|
1429
|
-
}
|
|
1430
|
-
if (value[0] === "/") {
|
|
1431
|
-
return true;
|
|
1432
|
-
}
|
|
1433
|
-
return startsWithWindowsDriveLetter(value);
|
|
1434
|
-
};
|
|
1435
|
-
|
|
1436
|
-
const startsWithWindowsDriveLetter = (string) => {
|
|
1437
|
-
const firstChar = string[0];
|
|
1438
|
-
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
1439
|
-
|
|
1440
|
-
const secondChar = string[1];
|
|
1441
|
-
if (secondChar !== ":") return false;
|
|
1442
|
-
|
|
1443
|
-
return true;
|
|
1444
|
-
};
|
|
1445
|
-
|
|
1446
|
-
const fileSystemPathToUrl = (value) => {
|
|
1447
|
-
if (!isFileSystemPath(value)) {
|
|
1448
|
-
throw new Error(`value must be a filesystem path, got ${value}`);
|
|
1449
|
-
}
|
|
1450
|
-
return String(pathToFileURL(value));
|
|
1451
|
-
};
|
|
1452
|
-
|
|
1453
|
-
const getCallerPosition = () => {
|
|
1454
|
-
const { prepareStackTrace } = Error;
|
|
1455
|
-
Error.prepareStackTrace = (error, stack) => {
|
|
1456
|
-
Error.prepareStackTrace = prepareStackTrace;
|
|
1457
|
-
return stack;
|
|
1458
|
-
};
|
|
1459
|
-
const { stack } = new Error();
|
|
1460
|
-
const callerCallsite = stack[2];
|
|
1461
|
-
const fileName = callerCallsite.getFileName();
|
|
1462
|
-
return {
|
|
1463
|
-
url:
|
|
1464
|
-
fileName && isFileSystemPath(fileName)
|
|
1465
|
-
? fileSystemPathToUrl(fileName)
|
|
1466
|
-
: fileName,
|
|
1467
|
-
line: callerCallsite.getLineNumber(),
|
|
1468
|
-
column: callerCallsite.getColumnNumber(),
|
|
1469
|
-
};
|
|
1470
|
-
};
|
|
1471
|
-
|
|
1472
|
-
const resolveUrl$1 = (specifier, baseUrl) => {
|
|
1473
|
-
if (typeof baseUrl === "undefined") {
|
|
1474
|
-
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
1475
|
-
}
|
|
1476
|
-
return String(new URL(specifier, baseUrl));
|
|
1477
|
-
};
|
|
1478
|
-
|
|
1479
1549
|
const getCommonPathname = (pathname, otherPathname) => {
|
|
1480
1550
|
if (pathname === otherPathname) {
|
|
1481
1551
|
return pathname;
|
|
@@ -1585,6 +1655,13 @@ const moveUrl = ({ url, from, to, preferRelative }) => {
|
|
|
1585
1655
|
return absoluteUrl;
|
|
1586
1656
|
};
|
|
1587
1657
|
|
|
1658
|
+
const resolveUrl$1 = (specifier, baseUrl) => {
|
|
1659
|
+
if (typeof baseUrl === "undefined") {
|
|
1660
|
+
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
1661
|
+
}
|
|
1662
|
+
return String(new URL(specifier, baseUrl));
|
|
1663
|
+
};
|
|
1664
|
+
|
|
1588
1665
|
const urlIsInsideOf = (url, otherUrl) => {
|
|
1589
1666
|
const urlObject = new URL(url);
|
|
1590
1667
|
const otherUrlObject = new URL(otherUrl);
|
|
@@ -1603,31 +1680,6 @@ const urlIsInsideOf = (url, otherUrl) => {
|
|
|
1603
1680
|
return isInside;
|
|
1604
1681
|
};
|
|
1605
1682
|
|
|
1606
|
-
const urlToFileSystemPath = (url) => {
|
|
1607
|
-
const urlObject = new URL(url);
|
|
1608
|
-
let { origin, pathname, hash } = urlObject;
|
|
1609
|
-
if (urlObject.protocol === "file:") {
|
|
1610
|
-
origin = "file://";
|
|
1611
|
-
}
|
|
1612
|
-
pathname = pathname
|
|
1613
|
-
.split("/")
|
|
1614
|
-
.map((part) => {
|
|
1615
|
-
return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
|
|
1616
|
-
})
|
|
1617
|
-
.join("/");
|
|
1618
|
-
if (hash) {
|
|
1619
|
-
pathname += `%23${encodeURIComponent(hash.slice(1))}`;
|
|
1620
|
-
}
|
|
1621
|
-
const urlString = `${origin}${pathname}`;
|
|
1622
|
-
const fileSystemPath = fileURLToPath(urlString);
|
|
1623
|
-
if (fileSystemPath[fileSystemPath.length - 1] === "/") {
|
|
1624
|
-
// remove trailing / so that nodejs path becomes predictable otherwise it logs
|
|
1625
|
-
// the trailing slash on linux but does not on windows
|
|
1626
|
-
return fileSystemPath.slice(0, -1);
|
|
1627
|
-
}
|
|
1628
|
-
return fileSystemPath;
|
|
1629
|
-
};
|
|
1630
|
-
|
|
1631
1683
|
const validateDirectoryUrl = (value) => {
|
|
1632
1684
|
let urlString;
|
|
1633
1685
|
|
|
@@ -6205,4 +6257,4 @@ const memoizeByFirstArgument = (compute) => {
|
|
|
6205
6257
|
return fnWithMemoization;
|
|
6206
6258
|
};
|
|
6207
6259
|
|
|
6208
|
-
export { ANSI, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, bufferToEtag, compareFileUrls, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createLogger, createTaskLog, defaultLookupPackageScope, defaultReadPackageJson, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, generateContentFrame, getCallerPosition, getExtensionsToTry, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, memoizeByFirstArgument, moveUrl, normalizeImportMap, normalizeUrl, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename, stringifyUrlSite, urlIsInsideOf, urlToBasename, urlToExtension$1 as urlToExtension, urlToFileSystemPath, urlToFilename$1 as urlToFilename, urlToPathname$1 as urlToPathname, urlToRelativeUrl, validateResponseIntegrity, writeFileSync };
|
|
6260
|
+
export { ANSI, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, bufferToEtag, compareFileUrls, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createLogger, createTaskLog, defaultLookupPackageScope, defaultReadPackageJson, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, formatError, generateContentFrame, getCallerPosition, getExtensionsToTry, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, memoizeByFirstArgument, moveUrl, normalizeImportMap, normalizeUrl, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename, stringifyUrlSite, urlIsInsideOf, urlToBasename, urlToExtension$1 as urlToExtension, urlToFileSystemPath, urlToFilename$1 as urlToFilename, urlToPathname$1 as urlToPathname, urlToRelativeUrl, validateResponseIntegrity, writeFileSync };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WebSocketResponse, pickContentType, ServerEvents, jsenvServiceCORS, jsenvAccessControlAllowedHeaders, composeTwoResponses, serveDirectory, jsenvServiceErrorHandler, startServer } from "@jsenv/server";
|
|
2
2
|
import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js";
|
|
3
|
-
import { lookupPackageDirectory, registerDirectoryLifecycle, urlToRelativeUrl, moveUrl, urlIsInsideOf, ensureWindowsDriveLetter, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, setUrlFilename, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, RUNTIME_COMPAT, normalizeUrl, ANSI, CONTENT_TYPE, errorToHTML, DATA_URL, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, defaultLookupPackageScope, defaultReadPackageJson, readCustomConditionsFromProcessArgs, readEntryStatSync, urlToFilename, ensurePathnameTrailingSlash, compareFileUrls, applyFileSystemMagicResolution, getExtensionsToTry, setUrlExtension, isSpecifierForNodeBuiltin, memoizeByFirstArgument, assertAndNormalizeDirectoryUrl, createTaskLog, readPackageAtOrNull } from "./jsenv_core_packages.js";
|
|
3
|
+
import { lookupPackageDirectory, registerDirectoryLifecycle, urlToRelativeUrl, moveUrl, urlIsInsideOf, ensureWindowsDriveLetter, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, setUrlFilename, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, RUNTIME_COMPAT, normalizeUrl, ANSI, CONTENT_TYPE, errorToHTML, DATA_URL, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, defaultLookupPackageScope, defaultReadPackageJson, readCustomConditionsFromProcessArgs, readEntryStatSync, urlToFilename, ensurePathnameTrailingSlash, compareFileUrls, applyFileSystemMagicResolution, getExtensionsToTry, setUrlExtension, isSpecifierForNodeBuiltin, memoizeByFirstArgument, assertAndNormalizeDirectoryUrl, createTaskLog, formatError, readPackageAtOrNull } from "./jsenv_core_packages.js";
|
|
4
4
|
import { readFileSync, existsSync, readdirSync, lstatSync, realpathSync } from "node:fs";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
@@ -242,6 +242,12 @@ ${reason}`,
|
|
|
242
242
|
});
|
|
243
243
|
return error;
|
|
244
244
|
}
|
|
245
|
+
if (error.code === "PROTOCOL_NOT_SUPPORTED") {
|
|
246
|
+
const notSupportedError = createFailedToResolveUrlError({
|
|
247
|
+
reason: error.message,
|
|
248
|
+
});
|
|
249
|
+
return notSupportedError;
|
|
250
|
+
}
|
|
245
251
|
return createFailedToResolveUrlError({
|
|
246
252
|
reason: `An error occured during specifier resolution`,
|
|
247
253
|
...detailsFromValueThrown(error),
|
|
@@ -282,7 +288,6 @@ ${reason}`,
|
|
|
282
288
|
});
|
|
283
289
|
return fetchError;
|
|
284
290
|
};
|
|
285
|
-
|
|
286
291
|
if (error.code === "EPERM") {
|
|
287
292
|
return createFailedToFetchUrlContentError({
|
|
288
293
|
code: "NOT_ALLOWED",
|
|
@@ -329,6 +334,9 @@ const createTransformUrlContentError = ({
|
|
|
329
334
|
if (error.code === "MODULE_NOT_FOUND") {
|
|
330
335
|
return error;
|
|
331
336
|
}
|
|
337
|
+
if (error.code === "PROTOCOL_NOT_SUPPORTED") {
|
|
338
|
+
return error;
|
|
339
|
+
}
|
|
332
340
|
if (error.code === "DIRECTORY_REFERENCE_NOT_ALLOWED") {
|
|
333
341
|
return error;
|
|
334
342
|
}
|
|
@@ -336,47 +344,8 @@ const createTransformUrlContentError = ({
|
|
|
336
344
|
if (error.isJsenvCookingError) {
|
|
337
345
|
return error;
|
|
338
346
|
}
|
|
347
|
+
const trace = getErrorTrace(error, urlInfo.firstReference);
|
|
339
348
|
const reference = urlInfo.firstReference;
|
|
340
|
-
let trace = reference.trace;
|
|
341
|
-
let line = error.line;
|
|
342
|
-
let column = error.column;
|
|
343
|
-
if (urlInfo.isInline) {
|
|
344
|
-
line = trace.line + line;
|
|
345
|
-
line = line - 1;
|
|
346
|
-
trace = {
|
|
347
|
-
...trace,
|
|
348
|
-
line,
|
|
349
|
-
column,
|
|
350
|
-
codeFrame: generateContentFrame({
|
|
351
|
-
line,
|
|
352
|
-
column,
|
|
353
|
-
content: urlInfo.inlineUrlSite.content,
|
|
354
|
-
}),
|
|
355
|
-
message: stringifyUrlSite({
|
|
356
|
-
url: urlInfo.inlineUrlSite.url,
|
|
357
|
-
line,
|
|
358
|
-
column,
|
|
359
|
-
content: urlInfo.inlineUrlSite.content,
|
|
360
|
-
}),
|
|
361
|
-
};
|
|
362
|
-
} else {
|
|
363
|
-
trace = {
|
|
364
|
-
url: urlInfo.url,
|
|
365
|
-
line,
|
|
366
|
-
column: error.column,
|
|
367
|
-
codeFrame: generateContentFrame({
|
|
368
|
-
line,
|
|
369
|
-
column: error.column,
|
|
370
|
-
content: urlInfo.content,
|
|
371
|
-
}),
|
|
372
|
-
message: stringifyUrlSite({
|
|
373
|
-
url: urlInfo.url,
|
|
374
|
-
line,
|
|
375
|
-
column: error.column,
|
|
376
|
-
content: urlInfo.content,
|
|
377
|
-
}),
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
349
|
const transformError = new Error(
|
|
381
350
|
createDetailedMessage(
|
|
382
351
|
`parse error on "${urlInfo.type}"
|
|
@@ -467,9 +436,55 @@ ${reference.trace.message}`,
|
|
|
467
436
|
return finalizeError;
|
|
468
437
|
};
|
|
469
438
|
|
|
439
|
+
const getErrorTrace = (error, reference) => {
|
|
440
|
+
const urlInfo = reference.urlInfo;
|
|
441
|
+
let trace = reference.trace;
|
|
442
|
+
let line = error.line;
|
|
443
|
+
let column = error.column;
|
|
444
|
+
if (urlInfo.isInline) {
|
|
445
|
+
line = trace.line + line;
|
|
446
|
+
line = line - 1;
|
|
447
|
+
return {
|
|
448
|
+
...trace,
|
|
449
|
+
line,
|
|
450
|
+
column,
|
|
451
|
+
codeFrame: generateContentFrame({
|
|
452
|
+
line,
|
|
453
|
+
column,
|
|
454
|
+
content: urlInfo.inlineUrlSite.content,
|
|
455
|
+
}),
|
|
456
|
+
message: stringifyUrlSite({
|
|
457
|
+
url: urlInfo.inlineUrlSite.url,
|
|
458
|
+
line,
|
|
459
|
+
column,
|
|
460
|
+
content: urlInfo.inlineUrlSite.content,
|
|
461
|
+
}),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
url: urlInfo.url,
|
|
466
|
+
line,
|
|
467
|
+
column: error.column,
|
|
468
|
+
codeFrame: generateContentFrame({
|
|
469
|
+
line,
|
|
470
|
+
column: error.column,
|
|
471
|
+
content: urlInfo.content,
|
|
472
|
+
}),
|
|
473
|
+
message: stringifyUrlSite({
|
|
474
|
+
url: urlInfo.url,
|
|
475
|
+
line,
|
|
476
|
+
column: error.column,
|
|
477
|
+
content: urlInfo.content,
|
|
478
|
+
}),
|
|
479
|
+
};
|
|
480
|
+
};
|
|
481
|
+
|
|
470
482
|
const detailsFromFirstReference = (reference) => {
|
|
471
483
|
const referenceInProject = getFirstReferenceInProject(reference);
|
|
472
|
-
if (
|
|
484
|
+
if (
|
|
485
|
+
referenceInProject === reference ||
|
|
486
|
+
referenceInProject.type === "http_request"
|
|
487
|
+
) {
|
|
473
488
|
return {};
|
|
474
489
|
}
|
|
475
490
|
return {
|
|
@@ -478,6 +493,9 @@ const detailsFromFirstReference = (reference) => {
|
|
|
478
493
|
};
|
|
479
494
|
const getFirstReferenceInProject = (reference) => {
|
|
480
495
|
const ownerUrlInfo = reference.ownerUrlInfo;
|
|
496
|
+
if (ownerUrlInfo.isRoot) {
|
|
497
|
+
return reference;
|
|
498
|
+
}
|
|
481
499
|
if (
|
|
482
500
|
!ownerUrlInfo.url.includes("/node_modules/") &&
|
|
483
501
|
ownerUrlInfo.packageDirectoryUrl ===
|
|
@@ -485,7 +503,8 @@ const getFirstReferenceInProject = (reference) => {
|
|
|
485
503
|
) {
|
|
486
504
|
return reference;
|
|
487
505
|
}
|
|
488
|
-
|
|
506
|
+
const { firstReference } = ownerUrlInfo;
|
|
507
|
+
return getFirstReferenceInProject(firstReference);
|
|
489
508
|
};
|
|
490
509
|
|
|
491
510
|
const detailsFromPluginController = (pluginController) => {
|
|
@@ -2708,7 +2727,28 @@ const createKitchen = ({
|
|
|
2708
2727
|
|
|
2709
2728
|
ignore,
|
|
2710
2729
|
ignoreProtocol = "remove",
|
|
2711
|
-
supportedProtocols = [
|
|
2730
|
+
supportedProtocols = [
|
|
2731
|
+
"file:",
|
|
2732
|
+
"data:",
|
|
2733
|
+
// eslint-disable-next-line no-script-url
|
|
2734
|
+
"javascript:",
|
|
2735
|
+
"virtual:",
|
|
2736
|
+
"ignore:",
|
|
2737
|
+
"http:",
|
|
2738
|
+
"https:",
|
|
2739
|
+
"chrome:",
|
|
2740
|
+
"chrome-extension:",
|
|
2741
|
+
"chrome-untrusted:",
|
|
2742
|
+
"isolated-app:",
|
|
2743
|
+
],
|
|
2744
|
+
includedProtocols = [
|
|
2745
|
+
"file:",
|
|
2746
|
+
"data:",
|
|
2747
|
+
"virtual:",
|
|
2748
|
+
"ignore:",
|
|
2749
|
+
"http:",
|
|
2750
|
+
"https:",
|
|
2751
|
+
],
|
|
2712
2752
|
|
|
2713
2753
|
// during dev/test clientRuntimeCompat is a single runtime
|
|
2714
2754
|
// during build clientRuntimeCompat is runtimeCompat
|
|
@@ -2728,6 +2768,9 @@ const createKitchen = ({
|
|
|
2728
2768
|
|
|
2729
2769
|
const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
|
|
2730
2770
|
const packageConditions = [nodeRuntimeEnabled ? "node" : "browser", "import"];
|
|
2771
|
+
if (nodeRuntimeEnabled) {
|
|
2772
|
+
supportedProtocols.push("node:");
|
|
2773
|
+
}
|
|
2731
2774
|
|
|
2732
2775
|
if (packageDependencies === "auto") {
|
|
2733
2776
|
packageDependencies = build && nodeRuntimeEnabled ? "ignore" : "include";
|
|
@@ -2799,8 +2842,11 @@ const createKitchen = ({
|
|
|
2799
2842
|
|
|
2800
2843
|
const isIgnoredByProtocol = (url) => {
|
|
2801
2844
|
const { protocol } = new URL(url);
|
|
2802
|
-
const
|
|
2803
|
-
|
|
2845
|
+
const protocolIsIncluded = includedProtocols.includes(protocol);
|
|
2846
|
+
if (protocolIsIncluded) {
|
|
2847
|
+
return false;
|
|
2848
|
+
}
|
|
2849
|
+
return true;
|
|
2804
2850
|
};
|
|
2805
2851
|
const isIgnoredBecauseInPackageDependencies = (() => {
|
|
2806
2852
|
if (packageDependencies === undefined) {
|
|
@@ -3007,6 +3053,21 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
3007
3053
|
}
|
|
3008
3054
|
reference.generatedUrl = reference.url;
|
|
3009
3055
|
reference.generatedSearchParams = reference.searchParams;
|
|
3056
|
+
if (dev) {
|
|
3057
|
+
let url = reference.url;
|
|
3058
|
+
let { protocol } = new URL(url);
|
|
3059
|
+
if (protocol === "ignore:") {
|
|
3060
|
+
url = url.slice("ignore:".length);
|
|
3061
|
+
protocol = new URL(url, "http://example.com").protocol;
|
|
3062
|
+
}
|
|
3063
|
+
if (!supportedProtocols.includes(protocol)) {
|
|
3064
|
+
const protocolNotSupportedError = new Error(
|
|
3065
|
+
`Unsupported protocol "${protocol}" for url "${url}"`,
|
|
3066
|
+
);
|
|
3067
|
+
protocolNotSupportedError.code = "PROTOCOL_NOT_SUPPORTED";
|
|
3068
|
+
throw protocolNotSupportedError;
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3010
3071
|
return reference;
|
|
3011
3072
|
} catch (error) {
|
|
3012
3073
|
throw createResolveUrlError({
|
|
@@ -6548,6 +6609,9 @@ const jsenvPluginProtocolFile = ({
|
|
|
6548
6609
|
name: "jsenv:directory_as_json",
|
|
6549
6610
|
appliesDuring: "*",
|
|
6550
6611
|
fetchUrlContent: (urlInfo) => {
|
|
6612
|
+
if (!urlInfo.url.startsWith("file:")) {
|
|
6613
|
+
return null;
|
|
6614
|
+
}
|
|
6551
6615
|
const { firstReference } = urlInfo;
|
|
6552
6616
|
let { fsStat } = firstReference;
|
|
6553
6617
|
if (!fsStat) {
|
|
@@ -9399,7 +9463,7 @@ const startDevServer = async ({
|
|
|
9399
9463
|
url: reference.url,
|
|
9400
9464
|
status: 500,
|
|
9401
9465
|
statusText: error.reason,
|
|
9402
|
-
statusMessage: error
|
|
9466
|
+
statusMessage: formatError(error),
|
|
9403
9467
|
headers: {
|
|
9404
9468
|
"cache-control": "no-store",
|
|
9405
9469
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "40.6.
|
|
3
|
+
"version": "40.6.1",
|
|
4
4
|
"description": "Tool to develop, test and build js projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"/src/"
|
|
35
35
|
],
|
|
36
36
|
"volta": {
|
|
37
|
-
"node": "23.11.0"
|
|
37
|
+
"node": "23.11.0",
|
|
38
|
+
"npm": "11.3.0"
|
|
38
39
|
},
|
|
39
|
-
"packageManager": "npm@11.
|
|
40
|
+
"packageManager": "npm@11.3.0",
|
|
40
41
|
"workspaces": [
|
|
41
42
|
"./packages/back_and_front/*",
|
|
42
43
|
"./packages/backend/*",
|
|
@@ -81,14 +82,14 @@
|
|
|
81
82
|
},
|
|
82
83
|
"dependencies": {
|
|
83
84
|
"@financial-times/polyfill-useragent-normaliser": "1.10.2",
|
|
84
|
-
"@jsenv/ast": "6.7.
|
|
85
|
-
"@jsenv/js-module-fallback": "1.4.
|
|
86
|
-
"@jsenv/plugin-bundling": "2.9.
|
|
85
|
+
"@jsenv/ast": "6.7.2",
|
|
86
|
+
"@jsenv/js-module-fallback": "1.4.12",
|
|
87
|
+
"@jsenv/plugin-bundling": "2.9.7",
|
|
87
88
|
"@jsenv/plugin-minification": "1.7.0",
|
|
88
|
-
"@jsenv/plugin-supervisor": "1.
|
|
89
|
-
"@jsenv/plugin-transpilation": "1.5.
|
|
89
|
+
"@jsenv/plugin-supervisor": "1.7.0",
|
|
90
|
+
"@jsenv/plugin-transpilation": "1.5.19",
|
|
90
91
|
"@jsenv/server": "16.1.2",
|
|
91
|
-
"@jsenv/sourcemap": "1.3.
|
|
92
|
+
"@jsenv/sourcemap": "1.3.8"
|
|
92
93
|
},
|
|
93
94
|
"devDependencies": {
|
|
94
95
|
"@babel/plugin-syntax-decorators": "7.25.9",
|