@jsenv/plugin-supervisor 1.5.27 → 1.5.29

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.
@@ -3,8 +3,11 @@ import process$1 from "node:process";
3
3
  import os from "node:os";
4
4
  import tty from "node:tty";
5
5
  import "string-width";
6
- import { fileURLToPath } from "node:url";
6
+ import { pathToFileURL, fileURLToPath } from "node:url";
7
7
  import { createRequire } from "node:module";
8
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
9
+ import "node:path";
10
+ import "node:crypto";
8
11
 
9
12
  // From: https://github.com/sindresorhus/has-flag/blob/main/index.js
10
13
  /// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
@@ -486,6 +489,30 @@ const injectQueryParams = (url, params) => {
486
489
  return normalizeUrl(urlWithParams);
487
490
  };
488
491
 
492
+ const isFileSystemPath = value => {
493
+ if (typeof value !== "string") {
494
+ throw new TypeError("isFileSystemPath first arg must be a string, got ".concat(value));
495
+ }
496
+ if (value[0] === "/") {
497
+ return true;
498
+ }
499
+ return startsWithWindowsDriveLetter(value);
500
+ };
501
+ const startsWithWindowsDriveLetter = string => {
502
+ const firstChar = string[0];
503
+ if (!/[a-zA-Z]/.test(firstChar)) return false;
504
+ const secondChar = string[1];
505
+ if (secondChar !== ":") return false;
506
+ return true;
507
+ };
508
+
509
+ const fileSystemPathToUrl = value => {
510
+ if (!isFileSystemPath(value)) {
511
+ throw new Error("value must be a filesystem path, got ".concat(value));
512
+ }
513
+ return String(pathToFileURL(value));
514
+ };
515
+
489
516
  const getCommonPathname = (pathname, otherPathname) => {
490
517
  if (pathname === otherPathname) {
491
518
  return pathname;
@@ -570,6 +597,24 @@ const pathnameToParentPathname = pathname => {
570
597
  return pathname.slice(0, slashLastIndex + 1);
571
598
  };
572
599
 
600
+ const urlToFileSystemPath = url => {
601
+ const urlObject = new URL(url);
602
+ let urlString;
603
+ if (urlObject.hash) {
604
+ const origin = urlObject.protocol === "file:" ? "file://" : urlObject.origin;
605
+ urlString = "".concat(origin).concat(urlObject.pathname).concat(urlObject.search, "%23").concat(urlObject.hash.slice(1));
606
+ } else {
607
+ urlString = urlObject.href;
608
+ }
609
+ const fileSystemPath = fileURLToPath(urlString);
610
+ if (fileSystemPath[fileSystemPath.length - 1] === "/") {
611
+ // remove trailing / so that nodejs path becomes predictable otherwise it logs
612
+ // the trailing slash on linux but does not on windows
613
+ return fileSystemPath.slice(0, -1);
614
+ }
615
+ return fileSystemPath;
616
+ };
617
+
573
618
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
574
619
  const intToChar = new Uint8Array(64); // 64 possible chars.
575
620
  const charToInt = new Uint8Array(128); // z is 122 in ASCII
@@ -1216,6 +1261,868 @@ const generateCodeToSuperviseScriptWithSrc = ({
1216
1261
  return "window.__supervisor__.superviseScript(".concat(srcEncoded, ");");
1217
1262
  };
1218
1263
 
1264
+ // https://nodejs.org/api/packages.html#resolving-user-conditions
1265
+ const readCustomConditionsFromProcessArgs = () => {
1266
+ const packageConditions = [];
1267
+ process.execArgv.forEach(arg => {
1268
+ if (arg.includes("-C=")) {
1269
+ const packageCondition = arg.slice(0, "-C=".length);
1270
+ packageConditions.push(packageCondition);
1271
+ }
1272
+ if (arg.includes("--conditions=")) {
1273
+ const packageCondition = arg.slice("--conditions=".length);
1274
+ packageConditions.push(packageCondition);
1275
+ }
1276
+ });
1277
+ return packageConditions;
1278
+ };
1279
+
1280
+ const asDirectoryUrl = url => {
1281
+ const {
1282
+ pathname
1283
+ } = new URL(url);
1284
+ if (pathname.endsWith("/")) {
1285
+ return url;
1286
+ }
1287
+ return new URL("./", url).href;
1288
+ };
1289
+ const getParentUrl = url => {
1290
+ if (url.startsWith("file://")) {
1291
+ // With node.js new URL('../', 'file:///C:/').href
1292
+ // returns "file:///C:/" instead of "file:///"
1293
+ const resource = url.slice("file://".length);
1294
+ const slashLastIndex = resource.lastIndexOf("/");
1295
+ if (slashLastIndex === -1) {
1296
+ return url;
1297
+ }
1298
+ const lastCharIndex = resource.length - 1;
1299
+ if (slashLastIndex === lastCharIndex) {
1300
+ const slashBeforeLastIndex = resource.lastIndexOf("/", slashLastIndex - 1);
1301
+ if (slashBeforeLastIndex === -1) {
1302
+ return url;
1303
+ }
1304
+ return "file://".concat(resource.slice(0, slashBeforeLastIndex + 1));
1305
+ }
1306
+ return "file://".concat(resource.slice(0, slashLastIndex + 1));
1307
+ }
1308
+ return new URL(url.endsWith("/") ? "../" : "./", url).href;
1309
+ };
1310
+ const isValidUrl = url => {
1311
+ try {
1312
+ // eslint-disable-next-line no-new
1313
+ new URL(url);
1314
+ return true;
1315
+ } catch (_unused) {
1316
+ return false;
1317
+ }
1318
+ };
1319
+
1320
+ const defaultLookupPackageScope = url => {
1321
+ let scopeUrl = asDirectoryUrl(url);
1322
+ while (scopeUrl !== "file:///") {
1323
+ if (scopeUrl.endsWith("node_modules/")) {
1324
+ return null;
1325
+ }
1326
+ const packageJsonUrlObject = new URL("package.json", scopeUrl);
1327
+ if (existsSync(packageJsonUrlObject)) {
1328
+ return scopeUrl;
1329
+ }
1330
+ scopeUrl = getParentUrl(scopeUrl);
1331
+ }
1332
+ return null;
1333
+ };
1334
+
1335
+ const defaultReadPackageJson = packageUrl => {
1336
+ const packageJsonUrl = new URL("package.json", packageUrl);
1337
+ const buffer = readFileSync(packageJsonUrl);
1338
+ const string = String(buffer);
1339
+ try {
1340
+ return JSON.parse(string);
1341
+ } catch (_unused) {
1342
+ throw new Error("Invalid package configuration");
1343
+ }
1344
+ };
1345
+
1346
+ // https://github.com/nodejs/node/blob/0367b5c35ea0f98b323175a4aaa8e651af7a91e7/tools/node_modules/eslint/node_modules/%40babel/core/lib/vendor/import-meta-resolve.js#L2473
1347
+ const createInvalidModuleSpecifierError = (reason, specifier, {
1348
+ parentUrl
1349
+ }) => {
1350
+ const error = new Error("Invalid module \"".concat(specifier, "\" ").concat(reason, " imported from ").concat(fileURLToPath(parentUrl)));
1351
+ error.code = "INVALID_MODULE_SPECIFIER";
1352
+ return error;
1353
+ };
1354
+ const createInvalidPackageTargetError = (reason, target, {
1355
+ parentUrl,
1356
+ packageDirectoryUrl,
1357
+ key,
1358
+ isImport
1359
+ }) => {
1360
+ let message;
1361
+ if (key === ".") {
1362
+ message = "Invalid \"exports\" main target defined in ".concat(fileURLToPath(packageDirectoryUrl), "package.json imported from ").concat(fileURLToPath(parentUrl), "; ").concat(reason);
1363
+ } else {
1364
+ message = "Invalid \"".concat(isImport ? "imports" : "exports", "\" target ").concat(JSON.stringify(target), " defined for \"").concat(key, "\" in ").concat(fileURLToPath(packageDirectoryUrl), "package.json imported from ").concat(fileURLToPath(parentUrl), "; ").concat(reason);
1365
+ }
1366
+ const error = new Error(message);
1367
+ error.code = "INVALID_PACKAGE_TARGET";
1368
+ return error;
1369
+ };
1370
+ const createPackagePathNotExportedError = (subpath, {
1371
+ parentUrl,
1372
+ packageDirectoryUrl
1373
+ }) => {
1374
+ let message;
1375
+ if (subpath === ".") {
1376
+ message = "No \"exports\" main defined in ".concat(fileURLToPath(packageDirectoryUrl), "package.json imported from ").concat(fileURLToPath(parentUrl));
1377
+ } else {
1378
+ message = "Package subpath \"".concat(subpath, "\" is not defined by \"exports\" in ").concat(fileURLToPath(packageDirectoryUrl), "package.json imported from ").concat(fileURLToPath(parentUrl));
1379
+ }
1380
+ const error = new Error(message);
1381
+ error.code = "PACKAGE_PATH_NOT_EXPORTED";
1382
+ return error;
1383
+ };
1384
+ const createModuleNotFoundError = (specifier, {
1385
+ parentUrl
1386
+ }) => {
1387
+ const error = new Error("Cannot find \"".concat(specifier, "\" imported from ").concat(fileURLToPath(parentUrl)));
1388
+ error.code = "MODULE_NOT_FOUND";
1389
+ return error;
1390
+ };
1391
+ const createPackageImportNotDefinedError = (specifier, {
1392
+ parentUrl,
1393
+ packageDirectoryUrl
1394
+ }) => {
1395
+ const error = new Error("Package import specifier \"".concat(specifier, "\" is not defined in ").concat(fileURLToPath(packageDirectoryUrl), "package.json imported from ").concat(fileURLToPath(parentUrl)));
1396
+ error.code = "PACKAGE_IMPORT_NOT_DEFINED";
1397
+ return error;
1398
+ };
1399
+
1400
+ const isSpecifierForNodeBuiltin = specifier => {
1401
+ return specifier.startsWith("node:") || NODE_BUILTIN_MODULE_SPECIFIERS.includes(specifier);
1402
+ };
1403
+ const NODE_BUILTIN_MODULE_SPECIFIERS = ["assert", "assert/strict", "async_hooks", "buffer_ieee754", "buffer", "child_process", "cluster", "console", "constants", "crypto", "_debugger", "dgram", "dns", "domain", "events", "freelist", "fs", "fs/promises", "_http_agent", "_http_client", "_http_common", "_http_incoming", "_http_outgoing", "_http_server", "http", "http2", "https", "inspector", "_linklist", "module", "net", "node-inspect/lib/_inspect", "node-inspect/lib/internal/inspect_client", "node-inspect/lib/internal/inspect_repl", "os", "path", "perf_hooks", "process", "punycode", "querystring", "readline", "repl", "smalloc", "_stream_duplex", "_stream_transform", "_stream_wrap", "_stream_passthrough", "_stream_readable", "_stream_writable", "stream", "stream/promises", "string_decoder", "sys", "timers", "_tls_common", "_tls_legacy", "_tls_wrap", "tls", "trace_events", "tty", "url", "util", "v8/tools/arguments", "v8/tools/codemap", "v8/tools/consarray", "v8/tools/csvparser", "v8/tools/logreader", "v8/tools/profile_view", "v8/tools/splaytree", "v8", "vm", "worker_threads", "zlib",
1404
+ // global is special
1405
+ "global"];
1406
+
1407
+ /*
1408
+ * https://nodejs.org/api/esm.html#resolver-algorithm-specification
1409
+ * https://github.com/nodejs/node/blob/0367b5c35ea0f98b323175a4aaa8e651af7a91e7/lib/internal/modules/esm/resolve.js#L1
1410
+ * deviations from the spec:
1411
+ * - take into account "browser", "module" and "jsnext"
1412
+ * - the check for isDirectory -> throw is delayed is descoped to the caller
1413
+ * - the call to real path ->
1414
+ * delayed to the caller so that we can decide to
1415
+ * maintain symlink as facade url when it's outside project directory
1416
+ * or use the real path when inside
1417
+ */
1418
+ const applyNodeEsmResolution = ({
1419
+ specifier,
1420
+ parentUrl,
1421
+ conditions = [...readCustomConditionsFromProcessArgs(), "node", "import"],
1422
+ lookupPackageScope = defaultLookupPackageScope,
1423
+ readPackageJson = defaultReadPackageJson,
1424
+ preservesSymlink = false
1425
+ }) => {
1426
+ const resolution = applyPackageSpecifierResolution(specifier, {
1427
+ parentUrl: String(parentUrl),
1428
+ conditions,
1429
+ lookupPackageScope,
1430
+ readPackageJson,
1431
+ preservesSymlink
1432
+ });
1433
+ const {
1434
+ url
1435
+ } = resolution;
1436
+ if (url.startsWith("file:")) {
1437
+ if (url.includes("%2F") || url.includes("%5C")) {
1438
+ throw createInvalidModuleSpecifierError("must not include encoded \"/\" or \"\\\" characters", specifier, {
1439
+ parentUrl
1440
+ });
1441
+ }
1442
+ return resolution;
1443
+ }
1444
+ return resolution;
1445
+ };
1446
+ const applyPackageSpecifierResolution = (specifier, resolutionContext) => {
1447
+ const {
1448
+ parentUrl
1449
+ } = resolutionContext;
1450
+ // relative specifier
1451
+ if (specifier[0] === "/" || specifier.startsWith("./") || specifier.startsWith("../")) {
1452
+ if (specifier[0] !== "/") {
1453
+ const browserFieldResolution = applyBrowserFieldResolution(specifier, resolutionContext);
1454
+ if (browserFieldResolution) {
1455
+ return browserFieldResolution;
1456
+ }
1457
+ }
1458
+ return {
1459
+ type: "relative_specifier",
1460
+ url: new URL(specifier, parentUrl).href
1461
+ };
1462
+ }
1463
+ if (specifier[0] === "#") {
1464
+ return applyPackageImportsResolution(specifier, resolutionContext);
1465
+ }
1466
+ try {
1467
+ const urlObject = new URL(specifier);
1468
+ if (specifier.startsWith("node:")) {
1469
+ return {
1470
+ type: "node_builtin_specifier",
1471
+ url: specifier
1472
+ };
1473
+ }
1474
+ return {
1475
+ type: "absolute_specifier",
1476
+ url: urlObject.href
1477
+ };
1478
+ } catch (_unused) {
1479
+ // bare specifier
1480
+ const browserFieldResolution = applyBrowserFieldResolution(specifier, resolutionContext);
1481
+ if (browserFieldResolution) {
1482
+ return browserFieldResolution;
1483
+ }
1484
+ const packageResolution = applyPackageResolve(specifier, resolutionContext);
1485
+ const search = new URL(specifier, "file:///").search;
1486
+ if (search && !new URL(packageResolution.url).search) {
1487
+ packageResolution.url = "".concat(packageResolution.url).concat(search);
1488
+ }
1489
+ return packageResolution;
1490
+ }
1491
+ };
1492
+ const applyBrowserFieldResolution = (specifier, resolutionContext) => {
1493
+ const {
1494
+ parentUrl,
1495
+ conditions,
1496
+ lookupPackageScope,
1497
+ readPackageJson
1498
+ } = resolutionContext;
1499
+ const browserCondition = conditions.includes("browser");
1500
+ if (!browserCondition) {
1501
+ return null;
1502
+ }
1503
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
1504
+ if (!packageDirectoryUrl) {
1505
+ return null;
1506
+ }
1507
+ const packageJson = readPackageJson(packageDirectoryUrl);
1508
+ if (!packageJson) {
1509
+ return null;
1510
+ }
1511
+ const {
1512
+ browser
1513
+ } = packageJson;
1514
+ if (!browser) {
1515
+ return null;
1516
+ }
1517
+ if (typeof browser !== "object") {
1518
+ return null;
1519
+ }
1520
+ let url;
1521
+ if (specifier.startsWith(".")) {
1522
+ const specifierUrl = new URL(specifier, parentUrl).href;
1523
+ const specifierRelativeUrl = specifierUrl.slice(packageDirectoryUrl.length);
1524
+ const secifierRelativeNotation = "./".concat(specifierRelativeUrl);
1525
+ const browserMapping = browser[secifierRelativeNotation];
1526
+ if (typeof browserMapping === "string") {
1527
+ url = new URL(browserMapping, packageDirectoryUrl).href;
1528
+ } else if (browserMapping === false) {
1529
+ url = "file:///@ignore/".concat(specifierUrl.slice("file:///"));
1530
+ }
1531
+ } else {
1532
+ const browserMapping = browser[specifier];
1533
+ if (typeof browserMapping === "string") {
1534
+ url = new URL(browserMapping, packageDirectoryUrl).href;
1535
+ } else if (browserMapping === false) {
1536
+ url = "file:///@ignore/".concat(specifier);
1537
+ }
1538
+ }
1539
+ if (url) {
1540
+ return {
1541
+ type: "field:browser",
1542
+ packageDirectoryUrl,
1543
+ packageJson,
1544
+ url
1545
+ };
1546
+ }
1547
+ return null;
1548
+ };
1549
+ const applyPackageImportsResolution = (internalSpecifier, resolutionContext) => {
1550
+ const {
1551
+ parentUrl,
1552
+ lookupPackageScope,
1553
+ readPackageJson
1554
+ } = resolutionContext;
1555
+ if (internalSpecifier === "#" || internalSpecifier.startsWith("#/")) {
1556
+ throw createInvalidModuleSpecifierError("not a valid internal imports specifier name", internalSpecifier, resolutionContext);
1557
+ }
1558
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
1559
+ if (packageDirectoryUrl !== null) {
1560
+ const packageJson = readPackageJson(packageDirectoryUrl);
1561
+ const {
1562
+ imports
1563
+ } = packageJson;
1564
+ if (imports !== null && typeof imports === "object") {
1565
+ const resolved = applyPackageImportsExportsResolution(internalSpecifier, {
1566
+ ...resolutionContext,
1567
+ packageDirectoryUrl,
1568
+ packageJson,
1569
+ isImport: true
1570
+ });
1571
+ if (resolved) {
1572
+ return resolved;
1573
+ }
1574
+ }
1575
+ }
1576
+ throw createPackageImportNotDefinedError(internalSpecifier, {
1577
+ ...resolutionContext,
1578
+ packageDirectoryUrl
1579
+ });
1580
+ };
1581
+ const applyPackageResolve = (packageSpecifier, resolutionContext) => {
1582
+ const {
1583
+ parentUrl,
1584
+ conditions,
1585
+ readPackageJson,
1586
+ preservesSymlink
1587
+ } = resolutionContext;
1588
+ if (packageSpecifier === "") {
1589
+ throw new Error("invalid module specifier");
1590
+ }
1591
+ if (conditions.includes("node") && isSpecifierForNodeBuiltin(packageSpecifier)) {
1592
+ return {
1593
+ type: "node_builtin_specifier",
1594
+ url: "node:".concat(packageSpecifier)
1595
+ };
1596
+ }
1597
+ let {
1598
+ packageName,
1599
+ packageSubpath
1600
+ } = parsePackageSpecifier(packageSpecifier);
1601
+ if (packageName[0] === "." || packageName.includes("\\") || packageName.includes("%")) {
1602
+ throw createInvalidModuleSpecifierError("is not a valid package name", packageName, resolutionContext);
1603
+ }
1604
+ if (packageSubpath.endsWith("/")) {
1605
+ throw new Error("invalid module specifier");
1606
+ }
1607
+ const questionCharIndex = packageName.indexOf("?");
1608
+ if (questionCharIndex > -1) {
1609
+ packageName = packageName.slice(0, questionCharIndex);
1610
+ }
1611
+ const selfResolution = applyPackageSelfResolution(packageSubpath, {
1612
+ ...resolutionContext,
1613
+ packageName
1614
+ });
1615
+ if (selfResolution) {
1616
+ return selfResolution;
1617
+ }
1618
+ let currentUrl = parentUrl;
1619
+ while (currentUrl !== "file:///") {
1620
+ const packageDirectoryFacadeUrl = new URL("node_modules/".concat(packageName, "/"), currentUrl).href;
1621
+ if (!existsSync(new URL(packageDirectoryFacadeUrl))) {
1622
+ currentUrl = getParentUrl(currentUrl);
1623
+ continue;
1624
+ }
1625
+ const packageDirectoryUrl = preservesSymlink ? packageDirectoryFacadeUrl : resolvePackageSymlink(packageDirectoryFacadeUrl);
1626
+ const packageJson = readPackageJson(packageDirectoryUrl);
1627
+ if (packageJson !== null) {
1628
+ const {
1629
+ exports
1630
+ } = packageJson;
1631
+ if (exports !== null && exports !== undefined) {
1632
+ return applyPackageExportsResolution(packageSubpath, {
1633
+ ...resolutionContext,
1634
+ packageDirectoryUrl,
1635
+ packageJson,
1636
+ exports
1637
+ });
1638
+ }
1639
+ }
1640
+ return applyLegacySubpathResolution(packageSubpath, {
1641
+ ...resolutionContext,
1642
+ packageDirectoryUrl,
1643
+ packageJson
1644
+ });
1645
+ }
1646
+ throw createModuleNotFoundError(packageName, resolutionContext);
1647
+ };
1648
+ const applyPackageSelfResolution = (packageSubpath, resolutionContext) => {
1649
+ const {
1650
+ parentUrl,
1651
+ packageName,
1652
+ lookupPackageScope,
1653
+ readPackageJson
1654
+ } = resolutionContext;
1655
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
1656
+ if (!packageDirectoryUrl) {
1657
+ return undefined;
1658
+ }
1659
+ const packageJson = readPackageJson(packageDirectoryUrl);
1660
+ if (!packageJson) {
1661
+ return undefined;
1662
+ }
1663
+ if (packageJson.name !== packageName) {
1664
+ return undefined;
1665
+ }
1666
+ const {
1667
+ exports
1668
+ } = packageJson;
1669
+ if (!exports) {
1670
+ const subpathResolution = applyLegacySubpathResolution(packageSubpath, {
1671
+ ...resolutionContext,
1672
+ packageDirectoryUrl,
1673
+ packageJson
1674
+ });
1675
+ if (subpathResolution && subpathResolution.type !== "subpath") {
1676
+ return subpathResolution;
1677
+ }
1678
+ return undefined;
1679
+ }
1680
+ return applyPackageExportsResolution(packageSubpath, {
1681
+ ...resolutionContext,
1682
+ packageDirectoryUrl,
1683
+ packageJson
1684
+ });
1685
+ };
1686
+
1687
+ // https://github.com/nodejs/node/blob/0367b5c35ea0f98b323175a4aaa8e651af7a91e7/lib/internal/modules/esm/resolve.js#L642
1688
+ const applyPackageExportsResolution = (packageSubpath, resolutionContext) => {
1689
+ if (packageSubpath === ".") {
1690
+ const mainExport = applyMainExportResolution(resolutionContext);
1691
+ if (!mainExport) {
1692
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
1693
+ }
1694
+ const resolved = applyPackageTargetResolution(mainExport, {
1695
+ ...resolutionContext,
1696
+ key: "."
1697
+ });
1698
+ if (resolved) {
1699
+ return resolved;
1700
+ }
1701
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
1702
+ }
1703
+ const packageExportsInfo = readExports(resolutionContext);
1704
+ if (packageExportsInfo.type === "object" && packageExportsInfo.allKeysAreRelative) {
1705
+ const resolved = applyPackageImportsExportsResolution(packageSubpath, {
1706
+ ...resolutionContext,
1707
+ isImport: false
1708
+ });
1709
+ if (resolved) {
1710
+ return resolved;
1711
+ }
1712
+ }
1713
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
1714
+ };
1715
+ const applyPackageImportsExportsResolution = (matchKey, resolutionContext) => {
1716
+ const {
1717
+ packageJson,
1718
+ isImport
1719
+ } = resolutionContext;
1720
+ const matchObject = isImport ? packageJson.imports : packageJson.exports;
1721
+ if (!matchKey.includes("*") && matchObject.hasOwnProperty(matchKey)) {
1722
+ const target = matchObject[matchKey];
1723
+ return applyPackageTargetResolution(target, {
1724
+ ...resolutionContext,
1725
+ key: matchKey,
1726
+ isImport
1727
+ });
1728
+ }
1729
+ const expansionKeys = Object.keys(matchObject).filter(key => key.split("*").length === 2).sort(comparePatternKeys);
1730
+ for (const expansionKey of expansionKeys) {
1731
+ const [patternBase, patternTrailer] = expansionKey.split("*");
1732
+ if (matchKey === patternBase) continue;
1733
+ if (!matchKey.startsWith(patternBase)) continue;
1734
+ if (patternTrailer.length > 0) {
1735
+ if (!matchKey.endsWith(patternTrailer)) continue;
1736
+ if (matchKey.length < expansionKey.length) continue;
1737
+ }
1738
+ const target = matchObject[expansionKey];
1739
+ const subpath = matchKey.slice(patternBase.length, matchKey.length - patternTrailer.length);
1740
+ return applyPackageTargetResolution(target, {
1741
+ ...resolutionContext,
1742
+ key: matchKey,
1743
+ subpath,
1744
+ pattern: true,
1745
+ isImport
1746
+ });
1747
+ }
1748
+ return null;
1749
+ };
1750
+ const applyPackageTargetResolution = (target, resolutionContext) => {
1751
+ const {
1752
+ conditions,
1753
+ packageDirectoryUrl,
1754
+ packageJson,
1755
+ key,
1756
+ subpath = "",
1757
+ pattern = false,
1758
+ isImport = false
1759
+ } = resolutionContext;
1760
+ if (typeof target === "string") {
1761
+ if (pattern === false && subpath !== "" && !target.endsWith("/")) {
1762
+ throw new Error("invalid module specifier");
1763
+ }
1764
+ if (target.startsWith("./")) {
1765
+ const targetUrl = new URL(target, packageDirectoryUrl).href;
1766
+ if (!targetUrl.startsWith(packageDirectoryUrl)) {
1767
+ throw createInvalidPackageTargetError("target must be inside package", target, resolutionContext);
1768
+ }
1769
+ return {
1770
+ type: isImport ? "field:imports" : "field:exports",
1771
+ packageDirectoryUrl,
1772
+ packageJson,
1773
+ url: pattern ? targetUrl.replaceAll("*", subpath) : new URL(subpath, targetUrl).href
1774
+ };
1775
+ }
1776
+ if (!isImport || target.startsWith("../") || isValidUrl(target)) {
1777
+ throw createInvalidPackageTargetError("target must starst with \"./\"", target, resolutionContext);
1778
+ }
1779
+ return applyPackageResolve(pattern ? target.replaceAll("*", subpath) : "".concat(target).concat(subpath), {
1780
+ ...resolutionContext,
1781
+ parentUrl: packageDirectoryUrl
1782
+ });
1783
+ }
1784
+ if (Array.isArray(target)) {
1785
+ if (target.length === 0) {
1786
+ return null;
1787
+ }
1788
+ let lastResult;
1789
+ let i = 0;
1790
+ while (i < target.length) {
1791
+ const targetValue = target[i];
1792
+ i++;
1793
+ try {
1794
+ const resolved = applyPackageTargetResolution(targetValue, {
1795
+ ...resolutionContext,
1796
+ key: "".concat(key, "[").concat(i, "]"),
1797
+ subpath,
1798
+ pattern,
1799
+ isImport
1800
+ });
1801
+ if (resolved) {
1802
+ return resolved;
1803
+ }
1804
+ lastResult = resolved;
1805
+ } catch (e) {
1806
+ if (e.code === "INVALID_PACKAGE_TARGET") {
1807
+ continue;
1808
+ }
1809
+ lastResult = e;
1810
+ }
1811
+ }
1812
+ if (lastResult) {
1813
+ throw lastResult;
1814
+ }
1815
+ return null;
1816
+ }
1817
+ if (target === null) {
1818
+ return null;
1819
+ }
1820
+ if (typeof target === "object") {
1821
+ const keys = Object.keys(target);
1822
+ for (const key of keys) {
1823
+ if (Number.isInteger(key)) {
1824
+ throw new Error("Invalid package configuration");
1825
+ }
1826
+ if (key === "default" || conditions.includes(key)) {
1827
+ const targetValue = target[key];
1828
+ const resolved = applyPackageTargetResolution(targetValue, {
1829
+ ...resolutionContext,
1830
+ key,
1831
+ subpath,
1832
+ pattern,
1833
+ isImport
1834
+ });
1835
+ if (resolved) {
1836
+ return resolved;
1837
+ }
1838
+ }
1839
+ }
1840
+ return null;
1841
+ }
1842
+ throw createInvalidPackageTargetError("target must be a string, array, object or null", target, resolutionContext);
1843
+ };
1844
+ const readExports = ({
1845
+ packageDirectoryUrl,
1846
+ packageJson
1847
+ }) => {
1848
+ const packageExports = packageJson.exports;
1849
+ if (Array.isArray(packageExports)) {
1850
+ return {
1851
+ type: "array"
1852
+ };
1853
+ }
1854
+ if (packageExports === null) {
1855
+ return {};
1856
+ }
1857
+ if (typeof packageExports === "object") {
1858
+ const keys = Object.keys(packageExports);
1859
+ const relativeKeys = [];
1860
+ const conditionalKeys = [];
1861
+ keys.forEach(availableKey => {
1862
+ if (availableKey.startsWith(".")) {
1863
+ relativeKeys.push(availableKey);
1864
+ } else {
1865
+ conditionalKeys.push(availableKey);
1866
+ }
1867
+ });
1868
+ const hasRelativeKey = relativeKeys.length > 0;
1869
+ if (hasRelativeKey && conditionalKeys.length > 0) {
1870
+ throw new Error("Invalid package configuration: cannot mix relative and conditional keys in package.exports\n--- unexpected keys ---\n".concat(conditionalKeys.map(key => "\"".concat(key, "\"")).join("\n"), "\n--- package directory url ---\n").concat(packageDirectoryUrl));
1871
+ }
1872
+ return {
1873
+ type: "object",
1874
+ hasRelativeKey,
1875
+ allKeysAreRelative: relativeKeys.length === keys.length
1876
+ };
1877
+ }
1878
+ if (typeof packageExports === "string") {
1879
+ return {
1880
+ type: "string"
1881
+ };
1882
+ }
1883
+ return {};
1884
+ };
1885
+ const parsePackageSpecifier = packageSpecifier => {
1886
+ if (packageSpecifier[0] === "@") {
1887
+ const firstSlashIndex = packageSpecifier.indexOf("/");
1888
+ if (firstSlashIndex === -1) {
1889
+ throw new Error("invalid module specifier");
1890
+ }
1891
+ const secondSlashIndex = packageSpecifier.indexOf("/", firstSlashIndex + 1);
1892
+ if (secondSlashIndex === -1) {
1893
+ return {
1894
+ packageName: packageSpecifier,
1895
+ packageSubpath: ".",
1896
+ isScoped: true
1897
+ };
1898
+ }
1899
+ const packageName = packageSpecifier.slice(0, secondSlashIndex);
1900
+ const afterSecondSlash = packageSpecifier.slice(secondSlashIndex + 1);
1901
+ const packageSubpath = "./".concat(afterSecondSlash);
1902
+ return {
1903
+ packageName,
1904
+ packageSubpath,
1905
+ isScoped: true
1906
+ };
1907
+ }
1908
+ const firstSlashIndex = packageSpecifier.indexOf("/");
1909
+ if (firstSlashIndex === -1) {
1910
+ return {
1911
+ packageName: packageSpecifier,
1912
+ packageSubpath: "."
1913
+ };
1914
+ }
1915
+ const packageName = packageSpecifier.slice(0, firstSlashIndex);
1916
+ const afterFirstSlash = packageSpecifier.slice(firstSlashIndex + 1);
1917
+ const packageSubpath = "./".concat(afterFirstSlash);
1918
+ return {
1919
+ packageName,
1920
+ packageSubpath
1921
+ };
1922
+ };
1923
+ const applyMainExportResolution = resolutionContext => {
1924
+ const {
1925
+ packageJson
1926
+ } = resolutionContext;
1927
+ const packageExportsInfo = readExports(resolutionContext);
1928
+ if (packageExportsInfo.type === "array" || packageExportsInfo.type === "string") {
1929
+ return packageJson.exports;
1930
+ }
1931
+ if (packageExportsInfo.type === "object") {
1932
+ if (packageExportsInfo.hasRelativeKey) {
1933
+ return packageJson.exports["."];
1934
+ }
1935
+ return packageJson.exports;
1936
+ }
1937
+ return undefined;
1938
+ };
1939
+ const applyLegacySubpathResolution = (packageSubpath, resolutionContext) => {
1940
+ const {
1941
+ packageDirectoryUrl,
1942
+ packageJson
1943
+ } = resolutionContext;
1944
+ if (packageSubpath === ".") {
1945
+ return applyLegacyMainResolution(packageSubpath, resolutionContext);
1946
+ }
1947
+ const browserFieldResolution = applyBrowserFieldResolution(packageSubpath, resolutionContext);
1948
+ if (browserFieldResolution) {
1949
+ return browserFieldResolution;
1950
+ }
1951
+ return {
1952
+ type: "subpath",
1953
+ packageDirectoryUrl,
1954
+ packageJson,
1955
+ url: new URL(packageSubpath, packageDirectoryUrl).href
1956
+ };
1957
+ };
1958
+ const applyLegacyMainResolution = (packageSubpath, resolutionContext) => {
1959
+ const {
1960
+ conditions,
1961
+ packageDirectoryUrl,
1962
+ packageJson
1963
+ } = resolutionContext;
1964
+ for (const condition of conditions) {
1965
+ const conditionResolver = mainLegacyResolvers[condition];
1966
+ if (!conditionResolver) {
1967
+ continue;
1968
+ }
1969
+ const resolved = conditionResolver(resolutionContext);
1970
+ if (resolved) {
1971
+ return {
1972
+ type: resolved.type,
1973
+ packageDirectoryUrl,
1974
+ packageJson,
1975
+ url: new URL(resolved.path, packageDirectoryUrl).href
1976
+ };
1977
+ }
1978
+ }
1979
+ return {
1980
+ type: "field:main",
1981
+ // the absence of "main" field
1982
+ packageDirectoryUrl,
1983
+ packageJson,
1984
+ url: new URL("index.js", packageDirectoryUrl).href
1985
+ };
1986
+ };
1987
+ const mainLegacyResolvers = {
1988
+ import: ({
1989
+ packageJson
1990
+ }) => {
1991
+ if (typeof packageJson.module === "string") {
1992
+ return {
1993
+ type: "field:module",
1994
+ path: packageJson.module
1995
+ };
1996
+ }
1997
+ if (typeof packageJson.jsnext === "string") {
1998
+ return {
1999
+ type: "field:jsnext",
2000
+ path: packageJson.jsnext
2001
+ };
2002
+ }
2003
+ if (typeof packageJson.main === "string") {
2004
+ return {
2005
+ type: "field:main",
2006
+ path: packageJson.main
2007
+ };
2008
+ }
2009
+ return null;
2010
+ },
2011
+ browser: ({
2012
+ packageDirectoryUrl,
2013
+ packageJson
2014
+ }) => {
2015
+ const browserMain = (() => {
2016
+ if (typeof packageJson.browser === "string") {
2017
+ return packageJson.browser;
2018
+ }
2019
+ if (typeof packageJson.browser === "object" && packageJson.browser !== null) {
2020
+ return packageJson.browser["."];
2021
+ }
2022
+ return "";
2023
+ })();
2024
+ if (!browserMain) {
2025
+ if (typeof packageJson.module === "string") {
2026
+ return {
2027
+ type: "field:module",
2028
+ path: packageJson.module
2029
+ };
2030
+ }
2031
+ return null;
2032
+ }
2033
+ if (typeof packageJson.module !== "string" || packageJson.module === browserMain) {
2034
+ return {
2035
+ type: "field:browser",
2036
+ path: browserMain
2037
+ };
2038
+ }
2039
+ const browserMainUrlObject = new URL(browserMain, packageDirectoryUrl);
2040
+ const content = readFileSync(browserMainUrlObject, "utf-8");
2041
+ if (/typeof exports\s*==/.test(content) && /typeof module\s*==/.test(content) || /module\.exports\s*=/.test(content)) {
2042
+ return {
2043
+ type: "field:module",
2044
+ path: packageJson.module
2045
+ };
2046
+ }
2047
+ return {
2048
+ type: "field:browser",
2049
+ path: browserMain
2050
+ };
2051
+ },
2052
+ node: ({
2053
+ packageJson
2054
+ }) => {
2055
+ if (typeof packageJson.main === "string") {
2056
+ return {
2057
+ type: "field:main",
2058
+ path: packageJson.main
2059
+ };
2060
+ }
2061
+ return null;
2062
+ }
2063
+ };
2064
+ const comparePatternKeys = (keyA, keyB) => {
2065
+ if (!keyA.endsWith("/") && !keyA.includes("*")) {
2066
+ throw new Error("Invalid package configuration");
2067
+ }
2068
+ if (!keyB.endsWith("/") && !keyB.includes("*")) {
2069
+ throw new Error("Invalid package configuration");
2070
+ }
2071
+ const aStarIndex = keyA.indexOf("*");
2072
+ const baseLengthA = aStarIndex > -1 ? aStarIndex + 1 : keyA.length;
2073
+ const bStarIndex = keyB.indexOf("*");
2074
+ const baseLengthB = bStarIndex > -1 ? bStarIndex + 1 : keyB.length;
2075
+ if (baseLengthA > baseLengthB) {
2076
+ return -1;
2077
+ }
2078
+ if (baseLengthB > baseLengthA) {
2079
+ return 1;
2080
+ }
2081
+ if (aStarIndex === -1) {
2082
+ return 1;
2083
+ }
2084
+ if (bStarIndex === -1) {
2085
+ return -1;
2086
+ }
2087
+ if (keyA.length > keyB.length) {
2088
+ return -1;
2089
+ }
2090
+ if (keyB.length > keyA.length) {
2091
+ return 1;
2092
+ }
2093
+ return 0;
2094
+ };
2095
+ const resolvePackageSymlink = packageDirectoryUrl => {
2096
+ const packageDirectoryPath = realpathSync(new URL(packageDirectoryUrl));
2097
+ const packageDirectoryResolvedUrl = pathToFileURL(packageDirectoryPath).href;
2098
+ return "".concat(packageDirectoryResolvedUrl, "/");
2099
+ };
2100
+
2101
+ process.platform === "win32";
2102
+ fileSystemPathToUrl(process.cwd());
2103
+
2104
+ /*
2105
+ * - stats object documentation on Node.js
2106
+ * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
2107
+ */
2108
+
2109
+ process.platform === "win32";
2110
+
2111
+ /*
2112
+ * - stats object documentation on Node.js
2113
+ * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
2114
+ */
2115
+
2116
+ process.platform === "win32";
2117
+
2118
+ process.platform === "win32";
2119
+
2120
+ process.platform === "win32";
2121
+
2122
+ process.platform === "win32";
2123
+
2124
+ process.platform === "linux";
2125
+
1219
2126
  /*
1220
2127
  * This plugin provides a way for jsenv to supervisor js execution:
1221
2128
  * - Know how many js are executed, when they are done, collect errors, etc...
@@ -1347,6 +2254,14 @@ const jsenvPluginSupervisor = ({
1347
2254
  body: "Missing file in url"
1348
2255
  };
1349
2256
  }
2257
+ const {
2258
+ url
2259
+ } = applyNodeEsmResolution({
2260
+ conditions: [],
2261
+ parentUrl: serveInfo.rootDirectoryUrl,
2262
+ specifier: file
2263
+ });
2264
+ file = url;
1350
2265
  const getErrorCauseInfo = () => {
1351
2266
  const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
1352
2267
  if (!urlInfo) {
@@ -1396,7 +2311,7 @@ const jsenvPluginSupervisor = ({
1396
2311
  };
1397
2312
  }
1398
2313
  const fileUrl = new URL(file, serveInfo.rootDirectoryUrl);
1399
- const filePath = fileURLToPath(fileUrl);
2314
+ const filePath = urlToFileSystemPath(fileUrl);
1400
2315
  const require = createRequire(import.meta.url);
1401
2316
  const launch = require("launch-editor");
1402
2317
  launch(filePath, () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/plugin-supervisor",
3
- "version": "1.5.27",
3
+ "version": "1.5.29",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,9 +26,9 @@
26
26
  "/dist/"
27
27
  ],
28
28
  "dependencies": {
29
- "@jsenv/ast": "6.3.5",
30
- "@jsenv/urls": "2.5.2",
31
- "@jsenv/sourcemap": "1.2.25",
29
+ "@jsenv/ast": "6.3.6",
30
+ "@jsenv/urls": "2.5.3",
31
+ "@jsenv/sourcemap": "1.2.26",
32
32
  "launch-editor": "2.9.1"
33
33
  },
34
34
  "scripts": {
@@ -4,10 +4,10 @@
4
4
  */
5
5
 
6
6
  import { generateContentFrame } from "@jsenv/humanize";
7
+ import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
7
8
  import { getOriginalPosition } from "@jsenv/sourcemap";
8
- import { injectQueryParams } from "@jsenv/urls";
9
+ import { injectQueryParams, urlToFileSystemPath } from "@jsenv/urls";
9
10
  import { createRequire } from "node:module";
10
- import { fileURLToPath } from "node:url";
11
11
  import {
12
12
  injectSupervisorIntoHTML,
13
13
  supervisorFileUrl,
@@ -147,6 +147,12 @@ export const jsenvPluginSupervisor = ({
147
147
  body: "Missing file in url",
148
148
  };
149
149
  }
150
+ const { url } = applyNodeEsmResolution({
151
+ conditions: [],
152
+ parentUrl: serveInfo.rootDirectoryUrl,
153
+ specifier: file,
154
+ });
155
+ file = url;
150
156
  const getErrorCauseInfo = () => {
151
157
  const urlInfo = serveInfo.kitchen.graph.getUrlInfo(file);
152
158
  if (!urlInfo) {
@@ -205,7 +211,7 @@ export const jsenvPluginSupervisor = ({
205
211
  };
206
212
  }
207
213
  const fileUrl = new URL(file, serveInfo.rootDirectoryUrl);
208
- const filePath = fileURLToPath(fileUrl);
214
+ const filePath = urlToFileSystemPath(fileUrl);
209
215
  const require = createRequire(import.meta.url);
210
216
  const launch = require("launch-editor");
211
217
  launch(filePath, () => {