# core/validators/leak.validator.ts

> 53 lines of code and 12 definitions.

Tree: Bane's Lab Content
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/content#file-content-core-validators-leak-validator-ts
Source text: https://banes-lab.com/source/content/core/validators/leak.validator.ts.txt

Listed in [core/validators](https://banes-lab.com/api/source/content/core/validators.md), after [core/validators/evidence.validator.ts](https://banes-lab.com/source/content/core/validators/evidence.validator.ts.md) and before [core/validators/link.validator.ts](https://banes-lab.com/source/content/core/validators/link.validator.ts.md).

## Definitions

- `validatePayload` (lexical_declaration, line 40, exported)
- `validatePublished` (lexical_declaration, line 18, exported)
- `NEWLINE` (lexical_declaration, line 12)
- `lineAt` (lexical_declaration, line 14)
- `terms` (lexical_declaration, line 23, exported)
- `paths` (lexical_declaration, line 27, exported)
- `at` (lexical_declaration, line 28, exported)
- `REASON_LEADS` (lexical_declaration, line 34)
- `tokens` (lexical_declaration, line 45, exported)
- `findings` (lexical_declaration, line 46, exported)
- `seen` (lexical_declaration, line 47, exported)
- `key` (lexical_declaration, line 50, exported)

## Contained in

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

## Uses

- [core/matchers/leak.matcher.ts](https://banes-lab.com/source/content/core/matchers/leak.matcher.ts.md)

## Used by

- [runtime/entrypoints/leak.entrypoint.ts](https://banes-lab.com/source/content/runtime/entrypoints/leak.entrypoint.ts.md)

## Linked from

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

## Source

```typescript
import {
    LEAK_IDENTIFIER,
    LEAK_INLINE,
    LEAK_PATH,
    machinePathLine,
    privateTermLine,
} from "#configuration/strings/coverage.strings";
import type { LeakReason, LeakSet, PagePayload, PrivateHit, PublishedFile } from "#types/leak.types";
import type { Finding } from "#types/derivation.types";
import { leaksIn } from "#core/matchers/leak.matcher";

const NEWLINE = "\n";

const lineAt = function lineAt(text: string, at: number): number {
    return text.slice(0, at).split(NEWLINE).length;
};

export const validatePublished = function validatePublished(
    published: PublishedFile,
    scan: (text: string) => PrivateHit[],
    machinePaths: readonly string[],
): Finding[] {
    const terms = scan(published.text).map((hit) => ({
        file: published.file,
        message: privateTermLine(hit.line, hit.digest),
    }));
    const paths = machinePaths.flatMap((path) => {
        const at = published.text.indexOf(path);
        return at === -1 ? [] : [{ file: published.file, message: machinePathLine(lineAt(published.text, at)) }];
    });
    return [...terms, ...paths];
};

const REASON_LEADS: Readonly<Record<LeakReason, string>> = {
    identifier: LEAK_IDENTIFIER,
    "inline-code": LEAK_INLINE,
    path: LEAK_PATH,
};

export const validatePayload = function validatePayload(
    payload: PagePayload,
    leaks: LeakSet,
    roots: ReadonlySet<string>,
): Finding[] {
    const tokens = new Set(leaks.tokens);
    const findings: Finding[] = [];
    const seen = new Set<string>();
    for (const text of payload.strings) {
        for (const match of leaksIn(text, tokens, roots)) {
            const key = match.reason + match.token;
            if (!seen.has(key)) {
                seen.add(key);
                findings.push({ file: payload.file, message: `${REASON_LEADS[match.reason]}${match.token}` });
            }
        }
    }
    return findings;
};
```
