# core/classifiers/invocation.classifier.ts

> 36 lines of code and 7 definitions.

Tree: GovLab Quality
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-classifiers-invocation-classifier-ts
Source text: https://banes-lab.com/source/quality/core/classifiers/invocation.classifier.ts.txt

Listed in [core/classifiers](https://banes-lab.com/api/source/quality/core/classifiers.md), after [core/classifiers/concern.classifier.ts](https://banes-lab.com/source/quality/core/classifiers/concern.classifier.ts.md).

## Definitions

- `failedWhenEmpty` (lexical_declaration, line 24, exported)
- `failedOnStatus` (lexical_declaration, line 30, exported)
- `passOf` (lexical_declaration, line 34, exported)
- `exitOf` (lexical_declaration, line 13, exported)
- `terminalOf` (lexical_declaration, line 17, exported)
- `terminal` (lexical_declaration, line 35, exported)
- `findings` (lexical_declaration, line 39, exported)

## Contained in

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

## Uses

- [core/factories/finding.factory.ts](https://banes-lab.com/source/quality/core/factories/finding.factory.ts.md)
- [core/predicates/failure.predicate.ts](https://banes-lab.com/source/quality/core/predicates/failure.predicate.ts.md)

## Used by

- [core/adapters/tool.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.adapter.ts.md)
- [core/adapters/tool.golangci-lint.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.golangci-lint.adapter.ts.md)
- [core/adapters/tool.oxlint.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.oxlint.adapter.ts.md)
- [core/adapters/tool.sqlfluff.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.sqlfluff.adapter.ts.md)

## Linked from

- [core/adapters](https://banes-lab.com/anatomy/quality/folder-quality-core-adapters.md)
- [core/classifiers](https://banes-lab.com/anatomy/quality/folder-quality-core-classifiers.md)
- [core/factories](https://banes-lab.com/anatomy/quality/folder-quality-core-factories.md)
- [core/predicates](https://banes-lab.com/anatomy/quality/folder-quality-core-predicates.md)

## Source

```typescript
import type { AdvisoryContext, ScanSpec, ToolExit, ToolSpawn } from "#types/tool.types";
import type { Finding, PassOutcome, RunResult } from "#types/finding.types";
import { isNotFound, signalKilled, statusIn } from "#core/predicates/failure.predicate";
import {
    notInstalled,
    reportedPass,
    signalDeathResult,
    spawnFailure,
    terminatedPass,
} from "#core/factories/finding.factory";
import { UNKNOWN_STATUS } from "#configuration/constants/tool.constants";

export const exitOf = function exitOf(result: ToolSpawn): ToolExit {
    return { status: result.status ?? UNKNOWN_STATUS, stderr: result.stderr, stdout: result.stdout };
};

export const terminalOf = function terminalOf(advisory: AdvisoryContext, result: ToolSpawn): RunResult | null {
    if (result.error) {
        return isNotFound(result.error) ? notInstalled(advisory) : spawnFailure(advisory, result.error);
    }
    return signalKilled(result.status) ? signalDeathResult(advisory, result.signal) : null;
};

export const failedWhenEmpty = function failedWhenEmpty(
    statuses: ReadonlySet<number>,
): (result: ToolSpawn, findings: readonly Finding[]) => boolean {
    return (result, findings) => findings.length === 0 && !statusIn(statuses, result.status);
};

export const failedOnStatus = function failedOnStatus(statuses: ReadonlySet<number>): (result: ToolSpawn) => boolean {
    return (result) => !statusIn(statuses, result.status);
};

export const passOf = function passOf(advisory: AdvisoryContext, result: ToolSpawn, spec: ScanSpec): PassOutcome {
    const terminal = terminalOf(advisory, result);
    if (terminal !== null) {
        return terminatedPass(terminal);
    }
    const findings = spec.parse(result);
    return spec.failed(result, findings) ? terminatedPass(spec.failure(exitOf(result))) : reportedPass(findings);
};
```
