| Name | Size | Mode | Actions |
|---|---|---|---|
| assert-valid-pattern.js | 492 | 0644 | editdlrm |
| ast.js | 30629 | 0644 | editdlrm |
| brace-expressions.js | 5743 | 0644 | editdlrm |
| escape.js | 1253 | 0644 | editdlrm |
| index.js | 44993 | 0644 | editdlrm |
| package.json | 25 | 0644 | editdlrm |
| unescape.js | 1396 | 0644 | editdlrm |
/usr/local/lib/node_modules/npm/node_modules/minimatch/dist/commonjs/index.js (44993B)
// -> /if (!this.preserveMultipleSlashes) { for (let i = 1; i < parts.length - 1; i++) { const p = parts[i]; // don't squeeze out UNC patterns if (i === 1 && p === '' && parts[0] === '') continue; if (p === '.' || p === '') { didSomething = true; parts.splice(i, 1); i--; } } if (parts[0] === '.' && parts.length === 2 && (parts[1] === '.' || parts[1] === '')) { didSomething = true; parts.pop(); } } // //../
-> /let dd = 0; while (-1 !== (dd = parts.indexOf('..', dd + 1))) { const p = parts[dd - 1]; if (p && p !== '.' && p !== '..' && p !== '**') { didSomething = true; parts.splice(dd - 1, 2); dd -= 2; } } } while (didSomething); return parts.length === 0 ? [''] : parts; } // First phase: single-pattern processing // is 1 or more portions //is 1 or more portions // is any portion other than ., .., '', or ** //
is . or '' // // **/.. is *brutal* for filesystem walking performance, because // it effectively resets the recursive walk each time it occurs, // and ** cannot be reduced out by a .. pattern part like a regexp // or most strings (other than .., ., and '') can be. // // /**/..//
/
-> { /..//
/
, /**//
/
} // // -> /// //../
-> /// **/**/ -> **/ // // **/*/ -> */**/ <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(globParts) { let didSomething = false; do { didSomething = false; // /**/..//
/
-> { /..//
/
, /**//
/
} for (let parts of globParts) { let gs = -1; while (-1 !== (gs = parts.indexOf('**', gs + 1))) { let gss = gs; while (parts[gss + 1] === '**') { // /**/**/-> /**/gss++; } // eg, if gs is 2 and gss is 4, that means we have 3 ** // parts, and can remove 2 of them. if (gss > gs) { parts.splice(gs + 1, gss - gs); } let next = parts[gs + 1]; const p = parts[gs + 2]; const p2 = parts[gs + 3]; if (next !== '..') continue; if (!p || p === '.' || p === '..' || !p2 || p2 === '.' || p2 === '..') { continue; } didSomething = true; // edit parts in place, and push the new one parts.splice(gs, 1); const other = parts.slice(0); other[gs] = '**'; globParts.push(other); gs--; } // // -> /if (!this.preserveMultipleSlashes) { for (let i = 1; i < parts.length - 1; i++) { const p = parts[i]; // don't squeeze out UNC patterns if (i === 1 && p === '' && parts[0] === '') continue; if (p === '.' || p === '') { didSomething = true; parts.splice(i, 1); i--; } } if (parts[0] === '.' && parts.length === 2 && (parts[1] === '.' || parts[1] === '')) { didSomething = true; parts.pop(); } } // //../
-> /let dd = 0; while (-1 !== (dd = parts.indexOf('..', dd + 1))) { const p = parts[dd - 1]; if (p && p !== '.' && p !== '..' && p !== '**') { didSomething = true; const needDot = dd === 1 && parts[dd + 1] === '**'; const splin = needDot ? ['.'] : []; parts.splice(dd - 1, 2, ...splin); if (parts.length === 0) parts.push(''); dd -= 2; } } } } while (didSomething); return globParts; } // second phase: multi-pattern dedupes // { /*/, //
} -> /*/// { /, /} -> /// { /**/, /} -> /**/// // { /**/, /**//
} -> /**/// ^-- not valid because ** doens't follow symlinks secondPhasePreProcess(globParts) { for (let i = 0; i < globParts.length - 1; i++) { for (let j = i + 1; j < globParts.length; j++) { const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes); if (matched) { globParts[i] = []; globParts[j] = matched; break; } } } return globParts.filter(gs => gs.length); } partsMatch(a, b, emptyGSMatch = false) { let ai = 0; let bi = 0; let result = []; let which = ''; while (ai < a.length && bi < b.length) { if (a[ai] === b[bi]) { result.push(which === 'b' ? b[bi] : a[ai]); ai++; bi++; } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) { result.push(a[ai]); ai++; } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) { result.push(b[bi]); bi++; } else if (a[ai] === '*' && b[bi] && (this.options.dot || !b[bi].startsWith('.')) && b[bi] !== '**') { if (which === 'b') return false; which = 'a'; result.push(a[ai]); ai++; bi++; } else if (b[bi] === '*' && a[ai] && (this.options.dot || !a[ai].startsWith('.')) && a[ai] !== '**') { if (which === 'a') return false; which = 'b'; result.push(b[bi]); ai++; bi++; } else { return false; } } // if we fall out of the loop, it means they two are identical // as long as their lengths match return a.length === b.length && result; } parseNegate() { if (this.nonegate) return; const pattern = this.pattern; let negate = false; let negateOffset = 0; for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { negate = !negate; negateOffset++; } if (negateOffset) this.pattern = pattern.slice(negateOffset); this.negate = negate; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. matchOne(file, pattern, partial = false) { let fileStartIndex = 0; let patternStartIndex = 0; // UNC paths like //?/X:/... can match X:/... and vice versa // Drive letters in absolute drive or unc paths are always compared // case-insensitively. if (this.isWindows) { const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]); const fileUNC = !fileDrive && file[0] === '' && file[1] === '' && file[2] === '?' && /^[a-z]:$/i.test(file[3]); const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]); const patternUNC = !patternDrive && pattern[0] === '' && pattern[1] === '' && pattern[2] === '?' && typeof pattern[3] === 'string' && /^[a-z]:$/i.test(pattern[3]); const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined; const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined; if (typeof fdi === 'number' && typeof pdi === 'number') { const [fd, pd] = [ file[fdi], pattern[pdi], ]; // start matching at the drive letter index of each if (fd.toLowerCase() === pd.toLowerCase()) { pattern[pdi] = fd; patternStartIndex = pdi; fileStartIndex = fdi; } } } // resolve and reduce . and .. portions in the file as well. // don't need to do the second phase, because it's only one string[] const { optimizationLevel = 1 } = this.options; if (optimizationLevel >= 2) { file = this.levelTwoFileOptimize(file); } if (pattern.includes(exports.GLOBSTAR)) { return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex); } return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex); } #matchGlobstar(file, pattern, partial, fileIndex, patternIndex) { // split the pattern into head, tail, and middle of ** delimited parts const firstgs = pattern.indexOf(exports.GLOBSTAR, patternIndex); const lastgs = pattern.lastIndexOf(exports.GLOBSTAR); // split the pattern up into globstar-delimited sections // the tail has to be at the end, and the others just have // to be found in order from the head. const [head, body, tail] = partial ? [ pattern.slice(patternIndex, firstgs), pattern.slice(firstgs + 1), [], ] : [ pattern.slice(patternIndex, firstgs), pattern.slice(firstgs + 1, lastgs), pattern.slice(lastgs + 1), ]; // check the head, from the current file/pattern index. if (head.length) { const fileHead = file.slice(fileIndex, fileIndex + head.length); if (!this.#matchOne(fileHead, head, partial, 0, 0)) { return false; } fileIndex += head.length; patternIndex += head.length; } // now we know the head matches! // if the last portion is not empty, it MUST match the end // check the tail let fileTailMatch = 0; if (tail.length) { // if head + tail > file, then we cannot possibly match if (tail.length + fileIndex > file.length) return false; // try to match the tail let tailStart = file.length - tail.length; if (this.#matchOne(file, tail, partial, tailStart, 0)) { fileTailMatch = tail.length; } else { // affordance for stuff like a/**/* matching a/b/ // if the last file portion is '', and there's more to the pattern // then try without the '' bit. if (file[file.length - 1] !== '' || fileIndex + tail.length === file.length) { return false; } tailStart--; if (!this.#matchOne(file, tail, partial, tailStart, 0)) { return false; } fileTailMatch = tail.length + 1; } } // now we know the tail matches! // the middle is zero or more portions wrapped in **, possibly // containing more ** sections. // so a/**/b/**/c/**/d has become **/b/**/c/** // if it's empty, it means a/**/b, just verify we have no bad dots // if there's no tail, so it ends on /**, then we must have *something* // after the head, or it's not a matc if (!body.length) { let sawSome = !!fileTailMatch; for (let i = fileIndex; i < file.length - fileTailMatch; i++) { const f = String(file[i]); sawSome = true; if (f === '.' || f === '..' || (!this.options.dot && f.startsWith('.'))) { return false; } } // in partial mode, we just need to get past all file parts return partial || sawSome; } // now we know that there's one or more body sections, which can // be matched anywhere from the 0 index (because the head was pruned) // through to the length-fileTailMatch index. // split the body up into sections, and note the minimum index it can // be found at (start with the length of all previous segments) // [section, before, after] const bodySegments = [[[], 0]]; let currentBody = bodySegments[0]; let nonGsParts = 0; const nonGsPartsSums = [0]; for (const b of body) { if (b === exports.GLOBSTAR) { nonGsPartsSums.push(nonGsParts); currentBody = [[], 0]; bodySegments.push(currentBody); } else { currentBody[0].push(b); nonGsParts++; } } let i = bodySegments.length - 1; const fileLength = file.length - fileTailMatch; for (const b of bodySegments) { b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length); } return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch); } // return false for "nope, not matching" // return null for "not matching, cannot keep trying" #matchGlobStarBodySections(file, // pattern section, last possible position for it bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) { // take the first body segment, and walk from fileIndex to its "after" // value at the end // If it doesn't match at that position, we increment, until we hit // that final possible position, and give up. // If it does match, then advance and try to rest. // If any of them fail we keep walking forward. // this is still a bit recursively painful, but it's more constrained // than previous implementations, because we never test something that // can't possibly be a valid matching condition. const bs = bodySegments[bodyIndex]; if (!bs) { // just make sure that there's no bad dots for (let i = fileIndex; i < file.length; i++) { sawTail = true; const f = file[i]; if (f === '.' || f === '..' || (!this.options.dot && f.startsWith('.'))) { return false; } } return sawTail; } // have a non-globstar body section to test const [body, after] = bs; while (fileIndex <= after) { const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0); // if limit exceeded, no match. intentional false negative, // acceptable break in correctness for security. if (m && globStarDepth < this.maxGlobstarRecursion) { // match! see if the rest match. if so, we're done! const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail); if (sub !== false) { return sub; } } const f = file[fileIndex]; if (f === '.' || f === '..' || (!this.options.dot && f.startsWith('.'))) { return false; } fileIndex++; } // walked off. no point continuing return partial || null; } #matchOne(file, pattern, partial, fileIndex, patternIndex) { let fi; let pi; let pl; let fl; for (fi = fileIndex, pi = patternIndex, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { this.debug('matchOne loop'); let p = pattern[pi]; let f = file[fi]; this.debug(pattern, p, f); // should be impossible. // some invalid regexp stuff in the set. /* c8 ignore start */ if (p === false || p === exports.GLOBSTAR) { return false; } /* c8 ignore stop */ // something other than ** // non-magic patterns just have to match exactly // patterns with magic have been turned into regexps. let hit; if (typeof p === 'string') { hit = f === p; this.debug('string match', p, f, hit); } else { hit = p.test(f); this.debug('pattern match', p, f, hit); } if (!hit) return false; } // Note: ending in / means that we'll get a final "" // at the end of the pattern. This can only match a // corresponding "" at the end of the file. // If the file ends in /, then it can only match a // a pattern that ends in /, unless the pattern just // doesn't have any more for it. But, a/b/ should *not* // match "a/b/*", even though "" matches against the // [^/]*? pattern, except in partial mode, where it might // simply not be reached yet. // However, a/b/ should still satisfy a/* // now either we fell off the end of the pattern, or we're done. if (fi === fl && pi === pl) { // ran out of pattern and filename at the same time. // an exact hit! return true; } else if (fi === fl) { // ran out of file, but still had pattern left. // this is ok if we're doing the match as part of // a glob fs traversal. return partial; } else if (pi === pl) { // ran out of pattern, still have file left. // this is only acceptable if we're on the very last // empty segment of a file with a trailing slash. // a/* should match a/b/ return fi === fl - 1 && file[fi] === ''; /* c8 ignore start */ } else { // should be unreachable. throw new Error('wtf?'); } /* c8 ignore stop */ } braceExpand() { return (0, exports.braceExpand)(this.pattern, this.options); } parse(pattern) { (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); const options = this.options; // shortcuts if (pattern === '**') return exports.GLOBSTAR; if (pattern === '') return ''; // far and away, the most common glob pattern parts are // *, *.*, and *. Add a fast check method for those. let m; let fastTest = null; if ((m = pattern.match(starRE))) { fastTest = options.dot ? starTestDot : starTest; } else if ((m = pattern.match(starDotExtRE))) { fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]); } else if ((m = pattern.match(qmarksRE))) { fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m); } else if ((m = pattern.match(starDotStarRE))) { fastTest = options.dot ? starDotStarTestDot : starDotStarTest; } else if ((m = pattern.match(dotStarRE))) { fastTest = dotStarTest; } const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern(); if (fastTest && typeof re === 'object') { // Avoids overriding in frozen environments Reflect.defineProperty(re, 'test', { value: fastTest }); } return re; } makeRe() { if (this.regexp || this.regexp === false) return this.regexp; // at this point, this.set is a 2d array of partial // pattern strings, or "**". // // It's better to use .match(). This function shouldn't // be used, really, but it's pretty convenient sometimes, // when you just want to work with a regex. const set = this.set; if (!set.length) { this.regexp = false; return this.regexp; } const options = this.options; const twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; const flags = new Set(options.nocase ? ['i'] : []); // regexpify non-globstar patterns // if ** is only item, then we just do one twoStar // if ** is first, and there are more, prepend (\/|twoStar\/)? to next // if ** is last, append (\/twoStar|) to previous // if ** is in the middle, append (\/|\/twoStar\/) to previous // then filter out GLOBSTAR symbols let re = set .map(pattern => { const pp = pattern.map(p => { if (p instanceof RegExp) { for (const f of p.flags.split('')) flags.add(f); } return (typeof p === 'string' ? regExpEscape(p) : p === exports.GLOBSTAR ? exports.GLOBSTAR : p._src); }); pp.forEach((p, i) => { const next = pp[i + 1]; const prev = pp[i - 1]; if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) { return; } if (prev === undefined) { if (next !== undefined && next !== exports.GLOBSTAR) { pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; } else { pp[i] = twoStar; } } else if (next === undefined) { pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?'; } else if (next !== exports.GLOBSTAR) { pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; pp[i + 1] = exports.GLOBSTAR; } }); const filtered = pp.filter(p => p !== exports.GLOBSTAR); // For partial matches, we need to make the pattern match // any prefix of the full path. We do this by generating // alternative patterns that match progressively longer prefixes. if (this.partial && filtered.length >= 1) { const prefixes = []; for (let i = 1; i <= filtered.length; i++) { prefixes.push(filtered.slice(0, i).join('/')); } return '(?:' + prefixes.join('|') + ')'; } return filtered.join('/'); }) .join('|'); // need to wrap in parens if we had more than one thing with |, // otherwise only the first will be anchored to ^ and the last to $ const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']; // must match entire pattern // ending in a * or ** will make it less strict. re = '^' + open + re + close + '$'; // In partial mode, '/' should always match as it's a valid prefix for any pattern if (this.partial) { re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$'; } // can match anything, as long as it's not this. if (this.negate) re = '^(?!' + re + ').+$'; try { this.regexp = new RegExp(re, [...flags].join('')); /* c8 ignore start */ } catch (ex) { // should be impossible this.regexp = false; } /* c8 ignore stop */ return this.regexp; } slashSplit(p) { // if p starts with // on windows, we preserve that // so that UNC paths aren't broken. Otherwise, any number of // / characters are coalesced into one, unless // preserveMultipleSlashes is set to true. if (this.preserveMultipleSlashes) { return p.split('/'); } else if (this.isWindows && /^\/\/[^\/]+/.test(p)) { // add an extra '' for the one we lose return ['', ...p.split(/\/+/)]; } else { return p.split(/\/+/); } } match(f, partial = this.partial) { this.debug('match', f, this.pattern); // short-circuit in the case of busted things. // comments, etc. if (this.comment) { return false; } if (this.empty) { return f === ''; } if (f === '/' && partial) { return true; } const options = this.options; // windows: need to use /, not \ if (this.isWindows) { f = f.split('\\').join('/'); } // treat the test path as a set of pathparts. const ff = this.slashSplit(f); this.debug(this.pattern, 'split', ff); // just ONE of the pattern sets in this.set needs to match // in order for it to be valid. If negating, then just one // match means that we have failed. // Either way, return on the first hit. const set = this.set; this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment let filename = ff[ff.length - 1]; if (!filename) { for (let i = ff.length - 2; !filename && i >= 0; i--) { filename = ff[i]; } } for (let i = 0; i < set.length; i++) { const pattern = set[i]; let file = ff; if (options.matchBase && pattern.length === 1) { file = [filename]; } const hit = this.matchOne(file, pattern, partial); if (hit) { if (options.flipNegate) { return true; } return !this.negate; } } // didn't get any hits. this is success if it's a negative // pattern, failure otherwise. if (options.flipNegate) { return false; } return this.negate; } static defaults(def) { return exports.minimatch.defaults(def).Minimatch; } } exports.Minimatch = Minimatch; /* c8 ignore start */ var ast_js_2 = require("./ast.js"); Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } }); var escape_js_2 = require("./escape.js"); Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } }); var unescape_js_2 = require("./unescape.js"); Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } }); /* c8 ignore stop */ exports.minimatch.AST = ast_js_1.AST; exports.minimatch.Minimatch = Minimatch; exports.minimatch.escape = escape_js_1.escape; exports.minimatch.unescape = unescape_js_1.unescape; //# sourceMappingURL=index.js.map