feat(planning): grille hebdomadaire complète avec API et filtres

- Connexion API via proxy Angular (résolution CORS, base path /api)
- Import CSS ng-zorro global pour les modales et composants
- Filtres Camion/Show câblés sur l'affichage de la grille
- Camions affichés via TrucksService (linkés au show du même créneau)
- Panneau de détails : spectacles + camions du jour sélectionné
- Modale de création de spectacle stylisée avec fond et centrage
- Positionnement précis des events à la minute dans leur créneau
- Auto-scroll vers l'heure courante au chargement
- Ligne "maintenant" sur la colonne du jour actuel
- Régénération des services OpenAPI (nouveaux noms de types)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 20:36:03 +02:00
parent 150b97cd2e
commit 654b297e2e
3131 changed files with 149304 additions and 104334 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
export declare const assertValidPattern: (pattern: unknown) => void;
export declare const assertValidPattern: (pattern: any) => void;
//# sourceMappingURL=assert-valid-pattern.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAUtD,CAAA"}
{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AAC7B,MAAM,kBAAkB,GAA+B,CAC5D,OAAgB,EACW,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC,CAAA;AAVY,QAAA,kBAAkB,sBAU9B","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: unknown) => void = (\n pattern: unknown,\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]}
{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AAC7B,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA;AAVY,QAAA,kBAAkB,sBAU9B","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n pattern: any\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]}
+2 -4
View File
@@ -1,15 +1,13 @@
import type { MinimatchOptions, MMRegExp } from './index.js';
import { MinimatchOptions, MMRegExp } from './index.js';
export type ExtglobType = '!' | '?' | '+' | '*' | '@';
export declare class AST {
#private;
type: ExtglobType | null;
id: number;
get depth(): number;
constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions);
get hasMagic(): boolean | undefined;
toString(): string;
push(...parts: (string | AST)[]): void;
toJSON(): unknown[];
toJSON(): any[];
isStart(): boolean;
isEnd(): boolean;
copyIn(part: AST | string): void;
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwC5D,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAgJrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IAexB,EAAE,SAAO;IAET,IAAI,KAAK,IAAI,MAAM,CAElB;gBAgBC,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IAkDlB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAe/B,MAAM;IAkBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsQjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CA6OjE"}
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"}
+59 -312
View File
@@ -1,113 +1,11 @@
"use strict";
// parse a single path portion
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AST = void 0;
const brace_expressions_js_1 = require("./brace-expressions.js");
const unescape_js_1 = require("./unescape.js");
const types = new Set(['!', '?', '+', '*', '@']);
const isExtglobType = (c) => types.has(c);
const isExtglobAST = (c) => isExtglobType(c.type);
// Map of which extglob types can adopt the children of a nested extglob
//
// anything but ! can adopt a matching type:
// +(a|+(b|c)|d) => +(a|b|c|d)
// *(a|*(b|c)|d) => *(a|b|c|d)
// @(a|@(b|c)|d) => @(a|b|c|d)
// ?(a|?(b|c)|d) => ?(a|b|c|d)
//
// * can adopt anything, because 0 or repetition is allowed
// *(a|?(b|c)|d) => *(a|b|c|d)
// *(a|+(b|c)|d) => *(a|b|c|d)
// *(a|@(b|c)|d) => *(a|b|c|d)
//
// + can adopt @, because 1 or repetition is allowed
// +(a|@(b|c)|d) => +(a|b|c|d)
//
// + and @ CANNOT adopt *, because 0 would be allowed
// +(a|*(b|c)|d) => would match "", on *(b|c)
// @(a|*(b|c)|d) => would match "", on *(b|c)
//
// + and @ CANNOT adopt ?, because 0 would be allowed
// +(a|?(b|c)|d) => would match "", on ?(b|c)
// @(a|?(b|c)|d) => would match "", on ?(b|c)
//
// ? can adopt @, because 0 or 1 is allowed
// ?(a|@(b|c)|d) => ?(a|b|c|d)
//
// ? and @ CANNOT adopt * or +, because >1 would be allowed
// ?(a|*(b|c)|d) => would match bbb on *(b|c)
// @(a|*(b|c)|d) => would match bbb on *(b|c)
// ?(a|+(b|c)|d) => would match bbb on +(b|c)
// @(a|+(b|c)|d) => would match bbb on +(b|c)
//
// ! CANNOT adopt ! (nothing else can either)
// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)
//
// ! can adopt @
// !(a|@(b|c)|d) => !(a|b|c|d)
//
// ! CANNOT adopt *
// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
//
// ! CANNOT adopt +
// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
//
// ! CANNOT adopt ?
// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"
const adoptionMap = new Map([
['!', ['@']],
['?', ['?', '@']],
['@', ['@']],
['*', ['*', '+', '?', '@']],
['+', ['+', '@']],
]);
// nested extglobs that can be adopted in, but with the addition of
// a blank '' element.
const adoptionWithSpaceMap = new Map([
['!', ['?']],
['@', ['?']],
['+', ['?', '*']],
]);
// union of the previous two maps
const adoptionAnyMap = new Map([
['!', ['?', '@']],
['?', ['?', '@']],
['@', ['?', '@']],
['*', ['*', '+', '?', '@']],
['+', ['+', '@', '?', '*']],
]);
// Extglobs that can take over their parent if they are the only child
// the key is parent, value maps child to resulting extglob parent type
// '@' is omitted because it's a special case. An `@` extglob with a single
// member can always be usurped by that subpattern.
const usurpMap = new Map([
['!', new Map([['!', '@']])],
[
'?',
new Map([
['*', '*'],
['+', '*'],
]),
],
[
'@',
new Map([
['!', '!'],
['?', '?'],
['@', '@'],
['*', '*'],
['+', '+'],
]),
],
[
'+',
new Map([
['?', '*'],
['*', '*'],
]),
],
]);
// Patterns that get prepended to bind to the start of either the
// entire string, or just a single path portion, to prevent dots
// and/or traversal patterns, when needed.
@@ -131,7 +29,6 @@ const star = qmark + '*?';
const starNoEmpty = qmark + '+?';
// remove the \ chars that we added if we end up doing a nonmagic compare
// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
let ID = 0;
class AST {
type;
#root;
@@ -147,22 +44,6 @@ class AST {
// set to true if it's an extglob with no children
// (which really means one child of '')
#emptyExt = false;
id = ++ID;
get depth() {
return (this.#parent?.depth ?? -1) + 1;
}
[Symbol.for('nodejs.util.inspect.custom')]() {
return {
'@@type': 'AST',
id: this.id,
type: this.type,
root: this.#root.id,
parent: this.#parent?.id,
depth: this.depth,
partsLength: this.#parts.length,
parts: this.#parts,
};
}
constructor(type, parent, options = {}) {
this.type = type;
// extglobs are inherently magical
@@ -192,14 +73,15 @@ class AST {
}
// reconstructs the pattern
toString() {
return (this.#toString !== undefined ? this.#toString
: !this.type ?
(this.#toString = this.#parts.map(p => String(p)).join(''))
: (this.#toString =
this.type +
'(' +
this.#parts.map(p => String(p)).join('|') +
')'));
if (this.#toString !== undefined)
return this.#toString;
if (!this.type) {
return (this.#toString = this.#parts.map(p => String(p)).join(''));
}
else {
return (this.#toString =
this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
}
}
#fillNegs() {
/* c8 ignore start */
@@ -240,8 +122,7 @@ class AST {
if (p === '')
continue;
/* c8 ignore start */
if (typeof p !== 'string' &&
!(p instanceof _a && p.#parent === this)) {
if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {
throw new Error('invalid part: ' + p);
}
/* c8 ignore stop */
@@ -249,10 +130,8 @@ class AST {
}
}
toJSON() {
const ret = this.type === null ?
this.#parts
.slice()
.map(p => (typeof p === 'string' ? p : p.toJSON()))
const ret = this.type === null
? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))
: [this.type, ...this.#parts.map(p => p.toJSON())];
if (this.isStart() && !this.type)
ret.unshift([]);
@@ -275,7 +154,7 @@ class AST {
const p = this.#parent;
for (let i = 0; i < this.#parentIndex; i++) {
const pp = p.#parts[i];
if (!(pp instanceof _a && pp.type === '!')) {
if (!(pp instanceof AST && pp.type === '!')) {
return false;
}
}
@@ -303,14 +182,13 @@ class AST {
this.push(part.clone(this));
}
clone(parent) {
const c = new _a(this.type, parent);
const c = new AST(this.type, parent);
for (const p of this.#parts) {
c.copyIn(p);
}
return c;
}
static #parseAST(str, ast, pos, opt, extDepth) {
const maxDepth = opt.maxExtglobRecursion ?? 2;
static #parseAST(str, ast, pos, opt) {
let escaping = false;
let inBrace = false;
let braceStart = -1;
@@ -347,17 +225,11 @@ class AST {
acc += c;
continue;
}
// we don't have to check for adoption here, because that's
// done at the other recursion point.
const doRecurse = !opt.noext &&
isExtglobType(c) &&
str.charAt(i) === '(' &&
extDepth <= maxDepth;
if (doRecurse) {
if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
ast.push(acc);
acc = '';
const ext = new _a(c, ast);
i = _a.#parseAST(str, ext, i, opt, extDepth + 1);
const ext = new AST(c, ast);
i = AST.#parseAST(str, ext, i, opt);
ast.push(ext);
continue;
}
@@ -369,7 +241,7 @@ class AST {
// some kind of extglob, pos is at the (
// find the next | or )
let i = pos + 1;
let part = new _a(null, ast);
let part = new AST(null, ast);
const parts = [];
let acc = '';
while (i < str.length) {
@@ -400,26 +272,19 @@ class AST {
acc += c;
continue;
}
const doRecurse = !opt.noext &&
isExtglobType(c) &&
str.charAt(i) === '(' &&
/* c8 ignore start - the maxDepth is sufficient here */
(extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));
/* c8 ignore stop */
if (doRecurse) {
const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
if (isExtglobType(c) && str.charAt(i) === '(') {
part.push(acc);
acc = '';
const ext = new _a(c, part);
const ext = new AST(c, part);
part.push(ext);
i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);
i = AST.#parseAST(str, ext, i, opt);
continue;
}
if (c === '|') {
part.push(acc);
acc = '';
parts.push(part);
part = new _a(null, ast);
part = new AST(null, ast);
continue;
}
if (c === ')') {
@@ -441,82 +306,9 @@ class AST {
ast.#parts = [str.substring(pos - 1)];
return i;
}
#canAdoptWithSpace(child) {
return this.#canAdopt(child, adoptionWithSpaceMap);
}
#canAdopt(child, map = adoptionMap) {
if (!child ||
typeof child !== 'object' ||
child.type !== null ||
child.#parts.length !== 1 ||
this.type === null) {
return false;
}
const gc = child.#parts[0];
if (!gc || typeof gc !== 'object' || gc.type === null) {
return false;
}
return this.#canAdoptType(gc.type, map);
}
#canAdoptType(c, map = adoptionAnyMap) {
return !!map.get(this.type)?.includes(c);
}
#adoptWithSpace(child, index) {
const gc = child.#parts[0];
const blank = new _a(null, gc, this.options);
blank.#parts.push('');
gc.push(blank);
this.#adopt(child, index);
}
#adopt(child, index) {
const gc = child.#parts[0];
this.#parts.splice(index, 1, ...gc.#parts);
for (const p of gc.#parts) {
if (typeof p === 'object')
p.#parent = this;
}
this.#toString = undefined;
}
#canUsurpType(c) {
const m = usurpMap.get(this.type);
return !!m?.has(c);
}
#canUsurp(child) {
if (!child ||
typeof child !== 'object' ||
child.type !== null ||
child.#parts.length !== 1 ||
this.type === null ||
this.#parts.length !== 1) {
return false;
}
const gc = child.#parts[0];
if (!gc || typeof gc !== 'object' || gc.type === null) {
return false;
}
return this.#canUsurpType(gc.type);
}
#usurp(child) {
const m = usurpMap.get(this.type);
const gc = child.#parts[0];
const nt = m?.get(gc.type);
/* c8 ignore start - impossible */
if (!nt)
return false;
/* c8 ignore stop */
this.#parts = gc.#parts;
for (const p of this.#parts) {
if (typeof p === 'object') {
p.#parent = this;
}
}
this.type = nt;
this.#toString = undefined;
this.#emptyExt = false;
}
static fromGlob(pattern, options = {}) {
const ast = new _a(null, undefined, options);
_a.#parseAST(pattern, ast, 0, options, 0);
const ast = new AST(null, undefined, options);
AST.#parseAST(pattern, ast, 0, options);
return ast;
}
// returns the regular expression if there's magic, or the unescaped
@@ -620,18 +412,14 @@ class AST {
// or start or whatever) and prepend ^ or / at the Regexp construction.
toRegExpSource(allowDot) {
const dot = allowDot ?? !!this.#options.dot;
if (this.#root === this) {
this.#flatten();
if (this.#root === this)
this.#fillNegs();
}
if (!isExtglobAST(this)) {
const noEmpty = this.isStart() &&
this.isEnd() &&
!this.#parts.some(s => typeof s !== 'string');
if (!this.type) {
const noEmpty = this.isStart() && this.isEnd();
const src = this.#parts
.map(p => {
const [re, _, hasMagic, uflag] = typeof p === 'string' ?
_a.#parseGlob(p, this.#hasMagic, noEmpty)
const [re, _, hasMagic, uflag] = typeof p === 'string'
? AST.#parseGlob(p, this.#hasMagic, noEmpty)
: p.toRegExpSource(allowDot);
this.#hasMagic = this.#hasMagic || hasMagic;
this.#uflag = this.#uflag || uflag;
@@ -660,10 +448,7 @@ class AST {
// no need to prevent dots if it can't match a dot, or if a
// sub-pattern will be preventing it anyway.
const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
start =
needNoTrav ? startNoTraversal
: needNoDot ? startNoDot
: '';
start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : '';
}
}
}
@@ -693,14 +478,14 @@ class AST {
// invalid extglob, has to at least be *something* present, if it's
// the entire path portion.
const s = this.toString();
const me = this;
me.#parts = [s];
me.type = null;
me.#hasMagic = undefined;
this.#parts = [s];
this.type = null;
this.#hasMagic = undefined;
return [s, (0, unescape_js_1.unescape)(this.toString()), false, false];
}
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?
''
// XXX abstract out this map method
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot
? ''
: this.#partsToRegExp(true);
if (bodyDotAllowed === body) {
bodyDotAllowed = '';
@@ -714,16 +499,20 @@ class AST {
final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
}
else {
const close = this.type === '!' ?
// !() must match something,but !(x) can match ''
'))' +
(this.isStart() && !dot && !allowDot ? startNoDot : '') +
star +
')'
: this.type === '@' ? ')'
: this.type === '?' ? ')?'
: this.type === '+' && bodyDotAllowed ? ')'
: this.type === '*' && bodyDotAllowed ? `)?`
const close = this.type === '!'
? // !() must match something,but !(x) can match ''
'))' +
(this.isStart() && !dot && !allowDot ? startNoDot : '') +
star +
')'
: this.type === '@'
? ')'
: this.type === '?'
? ')?'
: this.type === '+' && bodyDotAllowed
? ')'
: this.type === '*' && bodyDotAllowed
? `)?`
: `)${this.type}`;
final = start + body + close;
}
@@ -734,42 +523,6 @@ class AST {
this.#uflag,
];
}
#flatten() {
if (!isExtglobAST(this)) {
for (const p of this.#parts) {
if (typeof p === 'object') {
p.#flatten();
}
}
}
else {
// do up to 10 passes to flatten as much as possible
let iterations = 0;
let done = false;
do {
done = true;
for (let i = 0; i < this.#parts.length; i++) {
const c = this.#parts[i];
if (typeof c === 'object') {
c.#flatten();
if (this.#canAdopt(c)) {
done = false;
this.#adopt(c, i);
}
else if (this.#canAdoptWithSpace(c)) {
done = false;
this.#adoptWithSpace(c, i);
}
else if (this.#canUsurp(c)) {
done = false;
this.#usurp(c);
}
}
}
} while (!done && ++iterations < 10);
}
this.#toString = undefined;
}
#partsToRegExp(dot) {
return this.#parts
.map(p => {
@@ -791,8 +544,6 @@ class AST {
let escaping = false;
let re = '';
let uflag = false;
// multiple stars that aren't globstars coalesce into one *
let inStar = false;
for (let i = 0; i < glob.length; i++) {
const c = glob.charAt(i);
if (escaping) {
@@ -800,17 +551,6 @@ class AST {
re += (reSpecials.has(c) ? '\\' : '') + c;
continue;
}
if (c === '*') {
if (inStar)
continue;
inStar = true;
re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star;
hasMagic = true;
continue;
}
else {
inStar = false;
}
if (c === '\\') {
if (i === glob.length - 1) {
re += '\\\\';
@@ -830,6 +570,14 @@ class AST {
continue;
}
}
if (c === '*') {
if (noEmpty && glob === '*')
re += starNoEmpty;
else
re += star;
hasMagic = true;
continue;
}
if (c === '?') {
re += qmark;
hasMagic = true;
@@ -841,5 +589,4 @@ class AST {
}
}
exports.AST = AST;
_a = AST;
//# sourceMappingURL=ast.js.map
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EACZ,UAAU,MAAM,KACf,gBA2HF,CAAA"}
{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"}
+4 -2
View File
@@ -141,8 +141,10 @@ const parseClass = (glob, position) => {
}
const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
const comb = ranges.length && negs.length ? '(' + sranges + '|' + snegs + ')'
: ranges.length ? sranges
const comb = ranges.length && negs.length
? '(' + sranges + '|' + snegs + ')'
: ranges.length
? sranges
: snegs;
return [comb, uflag, endPos - pos, true];
};
File diff suppressed because one or more lines are too long
+3 -6
View File
@@ -1,15 +1,12 @@
import type { MinimatchOptions } from './index.js';
import { MinimatchOptions } from './index.js';
/**
* Escape all magic characters in a glob pattern.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape}
* If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
* option is used, then characters are escaped by wrapping in `[]`, because
* a magic character wrapped in a character class can only be satisfied by
* that exact character. In this mode, `\` is _not_ escaped, because it is
* not interpreted as a magic character, but instead as a path separator.
*
* If the {@link MinimatchOptions.magicalBraces} option is used,
* then braces (`{` and `}`) will be escaped.
*/
export declare const escape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, 'windowsPathsNoEscape'>) => string;
//# sourceMappingURL=escape.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,MAAM,GACjB,GAAG,MAAM,EACT,2CAGG,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,eAAe,CAAM,WAazE,CAAA"}
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"}
+4 -12
View File
@@ -4,26 +4,18 @@ exports.escape = void 0;
/**
* Escape all magic characters in a glob pattern.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape}
* If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
* option is used, then characters are escaped by wrapping in `[]`, because
* a magic character wrapped in a character class can only be satisfied by
* that exact character. In this mode, `\` is _not_ escaped, because it is
* not interpreted as a magic character, but instead as a path separator.
*
* If the {@link MinimatchOptions.magicalBraces} option is used,
* then braces (`{` and `}`) will be escaped.
*/
const escape = (s, { windowsPathsNoEscape = false, magicalBraces = false, } = {}) => {
const escape = (s, { windowsPathsNoEscape = false, } = {}) => {
// don't need to escape +@! because we escape the parens
// that make those magic, and escaping ! as [!] isn't valid,
// because [!]] is a valid glob class meaning not ']'.
if (magicalBraces) {
return windowsPathsNoEscape ?
s.replace(/[?*()[\]{}]/g, '[$&]')
: s.replace(/[?*()[\]\\{}]/g, '\\$&');
}
return windowsPathsNoEscape ?
s.replace(/[?*()[\]]/g, '[$&]')
return windowsPathsNoEscape
? s.replace(/[?*()[\]]/g, '[$&]')
: s.replace(/[?*()[\]\\]/g, '\\$&');
};
exports.escape = escape;
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACI,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,EAC5B,aAAa,GAAG,KAAK,MAC+C,EAAE,EACxE,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,oBAAoB,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC;YACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,oBAAoB,CAAC,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA;AAlBY,QAAA,MAAM,UAkBlB","sourcesContent":["import type { MinimatchOptions } from './index.js'\n\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n *\n * If the {@link MinimatchOptions.magicalBraces} option is used,\n * then braces (`{` and `}`) will be escaped.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]{}]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\{}]/g, '\\\\$&')\n }\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;GAQG;AACI,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA;AAZY,QAAA,MAAM,UAYlB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape'> = {}\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n return windowsPathsNoEscape\n ? s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
+5 -85
View File
@@ -1,104 +1,26 @@
import { AST } from './ast.js';
export type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
export interface MinimatchOptions {
/** do not expand `{x,y}` style braces */
nobrace?: boolean;
/** do not treat patterns starting with `#` as a comment */
nocomment?: boolean;
/** do not treat patterns starting with `!` as a negation */
nonegate?: boolean;
/** print LOTS of debugging output */
debug?: boolean;
/** treat `**` the same as `*` */
noglobstar?: boolean;
/** do not expand extglobs like `+(a|b)` */
noext?: boolean;
/** return the pattern if nothing matches */
nonull?: boolean;
/** treat `\\` as a path separator, not an escape character */
windowsPathsNoEscape?: boolean;
/**
* inverse of {@link MinimatchOptions.windowsPathsNoEscape}
* @deprecated
*/
allowWindowsEscape?: boolean;
/**
* Compare a partial path to a pattern. As long as the parts
* of the path that are present are not contradicted by the
* pattern, it will be treated as a match. This is useful in
* applications where you're walking through a folder structure,
* and don't yet have the full path, but want to ensure that you
* do not walk down paths that can never be a match.
*/
partial?: boolean;
/** allow matches that start with `.` even if the pattern does not */
dot?: boolean;
/** ignore case */
nocase?: boolean;
/** ignore case only in wildcard patterns */
nocaseMagicOnly?: boolean;
/** consider braces to be "magic" for the purpose of `hasMagic` */
magicalBraces?: boolean;
/**
* If set, then patterns without slashes will be matched
* against the basename of the path if it contains slashes.
* For example, `a?b` would match the path `/xyz/123/acb`, but
* not `/xyz/acb/123`.
*/
matchBase?: boolean;
/** invert the results of negated matches */
flipNegate?: boolean;
/** do not collapse multiple `/` into a single `/` */
preserveMultipleSlashes?: boolean;
/**
* A number indicating the level of optimization that should be done
* to the pattern prior to parsing and using it for matches.
*/
optimizationLevel?: number;
/** operating system platform */
platform?: Platform;
/**
* When a pattern starts with a UNC path or drive letter, and in
* `nocase:true` mode, do not convert the root portions of the
* pattern into a case-insensitive regular expression, and instead
* leave them as strings.
*
* This is the default when the platform is `win32` and
* `nocase:true` is set.
*/
windowsNoMagicRoot?: boolean;
/**
* max number of `{...}` patterns to expand. Default 100_000.
*/
braceExpandMax?: number;
/**
* Max number of non-adjacent `**` patterns to recursively walk down.
*
* The default of 200 is almost certainly high enough for most purposes,
* and can handle absurdly excessive patterns.
*/
maxGlobstarRecursion?: number;
/**
* Max depth to traverse for nested extglobs like `*(a|b|c)`
*
* Default is 2, which is quite low, but any higher value
* swiftly results in punishing performance impacts. Note
* that this is *not* relevant when the globstar types can
* be safely coalesced into a single set.
*
* For example, `*(a|@(b|c)|d)` would be flattened into
* `*(a|b|c|d)`. Thus, many common extglobs will retain good
* performance and never hit this limit, even if they are
* excessively deep and complicated.
*
* If the limit is hit, then the extglob characters are simply
* not parsed, and the pattern effectively switches into
* `noextglob: true` mode for the contents of that nested
* sub-pattern. This will typically _not_ result in a match,
* but is considered a valid trade-off for security and
* performance.
*/
maxExtglobRecursion?: number;
}
export declare const minimatch: {
(p: string, pattern: string, options?: MinimatchOptions): boolean;
@@ -111,10 +33,10 @@ export declare const minimatch: {
match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
AST: typeof AST;
Minimatch: typeof Minimatch;
escape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
unescape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
escape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, "windowsPathsNoEscape">) => string;
unescape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, "windowsPathsNoEscape">) => string;
};
export type Sep = '\\' | '/';
type Sep = '\\' | '/';
export declare const sep: Sep;
export declare const GLOBSTAR: unique symbol;
export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
@@ -129,7 +51,6 @@ export type MMRegExp = RegExp & {
export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR;
export type ParseReturn = ParseReturnFiltered | false;
export declare class Minimatch {
#private;
options: MinimatchOptions;
set: ParseReturnFiltered[][];
pattern: string;
@@ -146,11 +67,10 @@ export declare class Minimatch {
isWindows: boolean;
platform: Platform;
windowsNoMagicRoot: boolean;
maxGlobstarRecursion: number;
regexp: false | null | MMRegExp;
constructor(pattern: string, options?: MinimatchOptions);
hasMagic(): boolean;
debug(..._: unknown[]): void;
debug(..._: any[]): void;
make(): void;
preprocess(globParts: string[][]): string[][];
adjascentGlobstarOptimize(globParts: string[][]): string[][];
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAI9B,MAAM,MAAM,QAAQ,GAChB,KAAK,GACL,SAAS,GACT,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,SAAS,GACT,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,CAAA;AAEZ,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,iCAAiC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qEAAqE;IACrE,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,kBAAkB;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kEAAkE;IAClE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qDAAqD;IACrD,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,eAAO,MAAM,SAAS;QACjB,MAAM,WACA,MAAM,YACN,gBAAgB;;;sBA4Gf,MAAM,YAAW,gBAAgB,MAC1C,GAAG,MAAM;oBAOkB,gBAAgB,KAAG,OAAO,SAAS;2BAuFtD,MAAM,YACN,gBAAgB;sBA2BK,MAAM,YAAW,gBAAgB;kBAKzD,MAAM,EAAE,WACL,MAAM,YACN,gBAAgB;;;;;CApO1B,CAAA;AAkED,MAAM,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAA;AAQ5B,eAAO,MAAM,GAAG,KAC+C,CAAA;AAG/D,eAAO,MAAM,QAAQ,eAAwB,CAAA;AAmB7C,eAAO,MAAM,MAAM,GAChB,SAAS,MAAM,EAAE,UAAS,gBAAqB,MAC/C,GAAG,MAAM,YACsB,CAAA;AAMlC,eAAO,MAAM,QAAQ,GAAI,KAAK,gBAAgB,KAAG,OAAO,SAyEvD,CAAA;AAaD,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,UAAS,gBAAqB,aAY/B,CAAA;AAeD,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,EAAE,UAAS,gBAAqB,qBAC5B,CAAA;AAG1C,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,EAAE,EACd,SAAS,MAAM,EACf,UAAS,gBAAqB,aAQ/B,CAAA;AAQD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,QAAQ,CAAA;AACrE,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,KAAK,CAAA;AAErD,qBAAa,SAAS;;IACpB,OAAO,EAAE,gBAAgB,CAAA;IACzB,GAAG,EAAE,mBAAmB,EAAE,EAAE,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IAEf,oBAAoB,EAAE,OAAO,CAAA;IAC7B,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,uBAAuB,EAAE,OAAO,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,EAAE,CAAA;IACrB,MAAM,EAAE,OAAO,CAAA;IAEf,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAE5B,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAA;gBACnB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAqC3D,QAAQ,IAAI,OAAO;IAYnB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAErB,IAAI;IA8FJ,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IA8BhC,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IAiB/C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IAoBtC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAoE7C,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;IA0F1C,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE;IAkBxD,UAAU,CACR,CAAC,EAAE,MAAM,EAAE,EACX,CAAC,EAAE,MAAM,EAAE,EACX,YAAY,GAAE,OAAe,GAC5B,KAAK,GAAG,MAAM,EAAE;IA+CnB,WAAW;IAqBX,QAAQ,CACN,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,EAAE,EACtB,OAAO,GAAE,OAAe;IAiX1B,WAAW;IAIX,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IA6CnC,MAAM;IAuGN,UAAU,CAAC,CAAC,EAAE,MAAM;IAepB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,UAAe;IAgEvC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,gBAAgB;CAGtC;AAED,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
+140 -250
View File
@@ -1,7 +1,10 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.unescape = exports.escape = exports.AST = exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0;
const brace_expansion_1 = require("brace-expansion");
const brace_expansion_1 = __importDefault(require("brace-expansion"));
const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js");
const ast_js_1 = require("./ast.js");
const escape_js_1 = require("./escape.js");
@@ -16,7 +19,7 @@ const minimatch = (p, pattern, options = {}) => {
};
exports.minimatch = minimatch;
// Optimized checking for the most common glob patterns.
const starDotExtRE = /^\*+([^+@!?*[(]*)$/;
const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
const starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
const starDotExtTestNocase = (ext) => {
@@ -35,7 +38,7 @@ const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
const starRE = /^\*+$/;
const starTest = (f) => f.length !== 0 && !f.startsWith('.');
const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
const qmarksRE = /^\?+([^+@!?*[(]*)?$/;
const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
const qmarksTestNocase = ([$0, ext = '']) => {
const noext = qmarksTestNoExt([$0]);
if (!ext)
@@ -67,8 +70,8 @@ const qmarksTestNoExtDot = ([$0]) => {
return (f) => f.length === len && f !== '.' && f !== '..';
};
/* c8 ignore start */
const defaultPlatform = (typeof process === 'object' && process ?
(typeof process.env === 'object' &&
const defaultPlatform = (typeof process === 'object' && process
? (typeof process.env === 'object' &&
process.env &&
process.env.__MINIMATCH_TESTING_PLATFORM__) ||
process.platform
@@ -154,7 +157,7 @@ const braceExpand = (pattern, options = {}) => {
// shortcut. no need to expand.
return [pattern];
}
return (0, brace_expansion_1.expand)(pattern, { max: options.braceExpandMax });
return (0, brace_expansion_1.default)(pattern);
};
exports.braceExpand = braceExpand;
exports.minimatch.braceExpand = exports.braceExpand;
@@ -202,20 +205,16 @@ class Minimatch {
isWindows;
platform;
windowsNoMagicRoot;
maxGlobstarRecursion;
regexp;
constructor(pattern, options = {}) {
(0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
options = options || {};
this.options = options;
this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
this.pattern = pattern;
this.platform = options.platform || defaultPlatform;
this.isWindows = this.platform === 'win32';
// avoid the annoying deprecation flag lol
const awe = ('allowWindow' + 'sEscape');
this.windowsPathsNoEscape =
!!options.windowsPathsNoEscape || options[awe] === false;
!!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
if (this.windowsPathsNoEscape) {
this.pattern = this.pattern.replace(/\\/g, '/');
}
@@ -228,8 +227,8 @@ class Minimatch {
this.partial = !!options.partial;
this.nocase = !!this.options.nocase;
this.windowsNoMagicRoot =
options.windowsNoMagicRoot !== undefined ?
options.windowsNoMagicRoot
options.windowsNoMagicRoot !== undefined
? options.windowsNoMagicRoot
: !!(this.isWindows && this.nocase);
this.globSet = [];
this.globParts = [];
@@ -267,7 +266,6 @@ class Minimatch {
// step 2: expand braces
this.globSet = [...new Set(this.braceExpand())];
if (options.debug) {
//oxlint-disable-next-line no-console
this.debug = (...args) => console.error(...args);
}
this.debug(this.pattern, this.globSet);
@@ -293,10 +291,7 @@ class Minimatch {
!globMagic.test(s[3]);
const isDrive = /^[a-z]:/i.test(s[0]);
if (isUNC) {
return [
...s.slice(0, 4),
...s.slice(4).map(ss => this.parse(ss)),
];
return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
}
else if (isDrive) {
return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
@@ -328,12 +323,12 @@ class Minimatch {
// to the right as possible, even if it increases the number
// of patterns that we have to process.
preprocess(globParts) {
// if we're not in globstar mode, then turn ** into *
// if we're not in globstar mode, then turn all ** into *
if (this.options.noglobstar) {
for (const partset of globParts) {
for (let j = 0; j < partset.length; j++) {
if (partset[j] === '**') {
partset[j] = '*';
for (let i = 0; i < globParts.length; i++) {
for (let j = 0; j < globParts[i].length; j++) {
if (globParts[i][j] === '**') {
globParts[i][j] = '*';
}
}
}
@@ -421,11 +416,7 @@ class Minimatch {
let dd = 0;
while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
const p = parts[dd - 1];
if (p &&
p !== '.' &&
p !== '..' &&
p !== '**' &&
!(this.isWindows && /^[a-z]:$/i.test(p))) {
if (p && p !== '.' && p !== '..' && p !== '**') {
didSomething = true;
parts.splice(dd - 1, 2);
dd -= 2;
@@ -618,8 +609,7 @@ class Minimatch {
// out of pattern, then that's fine, as long as all
// the parts match.
matchOne(file, pattern, partial = false) {
let fileStartIndex = 0;
let patternStartIndex = 0;
const options = this.options;
// UNC paths like //?/X:/... can match X:/... and vice versa
// Drive letters in absolute drive or unc paths are always compared
// case-insensitively.
@@ -637,212 +627,120 @@ class Minimatch {
pattern[2] === '?' &&
typeof pattern[3] === 'string' &&
/^[a-z]:$/i.test(pattern[3]);
const fdi = fileUNC ? 3
: fileDrive ? 0
: undefined;
const pdi = patternUNC ? 3
: patternDrive ? 0
: undefined;
const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
if (typeof fdi === 'number' && typeof pdi === 'number') {
const [fd, pd] = [
file[fdi],
pattern[pdi],
];
// start matching at the drive letter index of each
const [fd, pd] = [file[fdi], pattern[pdi]];
if (fd.toLowerCase() === pd.toLowerCase()) {
pattern[pdi] = fd;
patternStartIndex = pdi;
fileStartIndex = fdi;
if (pdi > fdi) {
pattern = pattern.slice(pdi);
}
else if (fdi > pdi) {
file = file.slice(fdi);
}
}
}
}
// resolve and reduce . and .. portions in the file as well.
// don't need to do the second phase, because it's only one string[]
// dont' need to do the second phase, because it's only one string[]
const { optimizationLevel = 1 } = this.options;
if (optimizationLevel >= 2) {
file = this.levelTwoFileOptimize(file);
}
if (pattern.includes(exports.GLOBSTAR)) {
return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
}
return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
}
#matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
// split the pattern into head, tail, and middle of ** delimited parts
const firstgs = pattern.indexOf(exports.GLOBSTAR, patternIndex);
const lastgs = pattern.lastIndexOf(exports.GLOBSTAR);
// split the pattern up into globstar-delimited sections
// the tail has to be at the end, and the others just have
// to be found in order from the head.
const [head, body, tail] = partial ?
[
pattern.slice(patternIndex, firstgs),
pattern.slice(firstgs + 1),
[],
]
: [
pattern.slice(patternIndex, firstgs),
pattern.slice(firstgs + 1, lastgs),
pattern.slice(lastgs + 1),
];
// check the head, from the current file/pattern index.
if (head.length) {
const fileHead = file.slice(fileIndex, fileIndex + head.length);
if (!this.#matchOne(fileHead, head, partial, 0, 0)) {
return false;
}
fileIndex += head.length;
patternIndex += head.length;
}
// now we know the head matches!
// if the last portion is not empty, it MUST match the end
// check the tail
let fileTailMatch = 0;
if (tail.length) {
// if head + tail > file, then we cannot possibly match
if (tail.length + fileIndex > file.length)
return false;
// try to match the tail
let tailStart = file.length - tail.length;
if (this.#matchOne(file, tail, partial, tailStart, 0)) {
fileTailMatch = tail.length;
}
else {
// affordance for stuff like a/**/* matching a/b/
// if the last file portion is '', and there's more to the pattern
// then try without the '' bit.
if (file[file.length - 1] !== '' ||
fileIndex + tail.length === file.length) {
return false;
}
tailStart--;
if (!this.#matchOne(file, tail, partial, tailStart, 0)) {
return false;
}
fileTailMatch = tail.length + 1;
}
}
// now we know the tail matches!
// the middle is zero or more portions wrapped in **, possibly
// containing more ** sections.
// so a/**/b/**/c/**/d has become **/b/**/c/**
// if it's empty, it means a/**/b, just verify we have no bad dots
// if there's no tail, so it ends on /**, then we must have *something*
// after the head, or it's not a matc
if (!body.length) {
let sawSome = !!fileTailMatch;
for (let i = fileIndex; i < file.length - fileTailMatch; i++) {
const f = String(file[i]);
sawSome = true;
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
}
// in partial mode, we just need to get past all file parts
return partial || sawSome;
}
// now we know that there's one or more body sections, which can
// be matched anywhere from the 0 index (because the head was pruned)
// through to the length-fileTailMatch index.
// split the body up into sections, and note the minimum index it can
// be found at (start with the length of all previous segments)
// [section, before, after]
const bodySegments = [[[], 0]];
let currentBody = bodySegments[0];
let nonGsParts = 0;
const nonGsPartsSums = [0];
for (const b of body) {
if (b === exports.GLOBSTAR) {
nonGsPartsSums.push(nonGsParts);
currentBody = [[], 0];
bodySegments.push(currentBody);
}
else {
currentBody[0].push(b);
nonGsParts++;
}
}
let i = bodySegments.length - 1;
const fileLength = file.length - fileTailMatch;
for (const b of bodySegments) {
b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
}
return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
}
// return false for "nope, not matching"
// return null for "not matching, cannot keep trying"
#matchGlobStarBodySections(file,
// pattern section, last possible position for it
bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
// take the first body segment, and walk from fileIndex to its "after"
// value at the end
// If it doesn't match at that position, we increment, until we hit
// that final possible position, and give up.
// If it does match, then advance and try to rest.
// If any of them fail we keep walking forward.
// this is still a bit recursively painful, but it's more constrained
// than previous implementations, because we never test something that
// can't possibly be a valid matching condition.
const bs = bodySegments[bodyIndex];
if (!bs) {
// just make sure that there's no bad dots
for (let i = fileIndex; i < file.length; i++) {
sawTail = true;
const f = file[i];
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
}
return sawTail;
}
// have a non-globstar body section to test
const [body, after] = bs;
while (fileIndex <= after) {
const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
// if limit exceeded, no match. intentional false negative,
// acceptable break in correctness for security.
if (m && globStarDepth < this.maxGlobstarRecursion) {
// match! see if the rest match. if so, we're done!
const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
if (sub !== false) {
return sub;
}
}
const f = file[fileIndex];
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
fileIndex++;
}
// walked off. no point continuing
return partial || null;
}
#matchOne(file, pattern, partial, fileIndex, patternIndex) {
let fi;
let pi;
let pl;
let fl;
for (fi = fileIndex,
pi = patternIndex,
fl = file.length,
pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
this.debug('matchOne', this, { file, pattern });
this.debug('matchOne', file.length, pattern.length);
for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
this.debug('matchOne loop');
let p = pattern[pi];
let f = file[fi];
var p = pattern[pi];
var f = file[fi];
this.debug(pattern, p, f);
// should be impossible.
// some invalid regexp stuff in the set.
/* c8 ignore start */
if (p === false || p === exports.GLOBSTAR) {
if (p === false) {
return false;
}
/* c8 ignore stop */
if (p === exports.GLOBSTAR) {
this.debug('GLOBSTAR', [pattern, p, f]);
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
//
// a/**/b/**/c matching a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi;
var pr = pi + 1;
if (pr === pl) {
this.debug('** at the end');
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for (; fi < fl; fi++) {
if (file[fi] === '.' ||
file[fi] === '..' ||
(!options.dot && file[fi].charAt(0) === '.'))
return false;
}
return true;
}
// ok, let's see if we can swallow whatever we can.
while (fr < fl) {
var swallowee = file[fr];
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
this.debug('globstar found match!', fr, fl, swallowee);
// found a match.
return true;
}
else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
if (swallowee === '.' ||
swallowee === '..' ||
(!options.dot && swallowee.charAt(0) === '.')) {
this.debug('dot detected!', file, fr, pattern, pr);
break;
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue');
fr++;
}
}
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
/* c8 ignore start */
if (partial) {
// ran out of file
this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
if (fr === fl) {
return true;
}
}
/* c8 ignore stop */
return false;
}
// something other than **
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
@@ -913,19 +811,21 @@ class Minimatch {
fastTest = options.dot ? starTestDot : starTest;
}
else if ((m = pattern.match(starDotExtRE))) {
fastTest = (options.nocase ?
options.dot ?
starDotExtTestNocaseDot
fastTest = (options.nocase
? options.dot
? starDotExtTestNocaseDot
: starDotExtTestNocase
: options.dot ? starDotExtTestDot
: options.dot
? starDotExtTestDot
: starDotExtTest)(m[1]);
}
else if ((m = pattern.match(qmarksRE))) {
fastTest = (options.nocase ?
options.dot ?
qmarksTestNocaseDot
fastTest = (options.nocase
? options.dot
? qmarksTestNocaseDot
: qmarksTestNocase
: options.dot ? qmarksTestDot
: options.dot
? qmarksTestDot
: qmarksTest)(m);
}
else if ((m = pattern.match(starDotStarRE))) {
@@ -956,8 +856,10 @@ class Minimatch {
return this.regexp;
}
const options = this.options;
const twoStar = options.noglobstar ? star
: options.dot ? twoStarDot
const twoStar = options.noglobstar
? star
: options.dot
? twoStarDot
: twoStarNoDot;
const flags = new Set(options.nocase ? ['i'] : []);
// regexpify non-globstar patterns
@@ -973,9 +875,11 @@ class Minimatch {
for (const f of p.flags.split(''))
flags.add(f);
}
return (typeof p === 'string' ? regExpEscape(p)
: p === exports.GLOBSTAR ? exports.GLOBSTAR
: p._src);
return typeof p === 'string'
? regExpEscape(p)
: p === exports.GLOBSTAR
? exports.GLOBSTAR
: p._src;
});
pp.forEach((p, i) => {
const next = pp[i + 1];
@@ -992,25 +896,14 @@ class Minimatch {
}
}
else if (next === undefined) {
pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?';
pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
}
else if (next !== exports.GLOBSTAR) {
pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
pp[i + 1] = exports.GLOBSTAR;
}
});
const filtered = pp.filter(p => p !== exports.GLOBSTAR);
// For partial matches, we need to make the pattern match
// any prefix of the full path. We do this by generating
// alternative patterns that match progressively longer prefixes.
if (this.partial && filtered.length >= 1) {
const prefixes = [];
for (let i = 1; i <= filtered.length; i++) {
prefixes.push(filtered.slice(0, i).join('/'));
}
return '(?:' + prefixes.join('|') + ')';
}
return filtered.join('/');
return pp.filter(p => p !== exports.GLOBSTAR).join('/');
})
.join('|');
// need to wrap in parens if we had more than one thing with |,
@@ -1019,10 +912,6 @@ class Minimatch {
// must match entire pattern
// ending in a * or ** will make it less strict.
re = '^' + open + re + close + '$';
// In partial mode, '/' should always match as it's a valid prefix for any pattern
if (this.partial) {
re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$';
}
// can match anything, as long as it's not this.
if (this.negate)
re = '^(?!' + re + ').+$';
@@ -1030,7 +919,7 @@ class Minimatch {
this.regexp = new RegExp(re, [...flags].join(''));
/* c8 ignore start */
}
catch {
catch (ex) {
// should be impossible
this.regexp = false;
}
@@ -1045,7 +934,7 @@ class Minimatch {
if (this.preserveMultipleSlashes) {
return p.split('/');
}
else if (this.isWindows && /^\/\/[^/]+/.test(p)) {
else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
// add an extra '' for the one we lose
return ['', ...p.split(/\/+/)];
}
@@ -1087,7 +976,8 @@ class Minimatch {
filename = ff[i];
}
}
for (const pattern of set) {
for (let i = 0; i < set.length; i++) {
const pattern = set[i];
let file = ff;
if (options.matchBase && pattern.length === 1) {
file = [filename];
+1 -1
View File
File diff suppressed because one or more lines are too long
+7 -12
View File
@@ -1,22 +1,17 @@
import type { MinimatchOptions } from './index.js';
import { MinimatchOptions } from './index.js';
/**
* Un-escape a string that has been escaped with {@link escape}.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then
* square-bracket escapes are removed, but not backslash escapes.
* If the {@link windowsPathsNoEscape} option is used, then square-brace
* escapes are removed, but not backslash escapes. For example, it will turn
* the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
* becuase `\` is a path separator in `windowsPathsNoEscape` mode.
*
* For example, it will turn the string `'[*]'` into `*`, but it will not
* turn `'\\*'` into `'*'`, because `\` is a path separator in
* `windowsPathsNoEscape` mode.
*
* When `windowsPathsNoEscape` is not set, then both square-bracket escapes and
* When `windowsPathsNoEscape` is not set, then both brace escapes and
* backslash escapes are removed.
*
* Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
* or unescaped.
*
* When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be
* unescaped.
*/
export declare const unescape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, 'windowsPathsNoEscape'>) => string;
//# sourceMappingURL=unescape.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,EACT,2CAGG,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,eAAe,CAAM,WAczE,CAAA"}
{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
+9 -23
View File
@@ -4,35 +4,21 @@ exports.unescape = void 0;
/**
* Un-escape a string that has been escaped with {@link escape}.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then
* square-bracket escapes are removed, but not backslash escapes.
* If the {@link windowsPathsNoEscape} option is used, then square-brace
* escapes are removed, but not backslash escapes. For example, it will turn
* the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
* becuase `\` is a path separator in `windowsPathsNoEscape` mode.
*
* For example, it will turn the string `'[*]'` into `*`, but it will not
* turn `'\\*'` into `'*'`, because `\` is a path separator in
* `windowsPathsNoEscape` mode.
*
* When `windowsPathsNoEscape` is not set, then both square-bracket escapes and
* When `windowsPathsNoEscape` is not set, then both brace escapes and
* backslash escapes are removed.
*
* Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
* or unescaped.
*
* When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be
* unescaped.
*/
const unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true, } = {}) => {
if (magicalBraces) {
return windowsPathsNoEscape ?
s.replace(/\[([^/\\])\]/g, '$1')
: s
.replace(/((?!\\).|^)\[([^/\\])\]/g, '$1$2')
.replace(/\\([^/])/g, '$1');
}
return windowsPathsNoEscape ?
s.replace(/\[([^/\\{}])\]/g, '$1')
: s
.replace(/((?!\\).|^)\[([^/\\{}])\]/g, '$1$2')
.replace(/\\([^/{}])/g, '$1');
const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
return windowsPathsNoEscape
? s.replace(/\[([^\/\\])\]/g, '$1')
: s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
};
exports.unescape = unescape;
//# sourceMappingURL=unescape.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEI,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,EAC5B,aAAa,GAAG,IAAI,MACgD,EAAE,EACxE,EAAE;IACF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,oBAAoB,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC;YAClC,CAAC,CAAC,CAAC;iBACE,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC;iBAC3C,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,oBAAoB,CAAC,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;QACpC,CAAC,CAAC,CAAC;aACE,OAAO,CAAC,4BAA4B,EAAE,MAAM,CAAC;aAC7C,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC,CAAA;AAnBY,QAAA,QAAQ,YAmBpB","sourcesContent":["import type { MinimatchOptions } from './index.js'\n\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then\n * square-bracket escapes are removed, but not backslash escapes.\n *\n * For example, it will turn the string `'[*]'` into `*`, but it will not\n * turn `'\\\\*'` into `'*'`, because `\\` is a path separator in\n * `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n *\n * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be\n * unescaped.\n */\n\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = true,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\])\\]/g, '$1$2')\n .replace(/\\\\([^/])/g, '$1')\n }\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\{}])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\{}])\\]/g, '$1$2')\n .replace(/\\\\([^/{}])/g, '$1')\n}\n"]}
{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":";;;AACA;;;;;;;;;;;;;GAaG;AACI,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA;AATY,QAAA,QAAQ,YASpB","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes. For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape'> = {}\n) => {\n return windowsPathsNoEscape\n ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}
+1 -1
View File
@@ -1,2 +1,2 @@
export declare const assertValidPattern: (pattern: unknown) => void;
export declare const assertValidPattern: (pattern: any) => void;
//# sourceMappingURL=assert-valid-pattern.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAUtD,CAAA"}
{"version":3,"file":"assert-valid-pattern.d.ts","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAUlD,CAAA"}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAA+B,CAC5D,OAAgB,EACW,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC,CAAA","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: unknown) => void = (\n pattern: unknown,\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]}
{"version":3,"file":"assert-valid-pattern.js","sourceRoot":"","sources":["../../src/assert-valid-pattern.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAA2B,CACxD,OAAY,EACe,EAAE;IAC7B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAA;KACvC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,EAAE;QACvC,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;KAC3C;AACH,CAAC,CAAA","sourcesContent":["const MAX_PATTERN_LENGTH = 1024 * 64\nexport const assertValidPattern: (pattern: any) => void = (\n pattern: any\n): asserts pattern is string => {\n if (typeof pattern !== 'string') {\n throw new TypeError('invalid pattern')\n }\n\n if (pattern.length > MAX_PATTERN_LENGTH) {\n throw new TypeError('pattern is too long')\n }\n}\n"]}
+2 -4
View File
@@ -1,15 +1,13 @@
import type { MinimatchOptions, MMRegExp } from './index.js';
import { MinimatchOptions, MMRegExp } from './index.js';
export type ExtglobType = '!' | '?' | '+' | '*' | '@';
export declare class AST {
#private;
type: ExtglobType | null;
id: number;
get depth(): number;
constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions);
get hasMagic(): boolean | undefined;
toString(): string;
push(...parts: (string | AST)[]): void;
toJSON(): unknown[];
toJSON(): any[];
isStart(): boolean;
isEnd(): boolean;
copyIn(part: AST | string): void;
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwC5D,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAgJrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IAexB,EAAE,SAAO;IAET,IAAI,KAAK,IAAI,MAAM,CAElB;gBAgBC,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IAkDlB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAe/B,MAAM;IAkBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsQjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CA6OjE"}
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAwCvD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAkCrD,qBAAa,GAAG;;IACd,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;gBAiBtB,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,gBAAqB;IAahC,IAAI,QAAQ,IAAI,OAAO,GAAG,SAAS,CAUlC;IAGD,QAAQ,IAAI,MAAM;IA+ClB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;IAY/B,MAAM;IAgBN,OAAO,IAAI,OAAO;IAgBlB,KAAK,IAAI,OAAO;IAYhB,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM;IAKzB,KAAK,CAAC,MAAM,EAAE,GAAG;IAsIjB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAQ/D,WAAW,IAAI,QAAQ,GAAG,MAAM;IA2BhC,IAAI,OAAO,qBAEV;IAuED,cAAc,CACZ,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;CAiMjE"}
+59 -312
View File
@@ -1,110 +1,8 @@
// parse a single path portion
var _a;
import { parseClass } from './brace-expressions.js';
import { unescape } from './unescape.js';
const types = new Set(['!', '?', '+', '*', '@']);
const isExtglobType = (c) => types.has(c);
const isExtglobAST = (c) => isExtglobType(c.type);
// Map of which extglob types can adopt the children of a nested extglob
//
// anything but ! can adopt a matching type:
// +(a|+(b|c)|d) => +(a|b|c|d)
// *(a|*(b|c)|d) => *(a|b|c|d)
// @(a|@(b|c)|d) => @(a|b|c|d)
// ?(a|?(b|c)|d) => ?(a|b|c|d)
//
// * can adopt anything, because 0 or repetition is allowed
// *(a|?(b|c)|d) => *(a|b|c|d)
// *(a|+(b|c)|d) => *(a|b|c|d)
// *(a|@(b|c)|d) => *(a|b|c|d)
//
// + can adopt @, because 1 or repetition is allowed
// +(a|@(b|c)|d) => +(a|b|c|d)
//
// + and @ CANNOT adopt *, because 0 would be allowed
// +(a|*(b|c)|d) => would match "", on *(b|c)
// @(a|*(b|c)|d) => would match "", on *(b|c)
//
// + and @ CANNOT adopt ?, because 0 would be allowed
// +(a|?(b|c)|d) => would match "", on ?(b|c)
// @(a|?(b|c)|d) => would match "", on ?(b|c)
//
// ? can adopt @, because 0 or 1 is allowed
// ?(a|@(b|c)|d) => ?(a|b|c|d)
//
// ? and @ CANNOT adopt * or +, because >1 would be allowed
// ?(a|*(b|c)|d) => would match bbb on *(b|c)
// @(a|*(b|c)|d) => would match bbb on *(b|c)
// ?(a|+(b|c)|d) => would match bbb on +(b|c)
// @(a|+(b|c)|d) => would match bbb on +(b|c)
//
// ! CANNOT adopt ! (nothing else can either)
// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)
//
// ! can adopt @
// !(a|@(b|c)|d) => !(a|b|c|d)
//
// ! CANNOT adopt *
// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
//
// ! CANNOT adopt +
// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
//
// ! CANNOT adopt ?
// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"
const adoptionMap = new Map([
['!', ['@']],
['?', ['?', '@']],
['@', ['@']],
['*', ['*', '+', '?', '@']],
['+', ['+', '@']],
]);
// nested extglobs that can be adopted in, but with the addition of
// a blank '' element.
const adoptionWithSpaceMap = new Map([
['!', ['?']],
['@', ['?']],
['+', ['?', '*']],
]);
// union of the previous two maps
const adoptionAnyMap = new Map([
['!', ['?', '@']],
['?', ['?', '@']],
['@', ['?', '@']],
['*', ['*', '+', '?', '@']],
['+', ['+', '@', '?', '*']],
]);
// Extglobs that can take over their parent if they are the only child
// the key is parent, value maps child to resulting extglob parent type
// '@' is omitted because it's a special case. An `@` extglob with a single
// member can always be usurped by that subpattern.
const usurpMap = new Map([
['!', new Map([['!', '@']])],
[
'?',
new Map([
['*', '*'],
['+', '*'],
]),
],
[
'@',
new Map([
['!', '!'],
['?', '?'],
['@', '@'],
['*', '*'],
['+', '+'],
]),
],
[
'+',
new Map([
['?', '*'],
['*', '*'],
]),
],
]);
// Patterns that get prepended to bind to the start of either the
// entire string, or just a single path portion, to prevent dots
// and/or traversal patterns, when needed.
@@ -128,7 +26,6 @@ const star = qmark + '*?';
const starNoEmpty = qmark + '+?';
// remove the \ chars that we added if we end up doing a nonmagic compare
// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
let ID = 0;
export class AST {
type;
#root;
@@ -144,22 +41,6 @@ export class AST {
// set to true if it's an extglob with no children
// (which really means one child of '')
#emptyExt = false;
id = ++ID;
get depth() {
return (this.#parent?.depth ?? -1) + 1;
}
[Symbol.for('nodejs.util.inspect.custom')]() {
return {
'@@type': 'AST',
id: this.id,
type: this.type,
root: this.#root.id,
parent: this.#parent?.id,
depth: this.depth,
partsLength: this.#parts.length,
parts: this.#parts,
};
}
constructor(type, parent, options = {}) {
this.type = type;
// extglobs are inherently magical
@@ -189,14 +70,15 @@ export class AST {
}
// reconstructs the pattern
toString() {
return (this.#toString !== undefined ? this.#toString
: !this.type ?
(this.#toString = this.#parts.map(p => String(p)).join(''))
: (this.#toString =
this.type +
'(' +
this.#parts.map(p => String(p)).join('|') +
')'));
if (this.#toString !== undefined)
return this.#toString;
if (!this.type) {
return (this.#toString = this.#parts.map(p => String(p)).join(''));
}
else {
return (this.#toString =
this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
}
}
#fillNegs() {
/* c8 ignore start */
@@ -237,8 +119,7 @@ export class AST {
if (p === '')
continue;
/* c8 ignore start */
if (typeof p !== 'string' &&
!(p instanceof _a && p.#parent === this)) {
if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {
throw new Error('invalid part: ' + p);
}
/* c8 ignore stop */
@@ -246,10 +127,8 @@ export class AST {
}
}
toJSON() {
const ret = this.type === null ?
this.#parts
.slice()
.map(p => (typeof p === 'string' ? p : p.toJSON()))
const ret = this.type === null
? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))
: [this.type, ...this.#parts.map(p => p.toJSON())];
if (this.isStart() && !this.type)
ret.unshift([]);
@@ -272,7 +151,7 @@ export class AST {
const p = this.#parent;
for (let i = 0; i < this.#parentIndex; i++) {
const pp = p.#parts[i];
if (!(pp instanceof _a && pp.type === '!')) {
if (!(pp instanceof AST && pp.type === '!')) {
return false;
}
}
@@ -300,14 +179,13 @@ export class AST {
this.push(part.clone(this));
}
clone(parent) {
const c = new _a(this.type, parent);
const c = new AST(this.type, parent);
for (const p of this.#parts) {
c.copyIn(p);
}
return c;
}
static #parseAST(str, ast, pos, opt, extDepth) {
const maxDepth = opt.maxExtglobRecursion ?? 2;
static #parseAST(str, ast, pos, opt) {
let escaping = false;
let inBrace = false;
let braceStart = -1;
@@ -344,17 +222,11 @@ export class AST {
acc += c;
continue;
}
// we don't have to check for adoption here, because that's
// done at the other recursion point.
const doRecurse = !opt.noext &&
isExtglobType(c) &&
str.charAt(i) === '(' &&
extDepth <= maxDepth;
if (doRecurse) {
if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
ast.push(acc);
acc = '';
const ext = new _a(c, ast);
i = _a.#parseAST(str, ext, i, opt, extDepth + 1);
const ext = new AST(c, ast);
i = AST.#parseAST(str, ext, i, opt);
ast.push(ext);
continue;
}
@@ -366,7 +238,7 @@ export class AST {
// some kind of extglob, pos is at the (
// find the next | or )
let i = pos + 1;
let part = new _a(null, ast);
let part = new AST(null, ast);
const parts = [];
let acc = '';
while (i < str.length) {
@@ -397,26 +269,19 @@ export class AST {
acc += c;
continue;
}
const doRecurse = !opt.noext &&
isExtglobType(c) &&
str.charAt(i) === '(' &&
/* c8 ignore start - the maxDepth is sufficient here */
(extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));
/* c8 ignore stop */
if (doRecurse) {
const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
if (isExtglobType(c) && str.charAt(i) === '(') {
part.push(acc);
acc = '';
const ext = new _a(c, part);
const ext = new AST(c, part);
part.push(ext);
i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);
i = AST.#parseAST(str, ext, i, opt);
continue;
}
if (c === '|') {
part.push(acc);
acc = '';
parts.push(part);
part = new _a(null, ast);
part = new AST(null, ast);
continue;
}
if (c === ')') {
@@ -438,82 +303,9 @@ export class AST {
ast.#parts = [str.substring(pos - 1)];
return i;
}
#canAdoptWithSpace(child) {
return this.#canAdopt(child, adoptionWithSpaceMap);
}
#canAdopt(child, map = adoptionMap) {
if (!child ||
typeof child !== 'object' ||
child.type !== null ||
child.#parts.length !== 1 ||
this.type === null) {
return false;
}
const gc = child.#parts[0];
if (!gc || typeof gc !== 'object' || gc.type === null) {
return false;
}
return this.#canAdoptType(gc.type, map);
}
#canAdoptType(c, map = adoptionAnyMap) {
return !!map.get(this.type)?.includes(c);
}
#adoptWithSpace(child, index) {
const gc = child.#parts[0];
const blank = new _a(null, gc, this.options);
blank.#parts.push('');
gc.push(blank);
this.#adopt(child, index);
}
#adopt(child, index) {
const gc = child.#parts[0];
this.#parts.splice(index, 1, ...gc.#parts);
for (const p of gc.#parts) {
if (typeof p === 'object')
p.#parent = this;
}
this.#toString = undefined;
}
#canUsurpType(c) {
const m = usurpMap.get(this.type);
return !!m?.has(c);
}
#canUsurp(child) {
if (!child ||
typeof child !== 'object' ||
child.type !== null ||
child.#parts.length !== 1 ||
this.type === null ||
this.#parts.length !== 1) {
return false;
}
const gc = child.#parts[0];
if (!gc || typeof gc !== 'object' || gc.type === null) {
return false;
}
return this.#canUsurpType(gc.type);
}
#usurp(child) {
const m = usurpMap.get(this.type);
const gc = child.#parts[0];
const nt = m?.get(gc.type);
/* c8 ignore start - impossible */
if (!nt)
return false;
/* c8 ignore stop */
this.#parts = gc.#parts;
for (const p of this.#parts) {
if (typeof p === 'object') {
p.#parent = this;
}
}
this.type = nt;
this.#toString = undefined;
this.#emptyExt = false;
}
static fromGlob(pattern, options = {}) {
const ast = new _a(null, undefined, options);
_a.#parseAST(pattern, ast, 0, options, 0);
const ast = new AST(null, undefined, options);
AST.#parseAST(pattern, ast, 0, options);
return ast;
}
// returns the regular expression if there's magic, or the unescaped
@@ -617,18 +409,14 @@ export class AST {
// or start or whatever) and prepend ^ or / at the Regexp construction.
toRegExpSource(allowDot) {
const dot = allowDot ?? !!this.#options.dot;
if (this.#root === this) {
this.#flatten();
if (this.#root === this)
this.#fillNegs();
}
if (!isExtglobAST(this)) {
const noEmpty = this.isStart() &&
this.isEnd() &&
!this.#parts.some(s => typeof s !== 'string');
if (!this.type) {
const noEmpty = this.isStart() && this.isEnd();
const src = this.#parts
.map(p => {
const [re, _, hasMagic, uflag] = typeof p === 'string' ?
_a.#parseGlob(p, this.#hasMagic, noEmpty)
const [re, _, hasMagic, uflag] = typeof p === 'string'
? AST.#parseGlob(p, this.#hasMagic, noEmpty)
: p.toRegExpSource(allowDot);
this.#hasMagic = this.#hasMagic || hasMagic;
this.#uflag = this.#uflag || uflag;
@@ -657,10 +445,7 @@ export class AST {
// no need to prevent dots if it can't match a dot, or if a
// sub-pattern will be preventing it anyway.
const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
start =
needNoTrav ? startNoTraversal
: needNoDot ? startNoDot
: '';
start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : '';
}
}
}
@@ -690,14 +475,14 @@ export class AST {
// invalid extglob, has to at least be *something* present, if it's
// the entire path portion.
const s = this.toString();
const me = this;
me.#parts = [s];
me.type = null;
me.#hasMagic = undefined;
this.#parts = [s];
this.type = null;
this.#hasMagic = undefined;
return [s, unescape(this.toString()), false, false];
}
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?
''
// XXX abstract out this map method
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot
? ''
: this.#partsToRegExp(true);
if (bodyDotAllowed === body) {
bodyDotAllowed = '';
@@ -711,16 +496,20 @@ export class AST {
final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
}
else {
const close = this.type === '!' ?
// !() must match something,but !(x) can match ''
'))' +
(this.isStart() && !dot && !allowDot ? startNoDot : '') +
star +
')'
: this.type === '@' ? ')'
: this.type === '?' ? ')?'
: this.type === '+' && bodyDotAllowed ? ')'
: this.type === '*' && bodyDotAllowed ? `)?`
const close = this.type === '!'
? // !() must match something,but !(x) can match ''
'))' +
(this.isStart() && !dot && !allowDot ? startNoDot : '') +
star +
')'
: this.type === '@'
? ')'
: this.type === '?'
? ')?'
: this.type === '+' && bodyDotAllowed
? ')'
: this.type === '*' && bodyDotAllowed
? `)?`
: `)${this.type}`;
final = start + body + close;
}
@@ -731,42 +520,6 @@ export class AST {
this.#uflag,
];
}
#flatten() {
if (!isExtglobAST(this)) {
for (const p of this.#parts) {
if (typeof p === 'object') {
p.#flatten();
}
}
}
else {
// do up to 10 passes to flatten as much as possible
let iterations = 0;
let done = false;
do {
done = true;
for (let i = 0; i < this.#parts.length; i++) {
const c = this.#parts[i];
if (typeof c === 'object') {
c.#flatten();
if (this.#canAdopt(c)) {
done = false;
this.#adopt(c, i);
}
else if (this.#canAdoptWithSpace(c)) {
done = false;
this.#adoptWithSpace(c, i);
}
else if (this.#canUsurp(c)) {
done = false;
this.#usurp(c);
}
}
}
} while (!done && ++iterations < 10);
}
this.#toString = undefined;
}
#partsToRegExp(dot) {
return this.#parts
.map(p => {
@@ -788,8 +541,6 @@ export class AST {
let escaping = false;
let re = '';
let uflag = false;
// multiple stars that aren't globstars coalesce into one *
let inStar = false;
for (let i = 0; i < glob.length; i++) {
const c = glob.charAt(i);
if (escaping) {
@@ -797,17 +548,6 @@ export class AST {
re += (reSpecials.has(c) ? '\\' : '') + c;
continue;
}
if (c === '*') {
if (inStar)
continue;
inStar = true;
re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star;
hasMagic = true;
continue;
}
else {
inStar = false;
}
if (c === '\\') {
if (i === glob.length - 1) {
re += '\\\\';
@@ -827,6 +567,14 @@ export class AST {
continue;
}
}
if (c === '*') {
if (noEmpty && glob === '*')
re += starNoEmpty;
else
re += star;
hasMagic = true;
continue;
}
if (c === '?') {
re += qmark;
hasMagic = true;
@@ -837,5 +585,4 @@ export class AST {
return [re, unescape(glob), !!hasMagic, uflag];
}
}
_a = AST;
//# sourceMappingURL=ast.js.map
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EACZ,UAAU,MAAM,KACf,gBA2HF,CAAA"}
{"version":3,"file":"brace-expressions.d.ts","sourceRoot":"","sources":["../../src/brace-expressions.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAQD,eAAO,MAAM,UAAU,SACf,MAAM,YACF,MAAM,qBA8HjB,CAAA"}
+4 -2
View File
@@ -138,8 +138,10 @@ export const parseClass = (glob, position) => {
}
const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
const comb = ranges.length && negs.length ? '(' + sranges + '|' + snegs + ')'
: ranges.length ? sranges
const comb = ranges.length && negs.length
? '(' + sranges + '|' + snegs + ')'
: ranges.length
? sranges
: snegs;
return [comb, uflag, endPos - pos, true];
};
File diff suppressed because one or more lines are too long
+3 -6
View File
@@ -1,15 +1,12 @@
import type { MinimatchOptions } from './index.js';
import { MinimatchOptions } from './index.js';
/**
* Escape all magic characters in a glob pattern.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape}
* If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
* option is used, then characters are escaped by wrapping in `[]`, because
* a magic character wrapped in a character class can only be satisfied by
* that exact character. In this mode, `\` is _not_ escaped, because it is
* not interpreted as a magic character, but instead as a path separator.
*
* If the {@link MinimatchOptions.magicalBraces} option is used,
* then braces (`{` and `}`) will be escaped.
*/
export declare const escape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
export declare const escape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, 'windowsPathsNoEscape'>) => string;
//# sourceMappingURL=escape.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,MAAM,GACjB,GAAG,MAAM,EACT,2CAGG,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,eAAe,CAAM,WAazE,CAAA"}
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,MACd,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAQlD,CAAA"}
+4 -12
View File
@@ -1,26 +1,18 @@
/**
* Escape all magic characters in a glob pattern.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape}
* If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
* option is used, then characters are escaped by wrapping in `[]`, because
* a magic character wrapped in a character class can only be satisfied by
* that exact character. In this mode, `\` is _not_ escaped, because it is
* not interpreted as a magic character, but instead as a path separator.
*
* If the {@link MinimatchOptions.magicalBraces} option is used,
* then braces (`{` and `}`) will be escaped.
*/
export const escape = (s, { windowsPathsNoEscape = false, magicalBraces = false, } = {}) => {
export const escape = (s, { windowsPathsNoEscape = false, } = {}) => {
// don't need to escape +@! because we escape the parens
// that make those magic, and escaping ! as [!] isn't valid,
// because [!]] is a valid glob class meaning not ']'.
if (magicalBraces) {
return windowsPathsNoEscape ?
s.replace(/[?*()[\]{}]/g, '[$&]')
: s.replace(/[?*()[\]\\{}]/g, '\\$&');
}
return windowsPathsNoEscape ?
s.replace(/[?*()[\]]/g, '[$&]')
return windowsPathsNoEscape
? s.replace(/[?*()[\]]/g, '[$&]')
: s.replace(/[?*()[\]\\]/g, '\\$&');
};
//# sourceMappingURL=escape.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,EAC5B,aAAa,GAAG,KAAK,MAC+C,EAAE,EACxE,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,oBAAoB,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC;YACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,oBAAoB,CAAC,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA","sourcesContent":["import type { MinimatchOptions } from './index.js'\n\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n *\n * If the {@link MinimatchOptions.magicalBraces} option is used,\n * then braces (`{` and `}`) will be escaped.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]{}]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\{}]/g, '\\\\$&')\n }\n return windowsPathsNoEscape ?\n s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,wDAAwD;IACxD,4DAA4D;IAC5D,sDAAsD;IACtD,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Escape all magic characters in a glob pattern.\n *\n * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}\n * option is used, then characters are escaped by wrapping in `[]`, because\n * a magic character wrapped in a character class can only be satisfied by\n * that exact character. In this mode, `\\` is _not_ escaped, because it is\n * not interpreted as a magic character, but instead as a path separator.\n */\nexport const escape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape'> = {}\n) => {\n // don't need to escape +@! because we escape the parens\n // that make those magic, and escaping ! as [!] isn't valid,\n // because [!]] is a valid glob class meaning not ']'.\n return windowsPathsNoEscape\n ? s.replace(/[?*()[\\]]/g, '[$&]')\n : s.replace(/[?*()[\\]\\\\]/g, '\\\\$&')\n}\n"]}
+5 -85
View File
@@ -1,104 +1,26 @@
import { AST } from './ast.js';
export type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
type Platform = 'aix' | 'android' | 'darwin' | 'freebsd' | 'haiku' | 'linux' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | 'netbsd';
export interface MinimatchOptions {
/** do not expand `{x,y}` style braces */
nobrace?: boolean;
/** do not treat patterns starting with `#` as a comment */
nocomment?: boolean;
/** do not treat patterns starting with `!` as a negation */
nonegate?: boolean;
/** print LOTS of debugging output */
debug?: boolean;
/** treat `**` the same as `*` */
noglobstar?: boolean;
/** do not expand extglobs like `+(a|b)` */
noext?: boolean;
/** return the pattern if nothing matches */
nonull?: boolean;
/** treat `\\` as a path separator, not an escape character */
windowsPathsNoEscape?: boolean;
/**
* inverse of {@link MinimatchOptions.windowsPathsNoEscape}
* @deprecated
*/
allowWindowsEscape?: boolean;
/**
* Compare a partial path to a pattern. As long as the parts
* of the path that are present are not contradicted by the
* pattern, it will be treated as a match. This is useful in
* applications where you're walking through a folder structure,
* and don't yet have the full path, but want to ensure that you
* do not walk down paths that can never be a match.
*/
partial?: boolean;
/** allow matches that start with `.` even if the pattern does not */
dot?: boolean;
/** ignore case */
nocase?: boolean;
/** ignore case only in wildcard patterns */
nocaseMagicOnly?: boolean;
/** consider braces to be "magic" for the purpose of `hasMagic` */
magicalBraces?: boolean;
/**
* If set, then patterns without slashes will be matched
* against the basename of the path if it contains slashes.
* For example, `a?b` would match the path `/xyz/123/acb`, but
* not `/xyz/acb/123`.
*/
matchBase?: boolean;
/** invert the results of negated matches */
flipNegate?: boolean;
/** do not collapse multiple `/` into a single `/` */
preserveMultipleSlashes?: boolean;
/**
* A number indicating the level of optimization that should be done
* to the pattern prior to parsing and using it for matches.
*/
optimizationLevel?: number;
/** operating system platform */
platform?: Platform;
/**
* When a pattern starts with a UNC path or drive letter, and in
* `nocase:true` mode, do not convert the root portions of the
* pattern into a case-insensitive regular expression, and instead
* leave them as strings.
*
* This is the default when the platform is `win32` and
* `nocase:true` is set.
*/
windowsNoMagicRoot?: boolean;
/**
* max number of `{...}` patterns to expand. Default 100_000.
*/
braceExpandMax?: number;
/**
* Max number of non-adjacent `**` patterns to recursively walk down.
*
* The default of 200 is almost certainly high enough for most purposes,
* and can handle absurdly excessive patterns.
*/
maxGlobstarRecursion?: number;
/**
* Max depth to traverse for nested extglobs like `*(a|b|c)`
*
* Default is 2, which is quite low, but any higher value
* swiftly results in punishing performance impacts. Note
* that this is *not* relevant when the globstar types can
* be safely coalesced into a single set.
*
* For example, `*(a|@(b|c)|d)` would be flattened into
* `*(a|b|c|d)`. Thus, many common extglobs will retain good
* performance and never hit this limit, even if they are
* excessively deep and complicated.
*
* If the limit is hit, then the extglob characters are simply
* not parsed, and the pattern effectively switches into
* `noextglob: true` mode for the contents of that nested
* sub-pattern. This will typically _not_ result in a match,
* but is considered a valid trade-off for security and
* performance.
*/
maxExtglobRecursion?: number;
}
export declare const minimatch: {
(p: string, pattern: string, options?: MinimatchOptions): boolean;
@@ -111,10 +33,10 @@ export declare const minimatch: {
match: (list: string[], pattern: string, options?: MinimatchOptions) => string[];
AST: typeof AST;
Minimatch: typeof Minimatch;
escape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
unescape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
escape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, "windowsPathsNoEscape">) => string;
unescape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, "windowsPathsNoEscape">) => string;
};
export type Sep = '\\' | '/';
type Sep = '\\' | '/';
export declare const sep: Sep;
export declare const GLOBSTAR: unique symbol;
export declare const filter: (pattern: string, options?: MinimatchOptions) => (p: string) => boolean;
@@ -129,7 +51,6 @@ export type MMRegExp = RegExp & {
export type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR;
export type ParseReturn = ParseReturnFiltered | false;
export declare class Minimatch {
#private;
options: MinimatchOptions;
set: ParseReturnFiltered[][];
pattern: string;
@@ -146,11 +67,10 @@ export declare class Minimatch {
isWindows: boolean;
platform: Platform;
windowsNoMagicRoot: boolean;
maxGlobstarRecursion: number;
regexp: false | null | MMRegExp;
constructor(pattern: string, options?: MinimatchOptions);
hasMagic(): boolean;
debug(..._: unknown[]): void;
debug(..._: any[]): void;
make(): void;
preprocess(globParts: string[][]): string[][];
adjascentGlobstarOptimize(globParts: string[][]): string[][];
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
+137 -250
View File
@@ -1,4 +1,4 @@
import { expand } from 'brace-expansion';
import expand from 'brace-expansion';
import { assertValidPattern } from './assert-valid-pattern.js';
import { AST } from './ast.js';
import { escape } from './escape.js';
@@ -12,7 +12,7 @@ export const minimatch = (p, pattern, options = {}) => {
return new Minimatch(pattern, options).match(p);
};
// Optimized checking for the most common glob patterns.
const starDotExtRE = /^\*+([^+@!?*[(]*)$/;
const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
const starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
const starDotExtTestNocase = (ext) => {
@@ -31,7 +31,7 @@ const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
const starRE = /^\*+$/;
const starTest = (f) => f.length !== 0 && !f.startsWith('.');
const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
const qmarksRE = /^\?+([^+@!?*[(]*)?$/;
const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
const qmarksTestNocase = ([$0, ext = '']) => {
const noext = qmarksTestNoExt([$0]);
if (!ext)
@@ -63,8 +63,8 @@ const qmarksTestNoExtDot = ([$0]) => {
return (f) => f.length === len && f !== '.' && f !== '..';
};
/* c8 ignore start */
const defaultPlatform = (typeof process === 'object' && process ?
(typeof process.env === 'object' &&
const defaultPlatform = (typeof process === 'object' && process
? (typeof process.env === 'object' &&
process.env &&
process.env.__MINIMATCH_TESTING_PLATFORM__) ||
process.platform
@@ -148,7 +148,7 @@ export const braceExpand = (pattern, options = {}) => {
// shortcut. no need to expand.
return [pattern];
}
return expand(pattern, { max: options.braceExpandMax });
return expand(pattern);
};
minimatch.braceExpand = braceExpand;
// parse a component of the expanded set.
@@ -193,20 +193,16 @@ export class Minimatch {
isWindows;
platform;
windowsNoMagicRoot;
maxGlobstarRecursion;
regexp;
constructor(pattern, options = {}) {
assertValidPattern(pattern);
options = options || {};
this.options = options;
this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
this.pattern = pattern;
this.platform = options.platform || defaultPlatform;
this.isWindows = this.platform === 'win32';
// avoid the annoying deprecation flag lol
const awe = ('allowWindow' + 'sEscape');
this.windowsPathsNoEscape =
!!options.windowsPathsNoEscape || options[awe] === false;
!!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
if (this.windowsPathsNoEscape) {
this.pattern = this.pattern.replace(/\\/g, '/');
}
@@ -219,8 +215,8 @@ export class Minimatch {
this.partial = !!options.partial;
this.nocase = !!this.options.nocase;
this.windowsNoMagicRoot =
options.windowsNoMagicRoot !== undefined ?
options.windowsNoMagicRoot
options.windowsNoMagicRoot !== undefined
? options.windowsNoMagicRoot
: !!(this.isWindows && this.nocase);
this.globSet = [];
this.globParts = [];
@@ -258,7 +254,6 @@ export class Minimatch {
// step 2: expand braces
this.globSet = [...new Set(this.braceExpand())];
if (options.debug) {
//oxlint-disable-next-line no-console
this.debug = (...args) => console.error(...args);
}
this.debug(this.pattern, this.globSet);
@@ -284,10 +279,7 @@ export class Minimatch {
!globMagic.test(s[3]);
const isDrive = /^[a-z]:/i.test(s[0]);
if (isUNC) {
return [
...s.slice(0, 4),
...s.slice(4).map(ss => this.parse(ss)),
];
return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
}
else if (isDrive) {
return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
@@ -319,12 +311,12 @@ export class Minimatch {
// to the right as possible, even if it increases the number
// of patterns that we have to process.
preprocess(globParts) {
// if we're not in globstar mode, then turn ** into *
// if we're not in globstar mode, then turn all ** into *
if (this.options.noglobstar) {
for (const partset of globParts) {
for (let j = 0; j < partset.length; j++) {
if (partset[j] === '**') {
partset[j] = '*';
for (let i = 0; i < globParts.length; i++) {
for (let j = 0; j < globParts[i].length; j++) {
if (globParts[i][j] === '**') {
globParts[i][j] = '*';
}
}
}
@@ -412,11 +404,7 @@ export class Minimatch {
let dd = 0;
while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
const p = parts[dd - 1];
if (p &&
p !== '.' &&
p !== '..' &&
p !== '**' &&
!(this.isWindows && /^[a-z]:$/i.test(p))) {
if (p && p !== '.' && p !== '..' && p !== '**') {
didSomething = true;
parts.splice(dd - 1, 2);
dd -= 2;
@@ -609,8 +597,7 @@ export class Minimatch {
// out of pattern, then that's fine, as long as all
// the parts match.
matchOne(file, pattern, partial = false) {
let fileStartIndex = 0;
let patternStartIndex = 0;
const options = this.options;
// UNC paths like //?/X:/... can match X:/... and vice versa
// Drive letters in absolute drive or unc paths are always compared
// case-insensitively.
@@ -628,212 +615,120 @@ export class Minimatch {
pattern[2] === '?' &&
typeof pattern[3] === 'string' &&
/^[a-z]:$/i.test(pattern[3]);
const fdi = fileUNC ? 3
: fileDrive ? 0
: undefined;
const pdi = patternUNC ? 3
: patternDrive ? 0
: undefined;
const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
if (typeof fdi === 'number' && typeof pdi === 'number') {
const [fd, pd] = [
file[fdi],
pattern[pdi],
];
// start matching at the drive letter index of each
const [fd, pd] = [file[fdi], pattern[pdi]];
if (fd.toLowerCase() === pd.toLowerCase()) {
pattern[pdi] = fd;
patternStartIndex = pdi;
fileStartIndex = fdi;
if (pdi > fdi) {
pattern = pattern.slice(pdi);
}
else if (fdi > pdi) {
file = file.slice(fdi);
}
}
}
}
// resolve and reduce . and .. portions in the file as well.
// don't need to do the second phase, because it's only one string[]
// dont' need to do the second phase, because it's only one string[]
const { optimizationLevel = 1 } = this.options;
if (optimizationLevel >= 2) {
file = this.levelTwoFileOptimize(file);
}
if (pattern.includes(GLOBSTAR)) {
return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
}
return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
}
#matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
// split the pattern into head, tail, and middle of ** delimited parts
const firstgs = pattern.indexOf(GLOBSTAR, patternIndex);
const lastgs = pattern.lastIndexOf(GLOBSTAR);
// split the pattern up into globstar-delimited sections
// the tail has to be at the end, and the others just have
// to be found in order from the head.
const [head, body, tail] = partial ?
[
pattern.slice(patternIndex, firstgs),
pattern.slice(firstgs + 1),
[],
]
: [
pattern.slice(patternIndex, firstgs),
pattern.slice(firstgs + 1, lastgs),
pattern.slice(lastgs + 1),
];
// check the head, from the current file/pattern index.
if (head.length) {
const fileHead = file.slice(fileIndex, fileIndex + head.length);
if (!this.#matchOne(fileHead, head, partial, 0, 0)) {
return false;
}
fileIndex += head.length;
patternIndex += head.length;
}
// now we know the head matches!
// if the last portion is not empty, it MUST match the end
// check the tail
let fileTailMatch = 0;
if (tail.length) {
// if head + tail > file, then we cannot possibly match
if (tail.length + fileIndex > file.length)
return false;
// try to match the tail
let tailStart = file.length - tail.length;
if (this.#matchOne(file, tail, partial, tailStart, 0)) {
fileTailMatch = tail.length;
}
else {
// affordance for stuff like a/**/* matching a/b/
// if the last file portion is '', and there's more to the pattern
// then try without the '' bit.
if (file[file.length - 1] !== '' ||
fileIndex + tail.length === file.length) {
return false;
}
tailStart--;
if (!this.#matchOne(file, tail, partial, tailStart, 0)) {
return false;
}
fileTailMatch = tail.length + 1;
}
}
// now we know the tail matches!
// the middle is zero or more portions wrapped in **, possibly
// containing more ** sections.
// so a/**/b/**/c/**/d has become **/b/**/c/**
// if it's empty, it means a/**/b, just verify we have no bad dots
// if there's no tail, so it ends on /**, then we must have *something*
// after the head, or it's not a matc
if (!body.length) {
let sawSome = !!fileTailMatch;
for (let i = fileIndex; i < file.length - fileTailMatch; i++) {
const f = String(file[i]);
sawSome = true;
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
}
// in partial mode, we just need to get past all file parts
return partial || sawSome;
}
// now we know that there's one or more body sections, which can
// be matched anywhere from the 0 index (because the head was pruned)
// through to the length-fileTailMatch index.
// split the body up into sections, and note the minimum index it can
// be found at (start with the length of all previous segments)
// [section, before, after]
const bodySegments = [[[], 0]];
let currentBody = bodySegments[0];
let nonGsParts = 0;
const nonGsPartsSums = [0];
for (const b of body) {
if (b === GLOBSTAR) {
nonGsPartsSums.push(nonGsParts);
currentBody = [[], 0];
bodySegments.push(currentBody);
}
else {
currentBody[0].push(b);
nonGsParts++;
}
}
let i = bodySegments.length - 1;
const fileLength = file.length - fileTailMatch;
for (const b of bodySegments) {
b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
}
return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
}
// return false for "nope, not matching"
// return null for "not matching, cannot keep trying"
#matchGlobStarBodySections(file,
// pattern section, last possible position for it
bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
// take the first body segment, and walk from fileIndex to its "after"
// value at the end
// If it doesn't match at that position, we increment, until we hit
// that final possible position, and give up.
// If it does match, then advance and try to rest.
// If any of them fail we keep walking forward.
// this is still a bit recursively painful, but it's more constrained
// than previous implementations, because we never test something that
// can't possibly be a valid matching condition.
const bs = bodySegments[bodyIndex];
if (!bs) {
// just make sure that there's no bad dots
for (let i = fileIndex; i < file.length; i++) {
sawTail = true;
const f = file[i];
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
}
return sawTail;
}
// have a non-globstar body section to test
const [body, after] = bs;
while (fileIndex <= after) {
const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
// if limit exceeded, no match. intentional false negative,
// acceptable break in correctness for security.
if (m && globStarDepth < this.maxGlobstarRecursion) {
// match! see if the rest match. if so, we're done!
const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
if (sub !== false) {
return sub;
}
}
const f = file[fileIndex];
if (f === '.' ||
f === '..' ||
(!this.options.dot && f.startsWith('.'))) {
return false;
}
fileIndex++;
}
// walked off. no point continuing
return partial || null;
}
#matchOne(file, pattern, partial, fileIndex, patternIndex) {
let fi;
let pi;
let pl;
let fl;
for (fi = fileIndex,
pi = patternIndex,
fl = file.length,
pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
this.debug('matchOne', this, { file, pattern });
this.debug('matchOne', file.length, pattern.length);
for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
this.debug('matchOne loop');
let p = pattern[pi];
let f = file[fi];
var p = pattern[pi];
var f = file[fi];
this.debug(pattern, p, f);
// should be impossible.
// some invalid regexp stuff in the set.
/* c8 ignore start */
if (p === false || p === GLOBSTAR) {
if (p === false) {
return false;
}
/* c8 ignore stop */
if (p === GLOBSTAR) {
this.debug('GLOBSTAR', [pattern, p, f]);
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
//
// a/**/b/**/c matching a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi;
var pr = pi + 1;
if (pr === pl) {
this.debug('** at the end');
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for (; fi < fl; fi++) {
if (file[fi] === '.' ||
file[fi] === '..' ||
(!options.dot && file[fi].charAt(0) === '.'))
return false;
}
return true;
}
// ok, let's see if we can swallow whatever we can.
while (fr < fl) {
var swallowee = file[fr];
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
this.debug('globstar found match!', fr, fl, swallowee);
// found a match.
return true;
}
else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
if (swallowee === '.' ||
swallowee === '..' ||
(!options.dot && swallowee.charAt(0) === '.')) {
this.debug('dot detected!', file, fr, pattern, pr);
break;
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue');
fr++;
}
}
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
/* c8 ignore start */
if (partial) {
// ran out of file
this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
if (fr === fl) {
return true;
}
}
/* c8 ignore stop */
return false;
}
// something other than **
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
@@ -904,19 +799,21 @@ export class Minimatch {
fastTest = options.dot ? starTestDot : starTest;
}
else if ((m = pattern.match(starDotExtRE))) {
fastTest = (options.nocase ?
options.dot ?
starDotExtTestNocaseDot
fastTest = (options.nocase
? options.dot
? starDotExtTestNocaseDot
: starDotExtTestNocase
: options.dot ? starDotExtTestDot
: options.dot
? starDotExtTestDot
: starDotExtTest)(m[1]);
}
else if ((m = pattern.match(qmarksRE))) {
fastTest = (options.nocase ?
options.dot ?
qmarksTestNocaseDot
fastTest = (options.nocase
? options.dot
? qmarksTestNocaseDot
: qmarksTestNocase
: options.dot ? qmarksTestDot
: options.dot
? qmarksTestDot
: qmarksTest)(m);
}
else if ((m = pattern.match(starDotStarRE))) {
@@ -947,8 +844,10 @@ export class Minimatch {
return this.regexp;
}
const options = this.options;
const twoStar = options.noglobstar ? star
: options.dot ? twoStarDot
const twoStar = options.noglobstar
? star
: options.dot
? twoStarDot
: twoStarNoDot;
const flags = new Set(options.nocase ? ['i'] : []);
// regexpify non-globstar patterns
@@ -964,9 +863,11 @@ export class Minimatch {
for (const f of p.flags.split(''))
flags.add(f);
}
return (typeof p === 'string' ? regExpEscape(p)
: p === GLOBSTAR ? GLOBSTAR
: p._src);
return typeof p === 'string'
? regExpEscape(p)
: p === GLOBSTAR
? GLOBSTAR
: p._src;
});
pp.forEach((p, i) => {
const next = pp[i + 1];
@@ -983,25 +884,14 @@ export class Minimatch {
}
}
else if (next === undefined) {
pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?';
pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
}
else if (next !== GLOBSTAR) {
pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
pp[i + 1] = GLOBSTAR;
}
});
const filtered = pp.filter(p => p !== GLOBSTAR);
// For partial matches, we need to make the pattern match
// any prefix of the full path. We do this by generating
// alternative patterns that match progressively longer prefixes.
if (this.partial && filtered.length >= 1) {
const prefixes = [];
for (let i = 1; i <= filtered.length; i++) {
prefixes.push(filtered.slice(0, i).join('/'));
}
return '(?:' + prefixes.join('|') + ')';
}
return filtered.join('/');
return pp.filter(p => p !== GLOBSTAR).join('/');
})
.join('|');
// need to wrap in parens if we had more than one thing with |,
@@ -1010,10 +900,6 @@ export class Minimatch {
// must match entire pattern
// ending in a * or ** will make it less strict.
re = '^' + open + re + close + '$';
// In partial mode, '/' should always match as it's a valid prefix for any pattern
if (this.partial) {
re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$';
}
// can match anything, as long as it's not this.
if (this.negate)
re = '^(?!' + re + ').+$';
@@ -1021,7 +907,7 @@ export class Minimatch {
this.regexp = new RegExp(re, [...flags].join(''));
/* c8 ignore start */
}
catch {
catch (ex) {
// should be impossible
this.regexp = false;
}
@@ -1036,7 +922,7 @@ export class Minimatch {
if (this.preserveMultipleSlashes) {
return p.split('/');
}
else if (this.isWindows && /^\/\/[^/]+/.test(p)) {
else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
// add an extra '' for the one we lose
return ['', ...p.split(/\/+/)];
}
@@ -1078,7 +964,8 @@ export class Minimatch {
filename = ff[i];
}
}
for (const pattern of set) {
for (let i = 0; i < set.length; i++) {
const pattern = set[i];
let file = ff;
if (options.matchBase && pattern.length === 1) {
file = [filename];
+1 -1
View File
File diff suppressed because one or more lines are too long
+7 -12
View File
@@ -1,22 +1,17 @@
import type { MinimatchOptions } from './index.js';
import { MinimatchOptions } from './index.js';
/**
* Un-escape a string that has been escaped with {@link escape}.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then
* square-bracket escapes are removed, but not backslash escapes.
* If the {@link windowsPathsNoEscape} option is used, then square-brace
* escapes are removed, but not backslash escapes. For example, it will turn
* the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
* becuase `\` is a path separator in `windowsPathsNoEscape` mode.
*
* For example, it will turn the string `'[*]'` into `*`, but it will not
* turn `'\\*'` into `'*'`, because `\` is a path separator in
* `windowsPathsNoEscape` mode.
*
* When `windowsPathsNoEscape` is not set, then both square-bracket escapes and
* When `windowsPathsNoEscape` is not set, then both brace escapes and
* backslash escapes are removed.
*
* Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
* or unescaped.
*
* When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be
* unescaped.
*/
export declare const unescape: (s: string, { windowsPathsNoEscape, magicalBraces, }?: Pick<MinimatchOptions, "windowsPathsNoEscape" | "magicalBraces">) => string;
export declare const unescape: (s: string, { windowsPathsNoEscape, }?: Pick<MinimatchOptions, 'windowsPathsNoEscape'>) => string;
//# sourceMappingURL=unescape.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,EACT,2CAGG,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,eAAe,CAAM,WAczE,CAAA"}
{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,MAChB,MAAM,8BAGN,KAAK,gBAAgB,EAAE,sBAAsB,CAAC,WAKlD,CAAA"}
+9 -23
View File
@@ -1,34 +1,20 @@
/**
* Un-escape a string that has been escaped with {@link escape}.
*
* If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then
* square-bracket escapes are removed, but not backslash escapes.
* If the {@link windowsPathsNoEscape} option is used, then square-brace
* escapes are removed, but not backslash escapes. For example, it will turn
* the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
* becuase `\` is a path separator in `windowsPathsNoEscape` mode.
*
* For example, it will turn the string `'[*]'` into `*`, but it will not
* turn `'\\*'` into `'*'`, because `\` is a path separator in
* `windowsPathsNoEscape` mode.
*
* When `windowsPathsNoEscape` is not set, then both square-bracket escapes and
* When `windowsPathsNoEscape` is not set, then both brace escapes and
* backslash escapes are removed.
*
* Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
* or unescaped.
*
* When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be
* unescaped.
*/
export const unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true, } = {}) => {
if (magicalBraces) {
return windowsPathsNoEscape ?
s.replace(/\[([^/\\])\]/g, '$1')
: s
.replace(/((?!\\).|^)\[([^/\\])\]/g, '$1$2')
.replace(/\\([^/])/g, '$1');
}
return windowsPathsNoEscape ?
s.replace(/\[([^/\\{}])\]/g, '$1')
: s
.replace(/((?!\\).|^)\[([^/\\{}])\]/g, '$1$2')
.replace(/\\([^/{}])/g, '$1');
export const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
return windowsPathsNoEscape
? s.replace(/\[([^\/\\])\]/g, '$1')
: s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
};
//# sourceMappingURL=unescape.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,EAC5B,aAAa,GAAG,IAAI,MACgD,EAAE,EACxE,EAAE;IACF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,oBAAoB,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC;YAClC,CAAC,CAAC,CAAC;iBACE,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC;iBAC3C,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,oBAAoB,CAAC,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;QACpC,CAAC,CAAC,CAAC;aACE,OAAO,CAAC,4BAA4B,EAAE,MAAM,CAAC;aAC7C,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC,CAAA","sourcesContent":["import type { MinimatchOptions } from './index.js'\n\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then\n * square-bracket escapes are removed, but not backslash escapes.\n *\n * For example, it will turn the string `'[*]'` into `*`, but it will not\n * turn `'\\\\*'` into `'*'`, because `\\` is a path separator in\n * `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n *\n * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be\n * unescaped.\n */\n\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = true,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\])\\]/g, '$1$2')\n .replace(/\\\\([^/])/g, '$1')\n }\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\{}])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\{}])\\]/g, '$1$2')\n .replace(/\\\\([^/{}])/g, '$1')\n}\n"]}
{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,MACsB,EAAE,EACtD,EAAE;IACF,OAAO,oBAAoB;QACzB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA","sourcesContent":["import { MinimatchOptions } from './index.js'\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link windowsPathsNoEscape} option is used, then square-brace\n * escapes are removed, but not backslash escapes. For example, it will turn\n * the string `'[*]'` into `*`, but it will not turn `'\\\\*'` into `'*'`,\n * becuase `\\` is a path separator in `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both brace escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n */\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape'> = {}\n) => {\n return windowsPathsNoEscape\n ? s.replace(/\\[([^\\/\\\\])\\]/g, '$1')\n : s.replace(/((?!\\\\).|^)\\[([^\\/\\\\])\\]/g, '$1$2').replace(/\\\\([^\\/])/g, '$1')\n}\n"]}