@jsenv/filesystem 2.6.1 → 2.7.2
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/main.js +1 -0
- package/package.json +6 -5
- package/src/getRealFileSystemUrlSync.js +59 -0
- package/src/internal/fileSystemNodeToTypeOrNull.js +3 -1
- package/src/internal/getCommonPathname.js +0 -1
- package/src/urlToPathname.js +8 -3
- package/src/urlToRelativeUrl.js +0 -1
- package/src/writeSymbolicLink.js +6 -4
package/main.js
CHANGED
|
@@ -24,6 +24,7 @@ export { ensureWindowsDriveLetter } from "./src/ensureWindowsDriveLetter.js"
|
|
|
24
24
|
export { copyFileSystemNode } from "./src/copyFileSystemNode.js"
|
|
25
25
|
export { copyDirectoryContent } from "./src/copyDirectoryContent.js"
|
|
26
26
|
export { fileSystemPathToUrl } from "./src/fileSystemPathToUrl.js"
|
|
27
|
+
export { getRealFileSystemUrlSync } from "./src/getRealFileSystemUrlSync.js"
|
|
27
28
|
export { grantPermissionsOnFileSystemNode } from "./src/grantPermissionsOnFileSystemNode.js"
|
|
28
29
|
export { isFileSystemPath } from "./src/isFileSystemPath.js"
|
|
29
30
|
export { listFilesMatching } from "./src/listFilesMatching.js"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/filesystem",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Collection of functions to interact with filesystem in Node.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"node": ">=16.13.0"
|
|
17
17
|
},
|
|
18
18
|
"publishConfig": {
|
|
19
|
-
"access": "public"
|
|
19
|
+
"access": "public",
|
|
20
|
+
"registry": "https://registry.npmjs.org"
|
|
20
21
|
},
|
|
21
22
|
"type": "module",
|
|
22
23
|
"exports": {
|
|
@@ -44,15 +45,15 @@
|
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@jsenv/assert": "2.4.1",
|
|
47
|
-
"@jsenv/core": "25.1
|
|
48
|
+
"@jsenv/core": "25.2.1",
|
|
48
49
|
"@jsenv/eslint-config": "16.0.9",
|
|
49
50
|
"@jsenv/github-release-package": "1.2.3",
|
|
50
51
|
"@jsenv/importmap-eslint-resolver": "5.2.2",
|
|
51
52
|
"@jsenv/importmap-node-module": "5.1.0",
|
|
52
53
|
"@jsenv/package-publish": "1.6.2",
|
|
53
54
|
"@jsenv/performance-impact": "2.2.1",
|
|
54
|
-
"eslint": "8.
|
|
55
|
+
"eslint": "8.7.0",
|
|
55
56
|
"eslint-plugin-import": "2.25.4",
|
|
56
57
|
"prettier": "2.5.1"
|
|
57
58
|
}
|
|
58
|
-
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readdirSync, realpathSync } from "node:fs"
|
|
2
|
+
|
|
3
|
+
import { fileSystemPathToUrl } from "./fileSystemPathToUrl.js"
|
|
4
|
+
import { urlToFileSystemPath } from "./urlToFileSystemPath.js"
|
|
5
|
+
|
|
6
|
+
export const getRealFileSystemUrlSync = (
|
|
7
|
+
fileUrl,
|
|
8
|
+
{ followLink = true } = {},
|
|
9
|
+
) => {
|
|
10
|
+
const pathname = new URL(fileUrl).pathname
|
|
11
|
+
const parts = pathname.slice(1).split("/")
|
|
12
|
+
let reconstructedFileUrl = `file:///`
|
|
13
|
+
if (process.platform === "win32") {
|
|
14
|
+
const windowsDriveLetter = parts.shift()
|
|
15
|
+
reconstructedFileUrl += `${windowsDriveLetter}/`
|
|
16
|
+
}
|
|
17
|
+
let i = 0
|
|
18
|
+
// eslint-disable-next-line no-constant-condition
|
|
19
|
+
while (true) {
|
|
20
|
+
const name = parts[i]
|
|
21
|
+
i++
|
|
22
|
+
let namesOnFileSystem
|
|
23
|
+
try {
|
|
24
|
+
namesOnFileSystem = readdirSync(
|
|
25
|
+
// When Node.js receives "C:/" on windows it returns
|
|
26
|
+
// the process.cwd() directory content...
|
|
27
|
+
// This can be fixed by passing "file:///C:/" directly but as a url object
|
|
28
|
+
new URL(reconstructedFileUrl),
|
|
29
|
+
)
|
|
30
|
+
} catch (e) {
|
|
31
|
+
if (e && e.code === "ENOENT") {
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
throw e
|
|
35
|
+
}
|
|
36
|
+
const foundOnFilesystem = namesOnFileSystem.includes(name)
|
|
37
|
+
if (foundOnFilesystem) {
|
|
38
|
+
reconstructedFileUrl += name
|
|
39
|
+
} else {
|
|
40
|
+
const nameOnFileSystem = namesOnFileSystem.find(
|
|
41
|
+
(nameCandidate) => nameCandidate.toLowerCase() === name.toLowerCase(),
|
|
42
|
+
)
|
|
43
|
+
if (!nameOnFileSystem) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
reconstructedFileUrl += nameOnFileSystem
|
|
47
|
+
}
|
|
48
|
+
if (i === parts.length) {
|
|
49
|
+
if (followLink) {
|
|
50
|
+
const realPath = realpathSync.native(
|
|
51
|
+
urlToFileSystemPath(reconstructedFileUrl),
|
|
52
|
+
)
|
|
53
|
+
return fileSystemPathToUrl(realPath)
|
|
54
|
+
}
|
|
55
|
+
return reconstructedFileUrl
|
|
56
|
+
}
|
|
57
|
+
reconstructedFileUrl += "/"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -10,7 +10,6 @@ export const getCommonPathname = (pathname, otherPathname) => {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const commonString = pathname.slice(0, firstDifferentCharacterIndex + 1)
|
|
13
|
-
|
|
14
13
|
// the first different char is at firstDifferentCharacterIndex
|
|
15
14
|
if (pathname.charAt(firstDifferentCharacterIndex) === "/") {
|
|
16
15
|
return commonString
|
package/src/urlToPathname.js
CHANGED
|
@@ -8,7 +8,12 @@ export const urlToPathname = (url) => {
|
|
|
8
8
|
|
|
9
9
|
const ressourceToPathname = (ressource) => {
|
|
10
10
|
const searchSeparatorIndex = ressource.indexOf("?")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
if (searchSeparatorIndex > -1) {
|
|
12
|
+
return ressource.slice(0, searchSeparatorIndex)
|
|
13
|
+
}
|
|
14
|
+
const hashIndex = ressource.indexOf("#")
|
|
15
|
+
if (hashIndex > -1) {
|
|
16
|
+
return ressource.slice(0, hashIndex)
|
|
17
|
+
}
|
|
18
|
+
return ressource
|
|
14
19
|
}
|
package/src/urlToRelativeUrl.js
CHANGED
|
@@ -31,7 +31,6 @@ export const urlToRelativeUrl = (url, baseUrl) => {
|
|
|
31
31
|
const urlAsString = String(url)
|
|
32
32
|
return urlAsString
|
|
33
33
|
}
|
|
34
|
-
|
|
35
34
|
const specificPathname = pathname.slice(commonPathname.length)
|
|
36
35
|
const baseSpecificPathname = basePathname.slice(commonPathname.length)
|
|
37
36
|
if (baseSpecificPathname.includes("/")) {
|
package/src/writeSymbolicLink.js
CHANGED
|
@@ -31,16 +31,18 @@ export const writeSymbolicLink = async ({
|
|
|
31
31
|
}) => {
|
|
32
32
|
const fromUrl = assertAndNormalizeFileUrl(from)
|
|
33
33
|
const toInfo = getToInfo(to, fromUrl)
|
|
34
|
-
|
|
34
|
+
// Node.js doc at https://nodejs.org/api/fs.html#fssymlinktarget-path-type-callback
|
|
35
|
+
// states the following:
|
|
36
|
+
// "If the type argument is not set, Node.js will autodetect
|
|
37
|
+
// target type and use 'file' or 'dir'"
|
|
38
|
+
// In practice, if code don't specify "type" on windows, you later get EPERM errors
|
|
39
|
+
// when doing operation on the symlink such as "fs.stat"
|
|
35
40
|
if (isWindows && typeof type === "undefined") {
|
|
36
|
-
// without this if you write a symbolic link without specifying the type on windows
|
|
37
|
-
// you later get EPERM when doing stat on the symlink
|
|
38
41
|
const toStats = await readFileSystemNodeStat(toInfo.url, {
|
|
39
42
|
nullIfNotFound: true,
|
|
40
43
|
})
|
|
41
44
|
type = toStats && toStats.isDirectory() ? "dir" : "file"
|
|
42
45
|
}
|
|
43
|
-
|
|
44
46
|
const symbolicLinkPath = urlToFileSystemPath(fromUrl)
|
|
45
47
|
try {
|
|
46
48
|
await symlink(toInfo.value, symbolicLinkPath, type)
|