minimatch 9.0.6 → 9.0.7
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/dist/commonjs/ast.d.ts.map +1 -1
- package/dist/commonjs/ast.js +168 -20
- package/dist/commonjs/ast.js.map +1 -1
- package/dist/commonjs/index.d.ts +4 -0
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +120 -118
- package/dist/commonjs/index.js.map +1 -1
- package/dist/esm/ast.d.ts.map +1 -1
- package/dist/esm/ast.js +168 -20
- package/dist/esm/ast.js.map +1 -1
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +120 -118
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -193,11 +193,13 @@ export class Minimatch {
|
|
|
193
193
|
isWindows;
|
|
194
194
|
platform;
|
|
195
195
|
windowsNoMagicRoot;
|
|
196
|
+
maxGlobstarRecursion;
|
|
196
197
|
regexp;
|
|
197
198
|
constructor(pattern, options = {}) {
|
|
198
199
|
assertValidPattern(pattern);
|
|
199
200
|
options = options || {};
|
|
200
201
|
this.options = options;
|
|
202
|
+
this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
|
|
201
203
|
this.pattern = pattern;
|
|
202
204
|
this.platform = options.platform || defaultPlatform;
|
|
203
205
|
this.isWindows = this.platform === 'win32';
|
|
@@ -597,7 +599,8 @@ export class Minimatch {
|
|
|
597
599
|
// out of pattern, then that's fine, as long as all
|
|
598
600
|
// the parts match.
|
|
599
601
|
matchOne(file, pattern, partial = false) {
|
|
600
|
-
|
|
602
|
+
let fileStartIndex = 0;
|
|
603
|
+
let patternStartIndex = 0;
|
|
601
604
|
// UNC paths like //?/X:/... can match X:/... and vice versa
|
|
602
605
|
// Drive letters in absolute drive or unc paths are always compared
|
|
603
606
|
// case-insensitively.
|
|
@@ -618,15 +621,14 @@ export class Minimatch {
|
|
|
618
621
|
const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
|
|
619
622
|
const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
|
|
620
623
|
if (typeof fdi === 'number' && typeof pdi === 'number') {
|
|
621
|
-
const [fd, pd] = [
|
|
624
|
+
const [fd, pd] = [
|
|
625
|
+
file[fdi],
|
|
626
|
+
pattern[pdi],
|
|
627
|
+
];
|
|
622
628
|
if (fd.toLowerCase() === pd.toLowerCase()) {
|
|
623
629
|
pattern[pdi] = fd;
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
else if (fdi > pdi) {
|
|
628
|
-
file = file.slice(fdi);
|
|
629
|
-
}
|
|
630
|
+
patternStartIndex = pdi;
|
|
631
|
+
fileStartIndex = fdi;
|
|
630
632
|
}
|
|
631
633
|
}
|
|
632
634
|
}
|
|
@@ -636,102 +638,123 @@ export class Minimatch {
|
|
|
636
638
|
if (optimizationLevel >= 2) {
|
|
637
639
|
file = this.levelTwoFileOptimize(file);
|
|
638
640
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
641
|
+
if (pattern.includes(GLOBSTAR)) {
|
|
642
|
+
return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
643
|
+
}
|
|
644
|
+
return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
645
|
+
}
|
|
646
|
+
#matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
|
|
647
|
+
const firstgs = pattern.indexOf(GLOBSTAR, patternIndex);
|
|
648
|
+
const lastgs = pattern.lastIndexOf(GLOBSTAR);
|
|
649
|
+
const [head, body, tail] = [
|
|
650
|
+
pattern.slice(patternIndex, firstgs),
|
|
651
|
+
pattern.slice(firstgs + 1, lastgs),
|
|
652
|
+
pattern.slice(lastgs + 1),
|
|
653
|
+
];
|
|
654
|
+
if (head.length) {
|
|
655
|
+
const fileHead = file.slice(fileIndex, fileIndex + head.length);
|
|
656
|
+
if (!this.#matchOne(fileHead, head, partial, 0, 0))
|
|
650
657
|
return false;
|
|
658
|
+
fileIndex += head.length;
|
|
659
|
+
}
|
|
660
|
+
let fileTailMatch = 0;
|
|
661
|
+
if (tail.length) {
|
|
662
|
+
if (tail.length + fileIndex > file.length)
|
|
663
|
+
return false;
|
|
664
|
+
let tailStart = file.length - tail.length;
|
|
665
|
+
if (this.#matchOne(file, tail, partial, tailStart, 0)) {
|
|
666
|
+
fileTailMatch = tail.length;
|
|
651
667
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
// a/**/b/**/c would match the following:
|
|
657
|
-
// a/b/x/y/z/c
|
|
658
|
-
// a/x/y/z/b/c
|
|
659
|
-
// a/b/x/b/x/c
|
|
660
|
-
// a/b/c
|
|
661
|
-
// To do this, take the rest of the pattern after
|
|
662
|
-
// the **, and see if it would match the file remainder.
|
|
663
|
-
// If so, return success.
|
|
664
|
-
// If not, the ** "swallows" a segment, and try again.
|
|
665
|
-
// This is recursively awful.
|
|
666
|
-
//
|
|
667
|
-
// a/**/b/**/c matching a/b/x/y/z/c
|
|
668
|
-
// - a matches a
|
|
669
|
-
// - doublestar
|
|
670
|
-
// - matchOne(b/x/y/z/c, b/**/c)
|
|
671
|
-
// - b matches b
|
|
672
|
-
// - doublestar
|
|
673
|
-
// - matchOne(x/y/z/c, c) -> no
|
|
674
|
-
// - matchOne(y/z/c, c) -> no
|
|
675
|
-
// - matchOne(z/c, c) -> no
|
|
676
|
-
// - matchOne(c, c) yes, hit
|
|
677
|
-
var fr = fi;
|
|
678
|
-
var pr = pi + 1;
|
|
679
|
-
if (pr === pl) {
|
|
680
|
-
this.debug('** at the end');
|
|
681
|
-
// a ** at the end will just swallow the rest.
|
|
682
|
-
// We have found a match.
|
|
683
|
-
// however, it will not swallow /.x, unless
|
|
684
|
-
// options.dot is set.
|
|
685
|
-
// . and .. are *never* matched by **, for explosively
|
|
686
|
-
// exponential reasons.
|
|
687
|
-
for (; fi < fl; fi++) {
|
|
688
|
-
if (file[fi] === '.' ||
|
|
689
|
-
file[fi] === '..' ||
|
|
690
|
-
(!options.dot && file[fi].charAt(0) === '.'))
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
return true;
|
|
668
|
+
else {
|
|
669
|
+
if (file[file.length - 1] !== '' ||
|
|
670
|
+
fileIndex + tail.length === file.length) {
|
|
671
|
+
return false;
|
|
694
672
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
swallowee === '..' ||
|
|
710
|
-
(!options.dot && swallowee.charAt(0) === '.')) {
|
|
711
|
-
this.debug('dot detected!', file, fr, pattern, pr);
|
|
712
|
-
break;
|
|
713
|
-
}
|
|
714
|
-
// ** swallows a segment, and continue.
|
|
715
|
-
this.debug('globstar swallow a segment, and continue');
|
|
716
|
-
fr++;
|
|
717
|
-
}
|
|
673
|
+
tailStart--;
|
|
674
|
+
if (!this.#matchOne(file, tail, partial, tailStart, 0))
|
|
675
|
+
return false;
|
|
676
|
+
fileTailMatch = tail.length + 1;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (!body.length) {
|
|
680
|
+
let sawSome = !!fileTailMatch;
|
|
681
|
+
for (let i = fileIndex; i < file.length - fileTailMatch; i++) {
|
|
682
|
+
const f = String(file[i]);
|
|
683
|
+
sawSome = true;
|
|
684
|
+
if (f === '.' || f === '..' ||
|
|
685
|
+
(!this.options.dot && f.startsWith('.'))) {
|
|
686
|
+
return false;
|
|
718
687
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
688
|
+
}
|
|
689
|
+
return sawSome;
|
|
690
|
+
}
|
|
691
|
+
const bodySegments = [[[], 0]];
|
|
692
|
+
let currentBody = bodySegments[0];
|
|
693
|
+
let nonGsParts = 0;
|
|
694
|
+
const nonGsPartsSums = [0];
|
|
695
|
+
for (const b of body) {
|
|
696
|
+
if (b === GLOBSTAR) {
|
|
697
|
+
nonGsPartsSums.push(nonGsParts);
|
|
698
|
+
currentBody = [[], 0];
|
|
699
|
+
bodySegments.push(currentBody);
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
702
|
+
currentBody[0].push(b);
|
|
703
|
+
nonGsParts++;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
let i = bodySegments.length - 1;
|
|
707
|
+
const fileLength = file.length - fileTailMatch;
|
|
708
|
+
for (const b of bodySegments) {
|
|
709
|
+
b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
|
|
710
|
+
}
|
|
711
|
+
return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
|
|
712
|
+
}
|
|
713
|
+
#matchGlobStarBodySections(file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
|
|
714
|
+
const bs = bodySegments[bodyIndex];
|
|
715
|
+
if (!bs) {
|
|
716
|
+
for (let i = fileIndex; i < file.length; i++) {
|
|
717
|
+
sawTail = true;
|
|
718
|
+
const f = file[i];
|
|
719
|
+
if (f === '.' || f === '..' ||
|
|
720
|
+
(!this.options.dot && f.startsWith('.'))) {
|
|
721
|
+
return false;
|
|
728
722
|
}
|
|
729
|
-
|
|
723
|
+
}
|
|
724
|
+
return sawTail;
|
|
725
|
+
}
|
|
726
|
+
const [body, after] = bs;
|
|
727
|
+
while (fileIndex <= after) {
|
|
728
|
+
const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
|
|
729
|
+
if (m && globStarDepth < this.maxGlobstarRecursion) {
|
|
730
|
+
const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
|
|
731
|
+
if (sub !== false)
|
|
732
|
+
return sub;
|
|
733
|
+
}
|
|
734
|
+
const f = file[fileIndex];
|
|
735
|
+
if (f === '.' || f === '..' ||
|
|
736
|
+
(!this.options.dot && f.startsWith('.'))) {
|
|
730
737
|
return false;
|
|
731
738
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
739
|
+
fileIndex++;
|
|
740
|
+
}
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
#matchOne(file, pattern, partial, fileIndex, patternIndex) {
|
|
744
|
+
let fi;
|
|
745
|
+
let pi;
|
|
746
|
+
let pl;
|
|
747
|
+
let fl;
|
|
748
|
+
for (fi = fileIndex, pi = patternIndex,
|
|
749
|
+
fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
|
|
750
|
+
this.debug('matchOne loop');
|
|
751
|
+
let p = pattern[pi];
|
|
752
|
+
let f = file[fi];
|
|
753
|
+
this.debug(pattern, p, f);
|
|
754
|
+
/* c8 ignore start */
|
|
755
|
+
if (p === false || p === GLOBSTAR)
|
|
756
|
+
return false;
|
|
757
|
+
/* c8 ignore stop */
|
|
735
758
|
let hit;
|
|
736
759
|
if (typeof p === 'string') {
|
|
737
760
|
hit = f === p;
|
|
@@ -744,38 +767,17 @@ export class Minimatch {
|
|
|
744
767
|
if (!hit)
|
|
745
768
|
return false;
|
|
746
769
|
}
|
|
747
|
-
// Note: ending in / means that we'll get a final ""
|
|
748
|
-
// at the end of the pattern. This can only match a
|
|
749
|
-
// corresponding "" at the end of the file.
|
|
750
|
-
// If the file ends in /, then it can only match a
|
|
751
|
-
// a pattern that ends in /, unless the pattern just
|
|
752
|
-
// doesn't have any more for it. But, a/b/ should *not*
|
|
753
|
-
// match "a/b/*", even though "" matches against the
|
|
754
|
-
// [^/]*? pattern, except in partial mode, where it might
|
|
755
|
-
// simply not be reached yet.
|
|
756
|
-
// However, a/b/ should still satisfy a/*
|
|
757
|
-
// now either we fell off the end of the pattern, or we're done.
|
|
758
770
|
if (fi === fl && pi === pl) {
|
|
759
|
-
// ran out of pattern and filename at the same time.
|
|
760
|
-
// an exact hit!
|
|
761
771
|
return true;
|
|
762
772
|
}
|
|
763
773
|
else if (fi === fl) {
|
|
764
|
-
// ran out of file, but still had pattern left.
|
|
765
|
-
// this is ok if we're doing the match as part of
|
|
766
|
-
// a glob fs traversal.
|
|
767
774
|
return partial;
|
|
768
775
|
}
|
|
769
776
|
else if (pi === pl) {
|
|
770
|
-
// ran out of pattern, still have file left.
|
|
771
|
-
// this is only acceptable if we're on the very last
|
|
772
|
-
// empty segment of a file with a trailing slash.
|
|
773
|
-
// a/* should match a/b/
|
|
774
777
|
return fi === fl - 1 && file[fi] === '';
|
|
775
778
|
/* c8 ignore start */
|
|
776
779
|
}
|
|
777
780
|
else {
|
|
778
|
-
// should be unreachable.
|
|
779
781
|
throw new Error('wtf?');
|
|
780
782
|
}
|
|
781
783
|
/* c8 ignore stop */
|