# core/matchers/exclusions.matcher.ts

> 62 lines of code and 21 definitions.

Tree: GovLab Quality
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-matchers-exclusions-matcher-ts
Source text: https://banes-lab.com/source/quality/core/matchers/exclusions.matcher.ts.txt

Listed in [core/matchers](https://banes-lab.com/api/source/quality/core/matchers.md), after [core/matchers/context.matcher.ts](https://banes-lab.com/source/quality/core/matchers/context.matcher.ts.md) and before [core/matchers/target.matcher.ts](https://banes-lab.com/source/quality/core/matchers/target.matcher.ts.md).

## Definitions

- `isExcludedPath` (lexical_declaration, line 45, exported)
- `pathExclusion` (lexical_declaration, line 61, exported)
- `matchesRunAt` (lexical_declaration, line 38)
- `matchesSegment` (lexical_declaration, line 17)
- `SEPARATOR` (lexical_declaration, line 4)
- `WILDCARD` (lexical_declaration, line 5)
- `PARENT` (lexical_declaration, line 6)
- `CURRENT` (lexical_declaration, line 7)
- `segmentsOf` (lexical_declaration, line 9)
- `parts` (lexical_declaration, line 18)
- `[head = ""]` (lexical_declaration, line 19)
- `cursor` (lexical_declaration, line 26)
- `at` (lexical_declaration, line 28)
- `tail` (lexical_declaration, line 34)
- `segment` (lexical_declaration, line 40)
- `path` (lexical_declaration, line 46, exported)
- `run` (lexical_declaration, line 48, exported)
- `start` (lexical_declaration, line 52, exported)
- `rel` (lexical_declaration, line 63, exported)
- `[first]` (lexical_declaration, line 64, exported)
- `outside` (lexical_declaration, line 65, exported)

## Contained in

- [core/matchers](https://banes-lab.com/anatomy/quality/folder-quality-core-matchers.md)

## Uses

- [core/validators/css.viewport.validator.ts](https://banes-lab.com/source/quality/core/validators/css.viewport.validator.ts.md)

## Used by

- [core/factories/exclusions.factory.ts](https://banes-lab.com/source/quality/core/factories/exclusions.factory.ts.md)
- [core/predicates/coverage.predicate.ts](https://banes-lab.com/source/quality/core/predicates/coverage.predicate.ts.md)
- [core/resolvers/scope.resolver.ts](https://banes-lab.com/source/quality/core/resolvers/scope.resolver.ts.md)

## Linked from

- [core/factories](https://banes-lab.com/anatomy/quality/folder-quality-core-factories.md)
- [core/matchers](https://banes-lab.com/anatomy/quality/folder-quality-core-matchers.md)
- [core/predicates](https://banes-lab.com/anatomy/quality/folder-quality-core-predicates.md)
- [core/resolvers](https://banes-lab.com/anatomy/quality/folder-quality-core-resolvers.md)
- [core/validators](https://banes-lab.com/anatomy/quality/folder-quality-core-validators.md)

## Source

```typescript
import { basename, isAbsolute, relative } from "node:path";
import type { PathExclusion } from "#types/exclusions.types";

const SEPARATOR = "/";
const WILDCARD = "*";
const PARENT = "..";
const CURRENT = ".";

const segmentsOf = function segmentsOf(path: string): string[] {
    return path
        .split("\\")
        .join(SEPARATOR)
        .split(SEPARATOR)
        .filter((segment) => segment.length > 0 && segment !== CURRENT);
};

const matchesSegment = function matchesSegment(text: string, marker: string): boolean {
    const parts = marker.split(WILDCARD);
    const [head = ""] = parts;
    if (parts.length === 1) {
        return text === marker;
    }
    if (!text.startsWith(head)) {
        return false;
    }
    let cursor = head.length;
    for (const part of parts.slice(1)) {
        const at = part === "" ? cursor : text.indexOf(part, cursor);
        if (at === -1) {
            return false;
        }
        cursor = at + part.length;
    }
    const tail = parts.at(-1) ?? "";
    return tail === "" || text.endsWith(tail);
};

const matchesRunAt = function matchesRunAt(path: readonly string[], marker: readonly string[], start: number): boolean {
    return marker.every((part, offset) => {
        const segment = path[start + offset];
        return segment !== undefined && matchesSegment(segment, part);
    });
};

export const isExcludedPath = function isExcludedPath(relPath: string, markers: readonly string[]): boolean {
    const path = segmentsOf(relPath);
    return markers.some((marker) => {
        const run = segmentsOf(marker);
        if (run.length === 0) {
            return false;
        }
        for (let start = 0; start + run.length <= path.length; start += 1) {
            if (matchesRunAt(path, run, start)) {
                return true;
            }
        }
        return false;
    });
};

export const pathExclusion = function pathExclusion(root: string, markers: readonly string[]): PathExclusion {
    return (target: string): boolean => {
        const rel = isAbsolute(target) ? relative(root, target) : target;
        const [first] = segmentsOf(rel);
        const outside = first === PARENT || isAbsolute(rel);
        return isExcludedPath(outside ? basename(target) : rel, markers);
    };
};
```
