{"id":13847068,"url":"https://github.com/axtgr/outmatch","last_synced_at":"2025-09-14T05:31:12.028Z","repository":{"id":57316924,"uuid":"278003245","full_name":"axtgr/outmatch","owner":"axtgr","description":"An extremely fast and lightweight glob-matching library for JavaScript with advanced features","archived":false,"fork":false,"pushed_at":"2024-04-11T15:09:35.000Z","size":1297,"stargazers_count":30,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-09T12:51:32.854Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/axtgr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.buymeacoffee.com/axtgr"]}},"created_at":"2020-07-08T06:00:39.000Z","updated_at":"2025-03-02T20:46:47.000Z","dependencies_parsed_at":"2024-01-15T20:47:40.088Z","dependency_job_id":"25ff8c15-cb94-4882-8178-54df778a3a9c","html_url":"https://github.com/axtgr/outmatch","commit_stats":{"total_commits":152,"total_committers":1,"mean_commits":152.0,"dds":0.0,"last_synced_commit":"847e76d2c9fdae827de000353af8984d73b849aa"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/axtgr/outmatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axtgr%2Foutmatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axtgr%2Foutmatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axtgr%2Foutmatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axtgr%2Foutmatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axtgr","download_url":"https://codeload.github.com/axtgr/outmatch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axtgr%2Foutmatch/sbom","scorecard":{"id":220315,"data":{"date":"2025-08-11","repo":{"name":"github.com/axtgr/outmatch","commit":"f733d6dc8030558148f1f53cd4595630d9adb5c1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/publish.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/axtgr/outmatch/release.yml/master?enable=pin","Info:   0 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: ISC License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'master'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'master'","Warn: PRs are not required to make changes on branch 'master'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":4,"reason":"6 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T02:19:33.547Z","repository_id":57316924,"created_at":"2025-08-17T02:19:33.547Z","updated_at":"2025-08-17T02:19:33.547Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275063184,"owners_count":25398931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-14T02:00:10.474Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T18:00:53.556Z","updated_at":"2025-09-14T05:31:11.670Z","avatar_url":"https://github.com/axtgr.png","language":"JavaScript","funding_links":["https://www.buymeacoffee.com/axtgr"],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cbr\u003e\n\n\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.png\" width=\"300\" height=\"69\" alt=\"Outmatch\"\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eAn extremely fast and lightweight glob-matching library for JavaScript with advanced features\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/outmatch\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/outmatch\" alt=\"npm package\"\u003e\u003c/a\u003e\n  \u0026nbsp;\n  \u003ca href=\"https://github.com/axtgr/outmatch/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/axtgr/outmatch/ci.yml?label=CI\u0026logo=github\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u0026nbsp;\n  \u003ca href=\"https://www.buymeacoffee.com/axtgr\"\u003e\u003cimg src=\"https://img.shields.io/badge/%F0%9F%8D%BA-Buy%20me%20a%20beer-red?style=flat\" alt=\"Buy me a beer\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\nOutmatch takes one or more glob patterns, compiles them into a RegExp and returns a function for matching strings with it.\n\nGlob patterns are strings that contain wildcards such as `*`, `?`, `[abc]` and others. When such a pattern is compared with another string, these wildcards can replace one or more symbols. For example, `src/*` would match both `src/foo` and `src/bar`.\n\nWhile globs are usually used to search file paths separated by slashes, with outmatch it is possible to match _arbitrary_ strings, whether separated or not.\n\n## Quickstart\n\n```\nnpm install outmatch\n```\n\n```js\nimport outmatch from 'outmatch'\n\nconst isMatch = outmatch('src/**/*.{js,ts}')\n\nisMatch('src/components/header/index.js') //=\u003e true\nisMatch('src/README.md') //=\u003e false\n\nisMatch.pattern //=\u003e 'src/**/*.{js,ts}'\nisMatch.options //=\u003e { separator: true }\nisMatch.regexp //=\u003e /^(?:src[/\\\\]+? ... \\.ts[/\\\\]*?)$/\n```\n\nMore details are available in the [Installation](#installation), [Usage](#usage), [Syntax](#syntax) and [API](#api) sections.\n\n## Features\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e🍃\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eLightweight\u003c/strong\u003e\u003cbr\u003eNo dependencies. Just 2.4\u0026nbsp;KB when minified and gzipped — less than ⅓\u0026nbsp;of\u0026nbsp;picomatch and ⅕\u0026nbsp;of\u0026nbsp;micromatch\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e💪\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003ePowerful\u003c/strong\u003e\u003cbr\u003eSupports basic and extended globbing, proper multi-pattern compilation and custom path separators — a\u0026nbsp;feature unique to\u0026nbsp;outmatch\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e🎯\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eAccurate\u003c/strong\u003e\u003cbr\u003eThe only library that can handle negated extglobs correctly. Actually expands braces instead of merely converting them to groups\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e🏎\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eFast\u003c/strong\u003e\u003cbr\u003eCompiles and matches patterns faster than minimatch, micromatch and picomatch\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e⚒\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eReliable\u003c/strong\u003e\u003cbr\u003eWritten in TypeScript. Covered by thousands of unit tests\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e🌞\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eSimple\u003c/strong\u003e\u003cbr\u003eThe API is a single function. Options can be specified in easy to understand language rather than Linux slang\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e🔌\u003c/td\u003e\n    \u003ctd\u003e\u003cstrong\u003eCompatible\u003c/strong\u003e\u003cbr\u003eWorks in any ES5 environment including older versions of Node.js, Deno, Bun, React Native and browsers\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nFor comparison with the alternatives, see the [corresponding section](#comparison).\n\n## Installation\n\nThe package is distributed via the npm package registry. It can be installed using one of the compatible package managers or included directly from a CDN.\n\n#### [npm](https://www.npmjs.com)\n\n```\nnpm install outmatch\n```\n\n#### [Yarn](https://yarnpkg.com)\n\n```\nyarn add outmatch\n```\n\n#### [pnpm](https://pnpm.js.org)\n\n```\npnpm install outmatch\n```\n\n#### CDN\n\nWhen included from a CDN, outmatch is available as the global function `outmatch`.\n\n- [unpkg](https://unpkg.com/outmatch)\n- [jsDelivr](https://www.jsdelivr.com/package/npm/outmatch)\n\n## Usage\n\nOutmatch comes built in ESM, CommonJS and UMD formats and includes TypeScript typings. The examples use ESM imports, which can be replaced with the following line for CommonJS: `const outmatch = require('outmatch')`.\n\nThe default export is a function of two arguments, first of which can be either a single glob string or an array of such patterns. The second argument is optional and can be either an [options](#options) object or a separator (which will be the value of the `separator` option). Outmatch compiles them into a regular expression and returns a function (usually called `isMatch` in the examples) that tests strings against the pattern. The pattern, options and the compiled RegExp object are available as properties on the returned function:\n\n```js\nimport outmatch from 'outmatch'\n\nconst isMatch = outmatch('src/[bc]ar', { '{}': false })\n\nisMatch('src/bar') //=\u003e true\nisMatch('src/car') //=\u003e true\nisMatch('src/tar') //=\u003e false\n\nisMatch.pattern //=\u003e 'src/[bc]ar'\nisMatch.options //=\u003e { '{}': false }\nisMatch.regexp //=\u003e /^src[/\\\\]+?(?!\\.)(?![/\\\\])[bc]ar[/\\\\]*?$/\n```\n\nThe returned function can be invoked immediately if there is no need to match a pattern more than once:\n\n```js\noutmatch('src/**/*.js')('src/components/body/index.js') //=\u003e true\n```\n\nCompiling a pattern is much slower than comparing a string to it, so it is recommended to always reuse the returned function when possible.\n\n### File Paths and Separators\n\nGlobs are most often used to search file paths, which are, essentially, strings split into segments by slashes. While other libraries\nare usually restricted to this use-case, outmatch is able to work with _arbitrary_ strings by accepting a custom separator via the second argument:\n\n```js\nconst matchDomain = outmatch('*.example.com', { separator: '.' })\nmatchDomain('subdomain.example.com') //=\u003e true\n\nconst matchLike = outmatch('wh?t like**like mean', 'like') // shorthand for { separator: 'like' }\nmatchLike('what like do like you like mean') //=\u003e true\n```\n\nThe only limitation is that backslashes `\\` cannot be used as separators in patterns because\noutmatch uses them for character escaping. However, when `separator` is `undefined` or `true`,\n`/` in patterns will match both `/` and `\\`, so a single pattern with forward slashes\ncan match both Unix and Windows paths:\n\n```js\nconst isMatchA = outmatch('foo\\\\bar') // throws an error\n\nconst isMatchB = outmatch('foo/bar') // same as passing `true` as the separator\n\nisMatchB('foo/bar') //=\u003e true\nisMatchB('foo\\\\bar') //=\u003e true\n\nconst isMatchC = outmatch('foo/bar', '/')\n\nisMatchC('foo/bar') //=\u003e true\nisMatchC('foo\\\\bar') //=\u003e false\n```\n\nA thing to note is that most matching features work with a _segment_ rather than a whole pattern. For example, `foo/b*` will match `foo/bar`\nbut not `foo/b/ar`. The two exceptions to this are _brace expansion_ and _pattern negation_, both of which work with whole patterns:\n\n```js\noutmatch('src/{foo/bar,baz}')('src/foo/bar') //=\u003e true (brace expansion)\noutmatch('src/@(foo/bar|baz)')('src/foo/bar') //=\u003e false (extglob)\n```\n\nAny string that contains a segment starting with a dot (a dotfile) is excluded unless the dot is specified explicitly in the pattern.\nThis behavior can be disabled by setting `excludeDot` to `false`, in which case leading dots are treated like any other symbol:\n\n```js\noutmatch('project/*')('project/.git') //=\u003e false\noutmatch('project/.*')('project/.git') //=\u003e true (dot is specified explicitly)\noutmatch('project/*', { excludeDot: false })('project/.git') //=\u003e true\n```\n\nSegmentation can be turned off completely by passing `false` as the separator, which makes outmatch treat whole patterns as a single segment.\nSlashes become regular symbols, `**` works identically to `*` and leading dots get excluded only when they are the very first character of a pattern:\n\n```js\nconst isMatch = outmatch('foo?ba*', false)\nisMatch('foo/bar/.qux') //=\u003e true\n```\n\nA single separator in a pattern will match any number of separators in a sample string:\n\n```js\noutmatch('foo/bar/baz')('foo/bar///baz') //=\u003e true\n```\n\nWhen a pattern has an explicit separator at its end, samples also require one or more trailing separators:\n\n```js\nconst isMatch = outmatch('foo/bar/')\n\nisMatch('foo/bar') //=\u003e false\nisMatch('foo/bar/') //=\u003e true\nisMatch('foo/bar///') //=\u003e true\n```\n\nHowever, if there is no trailing separator in a pattern, strings will match even if they have separators at the end:\n\n```js\nconst isMatch = outmatch('foo/bar')\n\nisMatch('foo/bar') //=\u003e true\nisMatch('foo/bar/') //=\u003e true\nisMatch('foo/bar///') //=\u003e true\n```\n\n### Multiple Patterns\n\nOutmatch can take an array of glob patterns as the first argument instead of a single pattern. In that case a string will be considered a match if it matches _any_ of the given patterns:\n\n```js\nconst isMatch = outmatch(['src/*', 'tests/*'])\n\nisMatch('src/utils.js') //=\u003e true\nisMatch('tests/utils.js') //=\u003e true\n```\n\nIf a [negated](#negation) pattern is given among positive patterns, it will work as an ignore filter for strings that match the positive patterns:\n\n```js\nconst isMatch = outmatch(['src/*', '!src/foo', '!src/bar'])\n\nisMatch('src/foo') //=\u003e false\nisMatch('src/bar') //=\u003e false\nisMatch('src/baz') //=\u003e true\n```\n\n### Matching Arrays of Strings\n\nThe returned function can work with arrays of strings when used as the predicate of the native array methods:\n\n```js\nconst isMatch = outmatch(['src/**/*.js', '!**/body.js'])\nconst paths = ['readme.md', 'src/index.js', 'src/components/body.js']\n\npaths.map(isMatch) //=\u003e [ false, true, false ]\npaths.filter(isMatch) //=\u003e [ 'src/index.js' ]\npaths.some(isMatch) //=\u003e true\npaths.every(isMatch) //=\u003e false\npaths.find(isMatch) //=\u003e 'src/index.js'\npaths.findIndex(isMatch) //=\u003e 1\n```\n\n## Syntax\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003ePattern\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eBasic Wildcards\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e?\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches exactly one arbitrary character excluding separators\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e*\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches zero or more arbitrary characters excluding separators\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eGlobstar\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e**\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches zero or more segments when used as a whole segment in a separated pattern (e.g. \u003ccode\u003e/**/\u003c/code\u003e if \u003ccode\u003e/\u003c/code\u003e is the separator)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eCharacter Classes (Brackets)\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e[abc1_]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches a single character from the specified list of characters\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e[a-z]\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e[0-9]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches a single character from the specified range of characters\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e[!abc]\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e[!f-k]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches a single character \u003cem\u003enot\u003c/em\u003e in the specified list or range\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e[[:alnum:]]\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e[[:alpha:]]\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e[[:lower:]]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ePOSIX classes are not supported. Other libraries claim to have support, but in reality it's just a gimmick.\u003cbr\u003e\u003cbr\u003eTheir original purpose was to match symbols from the current locale rather than just English. For example, \u003ccode\u003e[[:alpha:]]\u003c/code\u003e would match the russian letter \u003ccode\u003eы\u003c/code\u003e while \u003ccode\u003e[a-zA-Z]\u003c/code\u003e would not. However, making this work in JS is non-trivial, and most libraries that list POSIX classes as supported merely have them as aliases to regular character ranges, so \u003ccode\u003e[[:alpha:]]\u003c/code\u003e works identically to \u003ccode\u003e[a-zA-Z]\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"3\"\u003e\u003ch4\u003eExtglobs (Parens)\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e@(bar|baz)\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches one of the given subpatterns repeated exactly one time\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e?(foo)\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e?(bar|baz)\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches one of the given subpatterns repeated zero or one time\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e*(foo)\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e*(bar|baz)\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches one of the given subpatterns repeated zero or more times\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e+(foo)\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e+(bar|baz)\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches one of the given subpatterns repeated one or more times\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e!(foo)\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e!(bar|baz)\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches anything except the given subpatterns. Cannot be nested inside another negated glob\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eBraces\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e{bar,baz}\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eExpands the pattern to an array of patterns, so \u003ccode\u003eoutmatch('src/{foo,bar}/baz')\u003c/code\u003e is equivalent to \u003ccode\u003eoutmatch(['src/foo/baz', 'src/bar/baz'])\u003c/code\u003e\u003cbr\u003e\u003cbr\u003eWhile braces are similar to extglobs, they work differently. Braces are expanded \u003cem\u003ebefore anything else\u003c/em\u003e, so, unlike extglobs, they can handle subpatterns that contain separators.\u003cbr\u003e\u003cbr\u003eBraces can be nested: \u003ccode\u003esrc/{foo,bar/{baz,qux}}\u003c/code\u003e expands to \u003ccode\u003esrc/foo\u003c/code\u003e, \u003ccode\u003esrc/bar/baz\u003c/code\u003e and \u003ccode\u003esrc/bar/qux\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e{1..5}\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eMatches any character in the specified range\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e{01..300}\u003c/code\u003e\u003cbr\u003e\u003ccode\u003e{1..9..2}\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eLike most other libraries, outmatch doesn't support zero-padded and stepped ranges. The amount of code it would take to implement them is simply not justified by how rarely they are used\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eNegation\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e!\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eNegates a pattern when put at the start of it. If repeated multiple times, each \u003ccode\u003e!\u003c/code\u003e will invert the effect, so \u003ccode\u003e!!foo/bar\u003c/code\u003e is the same as \u003ccode\u003efoo/bar\u003c/code\u003e and \u003ccode\u003e!!!baz/qux\u003c/code\u003e is the same as \u003ccode\u003e!baz/qux\u003c/code\u003e.\u003cbr\u003e\u003cbr\u003eA negated pattern matches any string that doesn't match the part after the \u003ccode\u003e!\u003c/code\u003e. When put in an array among positive patterns, negated patterns effectively work as ignores\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"2\"\u003e\u003ch4\u003eEscaping\u003c/h4\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e\\\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eEscapes the following character making it be treated literally\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## API\n\n### outmatch(patterns, options?): isMatch\u003cbr\u003eoutmatch(patterns, separator?): isMatch\n\nTakes a single pattern string or an array of patterns and compiles them into a regular expression. Returns an isMatch function that takes a sample string as its only argument and returns true if the string matches the pattern(s).\n\n### isMatch(sample): boolean\n\nTests if a sample string matches the patterns that were used to compile the regular expression and create this function.\n\n### isMatch.regexp\n\nThe compiled regular expression.\n\n### isMatch.pattern\n\nThe original pattern or array of patterns that was used to compile the regular expression and create the isMatch function.\n\n### isMatch.options\n\nThe options object that was used to compile the regular expression and create the isMatch function.\n\n### Options\n\n| Option       | Type                        | Default Value | Description                                                                                                                                                                                                                       |\n| ------------ | --------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `separator`  | string\u0026nbsp;\\|\u0026nbsp;boolean | true          | Separator to be used to split patterns and samples into segments:\u003cul\u003e\u003cli\u003e`true` — `/` in patterns match both `/` and `\\` in samples\u003cli\u003e`false` — don't split\u003cli\u003e_any string_ — custom separator                                   |\n| `flags`      | string                      | undefined     | [Flags](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags) to pass to the RegExp. For example, setting this option to `'i'` will make the matching case-insensitive |\n| `excludeDot` | boolean                     | true          | Toggles whether to exclude strings that contain segments starting with a dot                                                                                                                                                      |\n| `!`          | boolean                     | true          | Toggles pattern negation                                                                                                                                                                                                          |\n| `?`          | boolean                     | true          | Toggles single-char wildcards                                                                                                                                                                                                     |\n| `*`          | boolean                     | true          | Toggles multi-char wildcards                                                                                                                                                                                                      |\n| `**`         | boolean                     | true          | Toggles globstars                                                                                                                                                                                                                 |\n| `[]`         | boolean                     | true          | Toggles character classes                                                                                                                                                                                                         |\n| `()`         | boolean                     | true          | Toggles extglobs                                                                                                                                                                                                                  |\n| `{}`         | boolean                     | true          | Toggles brace expansion                                                                                                                                                                                                           |\n\n## Comparison\n\n```\nPattern: src/test/**/*.?s\nSample: src/test/foo/bar.js\n\nCompilation\n  outmatch     650,098 ops/sec\n  picomatch    136,927 ops/sec\n\nMatching\n  outmatch     34,524,204 ops/sec\n  picomatch    10,223,739 ops/sec\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxtgr%2Foutmatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxtgr%2Foutmatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxtgr%2Foutmatch/lists"}