# core/validators/diagram.validator.ts

> 44 lines of code and 9 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-validators-diagram-validator-ts
Source text: https://banes-lab.com/source/docs/core/validators/diagram.validator.ts.txt

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

## Definitions

- `check` (method_definition, line 31, exported)
- `parseBlocks` (lexical_declaration, line 8)
- `createMermaidChecker` (lexical_declaration, line 28, exported)
- `validateCharts` (lexical_declaration, line 16, exported)
- `findings` (lexical_declaration, line 10)
- `message` (lexical_declaration, line 11)
- `hardening` (lexical_declaration, line 17, exported)
- `state` (lexical_declaration, line 29, exported)
- `parser` (lexical_declaration, line 36, exported)

## Contained in

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

## Uses

- [configuration/strings/diagram.strings.ts](https://banes-lab.com/source/docs/configuration/strings/diagram.strings.ts.md)
- [core/adapters/diagram.adapter.ts](https://banes-lab.com/source/docs/core/adapters/diagram.adapter.ts.md)
- [core/parsers/diagram.parser.ts](https://banes-lab.com/source/docs/core/parsers/diagram.parser.ts.md)
- [core/reporters/base.reporter.ts](https://banes-lab.com/source/docs/core/reporters/base.reporter.ts.md)

## Used by

- [core/coordinators/validation.coordinator.ts](https://banes-lab.com/source/docs/core/coordinators/validation.coordinator.ts.md)
- [core/plugins/manifest.readme.plugin.ts](https://banes-lab.com/source/docs/core/plugins/manifest.readme.plugin.ts.md)
- [core/registries/manifest.registry.ts](https://banes-lab.com/source/docs/core/registries/manifest.registry.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/docs/folder-docs-configuration-strings.md)
- [core/adapters](https://banes-lab.com/anatomy/docs/folder-docs-core-adapters.md)
- [core/coordinators](https://banes-lab.com/anatomy/docs/folder-docs-core-coordinators.md)
- [core/parsers](https://banes-lab.com/anatomy/docs/folder-docs-core-parsers.md)
- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)
- [core/registries](https://banes-lab.com/anatomy/docs/folder-docs-core-registries.md)
- [core/reporters](https://banes-lab.com/anatomy/docs/folder-docs-core-reporters.md)
- [core/validators](https://banes-lab.com/anatomy/docs/folder-docs-core-validators.md)

## Source

```typescript
import type { AvailableParser, ChartChecker, ChartFinding, ChartReport, MermaidParser } from "#types/diagram.types";
import { hardeningMessage, parserUnavailable } from "#configuration/strings/diagram.strings";
import { createMermaidParser } from "#core/adapters/diagram.adapter";
import { mermaidBlocks } from "#core/parsers/diagram.parser";
import { mermaidHardening } from "#core/analyzers/diagram.analyzer";
import { print } from "#core/reporters/base.reporter";

const parseBlocks = async function parseBlocks(parser: AvailableParser, markdown: string): Promise<ChartFinding[]> {
    return mermaidBlocks(markdown).reduce(async (pending, block) => {
        const findings = await pending;
        const message = await parser.parse(block.code);
        return message === null ? findings : [...findings, { line: block.startLine, message }];
    }, Promise.resolve<ChartFinding[]>([]));
};

export const validateCharts = async function validateCharts(markdown: string): Promise<ChartReport> {
    const hardening = mermaidHardening(markdown).map((hit) => ({
        line: hit.line,
        message: hardeningMessage(hit.code, hit.detail),
    }));
    const parser = await createMermaidParser();
    if (!parser.available) {
        return { available: false, findings: hardening, reason: parser.reason };
    }
    return { available: true, findings: [...hardening, ...(await parseBlocks(parser, markdown))] };
};

export const createMermaidChecker = function createMermaidChecker(): ChartChecker {
    const state: { parser?: Promise<MermaidParser>; warned: boolean } = { warned: false };
    return {
        async check(source) {
            if (mermaidBlocks(source).length === 0) {
                return [];
            }
            state.parser ??= createMermaidParser();
            const parser = await state.parser;
            if (parser.available) {
                return parseBlocks(parser, source);
            }
            if (!state.warned) {
                print(parserUnavailable(parser.reason));
                state.warned = true;
            }
            return [];
        },
    };
};
```
