@jsenv/filesystem 2.3.1 → 2.6.0
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/README.md +7 -4
- package/package.json +18 -30
- package/src/collectDirectoryMatchReport.js +29 -23
- package/src/collectFiles.js +34 -45
- package/src/copyDirectoryContent.js +26 -14
- package/src/copyFileSystemNode.js +37 -23
- package/src/listFilesMatching.js +8 -20
- package/src/moveDirectoryContent.js +27 -14
- package/src/moveFileSystemNode.js +43 -28
- package/src/readFileSystemNodeStat.js +2 -2
- package/src/removeFileSystemNode.js +56 -35
- package/dist/commonjs/jsenv_filesystem.cjs +0 -2654
- package/dist/commonjs/jsenv_filesystem.cjs.map +0 -604
- package/dist/dev/template_node_package.dev.cjs +0 -20
- package/dist/dev/template_node_package.dev.cjs.map +0 -16
- package/dist/prod/template_node_package.prod.cjs +0 -20
- package/dist/prod/template_node_package.prod.cjs.map +0 -16
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { unlink, rmdir, openSync, closeSync } from "node:fs"
|
|
2
|
+
import { Abort } from "@jsenv/abort"
|
|
2
3
|
|
|
3
4
|
import { ensureUrlTrailingSlash } from "./internal/ensureUrlTrailingSlash.js"
|
|
4
5
|
import { assertAndNormalizeFileUrl } from "./assertAndNormalizeFileUrl.js"
|
|
@@ -10,6 +11,7 @@ import { resolveUrl } from "./resolveUrl.js"
|
|
|
10
11
|
export const removeFileSystemNode = async (
|
|
11
12
|
source,
|
|
12
13
|
{
|
|
14
|
+
signal = new AbortController().signal,
|
|
13
15
|
allowUseless = false,
|
|
14
16
|
recursive = false,
|
|
15
17
|
maxRetries = 3,
|
|
@@ -19,40 +21,49 @@ export const removeFileSystemNode = async (
|
|
|
19
21
|
) => {
|
|
20
22
|
const sourceUrl = assertAndNormalizeFileUrl(source)
|
|
21
23
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
const removeOperation = Abort.startOperation()
|
|
25
|
+
removeOperation.addAbortSignal(signal)
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
removeOperation.throwIfAborted()
|
|
29
|
+
const sourceStats = await readFileSystemNodeStat(sourceUrl, {
|
|
30
|
+
nullIfNotFound: true,
|
|
31
|
+
followLink: false,
|
|
32
|
+
})
|
|
33
|
+
if (!sourceStats) {
|
|
34
|
+
if (allowUseless) {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`)
|
|
29
38
|
}
|
|
30
|
-
throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`)
|
|
31
|
-
}
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
// https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_class_fs_stats
|
|
41
|
+
// FIFO and socket are ignored, not sure what they are exactly and what to do with them
|
|
42
|
+
// other libraries ignore them, let's do the same.
|
|
43
|
+
if (
|
|
44
|
+
sourceStats.isFile() ||
|
|
45
|
+
sourceStats.isSymbolicLink() ||
|
|
46
|
+
sourceStats.isCharacterDevice() ||
|
|
47
|
+
sourceStats.isBlockDevice()
|
|
48
|
+
) {
|
|
49
|
+
await removeNonDirectory(
|
|
50
|
+
sourceUrl.endsWith("/") ? sourceUrl.slice(0, -1) : sourceUrl,
|
|
51
|
+
{
|
|
52
|
+
maxRetries,
|
|
53
|
+
retryDelay,
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
} else if (sourceStats.isDirectory()) {
|
|
57
|
+
await removeDirectory(ensureUrlTrailingSlash(sourceUrl), {
|
|
58
|
+
signal: removeOperation.signal,
|
|
59
|
+
recursive,
|
|
45
60
|
maxRetries,
|
|
46
61
|
retryDelay,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
maxRetries,
|
|
53
|
-
retryDelay,
|
|
54
|
-
onlyContent,
|
|
55
|
-
})
|
|
62
|
+
onlyContent,
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
} finally {
|
|
66
|
+
await removeOperation.end()
|
|
56
67
|
}
|
|
57
68
|
}
|
|
58
69
|
|
|
@@ -105,9 +116,13 @@ const unlinkNaive = (sourcePath, { handleTemporaryError = null } = {}) => {
|
|
|
105
116
|
|
|
106
117
|
const removeDirectory = async (
|
|
107
118
|
rootDirectoryUrl,
|
|
108
|
-
{ maxRetries, retryDelay, recursive, onlyContent },
|
|
119
|
+
{ signal, maxRetries, retryDelay, recursive, onlyContent },
|
|
109
120
|
) => {
|
|
121
|
+
const removeDirectoryOperation = Abort.startOperation()
|
|
122
|
+
removeDirectoryOperation.addAbortSignal(signal)
|
|
123
|
+
|
|
110
124
|
const visit = async (sourceUrl) => {
|
|
125
|
+
removeDirectoryOperation.throwIfAborted()
|
|
111
126
|
const sourceStats = await readFileSystemNodeStat(sourceUrl, {
|
|
112
127
|
nullIfNotFound: true,
|
|
113
128
|
followLink: false,
|
|
@@ -141,6 +156,7 @@ const removeDirectory = async (
|
|
|
141
156
|
},
|
|
142
157
|
}
|
|
143
158
|
: {}
|
|
159
|
+
removeDirectoryOperation.throwIfAborted()
|
|
144
160
|
await removeDirectoryNaive(directoryPath, {
|
|
145
161
|
...optionsFromRecursive,
|
|
146
162
|
// Workaround for https://github.com/joyent/node/issues/4337
|
|
@@ -179,6 +195,7 @@ const removeDirectory = async (
|
|
|
179
195
|
}
|
|
180
196
|
|
|
181
197
|
const removeDirectoryContent = async (directoryUrl) => {
|
|
198
|
+
removeDirectoryOperation.throwIfAborted()
|
|
182
199
|
const names = await readDirectory(directoryUrl)
|
|
183
200
|
await Promise.all(
|
|
184
201
|
names.map(async (name) => {
|
|
@@ -196,10 +213,14 @@ const removeDirectory = async (
|
|
|
196
213
|
await removeNonDirectory(symbolicLinkUrl, { maxRetries, retryDelay })
|
|
197
214
|
}
|
|
198
215
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
216
|
+
try {
|
|
217
|
+
if (onlyContent) {
|
|
218
|
+
await removeDirectoryContent(rootDirectoryUrl)
|
|
219
|
+
} else {
|
|
220
|
+
await visitDirectory(rootDirectoryUrl)
|
|
221
|
+
}
|
|
222
|
+
} finally {
|
|
223
|
+
await removeDirectoryOperation.end()
|
|
203
224
|
}
|
|
204
225
|
}
|
|
205
226
|
|