Comparing version 1.2.0 to 2.0.0
'use strict'; | ||
const isWindows = process.platform === 'win32'; | ||
const path = require('path'); | ||
const isWindows = process.platform === 'win32' || path.sep === '\\'; | ||
const WIN_SLASH = '\\\\/'; | ||
const WIN_NO_SLASH = `[^${WIN_SLASH}]`; | ||
/** | ||
* Posix glob regex | ||
*/ | ||
const DOT_LITERAL = '\\.'; | ||
const PLUS_LITERAL = '\\+'; | ||
const QMARK_LITERAL = '\\?'; | ||
const SLASH_LITERAL = '\\/'; | ||
const ONE_CHAR = '(?=.)'; | ||
const QMARK = '[^/]'; | ||
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; | ||
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; | ||
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; | ||
const NO_DOT = `(?!${DOT_LITERAL})`; | ||
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; | ||
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; | ||
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; | ||
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; | ||
const STAR = `${QMARK}*?`; | ||
const POSIX_CHARS = { | ||
DOT_LITERAL, | ||
PLUS_LITERAL, | ||
QMARK_LITERAL, | ||
SLASH_LITERAL, | ||
ONE_CHAR, | ||
QMARK, | ||
END_ANCHOR, | ||
DOTS_SLASH, | ||
NO_DOT, | ||
NO_DOTS, | ||
NO_DOT_SLASH, | ||
NO_DOTS_SLASH, | ||
QMARK_NO_DOT, | ||
STAR, | ||
START_ANCHOR | ||
}; | ||
/** | ||
* Windows glob regex | ||
*/ | ||
const WINDOWS_CHARS = { | ||
...POSIX_CHARS, | ||
QMARK: WIN_NO_SLASH, | ||
STAR: `${WIN_NO_SLASH}*?`, | ||
DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, | ||
NO_DOT: `(?!${DOT_LITERAL})`, | ||
NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, | ||
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, | ||
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, | ||
QMARK_NO_DOT: `[^.${WIN_SLASH}]`, | ||
START_ANCHOR: `(?:^|[${WIN_SLASH}])`, | ||
END_ANCHOR: `(?:[${WIN_SLASH}]|$)` | ||
}; | ||
/** | ||
* POSIX Bracket Regex | ||
*/ | ||
const POSIX_REGEX = { | ||
alnum: 'a-zA-Z0-9', | ||
alpha: 'a-zA-Z', | ||
ascii: '\\x00-\\x7F', | ||
blank: ' \\t', | ||
cntrl: '\\x00-\\x1F\\x7F', | ||
digit: '0-9', | ||
graph: '\\x21-\\x7E', | ||
lower: 'a-z', | ||
print: '\\x20-\\x7E ', | ||
punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', | ||
space: ' \\t\\r\\n\\v\\f', | ||
upper: 'A-Z', | ||
word: 'A-Za-z0-9_', | ||
xdigit: 'A-Fa-f0-9' | ||
}; | ||
module.exports = { | ||
SPECIAL_CHAR_REGEX: /(\\?)((\W)(\3*))/g, | ||
NON_SPECIAL_CHAR_REGEX: /^[^@![\].,$*+?^{}()|\\/]+/, | ||
MAX_LENGTH: 1024 * 64, | ||
POSIX_REGEX, | ||
// Replace globs with equivalent patterns to reduce parsing time. | ||
REPLACEMENTS: { | ||
'***': '*', | ||
'**/**': '**', | ||
'**/**/**': '**' | ||
}, | ||
// Digits | ||
@@ -57,3 +150,25 @@ CHAR_0: 48, /* 0 */ | ||
SEP: isWindows ? '\\' : '/' | ||
SEP: isWindows ? '\\' : '/', | ||
/** | ||
* Create EXTGLOB_CHARS | ||
*/ | ||
extglobChars(chars) { | ||
return { | ||
'!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, | ||
'?': { type: 'qmark', open: '(?:', close: ')?' }, | ||
'+': { type: 'plus', open: '(?:', close: ')+' }, | ||
'*': { type: 'star', open: '(?:', close: ')*' }, | ||
'@': { type: 'at', open: '(?:', close: ')' } | ||
}; | ||
}, | ||
/** | ||
* Create GLOB_CHARS | ||
*/ | ||
globChars(win32) { | ||
return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; | ||
} | ||
}; |
228
lib/parse.js
'use strict'; | ||
const utils = require('./utils'); | ||
const SPECIAL_CHAR_REGEX = /(\\?)((\W)(\3*))/g; | ||
const NON_SPECIAL_CHAR_REGEX = /^[^@![\].,$*+?^{}()|\\/]+/; | ||
const MAX_LENGTH = 1024 * 64; | ||
const constants = require('./constants'); | ||
@@ -12,74 +10,14 @@ /** | ||
const START_ANCHOR = '(?:^|\\/)'; | ||
const END_ANCHOR = '(?:\\/|$)'; | ||
const DOT_LITERAL = '\\.'; | ||
const DOTS_SLASH = '\\.{1,2}' + END_ANCHOR; | ||
const NO_DOT = '(?!\\.)'; | ||
const NO_DOT_SLASH = `(?!${DOTS_SLASH})`; | ||
const ZERO_DOT_SLASH = `(?!\\.{0,1}${END_ANCHOR})`; | ||
const NO_DOTS = '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))'; | ||
const ONE_CHAR = '(?=.)'; | ||
const PLUS_LITERAL = '\\+'; | ||
const QMARK = '[^/]'; | ||
const QMARK_LITERAL = '\\?'; | ||
const QMARK_NO_DOT = '[^/.]'; | ||
const QMARK_WINDOWS = '[^\\\\/]'; | ||
const QMARK_WINDOWS_NO_DOT = '[^\\\\/.]'; | ||
const SLASH_LITERAL = '\\/'; | ||
const SLASH_LITERAL_WINDOWS = '[\\\\/]'; | ||
const STAR = `${QMARK}*?`; | ||
const STAR_WINDOWS = `${QMARK_WINDOWS}*?`; | ||
const { | ||
MAX_LENGTH, | ||
NON_SPECIAL_CHAR_REGEX, | ||
POSIX_REGEX, | ||
REPLACEMENTS, | ||
SPECIAL_CHAR_REGEX | ||
} = constants; | ||
/** | ||
* Extglobs | ||
*/ | ||
const EXTGLOB_CHARS = { | ||
'!': { type: 'negate', open: '(?:(?!(?:', close: `))${STAR})` }, | ||
'?': { type: 'qmark', open: '(?:', close: ')?' }, | ||
'+': { type: 'plus', open: '(?:', close: ')+' }, | ||
'*': { type: 'star', open: '(?:', close: ')*' }, | ||
'@': { type: 'at', open: '(?:', close: ')' } | ||
}; | ||
/** | ||
* POSIX Bracket Regex | ||
*/ | ||
const POSIX_REGEX = { | ||
alnum: 'a-zA-Z0-9', | ||
alpha: 'a-zA-Z', | ||
ascii: '\\x00-\\x7F', | ||
blank: ' \\t', | ||
cntrl: '\\x00-\\x1F\\x7F', | ||
digit: '0-9', | ||
graph: '\\x21-\\x7E', | ||
lower: 'a-z', | ||
print: '\\x20-\\x7E ', | ||
punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', | ||
space: ' \\t\\r\\n\\v\\f', | ||
upper: 'A-Z', | ||
word: 'A-Za-z0-9_', | ||
xdigit: 'A-Fa-f0-9' | ||
}; | ||
/** | ||
* Replace globs with equivalent patterns to reduce parsing time. | ||
*/ | ||
const REPLACEMENTS = { | ||
'***': '*', | ||
'**/**': '**', | ||
'**/**/**': '**' | ||
}; | ||
/** | ||
* Helpers | ||
*/ | ||
const globstar = opts => { | ||
let capture = opts.capture ? '' : '?:'; | ||
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; | ||
}; | ||
const syntaxError = (place, char) => { | ||
@@ -125,2 +63,9 @@ return `Missing ${place}: "${char}" - use "\\\\${char}" to match literal characters`; | ||
/** | ||
* Parse the given input string. | ||
* @param {String} input | ||
* @param {Object} options | ||
* @return {Object} | ||
*/ | ||
const parse = (input, options) => { | ||
@@ -144,2 +89,27 @@ if (typeof input !== 'string') { | ||
let capture = opts.capture ? '' : '?:'; | ||
let win32 = utils.isWindows(options); | ||
// create constants based on platform, for windows or posix | ||
const chars = constants.globChars(win32); | ||
const EXTGLOB_CHARS = constants.extglobChars(chars); | ||
const { | ||
DOT_LITERAL, | ||
PLUS_LITERAL, | ||
SLASH_LITERAL, | ||
ONE_CHAR, | ||
DOTS_SLASH, | ||
NO_DOT, | ||
NO_DOT_SLASH, | ||
NO_DOTS_SLASH, | ||
QMARK, | ||
QMARK_NO_DOT, | ||
STAR, | ||
START_ANCHOR | ||
} = chars; | ||
const globstar = (opts) => { | ||
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; | ||
}; | ||
let nodot = opts.dot ? '' : NO_DOT; | ||
@@ -150,3 +120,3 @@ let star = opts.bash === true ? globstar(opts) : STAR; | ||
if (opts.capture) { | ||
star = '(' + star + ')'; | ||
star = `(${star})`; | ||
} | ||
@@ -174,3 +144,2 @@ | ||
let stack = []; | ||
let block = state; | ||
let prev = bos; | ||
@@ -222,5 +191,4 @@ let value; | ||
if (state.parens && extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { | ||
let extglob = extglobs[extglobs.length - 1]; | ||
extglob.inner += tok.value; | ||
if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { | ||
extglobs[extglobs.length - 1].inner += tok.value; | ||
} | ||
@@ -234,3 +202,3 @@ | ||
Reflect.defineProperty(tok, 'prev', { value: prev }); | ||
tok.prev = prev; | ||
tokens.push(tok); | ||
@@ -241,5 +209,5 @@ prev = tok; | ||
const extglobOpen = (type, value) => { | ||
let token = { ...EXTGLOB_CHARS[value], inner: '' }; | ||
Reflect.defineProperty(token, 'prev', { value: prev }); | ||
let token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; | ||
token.prev = prev; | ||
token.parens = state.parens; | ||
@@ -562,3 +530,3 @@ token.output = state.output; | ||
if (block.dots === true) { | ||
if (state.dots === true) { | ||
let arr = tokens.slice(); | ||
@@ -587,2 +555,14 @@ let range = []; | ||
/** | ||
* Pipes | ||
*/ | ||
if (value === '|') { | ||
if (extglobs.length > 0) { | ||
extglobs[extglobs.length - 1].conditions++; | ||
} | ||
push({ type: 'text', value }); | ||
continue; | ||
} | ||
/** | ||
* Commas | ||
@@ -634,3 +614,3 @@ */ | ||
prev.value += value; | ||
block.dots = true; | ||
state.dots = true; | ||
continue; | ||
@@ -890,9 +870,9 @@ } | ||
if (prev.type === 'dot') { | ||
state.output += ZERO_DOT_SLASH; | ||
prev.output += ZERO_DOT_SLASH; | ||
} else if (opts.dot === true) { | ||
state.output += NO_DOT_SLASH; | ||
prev.output += NO_DOT_SLASH; | ||
} else if (opts.dot === true) { | ||
state.output += NO_DOTS_SLASH; | ||
prev.output += NO_DOTS_SLASH; | ||
} else { | ||
@@ -931,3 +911,3 @@ state.output += nodot; | ||
if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { | ||
push({ type: 'maybe_slash', value: '', output: '\\/?' }); | ||
push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); | ||
} | ||
@@ -966,44 +946,72 @@ | ||
input = REPLACEMENTS[input] || input; | ||
let win32 = utils.isWindows(options); | ||
// create constants based on platform, for windows or posix | ||
const { | ||
DOT_LITERAL, | ||
SLASH_LITERAL, | ||
ONE_CHAR, | ||
DOTS_SLASH, | ||
NO_DOT, | ||
NO_DOTS, | ||
NO_DOTS_SLASH, | ||
STAR, | ||
START_ANCHOR | ||
} = constants.globChars(win32); | ||
let capture = opts.capture ? '' : '?:'; | ||
let star = opts.bash === true ? '.*?' : STAR; | ||
let nodot = opts.dot ? NO_DOTS : NO_DOT; | ||
let slashDot = opts.dot ? NO_DOT_SLASH : NO_DOT; | ||
let qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; | ||
let slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; | ||
switch (input) { | ||
case '*': | ||
return `${nodot}${ONE_CHAR}${star}`; | ||
const globstar = (opts) => { | ||
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; | ||
}; | ||
case '.*': | ||
return `\\.${ONE_CHAR}${star}`; | ||
const create = str => { | ||
switch (str) { | ||
case '*': | ||
return `${nodot}${ONE_CHAR}${star}`; | ||
case '*.*': | ||
return `${nodot}${star}\\.${ONE_CHAR}${star}`; | ||
case '.*': | ||
return `${DOT_LITERAL}${ONE_CHAR}${star}`; | ||
case '*/*': | ||
return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; | ||
case '*.*': | ||
return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; | ||
case '**': | ||
return nodot + globstar(opts); | ||
case '*/*': | ||
return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; | ||
case '**/*': | ||
return `(?:${nodot}${globstar(opts)}\\/)?${slashDot}${ONE_CHAR}${star}`; | ||
case '**': | ||
return nodot + globstar(opts); | ||
case '**/*.*': | ||
return `(?:${nodot}${globstar(opts)}\\/)?${nodot}${star}\\.${ONE_CHAR}${star}`; | ||
case '**/*': | ||
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; | ||
case '**/.*': | ||
return `(?:${nodot}${globstar(opts)}\\/)?\\.${ONE_CHAR}${star}`; | ||
case '**/*.*': | ||
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; | ||
default: { | ||
let match = /^(.*?)(?:\.(\w+))$/.exec(input); | ||
if (!match) return; | ||
case '**/.*': | ||
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; | ||
let source = parse.fastpaths(match[1], options); | ||
if (!source) return; | ||
default: { | ||
let match = /^(.*?)\.(\w+)$/.exec(str); | ||
if (!match) return; | ||
return source + DOT_LITERAL + match[2]; | ||
let source = create(match[1], options); | ||
if (!source) return; | ||
return source + DOT_LITERAL + match[2]; | ||
} | ||
} | ||
}; | ||
let output = create(input); | ||
if (output && opts.strictSlashes !== true) { | ||
output += `${SLASH_LITERAL}?`; | ||
} | ||
return output; | ||
}; | ||
module.exports = parse; |
@@ -7,3 +7,2 @@ 'use strict'; | ||
const utils = require('./utils'); | ||
const toPosixSlashes = str => str.replace(/\\/g, '/'); | ||
@@ -17,3 +16,3 @@ /** | ||
* const picomatch = require('picomatch'); | ||
* picomatch(pattern[, options]); | ||
* // picomatch(pattern[, options]); | ||
* | ||
@@ -24,5 +23,6 @@ * const isMatch = picomatch('*.!(*a)'); | ||
* ``` | ||
* @name picomatch | ||
* @param {String} `pattern` Glob pattern | ||
* @param {Object} `options` | ||
* @return {Function} Returns a matcher function. | ||
* @param {Object=} `options` | ||
* @return {Function=} Returns a matcher function. | ||
* @api public | ||
@@ -55,3 +55,4 @@ */ | ||
if (opts.ignore) { | ||
isIgnored = picomatch(opts.ignore, { ...options, ignore: null, onMatch: null }, returnState); | ||
let ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; | ||
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); | ||
} | ||
@@ -93,2 +94,19 @@ | ||
/** | ||
* Test `input` with the given `regex`. This is used by the main | ||
* `picomatch()` function to | ||
* | ||
* ```js | ||
* const picomatch = require('picomatch'); | ||
* // picomatch.test(input, regex[, options]); | ||
* | ||
* console.log(pm.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); | ||
* // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } | ||
* ``` | ||
* @param {String} `input` String to test. | ||
* @param {RegExp} `regex` | ||
* @return {Object} Returns an object with matching info. | ||
* @api public | ||
*/ | ||
picomatch.test = (input, regex, options, { glob, posix } = {}) => { | ||
@@ -104,3 +122,3 @@ if (typeof input !== 'string') { | ||
let opts = options || {}; | ||
let format = opts.format || (posix ? toPosixSlashes : null); | ||
let format = opts.format || (posix ? utils.toPosixSlashes : null); | ||
let match = input === glob; | ||
@@ -132,3 +150,3 @@ let output = (match && format) ? format(input) : input; | ||
} | ||
return !!regex.exec(input); | ||
return regex.test(input); | ||
}; | ||
@@ -172,4 +190,3 @@ | ||
/** | ||
* Scan a glob pattern to separate the pattern into segments. Used | ||
* by the [split](#split) method. | ||
* Scan a glob pattern to separate the pattern into segments. | ||
* | ||
@@ -189,53 +206,2 @@ * ```js | ||
/** | ||
* Split a glob pattern into two parts: the directory part of the glob, | ||
* and the matching part. | ||
* | ||
* @param {String} `pattern` | ||
* @param {Object} `options` | ||
* @return {Array} | ||
* @api public | ||
*/ | ||
picomatch.split = (pattern, options) => { | ||
let state = scan(pattern, options); | ||
let cwd = options && options.cwd ? options.cwd : process.cwd(); | ||
let base = state.base; | ||
if (base[0] === '/') base = base.slice(1); | ||
return { | ||
base: state.base, | ||
glob: state.glob, | ||
cwd: path.resolve(cwd, state.base) | ||
}; | ||
}; | ||
/** | ||
* Properly join a file path (or paths) to a glob pattern. | ||
* | ||
* @param {...[string]} `args` One or more path segments to join. Only the last segment may be a glob pattern. | ||
* @return {String} | ||
* @api public | ||
*/ | ||
picomatch.join = (...args) => { | ||
let glob = args.pop(); | ||
let base = toPosixSlashes(path.posix.join(...args)); | ||
return path.posix.join(base, glob); | ||
}; | ||
/** | ||
* Same as [.join](#join) but returns an absolute path. | ||
* | ||
* @param {...[string]} `args` One or more path segments to join. Only the last segment may be a glob pattern. | ||
* @return {String} | ||
* @api public | ||
*/ | ||
picomatch.resolve = (...args) => { | ||
let glob = args.pop(); | ||
let base = toPosixSlashes(path.posix.resolve(...args)); | ||
return path.posix.join(base, glob); | ||
}; | ||
/** | ||
* Create a regular expression from the given glob `pattern`. | ||
@@ -271,12 +237,4 @@ * | ||
output = parse.fastpaths(input, options); | ||
if (output && opts.strictSlashes !== true) { | ||
output += '\\/?'; | ||
} | ||
} | ||
if (output === void 0 && !/[-![$*+?^{}(|)\\\]]/.test(input)) { | ||
output = input.replace(/([./])/g, '\\$1'); | ||
} | ||
if (output === void 0) { | ||
@@ -304,2 +262,9 @@ state = picomatch.parse(input, options); | ||
/** | ||
* Create a regular expression from the given source string. | ||
* @param {String} source | ||
* @param {Object} options | ||
* @return {RegExp} | ||
*/ | ||
picomatch.toRegex = (source, options) => { | ||
@@ -316,5 +281,5 @@ try { | ||
/** | ||
* Initialize the nocache property | ||
* Expose "picomatch" | ||
*/ | ||
module.exports = picomatch; |
@@ -14,4 +14,2 @@ 'use strict'; | ||
CHAR_LEFT_SQUARE_BRACKET, /* [ */ | ||
CHAR_LOWERCASE_A, /* a */ | ||
CHAR_LOWERCASE_Z, /* z */ | ||
CHAR_PLUS, /* + */ | ||
@@ -21,5 +19,3 @@ CHAR_QUESTION_MARK, /* ? */ | ||
CHAR_RIGHT_PARENTHESES, /* ) */ | ||
CHAR_RIGHT_SQUARE_BRACKET, /* ] */ | ||
CHAR_UPPERCASE_A, /* A */ | ||
CHAR_UPPERCASE_Z /* Z */ | ||
CHAR_RIGHT_SQUARE_BRACKET /* ] */ | ||
} = require('./constants'); | ||
@@ -198,3 +194,3 @@ | ||
if (isGlob === true && lastIndex > 0) { | ||
if (base && isGlob === true && lastIndex > 0) { | ||
base = input.slice(0, lastIndex); | ||
@@ -209,5 +205,5 @@ glob = input.slice(lastIndex); | ||
if (base !== '' && base !== '/' && base !== input) { | ||
if (base && base !== '' && base !== '/' && base !== input) { | ||
if (isPathSeparator(base.charCodeAt(base.length - 1))) { | ||
base = base.slice(0, base.length - 1); | ||
base = base.slice(0, -1); | ||
} | ||
@@ -214,0 +210,0 @@ } |
@@ -11,3 +11,11 @@ 'use strict'; | ||
exports.escapeRegex = str => str.replace(/([-[$*+?.^{}(|)\]])/g, '\\$1'); | ||
exports.toPosixSlashes = str => str.replace(/\\/g, '/'); | ||
exports.isWindows = options => { | ||
if (options && typeof options.windows === 'boolean') { | ||
return options.windows; | ||
} | ||
return win32 === true || path.sep === '\\'; | ||
}; | ||
exports.findLastIndex = (arr, fn, limit = arr.length) => { | ||
@@ -27,11 +35,1 @@ for (let i = arr.length - 1; i >= arr.length - limit; i--) { | ||
}; | ||
exports.isWindows = options => { | ||
if (options && (options.unixify === false || options.posixSlashes === false)) { | ||
return false; | ||
} | ||
if (options && (options.unixify === true || options.posixSlashes === true)) { | ||
return true; | ||
} | ||
return win32 === true || path.sep === '\\'; | ||
}; |
{ | ||
"name": "picomatch", | ||
"description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"homepage": "https://github.com/folder/picomatch", | ||
@@ -25,3 +25,3 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"devDependencies": { | ||
"fill-range": "^6.0.0", | ||
"fill-range": "^7.0.1", | ||
"gulp-format-md": "^2.0.0", | ||
@@ -59,2 +59,3 @@ "mocha": "^6.0.2", | ||
"extglob", | ||
"fill-range", | ||
"micromatch", | ||
@@ -66,2 +67,2 @@ "minimatch", | ||
} | ||
} | ||
} |
@@ -49,3 +49,2 @@ <h1 align="center">Picomatch</h1> | ||
<br> | ||
<br> | ||
@@ -67,3 +66,2 @@ ## Usage | ||
<br> | ||
<br> | ||
@@ -81,3 +79,3 @@ ## Options | ||
| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true | | ||
| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. This option is overridden by the `expandBrace` option. | | ||
| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. | | ||
| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. | | ||
@@ -114,2 +112,6 @@ | `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. | | ||
<br> | ||
## Options Examples | ||
### options.expandRange | ||
@@ -207,4 +209,4 @@ | ||
* Basic globbing (Wildcard matching) | ||
* Advanced globbing (extglobs, posix brackets, brace matching) | ||
* [Basic globbing](#basic-globbing) (Wildcard matching) | ||
* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching) | ||
@@ -228,3 +230,2 @@ ## Basic globbing | ||
<br> | ||
<br> | ||
@@ -235,4 +236,3 @@ ## Advanced globbing | ||
* [POSIX brackets](#posix-brackets) | ||
* brace expansion (todo) | ||
* regular expressions (todo) | ||
* [Braces](#brace-expansion) | ||
@@ -306,10 +306,6 @@ ### Extglobs | ||
## Brace Expansion | ||
## Braces | ||
TODO | ||
Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces. | ||
## Regular Expressions | ||
TODO | ||
## Matching special characters as literals | ||
@@ -353,25 +349,7 @@ | ||
## Performance comparison | ||
## Benchmarks | ||
### Load time | ||
Performance comparison of picomatch and minimatch. | ||
``` | ||
minimatch: 4.230ms | ||
picomatch: 2.123ms | ||
``` | ||
### First match | ||
Time it takes to return the first match, including `require()` time: | ||
```js | ||
console.log(require('minimatch').makeRe('**/*').test('foo/bar/baz/qux.js')); | ||
// 9.275ms | ||
console.log(require('picomatch').makeRe('**/*').test('foo/bar/baz/qux.js')); | ||
// 7.429ms | ||
``` | ||
### Benchmarks | ||
``` | ||
# .makeRe star | ||
@@ -397,5 +375,5 @@ picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled) | ||
# .makeRe - braces | ||
picomatch x 117,916 ops/sec ±2.03% (80 runs sampled)) | ||
minimatch x 108,573 ops/sec ±1.63% (91 runs sampled)) | ||
# .makeRe - basic braces | ||
picomatch x 392,067 ops/sec ±0.70% (90 runs sampled) | ||
minimatch x 99,532 ops/sec ±2.03% (87 runs sampled)) | ||
``` | ||
@@ -402,0 +380,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1410
0
67186
437