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