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