rrdir 13.1.1 → 13.1.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.
Files changed (2) hide show
  1. package/dist/index.js +175 -125
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,164 +1,214 @@
1
- import { readdir as U, stat as b, lstat as g } from "node:fs/promises";
2
- import { readdirSync as I, statSync as $, lstatSync as E } from "node:fs";
3
- import { sep as F, resolve as A } from "node:path";
4
- import P from "picomatch";
5
- const T = new TextEncoder(), O = T.encode.bind(T), p = new TextDecoder(), h = p.decode.bind(p), j = O(F), S = (t) => t instanceof Uint8Array ? "buffer" : "utf8", k = {
6
- strict: !1,
7
- stats: !1,
8
- followSymlinks: !1,
1
+ import { readdir, stat, lstat } from "node:fs/promises";
2
+ import { readdirSync, statSync, lstatSync } from "node:fs";
3
+ import { sep, resolve } from "node:path";
4
+ import picomatch from "picomatch";
5
+ const encoder = new TextEncoder();
6
+ const toUint8Array = encoder.encode.bind(encoder);
7
+ const decoder = new TextDecoder();
8
+ const toString = decoder.decode.bind(decoder);
9
+ const sepUint8Array = toUint8Array(sep);
10
+ const getEncoding = (dir) => dir instanceof Uint8Array ? "buffer" : "utf8";
11
+ const defaultOpts = {
12
+ strict: false,
13
+ stats: false,
14
+ followSymlinks: false,
9
15
  exclude: void 0,
10
16
  include: void 0,
11
- insensitive: !1
17
+ insensitive: false
12
18
  };
13
- function v({ name: t }, i, s) {
14
- return s === "buffer" ? i === "." ? t : Uint8Array.from([...i, ...j, ...t]) : i === "." ? t : `${i}${F}${t}`;
19
+ function makePath({ name }, dir, encoding) {
20
+ if (encoding === "buffer") {
21
+ return dir === "." ? name : Uint8Array.from([...dir, ...sepUint8Array, ...name]);
22
+ } else {
23
+ return dir === "." ? name : `${dir}${sep}${name}`;
24
+ }
15
25
  }
16
- function D(t, i, s, l) {
26
+ function build(dirent, path, stats, opts) {
17
27
  return {
18
- path: i,
19
- directory: (s || t).isDirectory(),
20
- symlink: (s || t).isSymbolicLink(),
21
- ...l.stats ? { stats: s } : {}
28
+ path,
29
+ directory: (stats || dirent).isDirectory(),
30
+ symlink: (stats || dirent).isSymbolicLink(),
31
+ ...opts.stats ? { stats } : {}
22
32
  };
23
33
  }
24
- function L({ include: t, exclude: i, insensitive: s }) {
25
- const l = {
26
- dot: !0,
27
- flags: s ? "i" : void 0
34
+ function makeMatchers({ include, exclude, insensitive }) {
35
+ const opts = {
36
+ dot: true,
37
+ flags: insensitive ? "i" : void 0
28
38
  };
29
39
  return {
30
- includeMatcher: t?.length ? (f) => P(t, l)(A(f)) : null,
31
- excludeMatcher: i?.length ? (f) => P(i, l)(A(f)) : null
40
+ includeMatcher: include?.length ? (path) => picomatch(include, opts)(resolve(path)) : null,
41
+ excludeMatcher: exclude?.length ? (path) => picomatch(exclude, opts)(resolve(path)) : null
32
42
  };
33
43
  }
34
- async function* q(t, i = {}, { includeMatcher: s, excludeMatcher: l, encoding: f } = {}) {
35
- s === void 0 && (i = { ...k, ...i }, { includeMatcher: s, excludeMatcher: l } = L(i), typeof t == "string" && /[/\\]$/.test(t) && (t = t.substring(0, t.length - 1)), f = S(t));
36
- let n = [];
44
+ async function* rrdir(dir, opts = {}, { includeMatcher, excludeMatcher, encoding } = {}) {
45
+ if (includeMatcher === void 0) {
46
+ opts = { ...defaultOpts, ...opts };
47
+ ({ includeMatcher, excludeMatcher } = makeMatchers(opts));
48
+ if (typeof dir === "string" && /[/\\]$/.test(dir))
49
+ dir = dir.substring(0, dir.length - 1);
50
+ encoding = getEncoding(dir);
51
+ }
52
+ let dirents = [];
37
53
  try {
38
- n = await U(t, { encoding: f, withFileTypes: !0 });
39
- } catch (y) {
40
- if (i.strict)
41
- throw y;
42
- yield { path: t, err: y };
54
+ dirents = await readdir(dir, { encoding, withFileTypes: true });
55
+ } catch (err) {
56
+ if (opts.strict)
57
+ throw err;
58
+ yield { path: dir, err };
43
59
  }
44
- if (n.length)
45
- for (const y of n) {
46
- const r = v(y, t, f);
47
- if (l?.(f === "buffer" ? h(r) : r))
48
- continue;
49
- const e = i.followSymlinks && y.isSymbolicLink(), u = f === "buffer" ? h(r) : r, m = !s || s(u);
50
- let c;
51
- if (m) {
52
- if (i.stats || e)
53
- try {
54
- c = await (i.followSymlinks ? b : g)(r);
55
- } catch (a) {
56
- if (i.strict)
57
- throw a;
58
- yield { path: r, err: a };
59
- }
60
- yield D(y, r, c, i);
60
+ if (!dirents.length)
61
+ return;
62
+ for (const dirent of dirents) {
63
+ const path = makePath(dirent, dir, encoding);
64
+ if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path))
65
+ continue;
66
+ const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
67
+ const encodedPath = encoding === "buffer" ? toString(path) : path;
68
+ const isIncluded = !includeMatcher || includeMatcher(encodedPath);
69
+ let stats;
70
+ if (isIncluded) {
71
+ if (opts.stats || isSymbolicLink) {
72
+ try {
73
+ stats = await (opts.followSymlinks ? stat : lstat)(path);
74
+ } catch (err) {
75
+ if (opts.strict)
76
+ throw err;
77
+ yield { path, err };
78
+ }
61
79
  }
62
- let o = !1;
63
- if (e) {
64
- if (!c)
65
- try {
66
- c = await b(r);
67
- } catch {
68
- }
69
- c && c.isDirectory() && (o = !0);
70
- } else
71
- y.isDirectory() && (o = !0);
72
- o && (yield* q(r, i, { includeMatcher: s, excludeMatcher: l, encoding: f }));
80
+ yield build(dirent, path, stats, opts);
81
+ }
82
+ let recurse = false;
83
+ if (isSymbolicLink) {
84
+ if (!stats)
85
+ try {
86
+ stats = await stat(path);
87
+ } catch {
88
+ }
89
+ if (stats && stats.isDirectory())
90
+ recurse = true;
91
+ } else if (dirent.isDirectory()) {
92
+ recurse = true;
73
93
  }
94
+ if (recurse)
95
+ yield* rrdir(path, opts, { includeMatcher, excludeMatcher, encoding });
96
+ }
74
97
  }
75
- async function z(t, i = {}, { includeMatcher: s, excludeMatcher: l, encoding: f } = {}) {
76
- s === void 0 && (i = { ...k, ...i }, { includeMatcher: s, excludeMatcher: l } = L(i), typeof t == "string" && /[/\\]$/.test(t) && (t = t.substring(0, t.length - 1)), f = S(t));
77
- const n = [];
78
- let y = [];
98
+ async function rrdirAsync(dir, opts = {}, { includeMatcher, excludeMatcher, encoding } = {}) {
99
+ if (includeMatcher === void 0) {
100
+ opts = { ...defaultOpts, ...opts };
101
+ ({ includeMatcher, excludeMatcher } = makeMatchers(opts));
102
+ if (typeof dir === "string" && /[/\\]$/.test(dir))
103
+ dir = dir.substring(0, dir.length - 1);
104
+ encoding = getEncoding(dir);
105
+ }
106
+ const results = [];
107
+ let dirents = [];
79
108
  try {
80
- y = await U(t, { encoding: f, withFileTypes: !0 });
81
- } catch (r) {
82
- if (i.strict)
83
- throw r;
84
- n.push({ path: t, err: r });
109
+ dirents = await readdir(dir, { encoding, withFileTypes: true });
110
+ } catch (err) {
111
+ if (opts.strict)
112
+ throw err;
113
+ results.push({ path: dir, err });
85
114
  }
86
- return y.length && await Promise.all(y.map(async (r) => {
87
- const e = v(r, t, f);
88
- if (l?.(f === "buffer" ? h(e) : e))
115
+ if (!dirents.length)
116
+ return results;
117
+ await Promise.all(dirents.map(async (dirent) => {
118
+ const path = makePath(dirent, dir, encoding);
119
+ if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path))
89
120
  return;
90
- const u = i.followSymlinks && r.isSymbolicLink(), m = f === "buffer" ? h(e) : e, c = !s || s(m);
91
- let o;
92
- if (c) {
93
- if (i.stats || u)
121
+ const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
122
+ const encodedPath = encoding === "buffer" ? toString(path) : path;
123
+ const isIncluded = !includeMatcher || includeMatcher(encodedPath);
124
+ let stats;
125
+ if (isIncluded) {
126
+ if (opts.stats || isSymbolicLink) {
94
127
  try {
95
- o = await (i.followSymlinks ? b : g)(e);
96
- } catch (w) {
97
- if (i.strict)
98
- throw w;
99
- n.push({ path: e, err: w });
128
+ stats = await (opts.followSymlinks ? stat : lstat)(path);
129
+ } catch (err) {
130
+ if (opts.strict)
131
+ throw err;
132
+ results.push({ path, err });
100
133
  }
101
- n.push(D(r, e, o, i));
134
+ }
135
+ results.push(build(dirent, path, stats, opts));
102
136
  }
103
- let a = !1;
104
- if (u) {
105
- if (!o)
137
+ let recurse = false;
138
+ if (isSymbolicLink) {
139
+ if (!stats)
106
140
  try {
107
- o = await b(e);
141
+ stats = await stat(path);
108
142
  } catch {
109
143
  }
110
- o && o.isDirectory() && (a = !0);
111
- } else
112
- r.isDirectory() && (a = !0);
113
- a && n.push(...await z(e, i, { includeMatcher: s, excludeMatcher: l, encoding: f }));
114
- })), n;
144
+ if (stats && stats.isDirectory())
145
+ recurse = true;
146
+ } else if (dirent.isDirectory()) {
147
+ recurse = true;
148
+ }
149
+ if (recurse)
150
+ results.push(...await rrdirAsync(path, opts, { includeMatcher, excludeMatcher, encoding }));
151
+ }));
152
+ return results;
115
153
  }
116
- function B(t, i = {}, { includeMatcher: s, excludeMatcher: l, encoding: f } = {}) {
117
- s === void 0 && (i = { ...k, ...i }, { includeMatcher: s, excludeMatcher: l } = L(i), typeof t == "string" && /[/\\]$/.test(t) && (t = t.substring(0, t.length - 1)), f = S(t));
118
- const n = [];
119
- let y = [];
154
+ function rrdirSync(dir, opts = {}, { includeMatcher, excludeMatcher, encoding } = {}) {
155
+ if (includeMatcher === void 0) {
156
+ opts = { ...defaultOpts, ...opts };
157
+ ({ includeMatcher, excludeMatcher } = makeMatchers(opts));
158
+ if (typeof dir === "string" && /[/\\]$/.test(dir))
159
+ dir = dir.substring(0, dir.length - 1);
160
+ encoding = getEncoding(dir);
161
+ }
162
+ const results = [];
163
+ let dirents = [];
120
164
  try {
121
- y = I(t, { encoding: f, withFileTypes: !0 });
122
- } catch (r) {
123
- if (i.strict)
124
- throw r;
125
- n.push({ path: t, err: r });
165
+ dirents = readdirSync(dir, { encoding, withFileTypes: true });
166
+ } catch (err) {
167
+ if (opts.strict)
168
+ throw err;
169
+ results.push({ path: dir, err });
126
170
  }
127
- if (!y.length)
128
- return n;
129
- for (const r of y) {
130
- const e = v(r, t, f);
131
- if (l?.(f === "buffer" ? h(e) : e))
171
+ if (!dirents.length)
172
+ return results;
173
+ for (const dirent of dirents) {
174
+ const path = makePath(dirent, dir, encoding);
175
+ if (excludeMatcher?.(encoding === "buffer" ? toString(path) : path))
132
176
  continue;
133
- const u = i.followSymlinks && r.isSymbolicLink(), m = f === "buffer" ? h(e) : e, c = !s || s(m);
134
- let o;
135
- if (c) {
136
- if (i.stats || u)
177
+ const isSymbolicLink = opts.followSymlinks && dirent.isSymbolicLink();
178
+ const encodedPath = encoding === "buffer" ? toString(path) : path;
179
+ const isIncluded = !includeMatcher || includeMatcher(encodedPath);
180
+ let stats;
181
+ if (isIncluded) {
182
+ if (opts.stats || isSymbolicLink) {
137
183
  try {
138
- o = (i.followSymlinks ? $ : E)(e);
139
- } catch (w) {
140
- if (i.strict)
141
- throw w;
142
- n.push({ path: e, err: w });
184
+ stats = (opts.followSymlinks ? statSync : lstatSync)(path);
185
+ } catch (err) {
186
+ if (opts.strict)
187
+ throw err;
188
+ results.push({ path, err });
143
189
  }
144
- n.push(D(r, e, o, i));
190
+ }
191
+ results.push(build(dirent, path, stats, opts));
145
192
  }
146
- let a = !1;
147
- if (u) {
148
- if (!o)
193
+ let recurse = false;
194
+ if (isSymbolicLink) {
195
+ if (!stats)
149
196
  try {
150
- o = $(e);
197
+ stats = statSync(path);
151
198
  } catch {
152
199
  }
153
- o && o.isDirectory() && (a = !0);
154
- } else
155
- r.isDirectory() && (a = !0);
156
- a && n.push(...B(e, i, { includeMatcher: s, excludeMatcher: l, encoding: f }));
200
+ if (stats && stats.isDirectory())
201
+ recurse = true;
202
+ } else if (dirent.isDirectory()) {
203
+ recurse = true;
204
+ }
205
+ if (recurse)
206
+ results.push(...rrdirSync(path, opts, { includeMatcher, excludeMatcher, encoding }));
157
207
  }
158
- return n;
208
+ return results;
159
209
  }
160
210
  export {
161
- q as rrdir,
162
- z as rrdirAsync,
163
- B as rrdirSync
211
+ rrdir,
212
+ rrdirAsync,
213
+ rrdirSync
164
214
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrdir",
3
- "version": "13.1.1",
3
+ "version": "13.1.2",
4
4
  "description": "Recursive directory reader with a delightful API",
5
5
  "author": "silverwind <me@silverwind.io>",
6
6
  "repository": "silverwind/rrdir",
@@ -29,7 +29,7 @@
29
29
  "updates": "16.0.1",
30
30
  "versions": "12.0.1",
31
31
  "vite": "5.2.11",
32
- "vite-config-silverwind": "2.0.3",
32
+ "vite-config-silverwind": "2.1.0",
33
33
  "vitest": "1.5.0",
34
34
  "vitest-config-silverwind": "8.0.4"
35
35
  }