1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.GlobStream = exports.GlobWalker = exports.GlobUtil = void 0;
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | const minipass_1 = require("minipass");
|
11 | const ignore_js_1 = require("./ignore.js");
|
12 | const processor_js_1 = require("./processor.js");
|
13 | const makeIgnore = (ignore, opts) => typeof ignore === 'string'
|
14 | ? new ignore_js_1.Ignore([ignore], opts)
|
15 | : Array.isArray(ignore)
|
16 | ? new ignore_js_1.Ignore(ignore, opts)
|
17 | : ignore;
|
18 |
|
19 |
|
20 |
|
21 | class GlobUtil {
|
22 | path;
|
23 | patterns;
|
24 | opts;
|
25 | seen = new Set();
|
26 | paused = false;
|
27 | aborted = false;
|
28 | #onResume = [];
|
29 | #ignore;
|
30 | #sep;
|
31 | signal;
|
32 | maxDepth;
|
33 | constructor(patterns, path, opts) {
|
34 | this.patterns = patterns;
|
35 | this.path = path;
|
36 | this.opts = opts;
|
37 | this.#sep = !opts.posix && opts.platform === 'win32' ? '\\' : '/';
|
38 | if (opts.ignore) {
|
39 | this.#ignore = makeIgnore(opts.ignore, opts);
|
40 | }
|
41 |
|
42 |
|
43 |
|
44 | this.maxDepth = opts.maxDepth || Infinity;
|
45 |
|
46 | if (opts.signal) {
|
47 | this.signal = opts.signal;
|
48 | this.signal.addEventListener('abort', () => {
|
49 | this.#onResume.length = 0;
|
50 | });
|
51 | }
|
52 | }
|
53 | #ignored(path) {
|
54 | return this.seen.has(path) || !!this.#ignore?.ignored?.(path);
|
55 | }
|
56 | #childrenIgnored(path) {
|
57 | return !!this.#ignore?.childrenIgnored?.(path);
|
58 | }
|
59 |
|
60 | pause() {
|
61 | this.paused = true;
|
62 | }
|
63 | resume() {
|
64 |
|
65 | if (this.signal?.aborted)
|
66 | return;
|
67 |
|
68 | this.paused = false;
|
69 | let fn = undefined;
|
70 | while (!this.paused && (fn = this.#onResume.shift())) {
|
71 | fn();
|
72 | }
|
73 | }
|
74 | onResume(fn) {
|
75 | if (this.signal?.aborted)
|
76 | return;
|
77 |
|
78 | if (!this.paused) {
|
79 | fn();
|
80 | }
|
81 | else {
|
82 |
|
83 | this.#onResume.push(fn);
|
84 | }
|
85 | }
|
86 |
|
87 |
|
88 | async matchCheck(e, ifDir) {
|
89 | if (ifDir && this.opts.nodir)
|
90 | return undefined;
|
91 | let rpc;
|
92 | if (this.opts.realpath) {
|
93 | rpc = e.realpathCached() || (await e.realpath());
|
94 | if (!rpc)
|
95 | return undefined;
|
96 | e = rpc;
|
97 | }
|
98 | const needStat = e.isUnknown() || this.opts.stat;
|
99 | const s = needStat ? await e.lstat() : e;
|
100 | if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) {
|
101 | const target = await s.realpath();
|
102 |
|
103 | if (target && (target.isUnknown() || this.opts.stat)) {
|
104 | await target.lstat();
|
105 | }
|
106 |
|
107 | }
|
108 | return this.matchCheckTest(s, ifDir);
|
109 | }
|
110 | matchCheckTest(e, ifDir) {
|
111 | return e &&
|
112 | (this.maxDepth === Infinity || e.depth() <= this.maxDepth) &&
|
113 | (!ifDir || e.canReaddir()) &&
|
114 | (!this.opts.nodir || !e.isDirectory()) &&
|
115 | (!this.opts.nodir ||
|
116 | !this.opts.follow ||
|
117 | !e.isSymbolicLink() ||
|
118 | !e.realpathCached()?.isDirectory()) &&
|
119 | !this.#ignored(e)
|
120 | ? e
|
121 | : undefined;
|
122 | }
|
123 | matchCheckSync(e, ifDir) {
|
124 | if (ifDir && this.opts.nodir)
|
125 | return undefined;
|
126 | let rpc;
|
127 | if (this.opts.realpath) {
|
128 | rpc = e.realpathCached() || e.realpathSync();
|
129 | if (!rpc)
|
130 | return undefined;
|
131 | e = rpc;
|
132 | }
|
133 | const needStat = e.isUnknown() || this.opts.stat;
|
134 | const s = needStat ? e.lstatSync() : e;
|
135 | if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) {
|
136 | const target = s.realpathSync();
|
137 | if (target && (target?.isUnknown() || this.opts.stat)) {
|
138 | target.lstatSync();
|
139 | }
|
140 | }
|
141 | return this.matchCheckTest(s, ifDir);
|
142 | }
|
143 | matchFinish(e, absolute) {
|
144 | if (this.#ignored(e))
|
145 | return;
|
146 | const abs = this.opts.absolute === undefined ? absolute : this.opts.absolute;
|
147 | this.seen.add(e);
|
148 | const mark = this.opts.mark && e.isDirectory() ? this.#sep : '';
|
149 |
|
150 | if (this.opts.withFileTypes) {
|
151 | this.matchEmit(e);
|
152 | }
|
153 | else if (abs) {
|
154 | const abs = this.opts.posix ? e.fullpathPosix() : e.fullpath();
|
155 | this.matchEmit(abs + mark);
|
156 | }
|
157 | else {
|
158 | const rel = this.opts.posix ? e.relativePosix() : e.relative();
|
159 | const pre = this.opts.dotRelative && !rel.startsWith('..' + this.#sep)
|
160 | ? '.' + this.#sep
|
161 | : '';
|
162 | this.matchEmit(!rel ? '.' + mark : pre + rel + mark);
|
163 | }
|
164 | }
|
165 | async match(e, absolute, ifDir) {
|
166 | const p = await this.matchCheck(e, ifDir);
|
167 | if (p)
|
168 | this.matchFinish(p, absolute);
|
169 | }
|
170 | matchSync(e, absolute, ifDir) {
|
171 | const p = this.matchCheckSync(e, ifDir);
|
172 | if (p)
|
173 | this.matchFinish(p, absolute);
|
174 | }
|
175 | walkCB(target, patterns, cb) {
|
176 |
|
177 | if (this.signal?.aborted)
|
178 | cb();
|
179 |
|
180 | this.walkCB2(target, patterns, new processor_js_1.Processor(this.opts), cb);
|
181 | }
|
182 | walkCB2(target, patterns, processor, cb) {
|
183 | if (this.#childrenIgnored(target))
|
184 | return cb();
|
185 | if (this.signal?.aborted)
|
186 | cb();
|
187 | if (this.paused) {
|
188 | this.onResume(() => this.walkCB2(target, patterns, processor, cb));
|
189 | return;
|
190 | }
|
191 | processor.processPatterns(target, patterns);
|
192 |
|
193 |
|
194 |
|
195 | let tasks = 1;
|
196 | const next = () => {
|
197 | if (--tasks === 0)
|
198 | cb();
|
199 | };
|
200 | for (const [m, absolute, ifDir] of processor.matches.entries()) {
|
201 | if (this.#ignored(m))
|
202 | continue;
|
203 | tasks++;
|
204 | this.match(m, absolute, ifDir).then(() => next());
|
205 | }
|
206 | for (const t of processor.subwalkTargets()) {
|
207 | if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
|
208 | continue;
|
209 | }
|
210 | tasks++;
|
211 | const childrenCached = t.readdirCached();
|
212 | if (t.calledReaddir())
|
213 | this.walkCB3(t, childrenCached, processor, next);
|
214 | else {
|
215 | t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true);
|
216 | }
|
217 | }
|
218 | next();
|
219 | }
|
220 | walkCB3(target, entries, processor, cb) {
|
221 | processor = processor.filterEntries(target, entries);
|
222 | let tasks = 1;
|
223 | const next = () => {
|
224 | if (--tasks === 0)
|
225 | cb();
|
226 | };
|
227 | for (const [m, absolute, ifDir] of processor.matches.entries()) {
|
228 | if (this.#ignored(m))
|
229 | continue;
|
230 | tasks++;
|
231 | this.match(m, absolute, ifDir).then(() => next());
|
232 | }
|
233 | for (const [target, patterns] of processor.subwalks.entries()) {
|
234 | tasks++;
|
235 | this.walkCB2(target, patterns, processor.child(), next);
|
236 | }
|
237 | next();
|
238 | }
|
239 | walkCBSync(target, patterns, cb) {
|
240 |
|
241 | if (this.signal?.aborted)
|
242 | cb();
|
243 |
|
244 | this.walkCB2Sync(target, patterns, new processor_js_1.Processor(this.opts), cb);
|
245 | }
|
246 | walkCB2Sync(target, patterns, processor, cb) {
|
247 | if (this.#childrenIgnored(target))
|
248 | return cb();
|
249 | if (this.signal?.aborted)
|
250 | cb();
|
251 | if (this.paused) {
|
252 | this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb));
|
253 | return;
|
254 | }
|
255 | processor.processPatterns(target, patterns);
|
256 |
|
257 |
|
258 |
|
259 | let tasks = 1;
|
260 | const next = () => {
|
261 | if (--tasks === 0)
|
262 | cb();
|
263 | };
|
264 | for (const [m, absolute, ifDir] of processor.matches.entries()) {
|
265 | if (this.#ignored(m))
|
266 | continue;
|
267 | this.matchSync(m, absolute, ifDir);
|
268 | }
|
269 | for (const t of processor.subwalkTargets()) {
|
270 | if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
|
271 | continue;
|
272 | }
|
273 | tasks++;
|
274 | const children = t.readdirSync();
|
275 | this.walkCB3Sync(t, children, processor, next);
|
276 | }
|
277 | next();
|
278 | }
|
279 | walkCB3Sync(target, entries, processor, cb) {
|
280 | processor = processor.filterEntries(target, entries);
|
281 | let tasks = 1;
|
282 | const next = () => {
|
283 | if (--tasks === 0)
|
284 | cb();
|
285 | };
|
286 | for (const [m, absolute, ifDir] of processor.matches.entries()) {
|
287 | if (this.#ignored(m))
|
288 | continue;
|
289 | this.matchSync(m, absolute, ifDir);
|
290 | }
|
291 | for (const [target, patterns] of processor.subwalks.entries()) {
|
292 | tasks++;
|
293 | this.walkCB2Sync(target, patterns, processor.child(), next);
|
294 | }
|
295 | next();
|
296 | }
|
297 | }
|
298 | exports.GlobUtil = GlobUtil;
|
299 | class GlobWalker extends GlobUtil {
|
300 | matches;
|
301 | constructor(patterns, path, opts) {
|
302 | super(patterns, path, opts);
|
303 | this.matches = new Set();
|
304 | }
|
305 | matchEmit(e) {
|
306 | this.matches.add(e);
|
307 | }
|
308 | async walk() {
|
309 | if (this.signal?.aborted)
|
310 | throw this.signal.reason;
|
311 | if (this.path.isUnknown()) {
|
312 | await this.path.lstat();
|
313 | }
|
314 | await new Promise((res, rej) => {
|
315 | this.walkCB(this.path, this.patterns, () => {
|
316 | if (this.signal?.aborted) {
|
317 | rej(this.signal.reason);
|
318 | }
|
319 | else {
|
320 | res(this.matches);
|
321 | }
|
322 | });
|
323 | });
|
324 | return this.matches;
|
325 | }
|
326 | walkSync() {
|
327 | if (this.signal?.aborted)
|
328 | throw this.signal.reason;
|
329 | if (this.path.isUnknown()) {
|
330 | this.path.lstatSync();
|
331 | }
|
332 |
|
333 | this.walkCBSync(this.path, this.patterns, () => {
|
334 | if (this.signal?.aborted)
|
335 | throw this.signal.reason;
|
336 | });
|
337 | return this.matches;
|
338 | }
|
339 | }
|
340 | exports.GlobWalker = GlobWalker;
|
341 | class GlobStream extends GlobUtil {
|
342 | results;
|
343 | constructor(patterns, path, opts) {
|
344 | super(patterns, path, opts);
|
345 | this.results = new minipass_1.Minipass({
|
346 | signal: this.signal,
|
347 | objectMode: true,
|
348 | });
|
349 | this.results.on('drain', () => this.resume());
|
350 | this.results.on('resume', () => this.resume());
|
351 | }
|
352 | matchEmit(e) {
|
353 | this.results.write(e);
|
354 | if (!this.results.flowing)
|
355 | this.pause();
|
356 | }
|
357 | stream() {
|
358 | const target = this.path;
|
359 | if (target.isUnknown()) {
|
360 | target.lstat().then(() => {
|
361 | this.walkCB(target, this.patterns, () => this.results.end());
|
362 | });
|
363 | }
|
364 | else {
|
365 | this.walkCB(target, this.patterns, () => this.results.end());
|
366 | }
|
367 | return this.results;
|
368 | }
|
369 | streamSync() {
|
370 | if (this.path.isUnknown()) {
|
371 | this.path.lstatSync();
|
372 | }
|
373 | this.walkCBSync(this.path, this.patterns, () => this.results.end());
|
374 | return this.results;
|
375 | }
|
376 | }
|
377 | exports.GlobStream = GlobStream;
|
378 |
|
\ | No newline at end of file |