# shared/matchers/pattern.matcher.ts

> 24 lines of code and 7 definitions.

Tree: Governance tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/governance#file-governance-shared-matchers-pattern-matcher-ts
Source text: https://banes-lab.com/source/governance/shared/matchers/pattern.matcher.ts.txt

Listed in [shared/matchers](https://banes-lab.com/api/source/governance/shared/matchers.md), after [shared/matchers/location.matcher.ts](https://banes-lab.com/source/governance/shared/matchers/location.matcher.ts.md) and before [shared/matchers/segment.matcher.ts](https://banes-lab.com/source/governance/shared/matchers/segment.matcher.ts.md).

## Definitions

- `matchesPattern` (lexical_declaration, line 3, exported)
- `WILDCARD` (lexical_declaration, line 1)
- `parts` (lexical_declaration, line 4, exported)
- `first` (lexical_declaration, line 8, exported)
- `last` (lexical_declaration, line 9, exported)
- `cursor` (lexical_declaration, line 16, exported)
- `at` (lexical_declaration, line 18, exported)

## Used by

- [shared/manifests/taxonomy.manifest.ts](https://banes-lab.com/source/governance/shared/manifests/taxonomy.manifest.ts.md)

## Source

```typescript
const WILDCARD = "*";

export const matchesPattern = function matchesPattern(pattern: string, name: string): boolean {
    const parts = pattern.split(WILDCARD);
    if (parts.length === 1) {
        return pattern === name;
    }
    const first = parts[0] ?? "";
    const last = parts.at(-1) ?? "";
    if (!name.startsWith(first) || !name.endsWith(last)) {
        return false;
    }
    if (name.length < first.length + last.length) {
        return false;
    }
    let cursor = first.length;
    for (const middle of parts.slice(1, -1)) {
        const at = name.indexOf(middle, cursor);
        if (at === -1 || at + middle.length > name.length - last.length) {
            return false;
        }
        cursor = at + middle.length;
    }
    return true;
};
```
