"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GlobMatcher = void 0; const mm = require("micromatch"); const path = require("path"); class GlobMatcher { /** * Construct a `.gitignore` emulator * @param patterns the contents of a `.gitignore` style file or an array of individual glob rules. * @param root the working directory */ constructor(patterns, root, nodePath) { this.patterns = patterns; this.root = root; this.path = nodePath !== null && nodePath !== void 0 ? nodePath : path; this.matchEx = buildMatcherFn(this.path, patterns, root); } /** * Check to see if a filename matches any of the globs. * If filename is relative, it is considered relative to the root. * If filename is absolute and contained within the root, it will be made relative before being tested for a glob match. * If filename is absolute and not contained within the root, it will be tested as is. * @param filename full path of the file to check. */ match(filename) { return this.matchEx(filename).matched; } } exports.GlobMatcher = GlobMatcher; /** * This function attempts to emulate .gitignore functionality as much as possible. * * The resulting matcher function: (filename: string) => GlobMatch * * If filename is relative, it is considered relative to the root. * If filename is absolute and contained within the root, it will be made relative before being tested for a glob match. * If filename is absolute and not contained within the root, it will be tested as is. * * @param patterns the contents of a .gitignore style file or an array of individual glob rules. * @param root the working directory * @returns a function given a filename returns true if it matches. */ function buildMatcherFn(path, patterns, root) { if (typeof patterns == 'string') { patterns = patterns.split(/\r?\n/g); } const dirRoot = path.normalize(root || '/'); const rules = patterns .map((p) => p.trim()) .map((p, index) => ({ glob: p, index })) .filter((r) => !!r.glob) .map(({ glob, index }) => { const matchNeg = glob.match(/^!+/); const isNeg = (matchNeg && matchNeg[0].length & 1 && true) || false; const pattern = mutations.reduce((p, [regex, replace]) => p.replace(regex, replace), glob); const reg = mm.makeRe(pattern); const fn = (filename) => { const match = filename.match(reg); return !!match; }; return { glob, index, isNeg, fn, reg }; }); const negRules = rules.filter((r) => r.isNeg); const posRules = rules.filter((r) => !r.isNeg); const fn = (filename) => { filename = path.normalize(filename); const offset = dirRoot === filename.slice(0, dirRoot.length) ? dirRoot.length : 0; const lName = filename.slice(offset); const filePath = path.parse(lName); const relPath = path.join(filePath.dir.slice(filePath.root.length), filePath.base); const fname = relPath.split(path.sep).join('/'); for (const rule of negRules) { if (rule.fn(fname)) { return { matched: false, glob: rule.glob, index: rule.index, isNeg: rule.isNeg }; } } for (const rule of posRules) { if (rule.fn(fname)) { return { matched: true, glob: rule.glob, index: rule.index, isNeg: rule.isNeg }; } } return { matched: false }; }; return fn; } const mutations = [ [/^!+/, ''], [/^[^/#][^/]*$/, '**/{$&,$&/**}'], [/^\/(?!\/)/, ''], [/\/$/, '$&**'], ]; //# sourceMappingURL=GlobMatcher.js.map