# core/validators/dependency.validator.ts

> 44 lines of code and 10 definitions.

Tree: Project Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/scripts#file-scripts-core-validators-dependency-validator-ts
Source text: https://banes-lab.com/source/scripts/core/validators/dependency.validator.ts.txt

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

## Definitions

- `pendingOf` (lexical_declaration, line 13)
- `hoistVerdict` (lexical_declaration, line 33, exported)
- `installScriptVerdict` (lexical_declaration, line 41, exported)
- `parsed` (lexical_declaration, line 14)
- `labelOf` (lexical_declaration, line 22)
- `changes` (lexical_declaration, line 23)
- `keys` (lexical_declaration, line 24)
- `key` (lexical_declaration, line 26)
- `pending` (lexical_declaration, line 42, exported)
- `lines` (lexical_declaration, line 46, exported)

## Contained in

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

## Uses

- [configuration/strings/dependency.strings.ts](https://banes-lab.com/source/scripts/configuration/strings/dependency.strings.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/scripts/folder-scripts-configuration-strings.md)

## Source

```typescript
import {
    EVERY_SCRIPT_DECIDED,
    HOIST_REMEDY,
    ONE_HOIST_HELD,
    REVIEW_REMEDY,
    hoistBreachHeading,
    missingAllowScripts,
    undecidedHeading,
} from "#configuration/strings/dependency.strings";
import type { CheckVerdict } from "#types/validation.types";
import { isRecord } from "@banes-lab/build-scripts/core/selectors/base.selector.ts";

const pendingOf = function pendingOf(output: string): readonly unknown[] {
    const parsed: unknown = JSON.parse(output);
    const pending = isRecord(parsed) ? parsed["allowScripts"] : null;
    if (!Array.isArray(pending)) {
        throw new TypeError(missingAllowScripts(output));
    }
    return pending;
};

const labelOf = function labelOf(entry: unknown): string {
    const changes = isRecord(entry) ? entry["changes"] : null;
    const keys = Array.isArray(changes)
        ? changes.flatMap((change) => {
              const key = isRecord(change) ? change["key"] : null;
              return typeof key === "string" ? [key] : [];
          })
        : [];
    return keys.length > 0 ? keys.join(", ") : JSON.stringify(entry);
};

export const hoistVerdict = function hoistVerdict(breaches: readonly string[]): CheckVerdict {
    if (breaches.length === 0) {
        return { held: true, text: ONE_HOIST_HELD };
    }
    const lines = breaches.map((breach) => `  ${breach}`);
    return { held: false, text: [hoistBreachHeading(breaches.length), ...lines, HOIST_REMEDY, ""].join("\n") };
};

export const installScriptVerdict = function installScriptVerdict(listing: string): CheckVerdict {
    const pending = pendingOf(listing);
    if (pending.length === 0) {
        return { held: true, text: EVERY_SCRIPT_DECIDED };
    }
    const lines = pending.map((entry) => `  ${labelOf(entry)}`);
    return { held: false, text: [undecidedHeading(pending.length), ...lines, REVIEW_REMEDY, ""].join("\n") };
};
```
