minimatch-fast 0.2.1

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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +950 -0
  3. package/dist/cjs/brace-expand.d.ts +42 -0
  4. package/dist/cjs/brace-expand.d.ts.map +1 -0
  5. package/dist/cjs/brace-expand.js +172 -0
  6. package/dist/cjs/brace-expand.js.map +1 -0
  7. package/dist/cjs/cache.d.ts +36 -0
  8. package/dist/cjs/cache.d.ts.map +1 -0
  9. package/dist/cjs/cache.js +91 -0
  10. package/dist/cjs/cache.js.map +1 -0
  11. package/dist/cjs/escape.d.ts +40 -0
  12. package/dist/cjs/escape.d.ts.map +1 -0
  13. package/dist/cjs/escape.js +52 -0
  14. package/dist/cjs/escape.js.map +1 -0
  15. package/dist/cjs/fast-paths.d.ts +54 -0
  16. package/dist/cjs/fast-paths.d.ts.map +1 -0
  17. package/dist/cjs/fast-paths.js +213 -0
  18. package/dist/cjs/fast-paths.js.map +1 -0
  19. package/dist/cjs/index.d.ts +150 -0
  20. package/dist/cjs/index.d.ts.map +1 -0
  21. package/dist/cjs/index.js +250 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/minimatch-class.d.ts +153 -0
  24. package/dist/cjs/minimatch-class.d.ts.map +1 -0
  25. package/dist/cjs/minimatch-class.js +618 -0
  26. package/dist/cjs/minimatch-class.js.map +1 -0
  27. package/dist/cjs/options.d.ts +31 -0
  28. package/dist/cjs/options.d.ts.map +1 -0
  29. package/dist/cjs/options.js +67 -0
  30. package/dist/cjs/options.js.map +1 -0
  31. package/dist/cjs/package.json +3 -0
  32. package/dist/cjs/types.d.ts +194 -0
  33. package/dist/cjs/types.d.ts.map +1 -0
  34. package/dist/cjs/types.js +19 -0
  35. package/dist/cjs/types.js.map +1 -0
  36. package/dist/cjs/unescape.d.ts +36 -0
  37. package/dist/cjs/unescape.d.ts.map +1 -0
  38. package/dist/cjs/unescape.js +49 -0
  39. package/dist/cjs/unescape.js.map +1 -0
  40. package/dist/cjs/utils.d.ts +62 -0
  41. package/dist/cjs/utils.d.ts.map +1 -0
  42. package/dist/cjs/utils.js +126 -0
  43. package/dist/cjs/utils.js.map +1 -0
  44. package/dist/esm/brace-expand.d.ts +42 -0
  45. package/dist/esm/brace-expand.d.ts.map +1 -0
  46. package/dist/esm/brace-expand.js +165 -0
  47. package/dist/esm/brace-expand.js.map +1 -0
  48. package/dist/esm/cache.d.ts +36 -0
  49. package/dist/esm/cache.d.ts.map +1 -0
  50. package/dist/esm/cache.js +86 -0
  51. package/dist/esm/cache.js.map +1 -0
  52. package/dist/esm/escape.d.ts +40 -0
  53. package/dist/esm/escape.d.ts.map +1 -0
  54. package/dist/esm/escape.js +49 -0
  55. package/dist/esm/escape.js.map +1 -0
  56. package/dist/esm/fast-paths.d.ts +54 -0
  57. package/dist/esm/fast-paths.d.ts.map +1 -0
  58. package/dist/esm/fast-paths.js +209 -0
  59. package/dist/esm/fast-paths.js.map +1 -0
  60. package/dist/esm/index.d.ts +150 -0
  61. package/dist/esm/index.d.ts.map +1 -0
  62. package/dist/esm/index.js +240 -0
  63. package/dist/esm/index.js.map +1 -0
  64. package/dist/esm/minimatch-class.d.ts +153 -0
  65. package/dist/esm/minimatch-class.d.ts.map +1 -0
  66. package/dist/esm/minimatch-class.js +611 -0
  67. package/dist/esm/minimatch-class.js.map +1 -0
  68. package/dist/esm/options.d.ts +31 -0
  69. package/dist/esm/options.d.ts.map +1 -0
  70. package/dist/esm/options.js +63 -0
  71. package/dist/esm/options.js.map +1 -0
  72. package/dist/esm/package.json +3 -0
  73. package/dist/esm/types.d.ts +194 -0
  74. package/dist/esm/types.d.ts.map +1 -0
  75. package/dist/esm/types.js +16 -0
  76. package/dist/esm/types.js.map +1 -0
  77. package/dist/esm/unescape.d.ts +36 -0
  78. package/dist/esm/unescape.d.ts.map +1 -0
  79. package/dist/esm/unescape.js +46 -0
  80. package/dist/esm/unescape.js.map +1 -0
  81. package/dist/esm/utils.d.ts +62 -0
  82. package/dist/esm/utils.d.ts.map +1 -0
  83. package/dist/esm/utils.js +116 -0
  84. package/dist/esm/utils.js.map +1 -0
  85. package/package.json +83 -0
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @fileoverview Brace expansion using the 'braces' package
3
+ *
4
+ * This module is critical because picomatch does NOT perform full brace expansion.
5
+ * picomatch only does brace matching, meaning {a,b} will match 'a' or 'b'
6
+ * but won't expand the pattern into ['a', 'b'].
7
+ *
8
+ * minimatch uses brace-expansion to fully expand patterns like:
9
+ * - {a,b,c} -> ['a', 'b', 'c']
10
+ * - {1..3} -> ['1', '2', '3']
11
+ * - {a..c} -> ['a', 'b', 'c']
12
+ * - a{b,c}d -> ['abd', 'acd']
13
+ *
14
+ * We use 'braces' package which is maintained by the same author as picomatch
15
+ * and is what micromatch uses internally.
16
+ *
17
+ * Security considerations:
18
+ * - Maximum expansion length is limited to prevent DoS attacks
19
+ * - Range expansion is limited (e.g., {1..1000000} is restricted)
20
+ *
21
+ * @author 686f6c61
22
+ * @see https://github.com/686f6c61/minimatch-fast
23
+ * @license MIT
24
+ */
25
+ import braces from 'braces';
26
+ /**
27
+ * Maximum number of patterns that can be generated from brace expansion
28
+ * This prevents DoS attacks from patterns like {1..1000000}
29
+ */
30
+ const MAX_EXPANSION_LENGTH = 10000;
31
+ /**
32
+ * Cache for brace expansion results.
33
+ * Key is the pattern, value is the expanded array.
34
+ * Limited to prevent memory issues.
35
+ */
36
+ const BRACE_CACHE_SIZE = 200;
37
+ const braceCache = new Map();
38
+ /**
39
+ * Simple brace pattern regex: prefix{a,b,c}suffix
40
+ * Matches patterns with a single brace group containing comma-separated values
41
+ * without nesting or ranges.
42
+ */
43
+ const SIMPLE_BRACE_RE = /^([^{]*)\{([^{}]+)\}([^{]*)$/;
44
+ /**
45
+ * Try fast path for simple brace patterns like prefix{a,b,c}suffix
46
+ * Returns null if pattern is not a simple brace pattern.
47
+ */
48
+ function trySimpleBraceExpand(pattern) {
49
+ const m = pattern.match(SIMPLE_BRACE_RE);
50
+ if (!m)
51
+ return null;
52
+ const [, prefix, content, suffix] = m;
53
+ // Check if it's a range pattern (contains ..)
54
+ if (content.includes('..'))
55
+ return null;
56
+ // Split by comma and expand
57
+ const items = content.split(',');
58
+ return items.map(item => prefix + item + suffix);
59
+ }
60
+ /**
61
+ * Expand brace patterns like {a,b,c} and {1..3}
62
+ *
63
+ * Optimized with:
64
+ * 1. Cache for repeated patterns
65
+ * 2. Fast path for simple {a,b,c} patterns
66
+ *
67
+ * @param pattern - The glob pattern to expand
68
+ * @param options - Minimatch options
69
+ * @returns Array of expanded patterns
70
+ */
71
+ export function braceExpand(pattern, options = {}) {
72
+ // If nobrace is set, return pattern unchanged
73
+ if (options.nobrace) {
74
+ return [pattern];
75
+ }
76
+ // Quick check: pattern must contain both { and }
77
+ const braceIdx = pattern.indexOf('{');
78
+ if (braceIdx === -1 || pattern.indexOf('}', braceIdx) === -1) {
79
+ return [pattern];
80
+ }
81
+ // Check cache first
82
+ const cached = braceCache.get(pattern);
83
+ if (cached) {
84
+ // Return a copy to prevent mutation
85
+ return [...cached];
86
+ }
87
+ // Try fast path for simple brace patterns
88
+ const fastResult = trySimpleBraceExpand(pattern);
89
+ if (fastResult !== null) {
90
+ // Cache and return
91
+ if (braceCache.size >= BRACE_CACHE_SIZE) {
92
+ const firstKey = braceCache.keys().next().value;
93
+ if (firstKey !== undefined) {
94
+ braceCache.delete(firstKey);
95
+ }
96
+ }
97
+ braceCache.set(pattern, fastResult);
98
+ return [...fastResult];
99
+ }
100
+ try {
101
+ // Use braces with expand: true for full bash-like expansion
102
+ const expanded = braces(pattern, {
103
+ expand: true,
104
+ // Limit range expansion to prevent DoS
105
+ // e.g., {1..10000} will be limited
106
+ rangeLimit: 1000,
107
+ });
108
+ // Check if expansion is too large (additional safety)
109
+ if (expanded.length > MAX_EXPANSION_LENGTH) {
110
+ // Return original pattern if expansion is too large
111
+ console.warn(`Brace expansion for "${pattern}" produced ${expanded.length} patterns, limiting to original pattern`);
112
+ return [pattern];
113
+ }
114
+ // Remove duplicates using Set (faster than manual loop for larger arrays)
115
+ const unique = [...new Set(expanded)];
116
+ const result = unique.length > 0 ? unique : [pattern];
117
+ // Cache the result
118
+ if (braceCache.size >= BRACE_CACHE_SIZE) {
119
+ const firstKey = braceCache.keys().next().value;
120
+ if (firstKey !== undefined) {
121
+ braceCache.delete(firstKey);
122
+ }
123
+ }
124
+ braceCache.set(pattern, result);
125
+ return [...result];
126
+ }
127
+ catch (e) {
128
+ // If expansion fails for any reason, return original pattern
129
+ // This matches minimatch's behavior of being lenient with invalid patterns
130
+ return [pattern];
131
+ }
132
+ }
133
+ /**
134
+ * Check if a pattern contains brace expansion syntax
135
+ */
136
+ export function hasBraces(pattern) {
137
+ // Simple check for balanced braces with content
138
+ let depth = 0;
139
+ let hasContent = false;
140
+ for (let i = 0; i < pattern.length; i++) {
141
+ const char = pattern[i];
142
+ const prevChar = i > 0 ? pattern[i - 1] : '';
143
+ // Skip escaped braces
144
+ if (prevChar === '\\') {
145
+ continue;
146
+ }
147
+ if (char === '{') {
148
+ depth++;
149
+ }
150
+ else if (char === '}') {
151
+ if (depth > 0) {
152
+ depth--;
153
+ if (depth === 0 && hasContent) {
154
+ return true;
155
+ }
156
+ }
157
+ }
158
+ else if (depth > 0 && (char === ',' || char === '.')) {
159
+ // Has content (comma for list, dots for range)
160
+ hasContent = true;
161
+ }
162
+ }
163
+ return false;
164
+ }
165
+ //# sourceMappingURL=brace-expand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brace-expand.js","sourceRoot":"","sources":["../../src/brace-expand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview LRU Cache for compiled Minimatch patterns
3
+ *
4
+ * This module provides a simple LRU (Least Recently Used) cache for Minimatch
5
+ * instances. Caching compiled patterns significantly improves performance
6
+ * when the same pattern is used multiple times with the minimatch() function.
7
+ *
8
+ * The cache stores compiled Minimatch instances keyed by a combination of
9
+ * the pattern string and relevant options that affect compilation.
10
+ *
11
+ * @author 686f6c61
12
+ * @see https://github.com/686f6c61/minimatch-fast
13
+ * @license MIT
14
+ */
15
+ import type { MinimatchOptions } from './types.js';
16
+ import { Minimatch } from './minimatch-class.js';
17
+ /**
18
+ * Get a cached Minimatch instance or create a new one.
19
+ * Implements LRU eviction when cache is full.
20
+ *
21
+ * @param pattern - The glob pattern
22
+ * @param options - Minimatch options
23
+ * @returns A Minimatch instance (cached or new)
24
+ */
25
+ export declare function getOrCreateMatcher(pattern: string, options: MinimatchOptions): Minimatch;
26
+ /**
27
+ * Clear the pattern cache.
28
+ * Useful for testing or when memory pressure is high.
29
+ */
30
+ export declare function clearCache(): void;
31
+ /**
32
+ * Get the current cache size.
33
+ * Useful for monitoring and testing.
34
+ */
35
+ export declare function getCacheSize(): number;
36
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AA4CjD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,SAAS,CA4BX;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @fileoverview LRU Cache for compiled Minimatch patterns
3
+ *
4
+ * This module provides a simple LRU (Least Recently Used) cache for Minimatch
5
+ * instances. Caching compiled patterns significantly improves performance
6
+ * when the same pattern is used multiple times with the minimatch() function.
7
+ *
8
+ * The cache stores compiled Minimatch instances keyed by a combination of
9
+ * the pattern string and relevant options that affect compilation.
10
+ *
11
+ * @author 686f6c61
12
+ * @see https://github.com/686f6c61/minimatch-fast
13
+ * @license MIT
14
+ */
15
+ import { Minimatch } from './minimatch-class.js';
16
+ /**
17
+ * Maximum number of patterns to cache.
18
+ * This prevents unbounded memory growth while still providing
19
+ * good cache hit rates for typical usage patterns.
20
+ */
21
+ const CACHE_SIZE = 500;
22
+ /**
23
+ * LRU cache for compiled Minimatch instances.
24
+ * Uses Map which maintains insertion order, making it easy
25
+ * to implement LRU eviction by deleting the oldest entry.
26
+ */
27
+ const patternCache = new Map();
28
+ /**
29
+ * Generate a cache key from pattern and options.
30
+ * Only includes options that affect pattern compilation.
31
+ *
32
+ * @param pattern - The glob pattern
33
+ * @param options - Minimatch options
34
+ * @returns A unique cache key string
35
+ */
36
+ function getCacheKey(pattern, options) {
37
+ // Use null byte as separator (cannot appear in patterns)
38
+ // Include all options that affect compilation
39
+ return `${pattern}\0${options.nocase ? '1' : '0'}${options.dot ? '1' : '0'}${options.noglobstar ? '1' : '0'}${options.nobrace ? '1' : '0'}${options.noext ? '1' : '0'}${options.nonegate ? '1' : '0'}${options.nocomment ? '1' : '0'}${options.matchBase ? '1' : '0'}${options.flipNegate ? '1' : '0'}${options.windowsPathsNoEscape ? '1' : '0'}${options.preserveMultipleSlashes ? '1' : '0'}${options.partial ? '1' : '0'}${options.platform ?? ''}`;
40
+ }
41
+ /**
42
+ * Get a cached Minimatch instance or create a new one.
43
+ * Implements LRU eviction when cache is full.
44
+ *
45
+ * @param pattern - The glob pattern
46
+ * @param options - Minimatch options
47
+ * @returns A Minimatch instance (cached or new)
48
+ */
49
+ export function getOrCreateMatcher(pattern, options) {
50
+ const key = getCacheKey(pattern, options);
51
+ // Check cache first
52
+ let mm = patternCache.get(key);
53
+ if (mm) {
54
+ // Move to end (most recently used) by re-inserting
55
+ patternCache.delete(key);
56
+ patternCache.set(key, mm);
57
+ return mm;
58
+ }
59
+ // Create new Minimatch instance
60
+ mm = new Minimatch(pattern, options);
61
+ // Evict oldest entry if cache is full
62
+ if (patternCache.size >= CACHE_SIZE) {
63
+ const firstKey = patternCache.keys().next().value;
64
+ if (firstKey !== undefined) {
65
+ patternCache.delete(firstKey);
66
+ }
67
+ }
68
+ // Add to cache
69
+ patternCache.set(key, mm);
70
+ return mm;
71
+ }
72
+ /**
73
+ * Clear the pattern cache.
74
+ * Useful for testing or when memory pressure is high.
75
+ */
76
+ export function clearCache() {
77
+ patternCache.clear();
78
+ }
79
+ /**
80
+ * Get the current cache size.
81
+ * Useful for monitoring and testing.
82
+ */
83
+ export function getCacheSize() {
84
+ return patternCache.size;
85
+ }
86
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;;;GAIG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAAqB,CAAC;AAElD;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,OAAyB;IAC7D,yDAAyD;IACzD,8CAA8C;IAC9C,OAAO,GAAG,OAAO,KACf,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GACzB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GACxB,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAC7B,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAC5B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GACxB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAC7B,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAC5B,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAC9B,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAC7B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GACzC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAC1C,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAC5B,OAAO,CAAC,QAAQ,IAAI,EACtB,EAAE,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,OAAyB;IAEzB,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE1C,oBAAoB;IACpB,IAAI,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,EAAE,EAAE,CAAC;QACP,mDAAmD;QACnD,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,gCAAgC;IAChC,EAAE,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAErC,sCAAsC;IACtC,IAAI,YAAY,CAAC,IAAI,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,eAAe;IACf,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAE1B,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,YAAY,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,CAAC,IAAI,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Escape glob magic characters
3
+ *
4
+ * This module provides functionality to escape special glob characters in strings,
5
+ * making them match literally instead of being interpreted as patterns.
6
+ *
7
+ * Escape modes:
8
+ * - Default mode: Uses backslash escaping (\* \? etc.)
9
+ * - Windows mode: Uses character class escaping ([*] [?] etc.)
10
+ *
11
+ * This is useful when you need to match file paths that contain glob
12
+ * special characters like *, ?, [], {}, etc.
13
+ *
14
+ * @example
15
+ * escape('*.js') // Returns '\\*.js'
16
+ * escape('[test].js') // Returns '\\[test\\].js'
17
+ * escape('*.js', { windowsPathsNoEscape: true }) // Returns '[*].js'
18
+ *
19
+ * @author 686f6c61
20
+ * @see https://github.com/686f6c61/minimatch-fast
21
+ * @license MIT
22
+ */
23
+ import type { MinimatchOptions } from './types.js';
24
+ /**
25
+ * Escape all magic characters in a glob pattern so it matches literally.
26
+ *
27
+ * If windowsPathsNoEscape is true, characters are escaped by wrapping in [],
28
+ * because a magic character wrapped in a character class can only be satisfied
29
+ * by that exact character. Backslash is NOT escaped in this mode because it
30
+ * is treated as a path separator.
31
+ *
32
+ * If windowsPathsNoEscape is false (default), characters are escaped with
33
+ * backslash.
34
+ *
35
+ * @param str - The string to escape
36
+ * @param options - Options controlling escape behavior
37
+ * @returns Escaped string
38
+ */
39
+ export declare function escape(str: string, options?: Pick<MinimatchOptions, 'windowsPathsNoEscape'>): string;
40
+ //# sourceMappingURL=escape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,CAAM,GAC3D,MAAM,CAYR"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Escape glob magic characters
3
+ *
4
+ * This module provides functionality to escape special glob characters in strings,
5
+ * making them match literally instead of being interpreted as patterns.
6
+ *
7
+ * Escape modes:
8
+ * - Default mode: Uses backslash escaping (\* \? etc.)
9
+ * - Windows mode: Uses character class escaping ([*] [?] etc.)
10
+ *
11
+ * This is useful when you need to match file paths that contain glob
12
+ * special characters like *, ?, [], {}, etc.
13
+ *
14
+ * @example
15
+ * escape('*.js') // Returns '\\*.js'
16
+ * escape('[test].js') // Returns '\\[test\\].js'
17
+ * escape('*.js', { windowsPathsNoEscape: true }) // Returns '[*].js'
18
+ *
19
+ * @author 686f6c61
20
+ * @see https://github.com/686f6c61/minimatch-fast
21
+ * @license MIT
22
+ */
23
+ /**
24
+ * Escape all magic characters in a glob pattern so it matches literally.
25
+ *
26
+ * If windowsPathsNoEscape is true, characters are escaped by wrapping in [],
27
+ * because a magic character wrapped in a character class can only be satisfied
28
+ * by that exact character. Backslash is NOT escaped in this mode because it
29
+ * is treated as a path separator.
30
+ *
31
+ * If windowsPathsNoEscape is false (default), characters are escaped with
32
+ * backslash.
33
+ *
34
+ * @param str - The string to escape
35
+ * @param options - Options controlling escape behavior
36
+ * @returns Escaped string
37
+ */
38
+ export function escape(str, options = {}) {
39
+ const { windowsPathsNoEscape = false } = options;
40
+ if (windowsPathsNoEscape) {
41
+ // Escape by wrapping in character class []
42
+ // Don't escape backslash since it's a path separator in this mode
43
+ return str.replace(/[?*()[\]{}]/g, '[$&]');
44
+ }
45
+ // Default: escape with backslash
46
+ // Include backslash in the escape set
47
+ return str.replace(/[?*()[\]{}\\]/g, '\\$&');
48
+ }
49
+ //# sourceMappingURL=escape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,MAAM,CACpB,GAAW,EACX,UAA0D,EAAE;IAE5D,MAAM,EAAE,oBAAoB,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEjD,IAAI,oBAAoB,EAAE,CAAC;QACzB,2CAA2C;QAC3C,kEAAkE;QAClE,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,iCAAiC;IACjC,sCAAsC;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @fileoverview Fast path handlers for common glob patterns
3
+ *
4
+ * This module provides optimized matching for the most common glob patterns,
5
+ * avoiding the overhead of full regex compilation. These fast paths use
6
+ * simple string operations like startsWith(), endsWith(), and includes()
7
+ * which are significantly faster than regex matching.
8
+ *
9
+ * Supported fast path patterns:
10
+ * - `*` - Match any single path segment (except dotfiles by default)
11
+ * - `*.ext` - Match files with specific extension (e.g., `*.js`, `*.ts`)
12
+ * - `*.*` - Match files with any extension
13
+ * - `.*` - Match hidden files (dotfiles)
14
+ * - `???` - Match files with exact length (question mark patterns)
15
+ *
16
+ * When a pattern doesn't match any fast path, null is returned and the
17
+ * caller should fall back to full pattern matching.
18
+ *
19
+ * @author 686f6c61
20
+ * @see https://github.com/686f6c61/minimatch-fast
21
+ * @license MIT
22
+ */
23
+ import type { MinimatchOptions } from './types.js';
24
+ /**
25
+ * Try to match a path against a pattern using a fast path.
26
+ *
27
+ * This function attempts to use optimized string operations for common
28
+ * glob patterns instead of full regex compilation. If the pattern is not
29
+ * a simple pattern that can be handled by a fast path, null is returned.
30
+ *
31
+ * @param path - The path to match (should be a filename without directory)
32
+ * @param pattern - The glob pattern to match against
33
+ * @param options - Minimatch options (dot, nocase are relevant)
34
+ * @returns true if matches, false if doesn't match, null if no fast path available
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * tryFastPath('foo.js', '*.js', {}); // true
39
+ * tryFastPath('foo.txt', '*.js', {}); // false
40
+ * tryFastPath('.hidden', '*', {}); // false
41
+ * tryFastPath('.hidden', '*', { dot: true }); // true
42
+ * tryFastPath('foo.js', '**\/*.js', {}); // null (has /, need full matching)
43
+ * ```
44
+ */
45
+ export declare function tryFastPath(path: string, pattern: string, options: MinimatchOptions): boolean | null;
46
+ /**
47
+ * Check if a pattern might be eligible for fast path.
48
+ * This is a quick pre-check to avoid expensive regex tests.
49
+ *
50
+ * @param pattern - The glob pattern
51
+ * @returns true if pattern might use fast path
52
+ */
53
+ export declare function mightUseFastPath(pattern: string): boolean;
54
+ //# sourceMappingURL=fast-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-paths.d.ts","sourceRoot":"","sources":["../../src/fast-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4CnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,GAAG,IAAI,CAmHhB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAYzD"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * @fileoverview Fast path handlers for common glob patterns
3
+ *
4
+ * This module provides optimized matching for the most common glob patterns,
5
+ * avoiding the overhead of full regex compilation. These fast paths use
6
+ * simple string operations like startsWith(), endsWith(), and includes()
7
+ * which are significantly faster than regex matching.
8
+ *
9
+ * Supported fast path patterns:
10
+ * - `*` - Match any single path segment (except dotfiles by default)
11
+ * - `*.ext` - Match files with specific extension (e.g., `*.js`, `*.ts`)
12
+ * - `*.*` - Match files with any extension
13
+ * - `.*` - Match hidden files (dotfiles)
14
+ * - `???` - Match files with exact length (question mark patterns)
15
+ *
16
+ * When a pattern doesn't match any fast path, null is returned and the
17
+ * caller should fall back to full pattern matching.
18
+ *
19
+ * @author 686f6c61
20
+ * @see https://github.com/686f6c61/minimatch-fast
21
+ * @license MIT
22
+ */
23
+ // ============================================================================
24
+ // PATTERN DETECTION REGEXES
25
+ // These regexes detect which fast path to use. They are compiled once at
26
+ // module load time and reused for all pattern checks.
27
+ // ============================================================================
28
+ /**
29
+ * Matches pure star patterns: *, **, ***
30
+ * Used for "match anything" patterns.
31
+ */
32
+ const STAR_RE = /^\*+$/;
33
+ /**
34
+ * Matches star-dot-extension patterns: *.js, *.ts, *.txt
35
+ * Captures the extension (including the dot).
36
+ * Excludes patterns with special glob characters in the extension.
37
+ */
38
+ const STAR_DOT_EXT_RE = /^\*+(\.[^+@!?\*\[\(]+)$/;
39
+ /**
40
+ * Matches star-dot-star patterns: *.*, **.*
41
+ * Used for "any file with an extension" matching.
42
+ */
43
+ const STAR_DOT_STAR_RE = /^\*+\.\*+$/;
44
+ /**
45
+ * Matches dot-star patterns: .*, .**
46
+ * Used for dotfile/hidden file matching.
47
+ */
48
+ const DOT_STAR_RE = /^\.\*+$/;
49
+ /**
50
+ * Matches question mark patterns: ?, ??, ???, ???.js
51
+ * Captures optional extension after the question marks.
52
+ * Used for exact-length matching.
53
+ */
54
+ const QMARKS_RE = /^(\?+)(\.[^+@!?\*\[\(]+)?$/;
55
+ // ============================================================================
56
+ // FAST PATH IMPLEMENTATION
57
+ // ============================================================================
58
+ /**
59
+ * Try to match a path against a pattern using a fast path.
60
+ *
61
+ * This function attempts to use optimized string operations for common
62
+ * glob patterns instead of full regex compilation. If the pattern is not
63
+ * a simple pattern that can be handled by a fast path, null is returned.
64
+ *
65
+ * @param path - The path to match (should be a filename without directory)
66
+ * @param pattern - The glob pattern to match against
67
+ * @param options - Minimatch options (dot, nocase are relevant)
68
+ * @returns true if matches, false if doesn't match, null if no fast path available
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * tryFastPath('foo.js', '*.js', {}); // true
73
+ * tryFastPath('foo.txt', '*.js', {}); // false
74
+ * tryFastPath('.hidden', '*', {}); // false
75
+ * tryFastPath('.hidden', '*', { dot: true }); // true
76
+ * tryFastPath('foo.js', '**\/*.js', {}); // null (has /, need full matching)
77
+ * ```
78
+ */
79
+ export function tryFastPath(path, pattern, options) {
80
+ // Skip if path contains / (need full path matching)
81
+ if (path.includes('/'))
82
+ return null;
83
+ // Skip if pattern has path separators (need full matching)
84
+ if (pattern.includes('/'))
85
+ return null;
86
+ // Skip if negated (need full matching for proper negation handling)
87
+ if (!options.nonegate && pattern.startsWith('!'))
88
+ return null;
89
+ // Skip if pattern has braces (need brace expansion)
90
+ if (!options.nobrace && pattern.includes('{'))
91
+ return null;
92
+ // Skip if pattern has extglob (need extglob handling)
93
+ if (!options.noext && /[@!?+*]\(/.test(pattern))
94
+ return null;
95
+ // Skip if pattern has character class (need regex)
96
+ if (pattern.includes('['))
97
+ return null;
98
+ const dot = options.dot ?? false;
99
+ const nocase = options.nocase ?? false;
100
+ let m;
101
+ // -------------------------------------------------------------------------
102
+ // Fast path: * (pure star)
103
+ // Matches any non-empty filename, respecting dot option
104
+ // -------------------------------------------------------------------------
105
+ if ((m = pattern.match(STAR_RE))) {
106
+ if (path.length === 0)
107
+ return false;
108
+ if (dot) {
109
+ // With dot option, match anything except . and ..
110
+ return path !== '.' && path !== '..';
111
+ }
112
+ // Without dot option, don't match dotfiles
113
+ return !path.startsWith('.');
114
+ }
115
+ // -------------------------------------------------------------------------
116
+ // Fast path: *.ext (star-dot-extension)
117
+ // Matches files ending with specific extension
118
+ // -------------------------------------------------------------------------
119
+ if ((m = pattern.match(STAR_DOT_EXT_RE))) {
120
+ const ext = m[1]; // Includes the dot, e.g., ".js"
121
+ if (path.length === 0)
122
+ return false;
123
+ if (nocase) {
124
+ const lpath = path.toLowerCase();
125
+ const lext = ext.toLowerCase();
126
+ if (dot)
127
+ return lpath.endsWith(lext);
128
+ return !path.startsWith('.') && lpath.endsWith(lext);
129
+ }
130
+ if (dot)
131
+ return path.endsWith(ext);
132
+ return !path.startsWith('.') && path.endsWith(ext);
133
+ }
134
+ // -------------------------------------------------------------------------
135
+ // Fast path: *.* (star-dot-star)
136
+ // Matches any file with an extension (contains a dot)
137
+ // -------------------------------------------------------------------------
138
+ if ((m = pattern.match(STAR_DOT_STAR_RE))) {
139
+ if (path.length === 0)
140
+ return false;
141
+ if (dot) {
142
+ // With dot, match anything with a dot except . and ..
143
+ return path !== '.' && path !== '..' && path.includes('.');
144
+ }
145
+ // Without dot, must have extension and not be a dotfile
146
+ return !path.startsWith('.') && path.includes('.');
147
+ }
148
+ // -------------------------------------------------------------------------
149
+ // Fast path: .* (dot-star)
150
+ // Matches hidden files (starting with dot)
151
+ // -------------------------------------------------------------------------
152
+ if ((m = pattern.match(DOT_STAR_RE))) {
153
+ // Must start with dot but not be . or ..
154
+ return path.startsWith('.') && path !== '.' && path !== '..';
155
+ }
156
+ // -------------------------------------------------------------------------
157
+ // Fast path: ??? (question marks with optional extension)
158
+ // Matches files with exact length
159
+ // -------------------------------------------------------------------------
160
+ if ((m = pattern.match(QMARKS_RE))) {
161
+ const qmarks = m[1]; // The question marks, e.g., "???"
162
+ const ext = m[2] ?? ''; // Optional extension, e.g., ".js"
163
+ const qLen = qmarks.length;
164
+ const expectedLen = qLen + ext.length;
165
+ if (path.length !== expectedLen)
166
+ return false;
167
+ // Never match . or .. (special directories)
168
+ if (path === '.' || path === '..')
169
+ return false;
170
+ if (ext) {
171
+ // Has extension - check length and extension match
172
+ if (nocase) {
173
+ const lpath = path.toLowerCase();
174
+ const lext = ext.toLowerCase();
175
+ if (!lpath.endsWith(lext))
176
+ return false;
177
+ }
178
+ else {
179
+ if (!path.endsWith(ext))
180
+ return false;
181
+ }
182
+ }
183
+ // Check dotfile restriction
184
+ if (!dot && path.startsWith('.'))
185
+ return false;
186
+ return true;
187
+ }
188
+ // No fast path available
189
+ return null;
190
+ }
191
+ /**
192
+ * Check if a pattern might be eligible for fast path.
193
+ * This is a quick pre-check to avoid expensive regex tests.
194
+ *
195
+ * @param pattern - The glob pattern
196
+ * @returns true if pattern might use fast path
197
+ */
198
+ export function mightUseFastPath(pattern) {
199
+ // Fast paths only work for simple patterns without:
200
+ // - Path separators
201
+ // - Braces
202
+ // - Character classes
203
+ // - Extglob patterns
204
+ return (!pattern.includes('/') &&
205
+ !pattern.includes('{') &&
206
+ !pattern.includes('[') &&
207
+ !/[@!?+*]\(/.test(pattern));
208
+ }
209
+ //# sourceMappingURL=fast-paths.js.map