Permalink
Cannot retrieve contributors at this time
467 lines (409 sloc)
13.4 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/micromatch/index.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const util = require('util'); | |
const braces = require('braces'); | |
const picomatch = require('picomatch'); | |
const utils = require('picomatch/lib/utils'); | |
const isEmptyString = val => val === '' || val === './'; | |
/** | |
* Returns an array of strings that match one or more glob patterns. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm(list, patterns[, options]); | |
* | |
* console.log(mm(['a.js', 'a.txt'], ['*.js'])); | |
* //=> [ 'a.js' ] | |
* ``` | |
* @param {String|Array<string>} `list` List of strings to match. | |
* @param {String|Array<string>} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `options` See available [options](#options) | |
* @return {Array} Returns an array of matches | |
* @summary false | |
* @api public | |
*/ | |
const micromatch = (list, patterns, options) => { | |
patterns = [].concat(patterns); | |
list = [].concat(list); | |
let omit = new Set(); | |
let keep = new Set(); | |
let items = new Set(); | |
let negatives = 0; | |
let onResult = state => { | |
items.add(state.output); | |
if (options && options.onResult) { | |
options.onResult(state); | |
} | |
}; | |
for (let i = 0; i < patterns.length; i++) { | |
let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); | |
let negated = isMatch.state.negated || isMatch.state.negatedExtglob; | |
if (negated) negatives++; | |
for (let item of list) { | |
let matched = isMatch(item, true); | |
let match = negated ? !matched.isMatch : matched.isMatch; | |
if (!match) continue; | |
if (negated) { | |
omit.add(matched.output); | |
} else { | |
omit.delete(matched.output); | |
keep.add(matched.output); | |
} | |
} | |
} | |
let result = negatives === patterns.length ? [...items] : [...keep]; | |
let matches = result.filter(item => !omit.has(item)); | |
if (options && matches.length === 0) { | |
if (options.failglob === true) { | |
throw new Error(`No matches found for "${patterns.join(', ')}"`); | |
} | |
if (options.nonull === true || options.nullglob === true) { | |
return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; | |
} | |
} | |
return matches; | |
}; | |
/** | |
* Backwards compatibility | |
*/ | |
micromatch.match = micromatch; | |
/** | |
* Returns a matcher function from the given glob `pattern` and `options`. | |
* The returned function takes a string to match as its only argument and returns | |
* true if the string is a match. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.matcher(pattern[, options]); | |
* | |
* const isMatch = mm.matcher('*.!(*a)'); | |
* console.log(isMatch('a.a')); //=> false | |
* console.log(isMatch('a.b')); //=> true | |
* ``` | |
* @param {String} `pattern` Glob pattern | |
* @param {Object} `options` | |
* @return {Function} Returns a matcher function. | |
* @api public | |
*/ | |
micromatch.matcher = (pattern, options) => picomatch(pattern, options); | |
/** | |
* Returns true if **any** of the given glob `patterns` match the specified `string`. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.isMatch(string, patterns[, options]); | |
* | |
* console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true | |
* console.log(mm.isMatch('a.a', 'b.*')); //=> false | |
* ``` | |
* @param {String} `str` The string to test. | |
* @param {String|Array} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `[options]` See available [options](#options). | |
* @return {Boolean} Returns true if any patterns match `str` | |
* @api public | |
*/ | |
micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); | |
/** | |
* Backwards compatibility | |
*/ | |
micromatch.any = micromatch.isMatch; | |
/** | |
* Returns a list of strings that _**do not match any**_ of the given `patterns`. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.not(list, patterns[, options]); | |
* | |
* console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); | |
* //=> ['b.b', 'c.c'] | |
* ``` | |
* @param {Array} `list` Array of strings to match. | |
* @param {String|Array} `patterns` One or more glob pattern to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Array} Returns an array of strings that **do not match** the given patterns. | |
* @api public | |
*/ | |
micromatch.not = (list, patterns, options = {}) => { | |
patterns = [].concat(patterns).map(String); | |
let result = new Set(); | |
let items = []; | |
let onResult = state => { | |
if (options.onResult) options.onResult(state); | |
items.push(state.output); | |
}; | |
let matches = new Set(micromatch(list, patterns, { ...options, onResult })); | |
for (let item of items) { | |
if (!matches.has(item)) { | |
result.add(item); | |
} | |
} | |
return [...result]; | |
}; | |
/** | |
* Returns true if the given `string` contains the given pattern. Similar | |
* to [.isMatch](#isMatch) but the pattern can match any part of the string. | |
* | |
* ```js | |
* var mm = require('micromatch'); | |
* // mm.contains(string, pattern[, options]); | |
* | |
* console.log(mm.contains('aa/bb/cc', '*b')); | |
* //=> true | |
* console.log(mm.contains('aa/bb/cc', '*d')); | |
* //=> false | |
* ``` | |
* @param {String} `str` The string to match. | |
* @param {String|Array} `patterns` Glob pattern to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Boolean} Returns true if any of the patterns matches any part of `str`. | |
* @api public | |
*/ | |
micromatch.contains = (str, pattern, options) => { | |
if (typeof str !== 'string') { | |
throw new TypeError(`Expected a string: "${util.inspect(str)}"`); | |
} | |
if (Array.isArray(pattern)) { | |
return pattern.some(p => micromatch.contains(str, p, options)); | |
} | |
if (typeof pattern === 'string') { | |
if (isEmptyString(str) || isEmptyString(pattern)) { | |
return false; | |
} | |
if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { | |
return true; | |
} | |
} | |
return micromatch.isMatch(str, pattern, { ...options, contains: true }); | |
}; | |
/** | |
* Filter the keys of the given object with the given `glob` pattern | |
* and `options`. Does not attempt to match nested keys. If you need this feature, | |
* use [glob-object][] instead. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.matchKeys(object, patterns[, options]); | |
* | |
* const obj = { aa: 'a', ab: 'b', ac: 'c' }; | |
* console.log(mm.matchKeys(obj, '*b')); | |
* //=> { ab: 'b' } | |
* ``` | |
* @param {Object} `object` The object with keys to filter. | |
* @param {String|Array} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Object} Returns an object with only keys that match the given patterns. | |
* @api public | |
*/ | |
micromatch.matchKeys = (obj, patterns, options) => { | |
if (!utils.isObject(obj)) { | |
throw new TypeError('Expected the first argument to be an object'); | |
} | |
let keys = micromatch(Object.keys(obj), patterns, options); | |
let res = {}; | |
for (let key of keys) res[key] = obj[key]; | |
return res; | |
}; | |
/** | |
* Returns true if some of the strings in the given `list` match any of the given glob `patterns`. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.some(list, patterns[, options]); | |
* | |
* console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); | |
* // true | |
* console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); | |
* // false | |
* ``` | |
* @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. | |
* @param {String|Array} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Boolean} Returns true if any `patterns` matches any of the strings in `list` | |
* @api public | |
*/ | |
micromatch.some = (list, patterns, options) => { | |
let items = [].concat(list); | |
for (let pattern of [].concat(patterns)) { | |
let isMatch = picomatch(String(pattern), options); | |
if (items.some(item => isMatch(item))) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
/** | |
* Returns true if every string in the given `list` matches | |
* any of the given glob `patterns`. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.every(list, patterns[, options]); | |
* | |
* console.log(mm.every('foo.js', ['foo.js'])); | |
* // true | |
* console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); | |
* // true | |
* console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); | |
* // false | |
* console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); | |
* // false | |
* ``` | |
* @param {String|Array} `list` The string or array of strings to test. | |
* @param {String|Array} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Boolean} Returns true if all `patterns` matches all of the strings in `list` | |
* @api public | |
*/ | |
micromatch.every = (list, patterns, options) => { | |
let items = [].concat(list); | |
for (let pattern of [].concat(patterns)) { | |
let isMatch = picomatch(String(pattern), options); | |
if (!items.every(item => isMatch(item))) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
/** | |
* Returns true if **all** of the given `patterns` match | |
* the specified string. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.all(string, patterns[, options]); | |
* | |
* console.log(mm.all('foo.js', ['foo.js'])); | |
* // true | |
* | |
* console.log(mm.all('foo.js', ['*.js', '!foo.js'])); | |
* // false | |
* | |
* console.log(mm.all('foo.js', ['*.js', 'foo.js'])); | |
* // true | |
* | |
* console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); | |
* // true | |
* ``` | |
* @param {String|Array} `str` The string to test. | |
* @param {String|Array} `patterns` One or more glob patterns to use for matching. | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Boolean} Returns true if any patterns match `str` | |
* @api public | |
*/ | |
micromatch.all = (str, patterns, options) => { | |
if (typeof str !== 'string') { | |
throw new TypeError(`Expected a string: "${util.inspect(str)}"`); | |
} | |
return [].concat(patterns).every(p => picomatch(p, options)(str)); | |
}; | |
/** | |
* Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.capture(pattern, string[, options]); | |
* | |
* console.log(mm.capture('test/*.js', 'test/foo.js')); | |
* //=> ['foo'] | |
* console.log(mm.capture('test/*.js', 'foo/bar.css')); | |
* //=> null | |
* ``` | |
* @param {String} `glob` Glob pattern to use for matching. | |
* @param {String} `input` String to match | |
* @param {Object} `options` See available [options](#options) for changing how matches are performed | |
* @return {Array|null} Returns an array of captures if the input matches the glob pattern, otherwise `null`. | |
* @api public | |
*/ | |
micromatch.capture = (glob, input, options) => { | |
let posix = utils.isWindows(options); | |
let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); | |
let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); | |
if (match) { | |
return match.slice(1).map(v => v === void 0 ? '' : v); | |
} | |
}; | |
/** | |
* Create a regular expression from the given glob `pattern`. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* // mm.makeRe(pattern[, options]); | |
* | |
* console.log(mm.makeRe('*.js')); | |
* //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ | |
* ``` | |
* @param {String} `pattern` A glob pattern to convert to regex. | |
* @param {Object} `options` | |
* @return {RegExp} Returns a regex created from the given pattern. | |
* @api public | |
*/ | |
micromatch.makeRe = (...args) => picomatch.makeRe(...args); | |
/** | |
* Scan a glob pattern to separate the pattern into segments. Used | |
* by the [split](#split) method. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* const state = mm.scan(pattern[, options]); | |
* ``` | |
* @param {String} `pattern` | |
* @param {Object} `options` | |
* @return {Object} Returns an object with | |
* @api public | |
*/ | |
micromatch.scan = (...args) => picomatch.scan(...args); | |
/** | |
* Parse a glob pattern to create the source string for a regular | |
* expression. | |
* | |
* ```js | |
* const mm = require('micromatch'); | |
* const state = mm.parse(pattern[, options]); | |
* ``` | |
* @param {String} `glob` | |
* @param {Object} `options` | |
* @return {Object} Returns an object with useful properties and output to be used as regex source string. | |
* @api public | |
*/ | |
micromatch.parse = (patterns, options) => { | |
let res = []; | |
for (let pattern of [].concat(patterns || [])) { | |
for (let str of braces(String(pattern), options)) { | |
res.push(picomatch.parse(str, options)); | |
} | |
} | |
return res; | |
}; | |
/** | |
* Process the given brace `pattern`. | |
* | |
* ```js | |
* const { braces } = require('micromatch'); | |
* console.log(braces('foo/{a,b,c}/bar')); | |
* //=> [ 'foo/(a|b|c)/bar' ] | |
* | |
* console.log(braces('foo/{a,b,c}/bar', { expand: true })); | |
* //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] | |
* ``` | |
* @param {String} `pattern` String with brace pattern to process. | |
* @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. | |
* @return {Array} | |
* @api public | |
*/ | |
micromatch.braces = (pattern, options) => { | |
if (typeof pattern !== 'string') throw new TypeError('Expected a string'); | |
if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { | |
return [pattern]; | |
} | |
return braces(pattern, options); | |
}; | |
/** | |
* Expand braces | |
*/ | |
micromatch.braceExpand = (pattern, options) => { | |
if (typeof pattern !== 'string') throw new TypeError('Expected a string'); | |
return micromatch.braces(pattern, { ...options, expand: true }); | |
}; | |
/** | |
* Expose micromatch | |
*/ | |
module.exports = micromatch; |