UNPKG

@reliverse/rematch

Version:

@reliverse/rematch is a high-performance minimal glob matcher, with micromatch-level power, zepto-level size, and reliverse-grade dx.

217 lines (160 loc) β€’ 7.65 kB
# @reliverse/rematch > @reliverse/rematch is a high-performance minimal glob matcher, with micromatch-level power, zepto-level size, and reliverse-grade dx. [πŸ“¦ NPM](https://npmjs.com/package/@reliverse/rematch) β€’ [✨ GitHub](https://github.com/reliverse/rematch) β€’ [πŸ’¬ Discord](https://discord.gg/reliverse) ## Installation ```bash bun add @reliverse/rematch # bun β€’ pnpm β€’ yarn β€’ npm ``` ## Features You want **micromatch/picomatch features** in a **zeptomatch-sized**(πŸ”œ) package. - 🧩 Drop-in replacement for `micromatch`, `zeptomatch`, `picomatch` - 🧠 Full bash-style globbing support with advanced pattern matching - πŸͺΆ Tiny ([7.5 kB](https://bundlephobia.com/package/@reliverse/rematch@latest)), tree-shakeable, dependency-free implementation - ⚑ Fast runtime with optimized regex compilation and caching - πŸ”§ Complete toolset: escape, parse, compile, and match - πŸ”œ 1700+ picomatch and zeptomatch tests passed - πŸͺ„ Rich feature set with intuitive API ## Heads Up - **Most of the things** mentioned in this doc **aren’t implemented yet** β€” they’re part of the vision for ~`v1.3.0`. - Got thoughts? Ideas? Send your feedback in [Discord](https://discord.gg/Pb8uKbwpsJ) or use [GitHub Issues](https://github.com/reliverse/relifso/issues). - Your feedback means the world and helps shape where this project goes next. Thank you! ## Features in Detail ### Core Pattern Matching - **Wildcards** - `*` - Matches any characters except path separators - `**` - Matches any characters including path separators (globstar) - `?` - Matches exactly one character except path separators ### Advanced Pattern Matching - **Character Classes** - `[abc]` - Matches any single character from the set - `[a-z]` - Matches any single character in the range - `[!abc]` or `[^abc]` - Matches any single character not in the set - **Brace Expansion** - `{a,b,c}` - Matches any of the comma-separated patterns - Nested braces supported: `{a,{b,c}}` expands correctly - Numeric ranges: `{1..5}` matches 1,2,3,4,5 - Padded numeric ranges: `{01..05}` matches 01,02,03,04,05 - Alphabetic ranges: `{a..e}` matches a,b,c,d,e - Case-sensitive alphabetic ranges: `{A..E}` vs `{a..e}` - **Pattern Negation** - `!pattern` - Matches anything that doesn't match the pattern - Multiple negations: `!!pattern` (negates the negation) - Combining with other patterns: `['*.js', '!test.js']` ### Special Features - **Dot File Handling** - By default, `*` won't match files starting with a dot - Explicit dot matching with `.*.js` or setting `dot: true` option - **Path Handling** - Automatic path normalization (converts backslashes to forward slashes) - Proper handling of path separators in globstar patterns ### Performance Optimizations - **Pattern Compilation** - Automatic caching of compiled patterns - Efficient regex generation with optimized character classes - Smart handling of static vs dynamic patterns - **Memory Efficiency** - Minimal memory footprint - Efficient pattern parsing and compilation - Smart caching strategies ## API Reference ### Main Function ```typescript // Returns true if input matches pattern(s) rematch(pattern: string, input: string, options?: RematchOptions): boolean rematch(patterns: string[], input: string, options?: RematchOptions): boolean // Returns a compiled matcher function rematch(pattern: string, options?: RematchOptions): Matcher rematch(patterns: string[], options?: RematchOptions): Matcher ``` #### Options ```typescript interface RematchOptions { dot?: boolean; // Match dotfiles (default: false) nocase?: boolean; // Case-insensitive matching (default: false) ignore?: string | string[]; // Patterns to ignore (applies to input) } ``` #### Types ```typescript type Matcher = (input: string) => boolean; type ScanResult = { isGlob: boolean; negated: boolean; glob: string; parts?: string[]; }; ``` ### Utility Functions All utility functions are available as named exports and as properties on the default export: ```typescript compile(pattern: string, options?: RematchOptions): Matcher makeRegex(pattern: string, options?: RematchOptions): RegExp makeRe(pattern: string, options?: RematchOptions): RegExp // Alias for makeRegex normalizePath(pathStr: string): string escapeGlob(str: string): string unescapeGlob(str: string): string isStatic(pattern: string, options?: { dot?: boolean }): boolean scan(pattern: string, options?: { parts?: boolean }): ScanResult explode(pattern: string): { static: string[]; dynamic: string[] } ``` ## Examples ```typescript import rematch, { compile, normalizePath } from "@reliverse/rematch"; // Basic matching rematch("*.js", "file.js"); // β†’ true rematch("**/*.js", "src/utils/file.js"); // β†’ true rematch("*.js", "file.ts"); // β†’ false // Dot files rematch("*.js", ".hidden.js"); // β†’ false rematch("*.js", ".hidden.js", { dot: true }); // β†’ true // Case-insensitive matching rematch("*.JS", "file.js", { nocase: true }); // β†’ true // Character classes rematch("[abc].js", "a.js"); // β†’ true rematch("[!a-z].js", "9.js"); // β†’ true // Brace expansion rematch("file.{js,ts}", "file.js"); // β†’ true rematch("file{1..3}.js", "file2.js"); // β†’ true rematch("file{01..03}.js", "file01.js"); // β†’ true // Multiple patterns and negation rematch(["*.js", "!test.js"], "file.js"); // β†’ true rematch(["*.js", "!file.js"], "file.js"); // β†’ false // Ignore option rematch("*.js", "file.js", { ignore: "file.js" }); // β†’ false rematch(["*.js", "!test.js"], "test.js", { ignore: "test.js" }); // β†’ false // Compiled matcher const matcher = compile("**/*.{js,ts}"); matcher("src/file.js"); // β†’ true matcher("deep/nested/file.ts"); // β†’ true // Path normalization (for Windows paths) rematch("src/*.js", "src\\file.js"); // β†’ true normalizePath("src\\file.js"); // β†’ "src/file.js" // Utility: escape/unescape rematch(escapeGlob("file[1].js"), "file[1].js"); // β†’ true unescapeGlob("file\\[1\\].js"); // β†’ "file[1].js" // Utility: isStatic, scan, explode isStatic("file.js"); // β†’ true isStatic("*.js"); // β†’ false scan("!src/*.js"); // β†’ { isGlob: true, negated: true, glob: "src/*.js" } explode("src/file[1-3].js"); // β†’ { static: ["src/file"], dynamic: ["[1-3].js"] } ``` ## Playground To test [example/e-mod.ts](./example/e-mod.ts), run: ```bash git clone https://github.com/reliverse/rematch cd rematch bun i bun dev # beginner-friendly example bun tests # advanced test suite ``` ## Contributing - πŸ§™ Star it on [GitHub](https://github.com/reliverse/rematch) - πŸ’¬ Join our [Discord](https://discord.gg/reliverse) - πŸ’– [Sponsor @blefnk](https://github.com/sponsors/blefnk) ## Related Reliverse Projects - [`@reliverse/reglob`](https://npmjs.com/package/@reliverse/reglob) β€” Tiny, fast globber - [`@reliverse/relifso`](https://npmjs.com/package/@reliverse/relifso) β€” Filesystem made fun again - [`@reliverse/repackr`](https://npmjs.com/package/@reliverse/repackr) β€” Alternative to tar/7zip ## License πŸ’– [MIT](./LICENSE) Β© [blefnk (Nazar Kornienko)](https://github.com/blefnk)