@jsenv/core 39.5.24 → 39.5.26

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,7 +3,7 @@ import os, { networkInterfaces } from "node:os";
3
3
  import tty from "node:tty";
4
4
  import stringWidth from "string-width";
5
5
  import { pathToFileURL, fileURLToPath } from "node:url";
6
- import { readdir, chmod, stat, lstat, promises, readFileSync, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, watch, readdirSync, statSync, createReadStream, lstatSync, readFile, existsSync, realpathSync } from "node:fs";
6
+ import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFileSync, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, watch, readdirSync, createReadStream, readFile, existsSync, realpathSync } from "node:fs";
7
7
  import { extname } from "node:path";
8
8
  import crypto, { createHash } from "node:crypto";
9
9
  import cluster from "node:cluster";
@@ -988,7 +988,7 @@ platform === 'Android'
988
988
  const ESC = '\u001B[';
989
989
 
990
990
  !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
991
- const isWindows$3 = !isBrowser && process$1.platform === 'win32';
991
+ const isWindows$4 = !isBrowser && process$1.platform === 'win32';
992
992
 
993
993
  isBrowser ? () => {
994
994
  throw new Error('`process.cwd()` only works in Node.js, not the browser.');
@@ -1014,7 +1014,7 @@ const eraseLines = count => {
1014
1014
  const eraseLine = ESC + '2K';
1015
1015
  const eraseScreen = ESC + '2J';
1016
1016
 
1017
- const clearTerminal = isWindows$3
1017
+ const clearTerminal = isWindows$4
1018
1018
  ? `${eraseScreen}${ESC}0f`
1019
1019
  // 1. Erases the screen (Only done in case `2` is not supported)
1020
1020
  // 2. Erases the whole screen including scrollback buffer
@@ -1808,13 +1808,27 @@ const urlIsInsideOf = (url, otherUrl) => {
1808
1808
  };
1809
1809
 
1810
1810
  const urlToFileSystemPath = (url) => {
1811
- let urlString = String(url);
1812
- if (urlString[urlString.length - 1] === "/") {
1811
+ const urlObject = new URL(url);
1812
+ let { origin, pathname, hash } = urlObject;
1813
+ if (urlObject.protocol === "file:") {
1814
+ origin = "file://";
1815
+ }
1816
+ pathname = pathname
1817
+ .split("/")
1818
+ .map((part) => {
1819
+ return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
1820
+ })
1821
+ .join("/");
1822
+ if (hash) {
1823
+ pathname += `%23${encodeURIComponent(hash.slice(1))}`;
1824
+ }
1825
+ const urlString = `${origin}${pathname}`;
1826
+ const fileSystemPath = fileURLToPath(urlString);
1827
+ if (fileSystemPath[fileSystemPath.length - 1] === "/") {
1813
1828
  // remove trailing / so that nodejs path becomes predictable otherwise it logs
1814
1829
  // the trailing slash on linux but does not on windows
1815
- urlString = urlString.slice(0, -1);
1830
+ return fileSystemPath.slice(0, -1);
1816
1831
  }
1817
- const fileSystemPath = fileURLToPath(urlString);
1818
1832
  return fileSystemPath;
1819
1833
  };
1820
1834
 
@@ -1977,7 +1991,7 @@ const comparePathnames = (leftPathame, rightPathname) => {
1977
1991
  return 0;
1978
1992
  };
1979
1993
 
1980
- const isWindows$2 = process.platform === "win32";
1994
+ const isWindows$3 = process.platform === "win32";
1981
1995
  const baseUrlFallback = fileSystemPathToUrl$1(process.cwd());
1982
1996
 
1983
1997
  /**
@@ -2000,7 +2014,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
2000
2014
  throw new Error(`absolute url expect but got ${url}`);
2001
2015
  }
2002
2016
 
2003
- if (!isWindows$2) {
2017
+ if (!isWindows$3) {
2004
2018
  return url;
2005
2019
  }
2006
2020
 
@@ -3165,7 +3179,7 @@ const writeEntryPermissions = async (source, permissions) => {
3165
3179
  */
3166
3180
 
3167
3181
 
3168
- const isWindows$1 = process.platform === "win32";
3182
+ const isWindows$2 = process.platform === "win32";
3169
3183
 
3170
3184
  const readEntryStat = async (
3171
3185
  source,
@@ -3185,7 +3199,7 @@ const readEntryStat = async (
3185
3199
  return readStat(sourcePath, {
3186
3200
  followLink,
3187
3201
  ...handleNotFoundOption,
3188
- ...(isWindows$1
3202
+ ...(isWindows$2
3189
3203
  ? {
3190
3204
  // Windows can EPERM on stat
3191
3205
  handlePermissionDeniedError: async (error) => {
@@ -3250,13 +3264,104 @@ const readStat = (
3250
3264
  });
3251
3265
  };
3252
3266
 
3267
+ const writeEntryPermissionsSync = (source, permissions) => {
3268
+ const sourceUrl = assertAndNormalizeFileUrl(source);
3269
+
3270
+ let binaryFlags;
3271
+ {
3272
+ binaryFlags = permissions;
3273
+ }
3274
+
3275
+ chmodSync(new URL(sourceUrl), binaryFlags);
3276
+ };
3277
+
3253
3278
  /*
3254
3279
  * - stats object documentation on Node.js
3255
3280
  * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
3256
3281
  */
3257
3282
 
3258
3283
 
3259
- process.platform === "win32";
3284
+ const isWindows$1 = process.platform === "win32";
3285
+
3286
+ const readEntryStatSync = (
3287
+ source,
3288
+ { nullIfNotFound = false, followLink = true } = {},
3289
+ ) => {
3290
+ let sourceUrl = assertAndNormalizeFileUrl(source);
3291
+ if (sourceUrl.endsWith("/")) sourceUrl = sourceUrl.slice(0, -1);
3292
+
3293
+ const sourcePath = urlToFileSystemPath(sourceUrl);
3294
+
3295
+ const handleNotFoundOption = nullIfNotFound
3296
+ ? {
3297
+ handleNotFoundError: () => null,
3298
+ }
3299
+ : {};
3300
+
3301
+ return statSyncNaive(sourcePath, {
3302
+ followLink,
3303
+ ...handleNotFoundOption,
3304
+ ...(isWindows$1
3305
+ ? {
3306
+ // Windows can EPERM on stat
3307
+ handlePermissionDeniedError: (error) => {
3308
+ console.error(
3309
+ `trying to fix windows EPERM after stats on ${sourcePath}`,
3310
+ );
3311
+
3312
+ try {
3313
+ // unfortunately it means we mutate the permissions
3314
+ // without being able to restore them to the previous value
3315
+ // (because reading current permission would also throw)
3316
+ writeEntryPermissionsSync(sourceUrl, 0o666);
3317
+ const stats = statSyncNaive(sourcePath, {
3318
+ followLink,
3319
+ ...handleNotFoundOption,
3320
+ // could not fix the permission error, give up and throw original error
3321
+ handlePermissionDeniedError: () => {
3322
+ console.error(`still got EPERM after stats on ${sourcePath}`);
3323
+ throw error;
3324
+ },
3325
+ });
3326
+ return stats;
3327
+ } catch (e) {
3328
+ console.error(
3329
+ `error while trying to fix windows EPERM after stats on ${sourcePath}: ${e.stack}`,
3330
+ );
3331
+ throw error;
3332
+ }
3333
+ },
3334
+ }
3335
+ : {}),
3336
+ });
3337
+ };
3338
+
3339
+ const statSyncNaive = (
3340
+ sourcePath,
3341
+ {
3342
+ followLink,
3343
+ handleNotFoundError = null,
3344
+ handlePermissionDeniedError = null,
3345
+ } = {},
3346
+ ) => {
3347
+ const nodeMethod = followLink ? statSync : lstatSync;
3348
+
3349
+ try {
3350
+ const stats = nodeMethod(sourcePath);
3351
+ return stats;
3352
+ } catch (error) {
3353
+ if (handleNotFoundError && error.code === "ENOENT") {
3354
+ return handleNotFoundError(error);
3355
+ }
3356
+ if (
3357
+ handlePermissionDeniedError &&
3358
+ (error.code === "EPERM" || error.code === "EACCES")
3359
+ ) {
3360
+ return handlePermissionDeniedError(error);
3361
+ }
3362
+ throw error;
3363
+ }
3364
+ };
3260
3365
 
3261
3366
  const statsToType = (stats) => {
3262
3367
  if (stats.isFile()) return "file";
@@ -3958,7 +4063,7 @@ const registerDirectoryLifecycle = (
3958
4063
  try {
3959
4064
  const relativeUrl = urlToRelativeUrl(url, source);
3960
4065
  const previousInfo = infoMap.get(relativeUrl);
3961
- const stat = statSync(new URL(url));
4066
+ const stat = readEntryStatSync(new URL(url));
3962
4067
  const type = statsToType(stat);
3963
4068
  const patternValue = previousInfo
3964
4069
  ? previousInfo.patternValue
@@ -4035,7 +4140,7 @@ const registerDirectoryLifecycle = (
4035
4140
  const removedEntryRelativeUrl = relativeUrlCandidateArray.find(
4036
4141
  (relativeUrlCandidate) => {
4037
4142
  try {
4038
- statSync(new URL(relativeUrlCandidate, sourceUrl));
4143
+ readEntryStatSync(new URL(relativeUrlCandidate, sourceUrl));
4039
4144
  return false;
4040
4145
  } catch (e) {
4041
4146
  if (e.code === "ENOENT") {
@@ -4186,8 +4291,8 @@ const registerDirectoryLifecycle = (
4186
4291
  }
4187
4292
  };
4188
4293
  const handleEntryUpdated = (entryInfo) => {
4189
- infoMap.set(entryInfo.relativeUrl, entryInfo);
4190
4294
  if (updated && entryInfo.patternValue && shouldCallUpdated(entryInfo)) {
4295
+ infoMap.set(entryInfo.relativeUrl, entryInfo);
4191
4296
  updated({
4192
4297
  relativeUrl: entryInfo.relativeUrl,
4193
4298
  type: entryInfo.type,
@@ -8686,7 +8791,7 @@ const bundleCss = async (cssUrlInfos) => {
8686
8791
  },
8687
8792
  resolve(specifier, from) {
8688
8793
  const fileUrlObject = new URL(specifier, pathToFileURL(from));
8689
- const filePath = fileURLToPath(fileUrlObject);
8794
+ const filePath = urlToFileSystemPath(fileUrlObject);
8690
8795
  return filePath;
8691
8796
  },
8692
8797
  },
@@ -8755,7 +8860,7 @@ const minifyCss = async (cssUrlInfo) => {
8755
8860
 
8756
8861
  const targets = runtimeCompatToTargets$1(cssUrlInfo.context.runtimeCompat);
8757
8862
  const { code, map } = transform({
8758
- filename: fileURLToPath(cssUrlInfo.originalUrl),
8863
+ filename: urlToFileSystemPath(cssUrlInfo.originalUrl),
8759
8864
  code: Buffer.from(cssUrlInfo.content),
8760
8865
  targets,
8761
8866
  minify: true,
@@ -10601,7 +10706,7 @@ const applyCssTranspilation = async ({
10601
10706
  const { transform } = await import("lightningcss");
10602
10707
  const targets = runtimeCompatToTargets(runtimeCompat);
10603
10708
  const { code, map } = transform({
10604
- filename: fileURLToPath(inputUrl),
10709
+ filename: urlToFileSystemPath(inputUrl),
10605
10710
  code: Buffer.from(input),
10606
10711
  targets,
10607
10712
  minify: false,
@@ -18276,7 +18381,7 @@ const applyFileSystemMagicResolution = (
18276
18381
 
18277
18382
  if (fileStat === undefined) {
18278
18383
  try {
18279
- fileStat = statSync(new URL(fileUrl));
18384
+ fileStat = readEntryStatSync(new URL(fileUrl));
18280
18385
  } catch (e) {
18281
18386
  if (e.code === "ENOENT") {
18282
18387
  result.lastENOENTError = e;
@@ -18318,7 +18423,7 @@ const applyFileSystemMagicResolution = (
18318
18423
  const urlCandidate = `${parentUrl}${urlFilename}${extensionToTry}`;
18319
18424
  let stat;
18320
18425
  try {
18321
- stat = statSync(new URL(urlCandidate));
18426
+ stat = readEntryStatSync(new URL(urlCandidate));
18322
18427
  } catch (e) {
18323
18428
  if (e.code === "ENOENT") {
18324
18429
  stat = null;
@@ -18679,7 +18784,7 @@ const jsenvPluginFsRedirection = ({
18679
18784
  const urlObject = new URL(reference.url);
18680
18785
  let stat;
18681
18786
  try {
18682
- stat = statSync(urlObject);
18787
+ stat = readEntryStatSync(urlObject);
18683
18788
  } catch (e) {
18684
18789
  if (e.code === "ENOENT") {
18685
18790
  stat = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "39.5.24",
3
+ "version": "39.5.26",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -69,29 +69,29 @@
69
69
  "dependencies": {
70
70
  "@financial-times/polyfill-useragent-normaliser": "1.10.2",
71
71
  "@jsenv/abort": "4.3.0",
72
- "@jsenv/ast": "6.3.5",
73
- "@jsenv/filesystem": "4.10.11",
72
+ "@jsenv/ast": "6.3.7",
73
+ "@jsenv/filesystem": "4.10.13",
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.49",
77
+ "@jsenv/js-module-fallback": "1.3.51",
78
78
  "@jsenv/node-esm-resolution": "1.0.6",
79
- "@jsenv/plugin-bundling": "2.7.16",
80
- "@jsenv/plugin-minification": "1.5.10",
81
- "@jsenv/plugin-supervisor": "1.5.28",
82
- "@jsenv/plugin-transpilation": "1.4.84",
79
+ "@jsenv/plugin-bundling": "2.7.19",
80
+ "@jsenv/plugin-minification": "1.5.11",
81
+ "@jsenv/plugin-supervisor": "1.5.30",
82
+ "@jsenv/plugin-transpilation": "1.4.86",
83
83
  "@jsenv/runtime-compat": "1.3.1",
84
84
  "@jsenv/server": "15.3.3",
85
- "@jsenv/sourcemap": "1.2.25",
85
+ "@jsenv/sourcemap": "1.2.27",
86
86
  "@jsenv/url-meta": "8.5.2",
87
- "@jsenv/urls": "2.5.2",
87
+ "@jsenv/urls": "2.5.4",
88
88
  "@jsenv/utils": "2.1.2",
89
89
  "string-width": "7.2.0"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@babel/plugin-syntax-import-attributes": "7.26.0",
93
93
  "@babel/plugin-syntax-optional-chaining-assign": "7.25.9",
94
- "@eslint/compat": "1.2.2",
94
+ "@eslint/compat": "1.2.3",
95
95
  "@jsenv/assert": "workspace:*",
96
96
  "@jsenv/cli": "workspace:*",
97
97
  "@jsenv/core": "./",
@@ -104,13 +104,13 @@
104
104
  "@jsenv/snapshot": "workspace:*",
105
105
  "@jsenv/md-up": "workspace:*",
106
106
  "@jsenv/test": "workspace:*",
107
- "@playwright/browser-chromium": "1.48.2",
108
- "@playwright/browser-firefox": "1.48.2",
109
- "@playwright/browser-webkit": "1.48.2",
107
+ "@playwright/browser-chromium": "1.49.0",
108
+ "@playwright/browser-firefox": "1.49.0",
109
+ "@playwright/browser-webkit": "1.49.0",
110
110
  "babel-plugin-transform-async-to-promises": "0.8.18",
111
- "eslint": "9.14.0",
111
+ "eslint": "9.15.0",
112
112
  "open": "10.1.0",
113
- "playwright": "1.48.2",
113
+ "playwright": "1.49.0",
114
114
  "prettier": "3.3.3",
115
115
  "prettier-plugin-organize-imports": "4.1.0",
116
116
  "strip-ansi": "7.1.0"
@@ -1,8 +1,9 @@
1
+ import { readEntryStatSync } from "@jsenv/filesystem";
1
2
  import {
2
3
  applyFileSystemMagicResolution,
3
4
  getExtensionsToTry,
4
5
  } from "@jsenv/node-esm-resolution";
5
- import { realpathSync, statSync } from "node:fs";
6
+ import { realpathSync } from "node:fs";
6
7
  import { pathToFileURL } from "node:url";
7
8
 
8
9
  export const jsenvPluginFsRedirection = ({
@@ -39,7 +40,7 @@ export const jsenvPluginFsRedirection = ({
39
40
  const urlObject = new URL(reference.url);
40
41
  let stat;
41
42
  try {
42
- stat = statSync(urlObject);
43
+ stat = readEntryStatSync(urlObject);
43
44
  } catch (e) {
44
45
  if (e.code === "ENOENT") {
45
46
  stat = null;