@reliverse/matcha 2.2.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/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # @reliverse/matcha
2
+
3
+ > @reliverse/matcha is a high-performance minimal glob matcher, with micromatch-level power, zepto-level size, and reliverse-grade dx.
4
+
5
+ [sponsor](https://github.com/sponsors/blefnk) — [discord](https://discord.gg/reliverse) — [npm](https://npmjs.com/package/@reliverse/matcha) — [github](https://github.com/reliverse/matcha)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ bun add @reliverse/matcha
11
+ # bun • pnpm • yarn • npm
12
+ ```
13
+
14
+ ## Features
15
+
16
+ You want **micromatch/picomatch features** in a **zeptomatch-sized**(🔜) package.
17
+
18
+ - 🧩 Drop-in replacement for `micromatch`, `zeptomatch`, `picomatch`
19
+ - 🧠 Full bash-style globbing support with advanced pattern matching
20
+ - 🪶 Tiny ([7.5 kB](https://bundlephobia.com/package/@reliverse/matcha@latest)), tree-shakeable, dependency-free implementation
21
+ - ⚡ Fast runtime with optimized regex compilation and caching
22
+ - 🔧 Complete toolset: escape, parse, compile, and match
23
+ - 🔜 1700+ picomatch and zeptomatch tests passed
24
+ - 🪄 Rich feature set with intuitive API
25
+
26
+ ## Features in Detail
27
+
28
+ ### Core Pattern Matching
29
+
30
+ - **Wildcards**
31
+ - `*` - Matches any characters except path separators
32
+ - `**` - Matches any characters including path separators (globstar)
33
+ - `?` - Matches exactly one character except path separators
34
+
35
+ ### Advanced Pattern Matching
36
+
37
+ - **Character Classes**
38
+ - `[abc]` - Matches any single character from the set
39
+ - `[a-z]` - Matches any single character in the range
40
+ - `[!abc]` or `[^abc]` - Matches any single character not in the set
41
+
42
+ - **Brace Expansion**
43
+ - `{a,b,c}` - Matches any of the comma-separated patterns
44
+ - Nested braces supported: `{a,{b,c}}` expands correctly
45
+ - Numeric ranges: `{1..5}` matches 1,2,3,4,5
46
+ - Padded numeric ranges: `{01..05}` matches 01,02,03,04,05
47
+ - Alphabetic ranges: `{a..e}` matches a,b,c,d,e
48
+ - Case-sensitive alphabetic ranges: `{A..E}` vs `{a..e}`
49
+
50
+ - **Pattern Negation**
51
+ - `!pattern` - Matches anything that doesn't match the pattern
52
+ - Multiple negations: `!!pattern` (negates the negation)
53
+ - Combining with other patterns: `['*.js', '!test.js']`
54
+
55
+ ### Special Features
56
+
57
+ - **Dot File Handling**
58
+ - By default, `*` won't match files starting with a dot
59
+ - Explicit dot matching with `.*.js` or setting `dot: true` option
60
+
61
+ - **Path Handling**
62
+ - Automatic path normalization (converts backslashes to forward slashes)
63
+ - Proper handling of path separators in globstar patterns
64
+
65
+ ### Performance Optimizations
66
+
67
+ - **Pattern Compilation**
68
+ - Automatic caching of compiled patterns
69
+ - Efficient regex generation with optimized character classes
70
+ - Smart handling of static vs dynamic patterns
71
+
72
+ - **Memory Efficiency**
73
+ - Minimal memory footprint
74
+ - Efficient pattern parsing and compilation
75
+ - Smart caching strategies
76
+
77
+ ## API Reference
78
+
79
+ ### Main Function
80
+
81
+ ```typescript
82
+ // Returns true if input matches pattern(s)
83
+ matcha(pattern: string, input: string, options?: matchaOptions): boolean
84
+ matcha(patterns: string[], input: string, options?: matchaOptions): boolean
85
+
86
+ // Returns a compiled matcher function
87
+ matcha(pattern: string, options?: matchaOptions): Matcher
88
+ matcha(patterns: string[], options?: matchaOptions): Matcher
89
+ ```
90
+
91
+ #### Options
92
+
93
+ ```typescript
94
+ interface matchaOptions {
95
+ dot?: boolean; // Match dotfiles (default: false)
96
+ nocase?: boolean; // Case-insensitive matching (default: false)
97
+ ignore?: string | string[]; // Patterns to ignore (applies to input)
98
+ }
99
+ ```
100
+
101
+ #### Types
102
+
103
+ ```typescript
104
+ type Matcher = (input: string) => boolean;
105
+
106
+ type ScanResult = {
107
+ isGlob: boolean;
108
+ negated: boolean;
109
+ glob: string;
110
+ parts?: string[];
111
+ };
112
+ ```
113
+
114
+ ### Utility Functions
115
+
116
+ All utility functions are available as named exports and as properties on the default export:
117
+
118
+ ```typescript
119
+ compile(pattern: string, options?: matchaOptions): Matcher
120
+ makeRegex(pattern: string, options?: matchaOptions): RegExp
121
+ makeRe(pattern: string, options?: matchaOptions): RegExp // Alias for makeRegex
122
+ normalizePath(pathStr: string): string
123
+ escapeGlob(str: string): string
124
+ unescapeGlob(str: string): string
125
+ isStatic(pattern: string, options?: { dot?: boolean }): boolean
126
+ scan(pattern: string, options?: { parts?: boolean }): ScanResult
127
+ explode(pattern: string): { static: string[]; dynamic: string[] }
128
+ ```
129
+
130
+ ## Examples
131
+
132
+ ```typescript
133
+ import matcha, { compile, normalizePath } from "@reliverse/matcha";
134
+
135
+ // Basic matching
136
+ matcha("*.js", "file.js"); // → true
137
+ matcha("**/*.js", "src/utils/file.js"); // → true
138
+ matcha("*.js", "file.ts"); // → false
139
+
140
+ // Dot files
141
+ matcha("*.js", ".hidden.js"); // → false
142
+ matcha("*.js", ".hidden.js", { dot: true }); // → true
143
+
144
+ // Case-insensitive matching
145
+ matcha("*.JS", "file.js", { nocase: true }); // → true
146
+
147
+ // Character classes
148
+ matcha("[abc].js", "a.js"); // → true
149
+ matcha("[!a-z].js", "9.js"); // → true
150
+
151
+ // Brace expansion
152
+ matcha("file.{js,ts}", "file.js"); // → true
153
+ matcha("file{1..3}.js", "file2.js"); // → true
154
+ matcha("file{01..03}.js", "file01.js"); // → true
155
+
156
+ // Multiple patterns and negation
157
+ matcha(["*.js", "!test.js"], "file.js"); // → true
158
+ matcha(["*.js", "!file.js"], "file.js"); // → false
159
+
160
+ // Ignore option
161
+ matcha("*.js", "file.js", { ignore: "file.js" }); // → false
162
+ matcha(["*.js", "!test.js"], "test.js", { ignore: "test.js" }); // → false
163
+
164
+ // Compiled matcher
165
+ const matcher = compile("**/*.{js,ts}");
166
+ matcher("src/file.js"); // → true
167
+ matcher("deep/nested/file.ts"); // → true
168
+
169
+ // Path normalization (for Windows paths)
170
+ matcha("src/*.js", "src\\file.js"); // → true
171
+ normalizePath("src\\file.js"); // → "src/file.js"
172
+
173
+ // Utility: escape/unescape
174
+ matcha(escapeGlob("file[1].js"), "file[1].js"); // → true
175
+ unescapeGlob("file\\[1\\].js"); // → "file[1].js"
176
+
177
+ // Utility: isStatic, scan, explode
178
+ isStatic("file.js"); // → true
179
+ isStatic("*.js"); // → false
180
+ scan("!src/*.js"); // → { isGlob: true, negated: true, glob: "src/*.js" }
181
+ explode("src/file[1-3].js"); // → { static: ["src/file"], dynamic: ["[1-3].js"] }
182
+ ```
183
+
184
+ ## Playground
185
+
186
+ To test [example/e-mod.ts](./example/e-mod.ts), run:
187
+
188
+ ```bash
189
+ git clone https://github.com/reliverse/matcha
190
+ cd matcha
191
+ bun i
192
+ bun dev # beginner-friendly example
193
+ bun tests # advanced test suite
194
+ ```
195
+
196
+ ## Contributing
197
+
198
+ - 🧙 Star it on [GitHub](https://github.com/reliverse/matcha)
199
+ - 💬 Join our [Discord](https://discord.gg/reliverse)
200
+ - 💖 [Sponsor @blefnk](https://github.com/sponsors/blefnk)
201
+
202
+ ## Related Reliverse Projects
203
+
204
+ - [`@reliverse/reglob`](https://npmjs.com/package/@reliverse/reglob) — Tiny, fast globber
205
+ - [`@reliverse/relifso`](https://npmjs.com/package/@reliverse/relifso) — Filesystem made fun again
206
+ - [`@reliverse/repackr`](https://npmjs.com/package/@reliverse/repackr) — Alternative to tar/7zip
207
+
208
+ ## License
209
+
210
+ 💖 [MIT](./LICENSE) © [blefnk (Nazar Kornienko)](https://github.com/blefnk)
package/dist/mod.d.ts ADDED
@@ -0,0 +1,129 @@
1
+ interface MatchOptions {
2
+ partial?: boolean;
3
+ }
4
+ interface CompileOptions {
5
+ partial?: boolean;
6
+ }
7
+ interface MatcherOptions {
8
+ partial?: boolean;
9
+ }
10
+ /**
11
+ * Check if a glob pattern matches a path
12
+ * @param pattern - The glob pattern to match against
13
+ * @param input - The input string to test
14
+ * @param options - Optional configuration
15
+ * @returns True if the pattern matches the input
16
+ */
17
+ export declare const match: (pattern: string, input: string, options?: MatchOptions) => boolean;
18
+ /**
19
+ * Check if a glob pattern matches a path (alias for match)
20
+ * @param pattern - The glob pattern to match against
21
+ * @param input - The input string to test
22
+ * @param options - Optional configuration
23
+ * @returns True if the pattern matches the input
24
+ */
25
+ export declare const isMatch: (pattern: string, input: string, options?: MatchOptions) => boolean;
26
+ /**
27
+ * Create a matcher function for a specific pattern
28
+ * @param pattern - The glob pattern to compile
29
+ * @param options - Optional configuration
30
+ * @returns A function that tests input against the pattern
31
+ */
32
+ export declare const createMatcher: (pattern: string, options?: MatcherOptions) => (input: string) => boolean;
33
+ /**
34
+ * Create multiple matcher functions for multiple patterns
35
+ * @param patterns - Array of glob patterns to compile
36
+ * @param options - Optional configuration
37
+ * @returns Array of matcher functions
38
+ */
39
+ export declare const createMatchers: (patterns: string[], options?: MatcherOptions) => ((input: string) => boolean)[];
40
+ /**
41
+ * Test if any of the patterns match the input
42
+ * @param patterns - Array of glob patterns to test
43
+ * @param input - The input string to test
44
+ * @param options - Optional configuration
45
+ * @returns True if any pattern matches
46
+ */
47
+ export declare const matchAny: (patterns: string[], input: string, options?: MatchOptions) => boolean;
48
+ /**
49
+ * Test if all patterns match the input
50
+ * @param patterns - Array of glob patterns to test
51
+ * @param input - The input string to test
52
+ * @param options - Optional configuration
53
+ * @returns True if all patterns match
54
+ */
55
+ export declare const matchAll: (patterns: string[], input: string, options?: MatchOptions) => boolean;
56
+ /**
57
+ * Filter an array of strings based on glob patterns
58
+ * @param patterns - Array of glob patterns to match against
59
+ * @param inputs - Array of strings to filter
60
+ * @param options - Optional configuration
61
+ * @returns Array of strings that match any of the patterns
62
+ */
63
+ export declare const filter: (patterns: string[], inputs: string[], options?: MatchOptions) => string[];
64
+ /**
65
+ * Filter an array of strings, excluding those that match glob patterns
66
+ * @param patterns - Array of glob patterns to exclude
67
+ * @param inputs - Array of strings to filter
68
+ * @param options - Optional configuration
69
+ * @returns Array of strings that don't match any of the patterns
70
+ */
71
+ export declare const exclude: (patterns: string[], inputs: string[], options?: MatchOptions) => string[];
72
+ /**
73
+ * Compile a glob pattern to a regular expression
74
+ * @param pattern - The glob pattern to compile
75
+ * @param options - Optional configuration
76
+ * @returns Compiled regular expression
77
+ */
78
+ export declare const compile: (pattern: string, options?: CompileOptions) => RegExp;
79
+ /**
80
+ * Compile multiple glob patterns to a single regular expression
81
+ * @param patterns - Array of glob patterns to compile
82
+ * @param options - Optional configuration
83
+ * @returns Compiled regular expression that matches any of the patterns
84
+ */
85
+ export declare const compileAny: (patterns: string[], options?: CompileOptions) => RegExp;
86
+ /**
87
+ * Normalize glob patterns by splitting on whitespace and filtering empty strings
88
+ * @param patterns - String or array of patterns to normalize
89
+ * @returns Normalized array of patterns
90
+ */
91
+ export declare const normalizePatterns: (patterns: string | string[]) => string[];
92
+ /**
93
+ * Create a filter function that excludes patterns
94
+ * @param ignorePatterns - Patterns to ignore (string or array)
95
+ * @param options - Optional configuration
96
+ * @returns Function that filters out matching items
97
+ */
98
+ export declare const createIgnoreFilter: (ignorePatterns: string | string[], options?: MatcherOptions) => <T extends {
99
+ name: string;
100
+ }>(items: T[]) => T[];
101
+ /**
102
+ * Create a filter function that includes only matching patterns
103
+ * @param includePatterns - Patterns to include (string or array)
104
+ * @param options - Optional configuration
105
+ * @returns Function that filters to only matching items
106
+ */
107
+ export declare const createIncludeFilter: (includePatterns: string | string[], options?: MatcherOptions) => <T extends {
108
+ name: string;
109
+ }>(items: T[]) => T[];
110
+ declare const _default: {
111
+ match: (pattern: string, input: string, options?: MatchOptions) => boolean;
112
+ isMatch: (pattern: string, input: string, options?: MatchOptions) => boolean;
113
+ createMatcher: (pattern: string, options?: MatcherOptions) => (input: string) => boolean;
114
+ createMatchers: (patterns: string[], options?: MatcherOptions) => ((input: string) => boolean)[];
115
+ matchAny: (patterns: string[], input: string, options?: MatchOptions) => boolean;
116
+ matchAll: (patterns: string[], input: string, options?: MatchOptions) => boolean;
117
+ filter: (patterns: string[], inputs: string[], options?: MatchOptions) => string[];
118
+ exclude: (patterns: string[], inputs: string[], options?: MatchOptions) => string[];
119
+ compile: (pattern: string, options?: CompileOptions) => RegExp;
120
+ compileAny: (patterns: string[], options?: CompileOptions) => RegExp;
121
+ normalizePatterns: (patterns: string | string[]) => string[];
122
+ createIgnoreFilter: (ignorePatterns: string | string[], options?: MatcherOptions) => <T extends {
123
+ name: string;
124
+ }>(items: T[]) => T[];
125
+ createIncludeFilter: (includePatterns: string | string[], options?: MatcherOptions) => <T extends {
126
+ name: string;
127
+ }>(items: T[]) => T[];
128
+ };
129
+ export default _default;
package/dist/mod.js ADDED
@@ -0,0 +1,79 @@
1
+ import zeptomatch from "zeptomatch";
2
+ export const match = (pattern, input, options = {}) => zeptomatch(pattern, input, options);
3
+ export const isMatch = match;
4
+ export const createMatcher = (pattern, options = {}) => (input) => zeptomatch(pattern, input, options);
5
+ export const createMatchers = (patterns, options = {}) => patterns.map((pattern) => createMatcher(pattern, options));
6
+ export const matchAny = (patterns, input, options = {}) => patterns.some((pattern) => zeptomatch(pattern, input, options));
7
+ export const matchAll = (patterns, input, options = {}) => patterns.every((pattern) => zeptomatch(pattern, input, options));
8
+ export const filter = (patterns, inputs, options = {}) => {
9
+ if (patterns.length > 1) {
10
+ const regex = compileAny(patterns, options);
11
+ return inputs.filter((input) => regex.test(input));
12
+ }
13
+ if (patterns.length === 1) {
14
+ const pattern = patterns[0];
15
+ if (pattern === void 0) return [];
16
+ return inputs.filter((input) => zeptomatch(pattern, input, options));
17
+ }
18
+ return [];
19
+ };
20
+ export const exclude = (patterns, inputs, options = {}) => {
21
+ if (patterns.length > 1) {
22
+ const regex = compileAny(patterns, options);
23
+ return inputs.filter((input) => !regex.test(input));
24
+ }
25
+ if (patterns.length === 1) {
26
+ const pattern = patterns[0];
27
+ if (pattern === void 0) return inputs;
28
+ return inputs.filter((input) => !zeptomatch(pattern, input, options));
29
+ }
30
+ return inputs;
31
+ };
32
+ export const compile = (pattern, options = {}) => zeptomatch.compile(pattern, options);
33
+ export const compileAny = (patterns, options = {}) => zeptomatch.compile(patterns, options);
34
+ export const normalizePatterns = (patterns) => Array.isArray(patterns) ? patterns.flatMap((pattern) => pattern.split(/\s+/).filter(Boolean)) : patterns.split(/\s+/).filter(Boolean);
35
+ export const createIgnoreFilter = (ignorePatterns, options = {}) => {
36
+ const patterns = normalizePatterns(ignorePatterns);
37
+ if (patterns.length > 1) {
38
+ const regex = compileAny(patterns, options);
39
+ return (items) => items.filter((item) => !regex.test(item.name));
40
+ }
41
+ if (patterns.length === 1) {
42
+ const pattern = patterns[0];
43
+ if (pattern === void 0) {
44
+ return (items) => items;
45
+ }
46
+ return (items) => items.filter((item) => !zeptomatch(pattern, item.name, options));
47
+ }
48
+ return (items) => items;
49
+ };
50
+ export const createIncludeFilter = (includePatterns, options = {}) => {
51
+ const patterns = normalizePatterns(includePatterns);
52
+ if (patterns.length > 1) {
53
+ const regex = compileAny(patterns, options);
54
+ return (items) => items.filter((item) => regex.test(item.name));
55
+ }
56
+ if (patterns.length === 1) {
57
+ const pattern = patterns[0];
58
+ if (pattern === void 0) {
59
+ return (_items) => [];
60
+ }
61
+ return (items) => items.filter((item) => zeptomatch(pattern, item.name, options));
62
+ }
63
+ return (_items) => [];
64
+ };
65
+ export default {
66
+ match,
67
+ isMatch,
68
+ createMatcher,
69
+ createMatchers,
70
+ matchAny,
71
+ matchAll,
72
+ filter,
73
+ exclude,
74
+ compile,
75
+ compileAny,
76
+ normalizePatterns,
77
+ createIgnoreFilter,
78
+ createIncludeFilter
79
+ };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@reliverse/matcha",
3
+ "version": "2.2.7",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "@reliverse/matcha is a high-performance minimal matcher, with micromatch-level power, zepto-level size, and reliverse-grade dx.",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/mod.d.ts",
10
+ "default": "./dist/mod.js"
11
+ }
12
+ },
13
+ "dependencies": {
14
+ "zeptomatch": "^2.1.0"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "package.json"
22
+ ],
23
+ "license": "MIT"
24
+ }