rrdir 12.0.3 → 13.0.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 +5 -3
- package/index.js +15 -11
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
`rrdir` recursively reads a directory and returns entries within via an async iterator or async/sync as Array. It can typically iterate millions of files in a matter of seconds. Memory usage is `O(1)` for the async iterator and `O(n)` for the Array variants.
|
|
7
7
|
|
|
8
|
+
Contrary to other similar modules, this module is optionally able to read any path including ones that contain invalid UTF-8 sequences.
|
|
9
|
+
|
|
8
10
|
## Usage
|
|
9
11
|
```console
|
|
10
12
|
npm i rrdir
|
|
@@ -31,9 +33,9 @@ const entries = rrdirSync("dir");
|
|
|
31
33
|
|
|
32
34
|
`rrdir` is an async iterator which yields `entry`. `rrdirAsync` and `rrdirSync` return an Array of `entry`.
|
|
33
35
|
|
|
34
|
-
#### `dir` *String* | *
|
|
36
|
+
#### `dir` *String* | *Uint8Array*
|
|
35
37
|
|
|
36
|
-
The directory to read, either absolute or relative. Pass a `
|
|
38
|
+
The directory to read, either absolute or relative. Pass a `Uint8Array` to switch the module into `Uint8Array` mode which is required to be able to read every file, like for example files with names that are invalid UTF-8 sequences.
|
|
37
39
|
|
|
38
40
|
#### `options` *Object*
|
|
39
41
|
|
|
@@ -46,7 +48,7 @@ The directory to read, either absolute or relative. Pass a `Buffer` to switch th
|
|
|
46
48
|
|
|
47
49
|
#### `entry` *Object*
|
|
48
50
|
|
|
49
|
-
- `path` *string* | *
|
|
51
|
+
- `path` *string* | *Uint8Array*: The path to the entry, will be relative if `dir` is given relative. If `dir` is a `Uint8Array`, this will be too. Always present.
|
|
50
52
|
- `directory` *boolean*: Boolean indicating whether the entry is a directory. `undefined` on error.
|
|
51
53
|
- `symlink` *boolean*: Boolean indicating whether the entry is a symbolic link. `undefined` on error.
|
|
52
54
|
- `stats` *Object*: A [`fs.stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object, present when `options.stats` is set. `undefined` on error.
|
package/index.js
CHANGED
|
@@ -3,7 +3,11 @@ import {readdirSync, statSync, lstatSync} from "node:fs";
|
|
|
3
3
|
import {sep, resolve} from "node:path";
|
|
4
4
|
import picomatch from "picomatch";
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const encoder = new TextEncoder();
|
|
7
|
+
const toUint8Array = encoder.encode.bind(encoder);
|
|
8
|
+
const decoder = new TextDecoder();
|
|
9
|
+
const toString = decoder.decode.bind(decoder);
|
|
10
|
+
const sepUint8Array = toUint8Array(sep);
|
|
7
11
|
|
|
8
12
|
const defaults = {
|
|
9
13
|
strict: false,
|
|
@@ -16,7 +20,7 @@ const defaults = {
|
|
|
16
20
|
|
|
17
21
|
function makePath(entry, dir, encoding) {
|
|
18
22
|
if (encoding === "buffer") {
|
|
19
|
-
return dir === "." ? entry.name :
|
|
23
|
+
return dir === "." ? entry.name : Uint8Array.from([...dir, ...sepUint8Array, ...entry.name]);
|
|
20
24
|
} else {
|
|
21
25
|
return dir === "." ? entry.name : `${dir}${sep}${entry.name}`;
|
|
22
26
|
}
|
|
@@ -51,7 +55,7 @@ export async function* rrdir(dir, opts = {}, {includeMatcher, excludeMatcher, en
|
|
|
51
55
|
opts = {...defaults, ...opts};
|
|
52
56
|
({includeMatcher, excludeMatcher} = makeMatchers(opts));
|
|
53
57
|
if (/[/\\]$/.test(dir)) dir = dir.substring(0, dir.length - 1);
|
|
54
|
-
encoding =
|
|
58
|
+
encoding = dir instanceof Uint8Array ? "buffer" : undefined;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
let dirents = [];
|
|
@@ -65,10 +69,10 @@ export async function* rrdir(dir, opts = {}, {includeMatcher, excludeMatcher, en
|
|
|
65
69
|
|
|
66
70
|
for (const dirent of dirents) {
|
|
67
71
|
const path = makePath(dirent, dir, encoding);
|
|
68
|
-
if (excludeMatcher?.(encoding === "buffer" ?
|
|
72
|
+
if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path)) continue;
|
|
69
73
|
|
|
70
74
|
const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
|
|
71
|
-
const encodedPath = encoding === "buffer" ?
|
|
75
|
+
const encodedPath = encoding === "buffer" ? toString(path) : path;
|
|
72
76
|
const isIncluded = !includeMatcher || includeMatcher(encodedPath);
|
|
73
77
|
let stats;
|
|
74
78
|
|
|
@@ -102,7 +106,7 @@ export async function rrdirAsync(dir, opts = {}, {includeMatcher, excludeMatcher
|
|
|
102
106
|
opts = {...defaults, ...opts};
|
|
103
107
|
({includeMatcher, excludeMatcher} = makeMatchers(opts));
|
|
104
108
|
if (/[/\\]$/.test(dir)) dir = dir.substring(0, dir.length - 1);
|
|
105
|
-
encoding =
|
|
109
|
+
encoding = dir instanceof Uint8Array ? "buffer" : undefined;
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
const results = [];
|
|
@@ -117,10 +121,10 @@ export async function rrdirAsync(dir, opts = {}, {includeMatcher, excludeMatcher
|
|
|
117
121
|
|
|
118
122
|
await Promise.all(dirents.map(async dirent => {
|
|
119
123
|
const path = makePath(dirent, dir, encoding);
|
|
120
|
-
if (excludeMatcher?.(encoding === "buffer" ?
|
|
124
|
+
if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path)) return;
|
|
121
125
|
|
|
122
126
|
const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
|
|
123
|
-
const encodedPath = encoding === "buffer" ?
|
|
127
|
+
const encodedPath = encoding === "buffer" ? toString(path) : path;
|
|
124
128
|
const isIncluded = !includeMatcher || includeMatcher(encodedPath);
|
|
125
129
|
let stats;
|
|
126
130
|
|
|
@@ -156,7 +160,7 @@ export function rrdirSync(dir, opts = {}, {includeMatcher, excludeMatcher, encod
|
|
|
156
160
|
opts = {...defaults, ...opts};
|
|
157
161
|
({includeMatcher, excludeMatcher} = makeMatchers(opts));
|
|
158
162
|
if (/[/\\]$/.test(dir)) dir = dir.substring(0, dir.length - 1);
|
|
159
|
-
encoding =
|
|
163
|
+
encoding = dir instanceof Uint8Array ? "buffer" : undefined;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
const results = [];
|
|
@@ -171,10 +175,10 @@ export function rrdirSync(dir, opts = {}, {includeMatcher, excludeMatcher, encod
|
|
|
171
175
|
|
|
172
176
|
for (const dirent of dirents) {
|
|
173
177
|
const path = makePath(dirent, dir, encoding);
|
|
174
|
-
if (excludeMatcher?.(encoding === "buffer" ?
|
|
178
|
+
if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path)) continue;
|
|
175
179
|
|
|
176
180
|
const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
|
|
177
|
-
const encodedPath = encoding === "buffer" ?
|
|
181
|
+
const encodedPath = encoding === "buffer" ? toString(path) : path;
|
|
178
182
|
const isIncluded = !includeMatcher || includeMatcher(encodedPath);
|
|
179
183
|
let stats;
|
|
180
184
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rrdir",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "Recursive directory reader with a delightful API",
|
|
5
5
|
"author": "silverwind <me@silverwind.io>",
|
|
6
6
|
"repository": "silverwind/rrdir",
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
"node": ">=18"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
|
-
"
|
|
15
|
+
"index.js"
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"eslint": "8.
|
|
19
|
-
"eslint-config-silverwind": "
|
|
20
|
-
"updates": "15.
|
|
21
|
-
"versions": "12.0.
|
|
22
|
-
"vitest": "
|
|
23
|
-
"vitest-config-silverwind": "
|
|
18
|
+
"eslint": "8.57.0",
|
|
19
|
+
"eslint-config-silverwind": "80.0.5",
|
|
20
|
+
"updates": "15.1.2",
|
|
21
|
+
"versions": "12.0.1",
|
|
22
|
+
"vitest": "1.3.1",
|
|
23
|
+
"vitest-config-silverwind": "5.1.1"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"picomatch": "
|
|
26
|
+
"picomatch": "4.0.1"
|
|
27
27
|
}
|
|
28
28
|
}
|