minimatch
Advanced tools
Comparing version
@@ -40,3 +40,2 @@ export interface MinimatchOptions { | ||
export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; | ||
declare const SUBPARSE: unique symbol; | ||
export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; | ||
@@ -82,3 +81,3 @@ export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; | ||
braceExpand(): string[]; | ||
parse(pattern: string, isSub?: typeof SUBPARSE): ParseReturn | SubparseReturn; | ||
parse(pattern: string): ParseReturn | SubparseReturn; | ||
makeRe(): false | MMRegExp; | ||
@@ -85,0 +84,0 @@ slashSplit(p: string): string[]; |
@@ -7,2 +7,4 @@ "use strict"; | ||
exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; | ||
const brace_expansion_1 = __importDefault(require("brace-expansion")); | ||
const brace_expressions_js_1 = require("./brace-expressions.js"); | ||
const minimatch = (p, pattern, options = {}) => { | ||
@@ -85,3 +87,2 @@ assertValidPattern(pattern); | ||
exports.minimatch.GLOBSTAR = exports.GLOBSTAR; | ||
const brace_expansion_1 = __importDefault(require("brace-expansion")); | ||
const plTypes = { | ||
@@ -187,3 +188,2 @@ '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, | ||
// default, and can be disabled by setting options.noglobstar. | ||
const SUBPARSE = Symbol('subparse'); | ||
const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); | ||
@@ -205,5 +205,3 @@ exports.makeRe = makeRe; | ||
const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; | ||
const charUnescape = (s) => s.replace(/\\([^-\]])/g, '$1'); | ||
const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
const braExpEscape = (s) => s.replace(/[[\]\\]/g, '\\$&'); | ||
class Minimatch { | ||
@@ -806,3 +804,3 @@ options; | ||
} | ||
parse(pattern, isSub) { | ||
parse(pattern) { | ||
assertValidPattern(pattern); | ||
@@ -819,31 +817,29 @@ const options = this.options; | ||
let fastTest = null; | ||
if (isSub !== SUBPARSE) { | ||
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; | ||
} | ||
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; | ||
} | ||
let re = ''; | ||
@@ -856,8 +852,4 @@ let hasMagic = false; | ||
let stateChar = false; | ||
let inClass = false; | ||
let reClassStart = -1; | ||
let classStart = -1; | ||
let cs; | ||
let uflag = false; | ||
let pl; | ||
let sp; | ||
// . and .. never match anything that doesn't start with ., | ||
@@ -925,6 +917,2 @@ // even when options.dot is set. However, if the pattern | ||
case '\\': | ||
if (inClass && pattern.charAt(i + 1) === '-') { | ||
re += c; | ||
continue; | ||
} | ||
clearStateChar(); | ||
@@ -941,11 +929,2 @@ escaping = true; | ||
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); | ||
// all of those are literals inside a class, except that | ||
// the glob [!a] means [^a] in regexp | ||
if (inClass) { | ||
this.debug(' in class'); | ||
if (c === '!' && i === classStart + 1) | ||
c = '^'; | ||
re += c; | ||
continue; | ||
} | ||
// if we already have a stateChar, then it means | ||
@@ -964,6 +943,2 @@ // that there was something like ** or +? in there. | ||
case '(': { | ||
if (inClass) { | ||
re += '('; | ||
continue; | ||
} | ||
if (!stateChar) { | ||
@@ -995,3 +970,3 @@ re += '\\('; | ||
const plEntry = patternListStack[patternListStack.length - 1]; | ||
if (inClass || !plEntry) { | ||
if (!plEntry) { | ||
re += '\\)'; | ||
@@ -1015,3 +990,3 @@ continue; | ||
const plEntry = patternListStack[patternListStack.length - 1]; | ||
if (inClass || !plEntry) { | ||
if (!plEntry) { | ||
re += '\\|'; | ||
@@ -1033,40 +1008,15 @@ continue; | ||
clearStateChar(); | ||
if (inClass) { | ||
re += '\\' + c; | ||
continue; | ||
const [src, needUflag, consumed] = (0, brace_expressions_js_1.parseClass)(pattern, i); | ||
if (consumed) { | ||
re += src; | ||
uflag = uflag || needUflag; | ||
i += consumed - 1; | ||
hasMagic = true; | ||
} | ||
inClass = true; | ||
classStart = i; | ||
reClassStart = re.length; | ||
re += c; | ||
else { | ||
re += '\\['; | ||
} | ||
continue; | ||
case ']': | ||
// a right bracket shall lose its special | ||
// meaning and represent itself in | ||
// a bracket expression if it occurs | ||
// first in the list. -- POSIX.2 2.8.3.2 | ||
if (i === classStart + 1 || !inClass) { | ||
re += '\\' + c; | ||
continue; | ||
} | ||
// split where the last [ was, make sure we don't have | ||
// an invalid re. if so, re-walk the contents of the | ||
// would-be class to re-translate any characters that | ||
// were passed through as-is | ||
// TODO: It would probably be faster to determine this | ||
// without a try/catch and a new RegExp, but it's tricky | ||
// to do safely. For now, this is safe and works. | ||
cs = pattern.substring(classStart + 1, i); | ||
try { | ||
RegExp('[' + braExpEscape(charUnescape(cs)) + ']'); | ||
// looks good, finish up the class. | ||
re += c; | ||
} | ||
catch (er) { | ||
// out of order ranges in JS are errors, but in glob syntax, | ||
// they're just a range that matches nothing. | ||
re = re.substring(0, reClassStart) + '(?:$.)'; // match nothing ever | ||
} | ||
hasMagic = true; | ||
inClass = false; | ||
re += '\\' + c; | ||
continue; | ||
@@ -1076,21 +1026,6 @@ default: | ||
clearStateChar(); | ||
if (reSpecials[c] && !(c === '^' && inClass)) { | ||
re += '\\'; | ||
} | ||
re += c; | ||
re += regExpEscape(c); | ||
break; | ||
} // switch | ||
} // for | ||
// handle the case where we left a class open. | ||
// "[abc" is valid, equivalent to "\[abc" | ||
if (inClass) { | ||
// split where the last [ was, and escape it | ||
// this is a huge pita. We now have to re-walk | ||
// the contents of the would-be class to re-translate | ||
// any characters that were passed through as-is | ||
cs = pattern.slice(classStart + 1); | ||
sp = this.parse(cs, SUBPARSE); | ||
re = re.substring(0, reClassStart) + '\\[' + sp[0]; | ||
hasMagic = hasMagic || sp[1]; | ||
} | ||
// handle the case where we had a +( thing at the *end* | ||
@@ -1158,3 +1093,3 @@ // of the pattern. | ||
nlAfter = cleanAfter; | ||
const dollar = nlAfter === '' && isSub !== SUBPARSE ? '(?:$|\\/)' : ''; | ||
const dollar = nlAfter === '' ? '(?:$|\\/)' : ''; | ||
re = nlBefore + nlFirst + nlAfter + dollar + nlLast; | ||
@@ -1171,6 +1106,2 @@ } | ||
} | ||
// parsing just a piece of a larger pattern. | ||
if (isSub === SUBPARSE) { | ||
return [re, hasMagic]; | ||
} | ||
// if it's nocase, and the lcase/uppercase don't match, it's magic | ||
@@ -1186,3 +1117,3 @@ if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { | ||
} | ||
const flags = options.nocase ? 'i' : ''; | ||
const flags = (options.nocase ? 'i' : '') + (uflag ? 'u' : ''); | ||
try { | ||
@@ -1189,0 +1120,0 @@ const ext = fastTest |
@@ -40,3 +40,2 @@ export interface MinimatchOptions { | ||
export declare const braceExpand: (pattern: string, options?: MinimatchOptions) => string[]; | ||
declare const SUBPARSE: unique symbol; | ||
export declare const makeRe: (pattern: string, options?: MinimatchOptions) => false | MMRegExp; | ||
@@ -82,3 +81,3 @@ export declare const match: (list: string[], pattern: string, options?: MinimatchOptions) => string[]; | ||
braceExpand(): string[]; | ||
parse(pattern: string, isSub?: typeof SUBPARSE): ParseReturn | SubparseReturn; | ||
parse(pattern: string): ParseReturn | SubparseReturn; | ||
makeRe(): false | MMRegExp; | ||
@@ -85,0 +84,0 @@ slashSplit(p: string): string[]; |
@@ -0,1 +1,3 @@ | ||
import expand from 'brace-expansion'; | ||
import { parseClass } from './brace-expressions.js'; | ||
export const minimatch = (p, pattern, options = {}) => { | ||
@@ -77,3 +79,2 @@ assertValidPattern(pattern); | ||
minimatch.GLOBSTAR = GLOBSTAR; | ||
import expand from 'brace-expansion'; | ||
const plTypes = { | ||
@@ -176,3 +177,2 @@ '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, | ||
// default, and can be disabled by setting options.noglobstar. | ||
const SUBPARSE = Symbol('subparse'); | ||
export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); | ||
@@ -192,5 +192,3 @@ minimatch.makeRe = makeRe; | ||
const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; | ||
const charUnescape = (s) => s.replace(/\\([^-\]])/g, '$1'); | ||
const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); | ||
const braExpEscape = (s) => s.replace(/[[\]\\]/g, '\\$&'); | ||
export class Minimatch { | ||
@@ -793,3 +791,3 @@ options; | ||
} | ||
parse(pattern, isSub) { | ||
parse(pattern) { | ||
assertValidPattern(pattern); | ||
@@ -806,31 +804,29 @@ const options = this.options; | ||
let fastTest = null; | ||
if (isSub !== SUBPARSE) { | ||
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; | ||
} | ||
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; | ||
} | ||
let re = ''; | ||
@@ -843,8 +839,4 @@ let hasMagic = false; | ||
let stateChar = false; | ||
let inClass = false; | ||
let reClassStart = -1; | ||
let classStart = -1; | ||
let cs; | ||
let uflag = false; | ||
let pl; | ||
let sp; | ||
// . and .. never match anything that doesn't start with ., | ||
@@ -912,6 +904,2 @@ // even when options.dot is set. However, if the pattern | ||
case '\\': | ||
if (inClass && pattern.charAt(i + 1) === '-') { | ||
re += c; | ||
continue; | ||
} | ||
clearStateChar(); | ||
@@ -928,11 +916,2 @@ escaping = true; | ||
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); | ||
// all of those are literals inside a class, except that | ||
// the glob [!a] means [^a] in regexp | ||
if (inClass) { | ||
this.debug(' in class'); | ||
if (c === '!' && i === classStart + 1) | ||
c = '^'; | ||
re += c; | ||
continue; | ||
} | ||
// if we already have a stateChar, then it means | ||
@@ -951,6 +930,2 @@ // that there was something like ** or +? in there. | ||
case '(': { | ||
if (inClass) { | ||
re += '('; | ||
continue; | ||
} | ||
if (!stateChar) { | ||
@@ -982,3 +957,3 @@ re += '\\('; | ||
const plEntry = patternListStack[patternListStack.length - 1]; | ||
if (inClass || !plEntry) { | ||
if (!plEntry) { | ||
re += '\\)'; | ||
@@ -1002,3 +977,3 @@ continue; | ||
const plEntry = patternListStack[patternListStack.length - 1]; | ||
if (inClass || !plEntry) { | ||
if (!plEntry) { | ||
re += '\\|'; | ||
@@ -1020,40 +995,15 @@ continue; | ||
clearStateChar(); | ||
if (inClass) { | ||
re += '\\' + c; | ||
continue; | ||
const [src, needUflag, consumed] = parseClass(pattern, i); | ||
if (consumed) { | ||
re += src; | ||
uflag = uflag || needUflag; | ||
i += consumed - 1; | ||
hasMagic = true; | ||
} | ||
inClass = true; | ||
classStart = i; | ||
reClassStart = re.length; | ||
re += c; | ||
else { | ||
re += '\\['; | ||
} | ||
continue; | ||
case ']': | ||
// a right bracket shall lose its special | ||
// meaning and represent itself in | ||
// a bracket expression if it occurs | ||
// first in the list. -- POSIX.2 2.8.3.2 | ||
if (i === classStart + 1 || !inClass) { | ||
re += '\\' + c; | ||
continue; | ||
} | ||
// split where the last [ was, make sure we don't have | ||
// an invalid re. if so, re-walk the contents of the | ||
// would-be class to re-translate any characters that | ||
// were passed through as-is | ||
// TODO: It would probably be faster to determine this | ||
// without a try/catch and a new RegExp, but it's tricky | ||
// to do safely. For now, this is safe and works. | ||
cs = pattern.substring(classStart + 1, i); | ||
try { | ||
RegExp('[' + braExpEscape(charUnescape(cs)) + ']'); | ||
// looks good, finish up the class. | ||
re += c; | ||
} | ||
catch (er) { | ||
// out of order ranges in JS are errors, but in glob syntax, | ||
// they're just a range that matches nothing. | ||
re = re.substring(0, reClassStart) + '(?:$.)'; // match nothing ever | ||
} | ||
hasMagic = true; | ||
inClass = false; | ||
re += '\\' + c; | ||
continue; | ||
@@ -1063,21 +1013,6 @@ default: | ||
clearStateChar(); | ||
if (reSpecials[c] && !(c === '^' && inClass)) { | ||
re += '\\'; | ||
} | ||
re += c; | ||
re += regExpEscape(c); | ||
break; | ||
} // switch | ||
} // for | ||
// handle the case where we left a class open. | ||
// "[abc" is valid, equivalent to "\[abc" | ||
if (inClass) { | ||
// split where the last [ was, and escape it | ||
// this is a huge pita. We now have to re-walk | ||
// the contents of the would-be class to re-translate | ||
// any characters that were passed through as-is | ||
cs = pattern.slice(classStart + 1); | ||
sp = this.parse(cs, SUBPARSE); | ||
re = re.substring(0, reClassStart) + '\\[' + sp[0]; | ||
hasMagic = hasMagic || sp[1]; | ||
} | ||
// handle the case where we had a +( thing at the *end* | ||
@@ -1145,3 +1080,3 @@ // of the pattern. | ||
nlAfter = cleanAfter; | ||
const dollar = nlAfter === '' && isSub !== SUBPARSE ? '(?:$|\\/)' : ''; | ||
const dollar = nlAfter === '' ? '(?:$|\\/)' : ''; | ||
re = nlBefore + nlFirst + nlAfter + dollar + nlLast; | ||
@@ -1158,6 +1093,2 @@ } | ||
} | ||
// parsing just a piece of a larger pattern. | ||
if (isSub === SUBPARSE) { | ||
return [re, hasMagic]; | ||
} | ||
// if it's nocase, and the lcase/uppercase don't match, it's magic | ||
@@ -1173,3 +1104,3 @@ if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { | ||
} | ||
const flags = options.nocase ? 'i' : ''; | ||
const flags = (options.nocase ? 'i' : '') + (uflag ? 'u' : ''); | ||
try { | ||
@@ -1176,0 +1107,0 @@ const ext = fastTest |
@@ -5,3 +5,3 @@ { | ||
"description": "a glob matcher in javascript", | ||
"version": "7.2.0", | ||
"version": "7.3.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -35,2 +35,10 @@ # minimatch | ||
- "Globstar" `**` matching | ||
- [Posix character | ||
classes](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html), | ||
like `[[:alpha:]]`, supporting the full range of Unicode | ||
characters. For example, `[[:alpha:]]` will match against | ||
`'é'`, though `[a-zA-Z]` will not. Collating symbol and set | ||
matching is not supported, so `[[=e=]]` will _not_ match `'é'` | ||
and `[[.ch.]]` will not match `'ch'` in locales where `ch` is | ||
considered a single character. | ||
@@ -40,3 +48,4 @@ See: | ||
- `man sh` | ||
- `man bash` | ||
- `man bash` [Pattern | ||
Matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) | ||
- `man 3 fnmatch` | ||
@@ -43,0 +52,0 @@ - `man 5 gitignore` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
230092
4.08%20
42.86%3034
4.77%407
2.26%