• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Glob = void 0;
4const minimatch_1 = require("minimatch");
5const path_scurry_1 = require("path-scurry");
6const url_1 = require("url");
7const pattern_js_1 = require("./pattern.js");
8const walker_js_1 = require("./walker.js");
9// if no process global, just call it linux.
10// so we default to case-sensitive, / separators
11const defaultPlatform = typeof process === 'object' &&
12    process &&
13    typeof process.platform === 'string'
14    ? process.platform
15    : 'linux';
16/**
17 * An object that can perform glob pattern traversals.
18 */
19class Glob {
20    absolute;
21    cwd;
22    root;
23    dot;
24    dotRelative;
25    follow;
26    ignore;
27    magicalBraces;
28    mark;
29    matchBase;
30    maxDepth;
31    nobrace;
32    nocase;
33    nodir;
34    noext;
35    noglobstar;
36    pattern;
37    platform;
38    realpath;
39    scurry;
40    stat;
41    signal;
42    windowsPathsNoEscape;
43    withFileTypes;
44    /**
45     * The options provided to the constructor.
46     */
47    opts;
48    /**
49     * An array of parsed immutable {@link Pattern} objects.
50     */
51    patterns;
52    /**
53     * All options are stored as properties on the `Glob` object.
54     *
55     * See {@link GlobOptions} for full options descriptions.
56     *
57     * Note that a previous `Glob` object can be passed as the
58     * `GlobOptions` to another `Glob` instantiation to re-use settings
59     * and caches with a new pattern.
60     *
61     * Traversal functions can be called multiple times to run the walk
62     * again.
63     */
64    constructor(pattern, opts) {
65        this.withFileTypes = !!opts.withFileTypes;
66        this.signal = opts.signal;
67        this.follow = !!opts.follow;
68        this.dot = !!opts.dot;
69        this.dotRelative = !!opts.dotRelative;
70        this.nodir = !!opts.nodir;
71        this.mark = !!opts.mark;
72        if (!opts.cwd) {
73            this.cwd = '';
74        }
75        else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) {
76            opts.cwd = (0, url_1.fileURLToPath)(opts.cwd);
77        }
78        this.cwd = opts.cwd || '';
79        this.root = opts.root;
80        this.magicalBraces = !!opts.magicalBraces;
81        this.nobrace = !!opts.nobrace;
82        this.noext = !!opts.noext;
83        this.realpath = !!opts.realpath;
84        this.absolute = opts.absolute;
85        this.noglobstar = !!opts.noglobstar;
86        this.matchBase = !!opts.matchBase;
87        this.maxDepth =
88            typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity;
89        this.stat = !!opts.stat;
90        this.ignore = opts.ignore;
91        if (this.withFileTypes && this.absolute !== undefined) {
92            throw new Error('cannot set absolute and withFileTypes:true');
93        }
94        if (typeof pattern === 'string') {
95            pattern = [pattern];
96        }
97        this.windowsPathsNoEscape =
98            !!opts.windowsPathsNoEscape ||
99                opts.allowWindowsEscape === false;
100        if (this.windowsPathsNoEscape) {
101            pattern = pattern.map(p => p.replace(/\\/g, '/'));
102        }
103        if (this.matchBase) {
104            if (opts.noglobstar) {
105                throw new TypeError('base matching requires globstar');
106            }
107            pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`));
108        }
109        this.pattern = pattern;
110        this.platform = opts.platform || defaultPlatform;
111        this.opts = { ...opts, platform: this.platform };
112        if (opts.scurry) {
113            this.scurry = opts.scurry;
114            if (opts.nocase !== undefined &&
115                opts.nocase !== opts.scurry.nocase) {
116                throw new Error('nocase option contradicts provided scurry option');
117            }
118        }
119        else {
120            const Scurry = opts.platform === 'win32'
121                ? path_scurry_1.PathScurryWin32
122                : opts.platform === 'darwin'
123                    ? path_scurry_1.PathScurryDarwin
124                    : opts.platform
125                        ? path_scurry_1.PathScurryPosix
126                        : path_scurry_1.PathScurry;
127            this.scurry = new Scurry(this.cwd, {
128                nocase: opts.nocase,
129                fs: opts.fs,
130            });
131        }
132        this.nocase = this.scurry.nocase;
133        // If you do nocase:true on a case-sensitive file system, then
134        // we need to use regexps instead of strings for non-magic
135        // path portions, because statting `aBc` won't return results
136        // for the file `AbC` for example.
137        const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32';
138        const mmo = {
139            // default nocase based on platform
140            ...opts,
141            dot: this.dot,
142            matchBase: this.matchBase,
143            nobrace: this.nobrace,
144            nocase: this.nocase,
145            nocaseMagicOnly,
146            nocomment: true,
147            noext: this.noext,
148            nonegate: true,
149            optimizationLevel: 2,
150            platform: this.platform,
151            windowsPathsNoEscape: this.windowsPathsNoEscape,
152            debug: !!this.opts.debug,
153        };
154        const mms = this.pattern.map(p => new minimatch_1.Minimatch(p, mmo));
155        const [matchSet, globParts] = mms.reduce((set, m) => {
156            set[0].push(...m.set);
157            set[1].push(...m.globParts);
158            return set;
159        }, [[], []]);
160        this.patterns = matchSet.map((set, i) => {
161            return new pattern_js_1.Pattern(set, globParts[i], 0, this.platform);
162        });
163    }
164    async walk() {
165        // Walkers always return array of Path objects, so we just have to
166        // coerce them into the right shape.  It will have already called
167        // realpath() if the option was set to do so, so we know that's cached.
168        // start out knowing the cwd, at least
169        return [
170            ...(await new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, {
171                ...this.opts,
172                maxDepth: this.maxDepth !== Infinity
173                    ? this.maxDepth + this.scurry.cwd.depth()
174                    : Infinity,
175                platform: this.platform,
176                nocase: this.nocase,
177            }).walk()),
178        ];
179    }
180    walkSync() {
181        return [
182            ...new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, {
183                ...this.opts,
184                maxDepth: this.maxDepth !== Infinity
185                    ? this.maxDepth + this.scurry.cwd.depth()
186                    : Infinity,
187                platform: this.platform,
188                nocase: this.nocase,
189            }).walkSync(),
190        ];
191    }
192    stream() {
193        return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, {
194            ...this.opts,
195            maxDepth: this.maxDepth !== Infinity
196                ? this.maxDepth + this.scurry.cwd.depth()
197                : Infinity,
198            platform: this.platform,
199            nocase: this.nocase,
200        }).stream();
201    }
202    streamSync() {
203        return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, {
204            ...this.opts,
205            maxDepth: this.maxDepth !== Infinity
206                ? this.maxDepth + this.scurry.cwd.depth()
207                : Infinity,
208            platform: this.platform,
209            nocase: this.nocase,
210        }).streamSync();
211    }
212    /**
213     * Default sync iteration function. Returns a Generator that
214     * iterates over the results.
215     */
216    iterateSync() {
217        return this.streamSync()[Symbol.iterator]();
218    }
219    [Symbol.iterator]() {
220        return this.iterateSync();
221    }
222    /**
223     * Default async iteration function. Returns an AsyncGenerator that
224     * iterates over the results.
225     */
226    iterate() {
227        return this.stream()[Symbol.asyncIterator]();
228    }
229    [Symbol.asyncIterator]() {
230        return this.iterate();
231    }
232}
233exports.Glob = Glob;
234//# sourceMappingURL=glob.js.map