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 /* c8 ignore start */ 66 if (!opts) 67 throw new TypeError('glob options required'); 68 /* c8 ignore stop */ 69 this.withFileTypes = !!opts.withFileTypes; 70 this.signal = opts.signal; 71 this.follow = !!opts.follow; 72 this.dot = !!opts.dot; 73 this.dotRelative = !!opts.dotRelative; 74 this.nodir = !!opts.nodir; 75 this.mark = !!opts.mark; 76 if (!opts.cwd) { 77 this.cwd = ''; 78 } 79 else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) { 80 opts.cwd = (0, url_1.fileURLToPath)(opts.cwd); 81 } 82 this.cwd = opts.cwd || ''; 83 this.root = opts.root; 84 this.magicalBraces = !!opts.magicalBraces; 85 this.nobrace = !!opts.nobrace; 86 this.noext = !!opts.noext; 87 this.realpath = !!opts.realpath; 88 this.absolute = opts.absolute; 89 this.noglobstar = !!opts.noglobstar; 90 this.matchBase = !!opts.matchBase; 91 this.maxDepth = 92 typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity; 93 this.stat = !!opts.stat; 94 this.ignore = opts.ignore; 95 if (this.withFileTypes && this.absolute !== undefined) { 96 throw new Error('cannot set absolute and withFileTypes:true'); 97 } 98 if (typeof pattern === 'string') { 99 pattern = [pattern]; 100 } 101 this.windowsPathsNoEscape = 102 !!opts.windowsPathsNoEscape || 103 opts.allowWindowsEscape === false; 104 if (this.windowsPathsNoEscape) { 105 pattern = pattern.map(p => p.replace(/\\/g, '/')); 106 } 107 if (this.matchBase) { 108 if (opts.noglobstar) { 109 throw new TypeError('base matching requires globstar'); 110 } 111 pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`)); 112 } 113 this.pattern = pattern; 114 this.platform = opts.platform || defaultPlatform; 115 this.opts = { ...opts, platform: this.platform }; 116 if (opts.scurry) { 117 this.scurry = opts.scurry; 118 if (opts.nocase !== undefined && 119 opts.nocase !== opts.scurry.nocase) { 120 throw new Error('nocase option contradicts provided scurry option'); 121 } 122 } 123 else { 124 const Scurry = opts.platform === 'win32' 125 ? path_scurry_1.PathScurryWin32 126 : opts.platform === 'darwin' 127 ? path_scurry_1.PathScurryDarwin 128 : opts.platform 129 ? path_scurry_1.PathScurryPosix 130 : path_scurry_1.PathScurry; 131 this.scurry = new Scurry(this.cwd, { 132 nocase: opts.nocase, 133 fs: opts.fs, 134 }); 135 } 136 this.nocase = this.scurry.nocase; 137 // If you do nocase:true on a case-sensitive file system, then 138 // we need to use regexps instead of strings for non-magic 139 // path portions, because statting `aBc` won't return results 140 // for the file `AbC` for example. 141 const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32'; 142 const mmo = { 143 // default nocase based on platform 144 ...opts, 145 dot: this.dot, 146 matchBase: this.matchBase, 147 nobrace: this.nobrace, 148 nocase: this.nocase, 149 nocaseMagicOnly, 150 nocomment: true, 151 noext: this.noext, 152 nonegate: true, 153 optimizationLevel: 2, 154 platform: this.platform, 155 windowsPathsNoEscape: this.windowsPathsNoEscape, 156 debug: !!this.opts.debug, 157 }; 158 const mms = this.pattern.map(p => new minimatch_1.Minimatch(p, mmo)); 159 const [matchSet, globParts] = mms.reduce((set, m) => { 160 set[0].push(...m.set); 161 set[1].push(...m.globParts); 162 return set; 163 }, [[], []]); 164 this.patterns = matchSet.map((set, i) => { 165 const g = globParts[i]; 166 /* c8 ignore start */ 167 if (!g) 168 throw new Error('invalid pattern object'); 169 /* c8 ignore stop */ 170 return new pattern_js_1.Pattern(set, g, 0, this.platform); 171 }); 172 } 173 async walk() { 174 // Walkers always return array of Path objects, so we just have to 175 // coerce them into the right shape. It will have already called 176 // realpath() if the option was set to do so, so we know that's cached. 177 // start out knowing the cwd, at least 178 return [ 179 ...(await new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, { 180 ...this.opts, 181 maxDepth: this.maxDepth !== Infinity 182 ? this.maxDepth + this.scurry.cwd.depth() 183 : Infinity, 184 platform: this.platform, 185 nocase: this.nocase, 186 }).walk()), 187 ]; 188 } 189 walkSync() { 190 return [ 191 ...new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, { 192 ...this.opts, 193 maxDepth: this.maxDepth !== Infinity 194 ? this.maxDepth + this.scurry.cwd.depth() 195 : Infinity, 196 platform: this.platform, 197 nocase: this.nocase, 198 }).walkSync(), 199 ]; 200 } 201 stream() { 202 return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, { 203 ...this.opts, 204 maxDepth: this.maxDepth !== Infinity 205 ? this.maxDepth + this.scurry.cwd.depth() 206 : Infinity, 207 platform: this.platform, 208 nocase: this.nocase, 209 }).stream(); 210 } 211 streamSync() { 212 return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, { 213 ...this.opts, 214 maxDepth: this.maxDepth !== Infinity 215 ? this.maxDepth + this.scurry.cwd.depth() 216 : Infinity, 217 platform: this.platform, 218 nocase: this.nocase, 219 }).streamSync(); 220 } 221 /** 222 * Default sync iteration function. Returns a Generator that 223 * iterates over the results. 224 */ 225 iterateSync() { 226 return this.streamSync()[Symbol.iterator](); 227 } 228 [Symbol.iterator]() { 229 return this.iterateSync(); 230 } 231 /** 232 * Default async iteration function. Returns an AsyncGenerator that 233 * iterates over the results. 234 */ 235 iterate() { 236 return this.stream()[Symbol.asyncIterator](); 237 } 238 [Symbol.asyncIterator]() { 239 return this.iterate(); 240 } 241} 242exports.Glob = Glob; 243//# sourceMappingURL=glob.js.map