Comparing version 2.0.7 to 2.1.0
@@ -35,4 +35,36 @@ # Release history | ||
## [2.0.4] - 2019-04-10 | ||
## 2.1.0 (2019-10-31) | ||
* add benchmarks for scan ([4793b92](https://github.com/micromatch/picomatch/commit/4793b92)) | ||
* Add eslint object-curly-spacing rule ([707c650](https://github.com/micromatch/picomatch/commit/707c650)) | ||
* Add prefer-const eslint rule ([5c7501c](https://github.com/micromatch/picomatch/commit/5c7501c)) | ||
* Add support for nonegate in scan API ([275c9b9](https://github.com/micromatch/picomatch/commit/275c9b9)) | ||
* Change lets to consts. Move root import up. ([4840625](https://github.com/micromatch/picomatch/commit/4840625)) | ||
* closes https://github.com/micromatch/picomatch/issues/21 ([766bcb0](https://github.com/micromatch/picomatch/commit/766bcb0)) | ||
* Fix "Extglobs" table in readme ([eb19da8](https://github.com/micromatch/picomatch/commit/eb19da8)) | ||
* fixes https://github.com/micromatch/picomatch/issues/20 ([9caca07](https://github.com/micromatch/picomatch/commit/9caca07)) | ||
* fixes https://github.com/micromatch/picomatch/issues/26 ([fa58f45](https://github.com/micromatch/picomatch/commit/fa58f45)) | ||
* Lint test ([d433a34](https://github.com/micromatch/picomatch/commit/d433a34)) | ||
* lint unit tests ([0159b55](https://github.com/micromatch/picomatch/commit/0159b55)) | ||
* Make scan work with noext ([6c02e03](https://github.com/micromatch/picomatch/commit/6c02e03)) | ||
* minor linting ([c2a2b87](https://github.com/micromatch/picomatch/commit/c2a2b87)) | ||
* minor parser improvements ([197671d](https://github.com/micromatch/picomatch/commit/197671d)) | ||
* remove eslint since it... ([07876fa](https://github.com/micromatch/picomatch/commit/07876fa)) | ||
* remove funding file ([8ebe96d](https://github.com/micromatch/picomatch/commit/8ebe96d)) | ||
* Remove unused funks ([cbc6d54](https://github.com/micromatch/picomatch/commit/cbc6d54)) | ||
* Run eslint during pretest, fix existing eslint findings ([0682367](https://github.com/micromatch/picomatch/commit/0682367)) | ||
* support `noparen` in scan ([3d37569](https://github.com/micromatch/picomatch/commit/3d37569)) | ||
* update changelog ([7b34e77](https://github.com/micromatch/picomatch/commit/7b34e77)) | ||
* update travis ([777f038](https://github.com/micromatch/picomatch/commit/777f038)) | ||
* Use eslint-disable-next-line instead of eslint-disable ([4e7c1fd](https://github.com/micromatch/picomatch/commit/4e7c1fd)) | ||
## 2.0.7 (2019-05-14) | ||
* 2.0.7 ([9eb9a71](https://github.com/micromatch/picomatch/commit/9eb9a71)) | ||
* supports lookbehinds ([1f63f7e](https://github.com/micromatch/picomatch/commit/1f63f7e)) | ||
* update .verb.md file with typo change ([2741279](https://github.com/micromatch/picomatch/commit/2741279)) | ||
* fix: typo in README ([0753e44](https://github.com/micromatch/picomatch/commit/0753e44)) | ||
## 2.0.4 (2019-04-10) | ||
### Fixed | ||
@@ -43,3 +75,3 @@ | ||
## [2.0.0] - 2019-04-10 | ||
## 2.0.0 (2019-04-10) | ||
@@ -56,3 +88,3 @@ ### Added | ||
## [1.0.0] - 2018-11-05 | ||
## 1.0.0 (2018-11-05) | ||
@@ -69,5 +101,2 @@ - adds `.onMatch` option | ||
[2.0.4]: https://github.com/jonschlinkert/micromatch/compare/2.0.0...2.0.4 | ||
[2.0.0]: https://github.com/jonschlinkert/micromatch/compare/1.0.0...2.0.0 | ||
[1.0.0]: https://github.com/jonschlinkert/micromatch/compare/0.1.0...1.0.0 | ||
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog |
@@ -92,3 +92,3 @@ 'use strict'; | ||
REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, | ||
REGEX_NON_SPECIAL_CHAR: /^[^@![\].,$*+?^{}()|\\/]+/, | ||
REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, | ||
REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, | ||
@@ -95,0 +95,0 @@ REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, |
257
lib/parse.js
'use strict'; | ||
const constants = require('./constants'); | ||
const utils = require('./utils'); | ||
const constants = require('./constants'); | ||
@@ -13,3 +13,3 @@ /** | ||
POSIX_REGEX_SOURCE, | ||
REGEX_NON_SPECIAL_CHAR, | ||
REGEX_NON_SPECIAL_CHARS, | ||
REGEX_SPECIAL_CHARS_BACKREF, | ||
@@ -29,6 +29,6 @@ REPLACEMENTS | ||
args.sort(); | ||
let value = `[${args.join('-')}]`; | ||
const value = `[${args.join('-')}]`; | ||
try { | ||
/* eslint-disable no-new */ | ||
/* eslint-disable-next-line no-new */ | ||
new RegExp(value); | ||
@@ -42,20 +42,2 @@ } catch (ex) { | ||
const negate = state => { | ||
let count = 1; | ||
while (state.peek() === '!' && (state.peek(2) !== '(' || state.peek(3) === '?')) { | ||
state.advance(); | ||
state.start++; | ||
count++; | ||
} | ||
if (count % 2 === 0) { | ||
return false; | ||
} | ||
state.negated = true; | ||
state.start++; | ||
return true; | ||
}; | ||
/** | ||
@@ -83,4 +65,5 @@ * Create the message for a syntax error | ||
let opts = { ...options }; | ||
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; | ||
const opts = { ...options }; | ||
const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; | ||
let len = input.length; | ||
@@ -91,7 +74,7 @@ if (len > max) { | ||
let bos = { type: 'bos', value: '', output: opts.prepend || '' }; | ||
let tokens = [bos]; | ||
const bos = { type: 'bos', value: '', output: opts.prepend || '' }; | ||
const tokens = [bos]; | ||
let capture = opts.capture ? '' : '?:'; | ||
let win32 = utils.isWindows(options); | ||
const capture = opts.capture ? '' : '?:'; | ||
const win32 = utils.isWindows(options); | ||
@@ -121,5 +104,5 @@ // create constants based on platform, for windows or posix | ||
let nodot = opts.dot ? '' : NO_DOT; | ||
const nodot = opts.dot ? '' : NO_DOT; | ||
const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; | ||
let star = opts.bash === true ? globstar(opts) : STAR; | ||
let qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; | ||
@@ -135,8 +118,12 @@ if (opts.capture) { | ||
let state = { | ||
const state = { | ||
input, | ||
index: -1, | ||
start: 0, | ||
dot: opts.dot === true, | ||
consumed: '', | ||
output: '', | ||
prefix: '', | ||
backtrack: false, | ||
negated: false, | ||
brackets: 0, | ||
@@ -149,4 +136,7 @@ braces: 0, | ||
let extglobs = []; | ||
let stack = []; | ||
input = utils.removePrefix(input, state); | ||
len = input.length; | ||
const extglobs = []; | ||
const stack = []; | ||
let prev = bos; | ||
@@ -162,7 +152,30 @@ let value; | ||
const advance = state.advance = () => input[++state.index]; | ||
const remaining = () => input.slice(state.index + 1); | ||
const consume = (value = '', num = 0) => { | ||
state.consumed += value; | ||
state.index += num; | ||
}; | ||
const append = token => { | ||
state.output += token.output != null ? token.output : token.value; | ||
state.consumed += token.value || ''; | ||
consume(token.value); | ||
}; | ||
const negate = () => { | ||
let count = 1; | ||
while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { | ||
advance(); | ||
state.start++; | ||
count++; | ||
} | ||
if (count % 2 === 0) { | ||
return false; | ||
} | ||
state.negated = true; | ||
state.start++; | ||
return true; | ||
}; | ||
const increment = type => { | ||
@@ -188,4 +201,5 @@ state[type]++; | ||
if (prev.type === 'globstar') { | ||
let isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); | ||
let isExtglob = extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'); | ||
const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); | ||
const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); | ||
if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { | ||
@@ -216,3 +230,3 @@ state.output = state.output.slice(0, -prev.output.length); | ||
const extglobOpen = (type, value) => { | ||
let token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; | ||
const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; | ||
@@ -222,7 +236,7 @@ token.prev = prev; | ||
token.output = state.output; | ||
let output = (opts.capture ? '(' : '') + token.open; | ||
const output = (opts.capture ? '(' : '') + token.open; | ||
increment('parens'); | ||
push({ type, value, output: state.output ? '' : ONE_CHAR }); | ||
push({ type: 'paren', extglob: true, value: advance(), output }); | ||
increment('parens'); | ||
extglobs.push(token); | ||
@@ -241,3 +255,3 @@ }; | ||
if (extglobStar !== star || eos() || /^\)+$/.test(input.slice(state.index + 1))) { | ||
if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { | ||
output = token.close = ')$))' + extglobStar; | ||
@@ -255,3 +269,7 @@ } | ||
if (opts.fastpaths !== false && !/(^[*!]|[/{[()\]}"])/.test(input)) { | ||
/** | ||
* Fast paths | ||
*/ | ||
if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { | ||
let backslashes = false; | ||
@@ -298,3 +316,8 @@ | ||
state.output = output; | ||
if (output === input && opts.contains === true) { | ||
state.output = input; | ||
return state; | ||
} | ||
state.output = utils.wrapOutput(output, state, options); | ||
return state; | ||
@@ -319,3 +342,3 @@ } | ||
if (value === '\\') { | ||
let next = peek(); | ||
const next = peek(); | ||
@@ -337,3 +360,3 @@ if (next === '/' && opts.bash !== true) { | ||
// collapse slashes to reduce potential for exploits | ||
let match = /^\\+/.exec(input.slice(state.index + 1)); | ||
const match = /^\\+/.exec(remaining()); | ||
let slashes = 0; | ||
@@ -368,3 +391,3 @@ | ||
if (opts.posix !== false && value === ':') { | ||
let inner = prev.value.slice(1); | ||
const inner = prev.value.slice(1); | ||
if (inner.includes('[')) { | ||
@@ -374,6 +397,6 @@ prev.posix = true; | ||
if (inner.includes(':')) { | ||
let idx = prev.value.lastIndexOf('['); | ||
let pre = prev.value.slice(0, idx); | ||
let rest = prev.value.slice(idx + 2); | ||
let posix = POSIX_REGEX_SOURCE[rest]; | ||
const idx = prev.value.lastIndexOf('['); | ||
const pre = prev.value.slice(0, idx); | ||
const rest = prev.value.slice(idx + 2); | ||
const posix = POSIX_REGEX_SOURCE[rest]; | ||
if (posix) { | ||
@@ -439,4 +462,4 @@ prev.value = pre + posix; | ||
if (value === '(') { | ||
increment('parens'); | ||
push({ type: 'paren', value }); | ||
increment('parens'); | ||
continue; | ||
@@ -450,3 +473,3 @@ } | ||
let extglob = extglobs[extglobs.length - 1]; | ||
const extglob = extglobs[extglobs.length - 1]; | ||
if (extglob && state.parens === extglob.parens + 1) { | ||
@@ -463,7 +486,7 @@ extglobClose(extglobs.pop()); | ||
/** | ||
* Brackets | ||
* Square brackets | ||
*/ | ||
if (value === '[') { | ||
if (opts.nobracket === true || !input.slice(state.index + 1).includes(']')) { | ||
if (opts.nobracket === true || !remaining().includes(']')) { | ||
if (opts.nobracket !== true && opts.strictBrackets === true) { | ||
@@ -499,3 +522,3 @@ throw new SyntaxError(syntaxError('closing', ']')); | ||
let prevValue = prev.value.slice(1); | ||
const prevValue = prev.value.slice(1); | ||
if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { | ||
@@ -514,3 +537,3 @@ value = '/' + value; | ||
let escaped = utils.escapeRegex(prev.value); | ||
const escaped = utils.escapeRegex(prev.value); | ||
state.output = state.output.slice(0, -prev.value.length); | ||
@@ -537,4 +560,4 @@ | ||
if (value === '{' && opts.nobrace !== true) { | ||
increment('braces'); | ||
push({ type: 'brace', value, output: '(' }); | ||
increment('braces'); | ||
continue; | ||
@@ -545,3 +568,3 @@ } | ||
if (opts.nobrace === true || state.braces === 0) { | ||
push({ type: 'text', value, output: '\\' + value }); | ||
push({ type: 'text', value, output: value }); | ||
continue; | ||
@@ -553,4 +576,4 @@ } | ||
if (state.dots === true) { | ||
let arr = tokens.slice(); | ||
let range = []; | ||
const arr = tokens.slice(); | ||
const range = []; | ||
@@ -612,3 +635,3 @@ for (let i = arr.length - 1; i >= 0; i--) { | ||
// checking for BOS characters like "!" and "." (not "./") | ||
if (prev.type === 'dot' && state.index === 1) { | ||
if (prev.type === 'dot' && state.index === state.start + 1) { | ||
state.start = state.index + 1; | ||
@@ -640,2 +663,7 @@ state.consumed = ''; | ||
if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { | ||
push({ type: 'text', value, output: DOT_LITERAL }); | ||
continue; | ||
} | ||
push({ type: 'dot', value, output: DOT_LITERAL }); | ||
@@ -650,4 +678,10 @@ continue; | ||
if (value === '?') { | ||
const isGroup = prev && prev.value === '('; | ||
if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { | ||
extglobOpen('qmark', value); | ||
continue; | ||
} | ||
if (prev && prev.type === 'paren') { | ||
let next = peek(); | ||
const next = peek(); | ||
let output = value; | ||
@@ -659,3 +693,3 @@ | ||
if (prev.value === '(' && !/[!=<:]/.test(next) || (next === '<' && !/[!=]/.test(peek(2)))) { | ||
if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { | ||
output = '\\' + value; | ||
@@ -668,7 +702,2 @@ } | ||
if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { | ||
extglobOpen('qmark', value); | ||
continue; | ||
} | ||
if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { | ||
@@ -711,10 +740,8 @@ push({ type: 'qmark', value, output: QMARK_NO_DOT }); | ||
if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) { | ||
let output = prev.extglob === true ? '\\' + value : value; | ||
push({ type: 'plus', value, output }); | ||
if ((prev && prev.value === '(') || opts.regex === false) { | ||
push({ type: 'plus', value, output: PLUS_LITERAL }); | ||
continue; | ||
} | ||
// use regex behavior inside parens | ||
if (state.parens > 0 && opts.regex !== false) { | ||
if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { | ||
push({ type: 'plus', value }); | ||
@@ -734,3 +761,3 @@ continue; | ||
if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { | ||
push({ type: 'at', value, output: '' }); | ||
push({ type: 'at', extglob: true, value, output: '' }); | ||
continue; | ||
@@ -752,3 +779,3 @@ } | ||
let match = REGEX_NON_SPECIAL_CHAR.exec(input.slice(state.index + 1)); | ||
const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); | ||
if (match) { | ||
@@ -773,7 +800,8 @@ value += match[0]; | ||
state.backtrack = true; | ||
state.consumed += value; | ||
consume(value); | ||
continue; | ||
} | ||
if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { | ||
let rest = remaining(); | ||
if (opts.noextglob !== true && /^\([^?]/.test(rest)) { | ||
extglobOpen('star', value); | ||
@@ -785,12 +813,12 @@ continue; | ||
if (opts.noglobstar === true) { | ||
state.consumed += value; | ||
consume(value); | ||
continue; | ||
} | ||
let prior = prev.prev; | ||
let before = prior.prev; | ||
let isStart = prior.type === 'slash' || prior.type === 'bos'; | ||
let afterStar = before && (before.type === 'star' || before.type === 'globstar'); | ||
const prior = prev.prev; | ||
const before = prior.prev; | ||
const isStart = prior.type === 'slash' || prior.type === 'bos'; | ||
const afterStar = before && (before.type === 'star' || before.type === 'globstar'); | ||
if (opts.bash === true && (!isStart || (!eos() && peek() !== '/'))) { | ||
if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { | ||
push({ type: 'star', value, output: '' }); | ||
@@ -800,4 +828,4 @@ continue; | ||
let isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); | ||
let isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); | ||
const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); | ||
const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); | ||
if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { | ||
@@ -809,9 +837,9 @@ push({ type: 'star', value, output: '' }); | ||
// strip consecutive `/**/` | ||
while (input.slice(state.index + 1, state.index + 4) === '/**') { | ||
let after = input[state.index + 4]; | ||
while (rest.slice(0, 3) === '/**') { | ||
const after = input[state.index + 4]; | ||
if (after && after !== '/') { | ||
break; | ||
} | ||
state.consumed += '/**'; | ||
state.index += 3; | ||
rest = rest.slice(3); | ||
consume('/**', 3); | ||
} | ||
@@ -824,3 +852,3 @@ | ||
state.output = prev.output; | ||
state.consumed += value; | ||
consume(value); | ||
continue; | ||
@@ -834,13 +862,12 @@ } | ||
prev.type = 'globstar'; | ||
prev.output = globstar(opts) + '|$)'; | ||
prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); | ||
prev.value += value; | ||
state.output += prior.output + prev.output; | ||
state.consumed += value; | ||
consume(value); | ||
continue; | ||
} | ||
let next = peek(); | ||
if (prior.type === 'slash' && prior.prev.type !== 'bos' && next === '/') { | ||
let end = peek(2) !== void 0 ? '|$' : ''; | ||
if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { | ||
const end = rest[1] !== void 0 ? '|$' : ''; | ||
@@ -855,3 +882,3 @@ state.output = state.output.slice(0, -(prior.output + prev.output).length); | ||
state.output += prior.output + prev.output; | ||
state.consumed += value + advance(); | ||
consume(value + advance()); | ||
@@ -862,3 +889,3 @@ push({ type: 'slash', value, output: '' }); | ||
if (prior.type === 'bos' && next === '/') { | ||
if (prior.type === 'bos' && rest[0] === '/') { | ||
prev.type = 'globstar'; | ||
@@ -868,3 +895,3 @@ prev.value += value; | ||
state.output = prev.output; | ||
state.consumed += value + advance(); | ||
consume(value + advance()); | ||
push({ type: 'slash', value, output: '' }); | ||
@@ -884,7 +911,7 @@ continue; | ||
state.output += prev.output; | ||
state.consumed += value; | ||
consume(value); | ||
continue; | ||
} | ||
let token = { type: 'star', value, output: star }; | ||
const token = { type: 'star', value, output: star }; | ||
@@ -955,3 +982,3 @@ if (opts.bash === true) { | ||
for (let token of state.tokens) { | ||
for (const token of state.tokens) { | ||
state.output += token.output != null ? token.output : token.value; | ||
@@ -975,5 +1002,5 @@ | ||
parse.fastpaths = (input, options) => { | ||
let opts = { ...options }; | ||
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; | ||
let len = input.length; | ||
const opts = { ...options }; | ||
const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; | ||
const len = input.length; | ||
if (len > max) { | ||
@@ -984,3 +1011,3 @@ throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); | ||
input = REPLACEMENTS[input] || input; | ||
let win32 = utils.isWindows(options); | ||
const win32 = utils.isWindows(options); | ||
@@ -1000,6 +1027,7 @@ // create constants based on platform, for windows or posix | ||
let capture = opts.capture ? '' : '?:'; | ||
const nodot = opts.dot ? NO_DOTS : NO_DOT; | ||
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; | ||
const capture = opts.capture ? '' : '?:'; | ||
const state = { negated: false, prefix: '' }; | ||
let star = opts.bash === true ? '.*?' : STAR; | ||
let nodot = opts.dot ? NO_DOTS : NO_DOT; | ||
let slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; | ||
@@ -1011,2 +1039,3 @@ if (opts.capture) { | ||
const globstar = (opts) => { | ||
if (opts.noglobstar === true) return star; | ||
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; | ||
@@ -1042,6 +1071,6 @@ }; | ||
default: { | ||
let match = /^(.*?)\.(\w+)$/.exec(str); | ||
const match = /^(.*?)\.(\w+)$/.exec(str); | ||
if (!match) return; | ||
let source = create(match[1], options); | ||
const source = create(match[1], options); | ||
if (!source) return; | ||
@@ -1054,10 +1083,12 @@ | ||
let output = create(input); | ||
if (output && opts.strictSlashes !== true) { | ||
output += `${SLASH_LITERAL}?`; | ||
const output = utils.removePrefix(input, state); | ||
let source = create(output); | ||
if (source && opts.strictSlashes !== true) { | ||
source += `${SLASH_LITERAL}?`; | ||
} | ||
return output; | ||
return source; | ||
}; | ||
module.exports = parse; |
@@ -7,2 +7,3 @@ 'use strict'; | ||
const utils = require('./utils'); | ||
const constants = require('./constants'); | ||
@@ -33,6 +34,6 @@ /** | ||
if (Array.isArray(glob)) { | ||
let fns = glob.map(input => picomatch(input, options, returnState)); | ||
const fns = glob.map(input => picomatch(input, options, returnState)); | ||
return str => { | ||
for (let isMatch of fns) { | ||
let state = isMatch(str); | ||
for (const isMatch of fns) { | ||
const state = isMatch(str); | ||
if (state) return state; | ||
@@ -48,6 +49,6 @@ } | ||
let opts = options || {}; | ||
let posix = utils.isWindows(options); | ||
let regex = picomatch.makeRe(glob, options, false, true); | ||
let state = regex.state; | ||
const opts = options || {}; | ||
const posix = utils.isWindows(options); | ||
const regex = picomatch.makeRe(glob, options, false, true); | ||
const state = regex.state; | ||
delete regex.state; | ||
@@ -57,3 +58,3 @@ | ||
if (opts.ignore) { | ||
let ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; | ||
const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; | ||
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); | ||
@@ -63,4 +64,4 @@ } | ||
const matcher = (input, returnObject = false) => { | ||
let { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); | ||
let result = { glob, state, regex, posix, input, output, match, isMatch }; | ||
const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); | ||
const result = { glob, state, regex, posix, input, output, match, isMatch }; | ||
@@ -123,4 +124,4 @@ if (typeof opts.onResult === 'function') { | ||
let opts = options || {}; | ||
let format = opts.format || (posix ? utils.toPosixSlashes : null); | ||
const opts = options || {}; | ||
const format = opts.format || (posix ? utils.toPosixSlashes : null); | ||
let match = input === glob; | ||
@@ -160,3 +161,3 @@ let output = (match && format) ? format(input) : input; | ||
picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { | ||
let regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); | ||
const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); | ||
return regex.test(path.basename(input)); | ||
@@ -245,5 +246,5 @@ }; | ||
let opts = options || {}; | ||
let prepend = opts.contains ? '' : '^'; | ||
let append = opts.contains ? '' : '$'; | ||
const opts = options || {}; | ||
const prepend = opts.contains ? '' : '^'; | ||
const append = opts.contains ? '' : '$'; | ||
let state = { negated: false, fastpaths: true }; | ||
@@ -277,3 +278,3 @@ let prefix = ''; | ||
let regex = picomatch.toRegex(source, options); | ||
const regex = picomatch.toRegex(source, options); | ||
if (returnState === true) { | ||
@@ -305,3 +306,3 @@ regex.state = state; | ||
try { | ||
let opts = options || {}; | ||
const opts = options || {}; | ||
return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); | ||
@@ -319,3 +320,3 @@ } catch (err) { | ||
picomatch.constants = require('./constants'); | ||
picomatch.constants = constants; | ||
@@ -322,0 +323,0 @@ /** |
'use strict'; | ||
const utils = require('./utils'); | ||
const { | ||
@@ -20,3 +19,3 @@ CHAR_ASTERISK, /* * */ | ||
CHAR_RIGHT_PARENTHESES, /* ) */ | ||
CHAR_RIGHT_SQUARE_BRACKET /* ] */ | ||
CHAR_RIGHT_SQUARE_BRACKET /* ] */ | ||
} = require('./constants'); | ||
@@ -45,4 +44,4 @@ | ||
module.exports = (input, options) => { | ||
let opts = options || {}; | ||
let length = input.length - 1; | ||
const opts = options || {}; | ||
const length = input.length - 1; | ||
let index = -1; | ||
@@ -60,4 +59,4 @@ let start = 0; | ||
let eos = () => index >= length; | ||
let advance = () => { | ||
const eos = () => index >= length; | ||
const advance = () => { | ||
prev = code; | ||
@@ -151,3 +150,3 @@ return input.charCodeAt(++index); | ||
let isExtglobChar = code === CHAR_PLUS | ||
const isExtglobChar = code === CHAR_PLUS | ||
|| code === CHAR_AT | ||
@@ -161,3 +160,3 @@ || code === CHAR_EXCLAMATION_MARK; | ||
if (code === CHAR_EXCLAMATION_MARK && index === start) { | ||
if (!opts.nonegate && code === CHAR_EXCLAMATION_MARK && index === start) { | ||
negated = true; | ||
@@ -168,11 +167,11 @@ start++; | ||
if (code === CHAR_LEFT_PARENTHESES) { | ||
while (!eos() && (next = advance())) { | ||
if (next === CHAR_BACKWARD_SLASH) { | ||
if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { | ||
while (!eos() && (code = advance())) { | ||
if (code === CHAR_BACKWARD_SLASH) { | ||
backslashes = true; | ||
next = advance(); | ||
code = advance(); | ||
continue; | ||
} | ||
if (next === CHAR_RIGHT_PARENTHESES) { | ||
if (code === CHAR_RIGHT_PARENTHESES) { | ||
isGlob = true; | ||
@@ -189,4 +188,8 @@ break; | ||
if (opts.noext === true) { | ||
isGlob = false; | ||
} | ||
let prefix = ''; | ||
let orig = input; | ||
const orig = input; | ||
let base = input; | ||
@@ -193,0 +196,0 @@ let glob = ''; |
@@ -6,12 +6,11 @@ 'use strict'; | ||
const { | ||
REGEX_BACKSLASH, | ||
REGEX_REMOVE_BACKSLASH, | ||
REGEX_SPECIAL_CHARS, | ||
REGEX_SPECIAL_CHARS_GLOBAL, | ||
REGEX_REMOVE_BACKSLASH | ||
REGEX_SPECIAL_CHARS_GLOBAL | ||
} = require('./constants'); | ||
exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); | ||
exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); | ||
exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); | ||
exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); | ||
exports.toPosixSlashes = str => str.replace(/\\/g, '/'); | ||
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); | ||
@@ -22,7 +21,7 @@ exports.removeBackslashes = str => { | ||
}); | ||
} | ||
}; | ||
exports.supportsLookbehinds = () => { | ||
let segs = process.version.slice(1).split('.'); | ||
if (segs.length === 3 && +segs[0] >= 9 || (+segs[0] === 8 && +segs[1] >= 10)) { | ||
const segs = process.version.slice(1).split('.').map(Number); | ||
if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { | ||
return true; | ||
@@ -41,3 +40,3 @@ } | ||
exports.escapeLast = (input, char, lastIdx) => { | ||
let idx = input.lastIndexOf(char, lastIdx); | ||
const idx = input.lastIndexOf(char, lastIdx); | ||
if (idx === -1) return input; | ||
@@ -47,1 +46,21 @@ if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); | ||
}; | ||
exports.removePrefix = (input, state = {}) => { | ||
let output = input; | ||
if (output.startsWith('./')) { | ||
output = output.slice(2); | ||
state.prefix = './'; | ||
} | ||
return output; | ||
}; | ||
exports.wrapOutput = (input, state = {}, options = {}) => { | ||
const prepend = options.contains ? '' : '^'; | ||
const append = options.contains ? '' : '$'; | ||
let output = `${prepend}(?:${input})${append}`; | ||
if (state.negated === true) { | ||
output = `(?:^(?!${output}).*$)`; | ||
} | ||
return output; | ||
}; |
{ | ||
"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": "2.0.7", | ||
"version": "2.1.0", | ||
"homepage": "https://github.com/micromatch/picomatch", | ||
@@ -18,3 +18,3 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"engines": { | ||
"node": ">=8" | ||
"node": ">=8.6" | ||
}, | ||
@@ -21,0 +21,0 @@ "scripts": { |
@@ -68,3 +68,3 @@ <h1 align="center">Picomatch</h1> | ||
### [picomatch](lib/picomatch.js#L30) | ||
### [picomatch](lib/picomatch.js#L31) | ||
@@ -90,3 +90,3 @@ Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information. | ||
### [.test](lib/picomatch.js#L109) | ||
### [.test](lib/picomatch.js#L110) | ||
@@ -111,3 +111,3 @@ Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string. | ||
### [.matchBase](lib/picomatch.js#L153) | ||
### [.matchBase](lib/picomatch.js#L154) | ||
@@ -130,3 +130,3 @@ Match the basename of a filepath. | ||
### [.isMatch](lib/picomatch.js#L175) | ||
### [.isMatch](lib/picomatch.js#L176) | ||
@@ -152,3 +152,3 @@ Returns true if **any** of the given glob `patterns` match the specified `string`. | ||
### [.parse](lib/picomatch.js#L191) | ||
### [.parse](lib/picomatch.js#L192) | ||
@@ -170,3 +170,3 @@ Parse a glob pattern to create the source string for a regular expression. | ||
### [.scan](lib/picomatch.js#L215) | ||
### [.scan](lib/picomatch.js#L216) | ||
@@ -197,3 +197,3 @@ Scan a glob pattern to separate the pattern into segments. | ||
### [.makeRe](lib/picomatch.js#L233) | ||
### [.makeRe](lib/picomatch.js#L234) | ||
@@ -218,3 +218,3 @@ Create a regular expression from a glob pattern. | ||
### [.toRegex](lib/picomatch.js#L294) | ||
### [.toRegex](lib/picomatch.js#L295) | ||
@@ -435,5 +435,2 @@ Create a regular expression from the given regex source string. | ||
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false | ||
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false | ||
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false | ||
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // true | ||
@@ -614,2 +611,2 @@ // supports nested extglobs | ||
Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
Released under the [MIT License](LICENSE). | ||
Released under the [MIT License](LICENSE). |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
77098
1509
0
602