1 | const fs = require('fs');
|
2 | const globrex = require('globrex');
|
3 | const { promisify } = require('util');
|
4 | const globalyzer = require('globalyzer');
|
5 | const { join, resolve, relative } = require('path');
|
6 | const isHidden = /(^|[\\\/])\.[^\\\/\.]/g;
|
7 | const readdir = promisify(fs.readdir);
|
8 | let CACHE = {};
|
9 |
|
10 | async function walk(output, prefix, lexer, opts, dirname='', level=0) {
|
11 | const rgx = lexer.segments[level];
|
12 | const dir = join(opts.cwd, prefix, dirname);
|
13 | const files = await readdir(dir);
|
14 | const { dot, filesOnly } = opts;
|
15 |
|
16 | let i=0, len=files.length, file;
|
17 | let fullpath, relpath, stats, isMatch;
|
18 |
|
19 | for (; i < len; i++) {
|
20 | fullpath = join(dir, file=files[i]);
|
21 | relpath = dirname ? join(dirname, file) : file;
|
22 | if (!dot && isHidden.test(relpath)) continue;
|
23 | isMatch = lexer.regex.test(relpath);
|
24 |
|
25 | if ((stats=CACHE[relpath]) === void 0) {
|
26 | CACHE[relpath] = stats = fs.lstatSync(fullpath);
|
27 | }
|
28 |
|
29 | if (!stats.isDirectory()) {
|
30 | isMatch && output.push(relative(opts.cwd, fullpath));
|
31 | continue;
|
32 | }
|
33 |
|
34 | if (rgx && !rgx.test(file)) continue;
|
35 | !filesOnly && isMatch && output.push(join(prefix, relpath));
|
36 |
|
37 | await walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && ++level);
|
38 | }
|
39 | }
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | module.exports = async function (str, opts={}) {
|
53 | if (!str) return [];
|
54 |
|
55 | let glob = globalyzer(str);
|
56 |
|
57 | opts.cwd = opts.cwd || '.';
|
58 |
|
59 | if (!glob.isGlob) {
|
60 | let resolved = resolve(opts.cwd, str);
|
61 | if (!fs.existsSync(resolved)) return []
|
62 |
|
63 | return opts.absolute ? [resolved] : [str];
|
64 | }
|
65 |
|
66 | if (opts.flush) CACHE = {};
|
67 |
|
68 | let matches = [];
|
69 | const { path } = globrex(glob.glob, { filepath:true, globstar:true, extended:true });
|
70 |
|
71 | path.globstar = path.globstar.toString();
|
72 | await walk(matches, glob.base, path, opts, '.', 0);
|
73 |
|
74 | return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches;
|
75 | };
|