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