minimatch 10.2.1 → 10.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/commonjs/assert-valid-pattern.d.ts +1 -1
- package/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
- package/dist/commonjs/assert-valid-pattern.js.map +1 -1
- package/dist/commonjs/ast.d.ts +2 -0
- package/dist/commonjs/ast.d.ts.map +1 -1
- package/dist/commonjs/ast.js +266 -21
- package/dist/commonjs/ast.js.map +1 -1
- package/dist/commonjs/index.d.ts +30 -0
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +173 -92
- package/dist/commonjs/index.js.map +1 -1
- package/dist/esm/assert-valid-pattern.d.ts +1 -1
- package/dist/esm/assert-valid-pattern.d.ts.map +1 -1
- package/dist/esm/assert-valid-pattern.js.map +1 -1
- package/dist/esm/ast.d.ts +2 -0
- package/dist/esm/ast.d.ts.map +1 -1
- package/dist/esm/ast.js +266 -21
- package/dist/esm/ast.js.map +1 -1
- package/dist/esm/index.d.ts +30 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +173 -92
- package/dist/esm/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -396,6 +396,42 @@ separators in file paths for comparison.)
|
|
|
396
396
|
|
|
397
397
|
Defaults to the value of `process.platform`.
|
|
398
398
|
|
|
399
|
+
### maxGlobstarRecursion
|
|
400
|
+
|
|
401
|
+
Max number of non-adjacent `**` patterns to recursively walk
|
|
402
|
+
down.
|
|
403
|
+
|
|
404
|
+
The default of `200` is almost certainly high enough for most
|
|
405
|
+
purposes, and can handle absurdly excessive patterns.
|
|
406
|
+
|
|
407
|
+
If the limit is exceeded (which would require very excessively
|
|
408
|
+
long patterns and paths containing lots of `**` patterns!), then
|
|
409
|
+
it is treated as non-matching, even if the path would normally
|
|
410
|
+
match the pattern provided.
|
|
411
|
+
|
|
412
|
+
That is, this is an intentional false negative, deemed an
|
|
413
|
+
acceptable break in correctness for security and performance.
|
|
414
|
+
|
|
415
|
+
### maxExtglobRecursion
|
|
416
|
+
|
|
417
|
+
Max depth to traverse for nested extglobs like `*(a|b|c)`
|
|
418
|
+
|
|
419
|
+
Default is 2, which is quite low, but any higher value swiftly
|
|
420
|
+
results in punishing performance impacts. Note that this is _not_
|
|
421
|
+
relevant when the globstar types can be safely coalesced into a
|
|
422
|
+
single set.
|
|
423
|
+
|
|
424
|
+
For example, `*(a|@(b|c)|d)` would be flattened into
|
|
425
|
+
`*(a|b|c|d)`. Thus, many common extglobs will retain good
|
|
426
|
+
performance and never hit this limit, even if they are
|
|
427
|
+
excessively deep and complicated.
|
|
428
|
+
|
|
429
|
+
If the limit is hit, then the extglob characters are simply not
|
|
430
|
+
parsed, and the pattern effectively switches into `noextglob:
|
|
431
|
+
true` mode for the contents of that nested sub-pattern. This will
|
|
432
|
+
typically _not_ result in a match, but is considered a valid
|
|
433
|
+
trade-off for security and performance.
|
|
434
|
+
|
|
399
435
|
## Comparisons to other fnmatch/glob implementations
|
|
400
436
|
|
|
401
437
|
While strict compliance with the existing standards is a
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const assertValidPattern: (pattern:
|
|
1
|
+
export declare const assertValidPattern: (pattern: unknown) => void;
|
|
2
2
|
//# sourceMappingURL=assert-valid-pattern.d.ts.map
|
|
@@ -1 +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,
|
|
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"}
|
|
@@ -1 +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,
|
|
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"]}
|
package/dist/commonjs/ast.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type ExtglobType = '!' | '?' | '+' | '*' | '@';
|
|
|
3
3
|
export declare class AST {
|
|
4
4
|
#private;
|
|
5
5
|
type: ExtglobType | null;
|
|
6
|
+
id: number;
|
|
7
|
+
get depth(): number;
|
|
6
8
|
constructor(type: ExtglobType | null, parent?: AST, options?: MinimatchOptions);
|
|
7
9
|
get hasMagic(): boolean | undefined;
|
|
8
10
|
toString(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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;
|
|
1
|
+
{"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;AA6IrD,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;IA+ClB,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;IAwQjB,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"}
|
package/dist/commonjs/ast.js
CHANGED
|
@@ -1,11 +1,113 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// parse a single path portion
|
|
3
|
+
var _a;
|
|
3
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
5
|
exports.AST = void 0;
|
|
5
6
|
const brace_expressions_js_1 = require("./brace-expressions.js");
|
|
6
7
|
const unescape_js_1 = require("./unescape.js");
|
|
7
8
|
const types = new Set(['!', '?', '+', '*', '@']);
|
|
8
9
|
const isExtglobType = (c) => types.has(c);
|
|
10
|
+
const isExtglobAST = (c) => isExtglobType(c.type);
|
|
11
|
+
// Map of which extglob types can adopt the children of a nested extglob
|
|
12
|
+
//
|
|
13
|
+
// anything but ! can adopt a matching type:
|
|
14
|
+
// +(a|+(b|c)|d) => +(a|b|c|d)
|
|
15
|
+
// *(a|*(b|c)|d) => *(a|b|c|d)
|
|
16
|
+
// @(a|@(b|c)|d) => @(a|b|c|d)
|
|
17
|
+
// ?(a|?(b|c)|d) => ?(a|b|c|d)
|
|
18
|
+
//
|
|
19
|
+
// * can adopt anything, because 0 or repetition is allowed
|
|
20
|
+
// *(a|?(b|c)|d) => *(a|b|c|d)
|
|
21
|
+
// *(a|+(b|c)|d) => *(a|b|c|d)
|
|
22
|
+
// *(a|@(b|c)|d) => *(a|b|c|d)
|
|
23
|
+
//
|
|
24
|
+
// + can adopt @, because 1 or repetition is allowed
|
|
25
|
+
// +(a|@(b|c)|d) => +(a|b|c|d)
|
|
26
|
+
//
|
|
27
|
+
// + and @ CANNOT adopt *, because 0 would be allowed
|
|
28
|
+
// +(a|*(b|c)|d) => would match "", on *(b|c)
|
|
29
|
+
// @(a|*(b|c)|d) => would match "", on *(b|c)
|
|
30
|
+
//
|
|
31
|
+
// + and @ CANNOT adopt ?, because 0 would be allowed
|
|
32
|
+
// +(a|?(b|c)|d) => would match "", on ?(b|c)
|
|
33
|
+
// @(a|?(b|c)|d) => would match "", on ?(b|c)
|
|
34
|
+
//
|
|
35
|
+
// ? can adopt @, because 0 or 1 is allowed
|
|
36
|
+
// ?(a|@(b|c)|d) => ?(a|b|c|d)
|
|
37
|
+
//
|
|
38
|
+
// ? and @ CANNOT adopt * or +, because >1 would be allowed
|
|
39
|
+
// ?(a|*(b|c)|d) => would match bbb on *(b|c)
|
|
40
|
+
// @(a|*(b|c)|d) => would match bbb on *(b|c)
|
|
41
|
+
// ?(a|+(b|c)|d) => would match bbb on +(b|c)
|
|
42
|
+
// @(a|+(b|c)|d) => would match bbb on +(b|c)
|
|
43
|
+
//
|
|
44
|
+
// ! CANNOT adopt ! (nothing else can either)
|
|
45
|
+
// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)
|
|
46
|
+
//
|
|
47
|
+
// ! can adopt @
|
|
48
|
+
// !(a|@(b|c)|d) => !(a|b|c|d)
|
|
49
|
+
//
|
|
50
|
+
// ! CANNOT adopt *
|
|
51
|
+
// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
|
|
52
|
+
//
|
|
53
|
+
// ! CANNOT adopt +
|
|
54
|
+
// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
|
|
55
|
+
//
|
|
56
|
+
// ! CANNOT adopt ?
|
|
57
|
+
// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"
|
|
58
|
+
const adoptionMap = new Map([
|
|
59
|
+
['!', ['@']],
|
|
60
|
+
['?', ['?', '@']],
|
|
61
|
+
['@', ['@']],
|
|
62
|
+
['*', ['*', '+', '?', '@']],
|
|
63
|
+
['+', ['+', '@']],
|
|
64
|
+
]);
|
|
65
|
+
// nested extglobs that can be adopted in, but with the addition of
|
|
66
|
+
// a blank '' element.
|
|
67
|
+
const adoptionWithSpaceMap = new Map([
|
|
68
|
+
['!', ['?']],
|
|
69
|
+
['@', ['?']],
|
|
70
|
+
['+', ['?', '*']],
|
|
71
|
+
]);
|
|
72
|
+
// union of the previous two maps
|
|
73
|
+
const adoptionAnyMap = new Map([
|
|
74
|
+
['!', ['?', '@']],
|
|
75
|
+
['?', ['?', '@']],
|
|
76
|
+
['@', ['?', '@']],
|
|
77
|
+
['*', ['*', '+', '?', '@']],
|
|
78
|
+
['+', ['+', '@', '?', '*']],
|
|
79
|
+
]);
|
|
80
|
+
// Extglobs that can take over their parent if they are the only child
|
|
81
|
+
// the key is parent, value maps child to resulting extglob parent type
|
|
82
|
+
// '@' is omitted because it's a special case. An `@` extglob with a single
|
|
83
|
+
// member can always be usurped by that subpattern.
|
|
84
|
+
const usurpMap = new Map([
|
|
85
|
+
['!', new Map([['!', '@']])],
|
|
86
|
+
[
|
|
87
|
+
'?',
|
|
88
|
+
new Map([
|
|
89
|
+
['*', '*'],
|
|
90
|
+
['+', '*'],
|
|
91
|
+
]),
|
|
92
|
+
],
|
|
93
|
+
[
|
|
94
|
+
'@',
|
|
95
|
+
new Map([
|
|
96
|
+
['!', '!'],
|
|
97
|
+
['?', '?'],
|
|
98
|
+
['@', '@'],
|
|
99
|
+
['*', '*'],
|
|
100
|
+
['+', '+'],
|
|
101
|
+
]),
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
'+',
|
|
105
|
+
new Map([
|
|
106
|
+
['?', '*'],
|
|
107
|
+
['*', '*'],
|
|
108
|
+
]),
|
|
109
|
+
],
|
|
110
|
+
]);
|
|
9
111
|
// Patterns that get prepended to bind to the start of either the
|
|
10
112
|
// entire string, or just a single path portion, to prevent dots
|
|
11
113
|
// and/or traversal patterns, when needed.
|
|
@@ -29,6 +131,7 @@ const star = qmark + '*?';
|
|
|
29
131
|
const starNoEmpty = qmark + '+?';
|
|
30
132
|
// remove the \ chars that we added if we end up doing a nonmagic compare
|
|
31
133
|
// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
|
|
134
|
+
let ID = 0;
|
|
32
135
|
class AST {
|
|
33
136
|
type;
|
|
34
137
|
#root;
|
|
@@ -44,6 +147,22 @@ class AST {
|
|
|
44
147
|
// set to true if it's an extglob with no children
|
|
45
148
|
// (which really means one child of '')
|
|
46
149
|
#emptyExt = false;
|
|
150
|
+
id = ++ID;
|
|
151
|
+
get depth() {
|
|
152
|
+
return (this.#parent?.depth ?? -1) + 1;
|
|
153
|
+
}
|
|
154
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
155
|
+
return {
|
|
156
|
+
'@@type': 'AST',
|
|
157
|
+
id: this.id,
|
|
158
|
+
type: this.type,
|
|
159
|
+
root: this.#root.id,
|
|
160
|
+
parent: this.#parent?.id,
|
|
161
|
+
depth: this.depth,
|
|
162
|
+
partsLength: this.#parts.length,
|
|
163
|
+
parts: this.#parts,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
47
166
|
constructor(type, parent, options = {}) {
|
|
48
167
|
this.type = type;
|
|
49
168
|
// extglobs are inherently magical
|
|
@@ -123,7 +242,7 @@ class AST {
|
|
|
123
242
|
continue;
|
|
124
243
|
/* c8 ignore start */
|
|
125
244
|
if (typeof p !== 'string' &&
|
|
126
|
-
!(p instanceof
|
|
245
|
+
!(p instanceof _a && p.#parent === this)) {
|
|
127
246
|
throw new Error('invalid part: ' + p);
|
|
128
247
|
}
|
|
129
248
|
/* c8 ignore stop */
|
|
@@ -157,7 +276,7 @@ class AST {
|
|
|
157
276
|
const p = this.#parent;
|
|
158
277
|
for (let i = 0; i < this.#parentIndex; i++) {
|
|
159
278
|
const pp = p.#parts[i];
|
|
160
|
-
if (!(pp instanceof
|
|
279
|
+
if (!(pp instanceof _a && pp.type === '!')) {
|
|
161
280
|
return false;
|
|
162
281
|
}
|
|
163
282
|
}
|
|
@@ -185,13 +304,14 @@ class AST {
|
|
|
185
304
|
this.push(part.clone(this));
|
|
186
305
|
}
|
|
187
306
|
clone(parent) {
|
|
188
|
-
const c = new
|
|
307
|
+
const c = new _a(this.type, parent);
|
|
189
308
|
for (const p of this.#parts) {
|
|
190
309
|
c.copyIn(p);
|
|
191
310
|
}
|
|
192
311
|
return c;
|
|
193
312
|
}
|
|
194
|
-
static #parseAST(str, ast, pos, opt) {
|
|
313
|
+
static #parseAST(str, ast, pos, opt, extDepth) {
|
|
314
|
+
const maxDepth = opt.maxExtglobRecursion ?? 2;
|
|
195
315
|
let escaping = false;
|
|
196
316
|
let inBrace = false;
|
|
197
317
|
let braceStart = -1;
|
|
@@ -228,11 +348,17 @@ class AST {
|
|
|
228
348
|
acc += c;
|
|
229
349
|
continue;
|
|
230
350
|
}
|
|
231
|
-
|
|
351
|
+
// we don't have to check for adoption here, because that's
|
|
352
|
+
// done at the other recursion point.
|
|
353
|
+
const doRecurse = !opt.noext &&
|
|
354
|
+
isExtglobType(c) &&
|
|
355
|
+
str.charAt(i) === '(' &&
|
|
356
|
+
extDepth <= maxDepth;
|
|
357
|
+
if (doRecurse) {
|
|
232
358
|
ast.push(acc);
|
|
233
359
|
acc = '';
|
|
234
|
-
const ext = new
|
|
235
|
-
i =
|
|
360
|
+
const ext = new _a(c, ast);
|
|
361
|
+
i = _a.#parseAST(str, ext, i, opt, extDepth + 1);
|
|
236
362
|
ast.push(ext);
|
|
237
363
|
continue;
|
|
238
364
|
}
|
|
@@ -244,7 +370,7 @@ class AST {
|
|
|
244
370
|
// some kind of extglob, pos is at the (
|
|
245
371
|
// find the next | or )
|
|
246
372
|
let i = pos + 1;
|
|
247
|
-
let part = new
|
|
373
|
+
let part = new _a(null, ast);
|
|
248
374
|
const parts = [];
|
|
249
375
|
let acc = '';
|
|
250
376
|
while (i < str.length) {
|
|
@@ -275,19 +401,26 @@ class AST {
|
|
|
275
401
|
acc += c;
|
|
276
402
|
continue;
|
|
277
403
|
}
|
|
278
|
-
|
|
404
|
+
const doRecurse = !opt.noext &&
|
|
405
|
+
isExtglobType(c) &&
|
|
406
|
+
str.charAt(i) === '(' &&
|
|
407
|
+
/* c8 ignore start - the maxDepth is sufficient here */
|
|
408
|
+
(extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));
|
|
409
|
+
/* c8 ignore stop */
|
|
410
|
+
if (doRecurse) {
|
|
411
|
+
const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
|
|
279
412
|
part.push(acc);
|
|
280
413
|
acc = '';
|
|
281
|
-
const ext = new
|
|
414
|
+
const ext = new _a(c, part);
|
|
282
415
|
part.push(ext);
|
|
283
|
-
i =
|
|
416
|
+
i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);
|
|
284
417
|
continue;
|
|
285
418
|
}
|
|
286
419
|
if (c === '|') {
|
|
287
420
|
part.push(acc);
|
|
288
421
|
acc = '';
|
|
289
422
|
parts.push(part);
|
|
290
|
-
part = new
|
|
423
|
+
part = new _a(null, ast);
|
|
291
424
|
continue;
|
|
292
425
|
}
|
|
293
426
|
if (c === ')') {
|
|
@@ -309,9 +442,82 @@ class AST {
|
|
|
309
442
|
ast.#parts = [str.substring(pos - 1)];
|
|
310
443
|
return i;
|
|
311
444
|
}
|
|
445
|
+
#canAdoptWithSpace(child) {
|
|
446
|
+
return this.#canAdopt(child, adoptionWithSpaceMap);
|
|
447
|
+
}
|
|
448
|
+
#canAdopt(child, map = adoptionMap) {
|
|
449
|
+
if (!child ||
|
|
450
|
+
typeof child !== 'object' ||
|
|
451
|
+
child.type !== null ||
|
|
452
|
+
child.#parts.length !== 1 ||
|
|
453
|
+
this.type === null) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
const gc = child.#parts[0];
|
|
457
|
+
if (!gc || typeof gc !== 'object' || gc.type === null) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
return this.#canAdoptType(gc.type, map);
|
|
461
|
+
}
|
|
462
|
+
#canAdoptType(c, map = adoptionAnyMap) {
|
|
463
|
+
return !!map.get(this.type)?.includes(c);
|
|
464
|
+
}
|
|
465
|
+
#adoptWithSpace(child, index) {
|
|
466
|
+
const gc = child.#parts[0];
|
|
467
|
+
const blank = new _a(null, gc, this.options);
|
|
468
|
+
blank.#parts.push('');
|
|
469
|
+
gc.push(blank);
|
|
470
|
+
this.#adopt(child, index);
|
|
471
|
+
}
|
|
472
|
+
#adopt(child, index) {
|
|
473
|
+
const gc = child.#parts[0];
|
|
474
|
+
this.#parts.splice(index, 1, ...gc.#parts);
|
|
475
|
+
for (const p of gc.#parts) {
|
|
476
|
+
if (typeof p === 'object')
|
|
477
|
+
p.#parent = this;
|
|
478
|
+
}
|
|
479
|
+
this.#toString = undefined;
|
|
480
|
+
}
|
|
481
|
+
#canUsurpType(c) {
|
|
482
|
+
const m = usurpMap.get(this.type);
|
|
483
|
+
return !!(m?.has(c));
|
|
484
|
+
}
|
|
485
|
+
#canUsurp(child) {
|
|
486
|
+
if (!child ||
|
|
487
|
+
typeof child !== 'object' ||
|
|
488
|
+
child.type !== null ||
|
|
489
|
+
child.#parts.length !== 1 ||
|
|
490
|
+
this.type === null ||
|
|
491
|
+
this.#parts.length !== 1) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
const gc = child.#parts[0];
|
|
495
|
+
if (!gc || typeof gc !== 'object' || gc.type === null) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
return this.#canUsurpType(gc.type);
|
|
499
|
+
}
|
|
500
|
+
#usurp(child) {
|
|
501
|
+
const m = usurpMap.get(this.type);
|
|
502
|
+
const gc = child.#parts[0];
|
|
503
|
+
const nt = m?.get(gc.type);
|
|
504
|
+
/* c8 ignore start - impossible */
|
|
505
|
+
if (!nt)
|
|
506
|
+
return false;
|
|
507
|
+
/* c8 ignore stop */
|
|
508
|
+
this.#parts = gc.#parts;
|
|
509
|
+
for (const p of this.#parts) {
|
|
510
|
+
if (typeof p === 'object') {
|
|
511
|
+
p.#parent = this;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
this.type = nt;
|
|
515
|
+
this.#toString = undefined;
|
|
516
|
+
this.#emptyExt = false;
|
|
517
|
+
}
|
|
312
518
|
static fromGlob(pattern, options = {}) {
|
|
313
|
-
const ast = new
|
|
314
|
-
|
|
519
|
+
const ast = new _a(null, undefined, options);
|
|
520
|
+
_a.#parseAST(pattern, ast, 0, options, 0);
|
|
315
521
|
return ast;
|
|
316
522
|
}
|
|
317
523
|
// returns the regular expression if there's magic, or the unescaped
|
|
@@ -415,16 +621,18 @@ class AST {
|
|
|
415
621
|
// or start or whatever) and prepend ^ or / at the Regexp construction.
|
|
416
622
|
toRegExpSource(allowDot) {
|
|
417
623
|
const dot = allowDot ?? !!this.#options.dot;
|
|
418
|
-
if (this.#root === this)
|
|
624
|
+
if (this.#root === this) {
|
|
625
|
+
this.#flatten();
|
|
419
626
|
this.#fillNegs();
|
|
420
|
-
|
|
627
|
+
}
|
|
628
|
+
if (!isExtglobAST(this)) {
|
|
421
629
|
const noEmpty = this.isStart() &&
|
|
422
630
|
this.isEnd() &&
|
|
423
631
|
!this.#parts.some(s => typeof s !== 'string');
|
|
424
632
|
const src = this.#parts
|
|
425
633
|
.map(p => {
|
|
426
634
|
const [re, _, hasMagic, uflag] = typeof p === 'string' ?
|
|
427
|
-
|
|
635
|
+
_a.#parseGlob(p, this.#hasMagic, noEmpty)
|
|
428
636
|
: p.toRegExpSource(allowDot);
|
|
429
637
|
this.#hasMagic = this.#hasMagic || hasMagic;
|
|
430
638
|
this.#uflag = this.#uflag || uflag;
|
|
@@ -486,12 +694,12 @@ class AST {
|
|
|
486
694
|
// invalid extglob, has to at least be *something* present, if it's
|
|
487
695
|
// the entire path portion.
|
|
488
696
|
const s = this.toString();
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
697
|
+
const me = this;
|
|
698
|
+
me.#parts = [s];
|
|
699
|
+
me.type = null;
|
|
700
|
+
me.#hasMagic = undefined;
|
|
492
701
|
return [s, (0, unescape_js_1.unescape)(this.toString()), false, false];
|
|
493
702
|
}
|
|
494
|
-
// XXX abstract out this map method
|
|
495
703
|
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?
|
|
496
704
|
''
|
|
497
705
|
: this.#partsToRegExp(true);
|
|
@@ -527,6 +735,42 @@ class AST {
|
|
|
527
735
|
this.#uflag,
|
|
528
736
|
];
|
|
529
737
|
}
|
|
738
|
+
#flatten() {
|
|
739
|
+
if (!isExtglobAST(this)) {
|
|
740
|
+
for (const p of this.#parts) {
|
|
741
|
+
if (typeof p === 'object') {
|
|
742
|
+
p.#flatten();
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// do up to 10 passes to flatten as much as possible
|
|
748
|
+
let iterations = 0;
|
|
749
|
+
let done = false;
|
|
750
|
+
do {
|
|
751
|
+
done = true;
|
|
752
|
+
for (let i = 0; i < this.#parts.length; i++) {
|
|
753
|
+
const c = this.#parts[i];
|
|
754
|
+
if (typeof c === 'object') {
|
|
755
|
+
c.#flatten();
|
|
756
|
+
if (this.#canAdopt(c)) {
|
|
757
|
+
done = false;
|
|
758
|
+
this.#adopt(c, i);
|
|
759
|
+
}
|
|
760
|
+
else if (this.#canAdoptWithSpace(c)) {
|
|
761
|
+
done = false;
|
|
762
|
+
this.#adoptWithSpace(c, i);
|
|
763
|
+
}
|
|
764
|
+
else if (this.#canUsurp(c)) {
|
|
765
|
+
done = false;
|
|
766
|
+
this.#usurp(c);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
} while (!done && ++iterations < 10);
|
|
771
|
+
}
|
|
772
|
+
this.#toString = undefined;
|
|
773
|
+
}
|
|
530
774
|
#partsToRegExp(dot) {
|
|
531
775
|
return this.#parts
|
|
532
776
|
.map(p => {
|
|
@@ -598,4 +842,5 @@ class AST {
|
|
|
598
842
|
}
|
|
599
843
|
}
|
|
600
844
|
exports.AST = AST;
|
|
845
|
+
_a = AST;
|
|
601
846
|
//# sourceMappingURL=ast.js.map
|