# domain/converters/principle.converter.ts

> 129 lines of code and 16 definitions.

Tree: Site tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/tree#file-domain-converters-principle-converter-ts
Source text: https://banes-lab.com/assets/sources/source.d855ebdf69ce7ba82a067a1f3c9d34284793da34113e6d6efa5ec8f24d4e54e5.generated.txt

## Definitions

- `relations` (lexical_declaration, line 64)
- `descriptors` (lexical_declaration, line 78)
- `facts` (lexical_declaration, line 54)
- `categoryDiagram` (lexical_declaration, line 101)
- `principleSubsection` (lexical_declaration, line 88)
- `categorySection` (lexical_declaration, line 122)
- `HEADER` (lexical_declaration, line 49)
- `SOLID` (lexical_declaration, line 50)
- `DOTTED` (lexical_declaration, line 51)
- `NEGATIVE` (lexical_declaration, line 52)
- `members` (lexical_declaration, line 102)
- `nodes` (lexical_declaration, line 103)
- `edges` (lexical_declaration, line 104)
- `arrows` (lexical_declaration, line 105)
- `id` (lexical_declaration, line 114)
- `principleSections` (lexical_declaration, line 133, exported)

## Uses

- [domain/converters/ontology.converter.ts](https://banes-lab.com/source/tree/domain/converters/ontology.converter.ts.md)

## Source

```typescript
import {
    AFTER_TITLE,
    ALIASES_LABEL,
    BEFORE_TITLE,
    CATEGORY_CAPTION,
    CATEGORY_INTRO,
    CONFLICTS_WITH_LABEL,
    CONTRACTS_LABEL,
    DETECTED_BY_LABEL,
    ENABLES_LABEL,
    ENFORCED_BY_LABEL,
    KIND_LABEL,
    LAYER_LABEL,
    MEASURED_BY_LABEL,
    REFACTORED_BY_LABEL,
    REFERENCED_BY_LABEL,
    REINFORCES_LABEL,
    REQUIRES_LABEL,
    SCOPE_LABEL,
    SEVERITY_LABEL,
    TENSIONS_LABEL,
    TENSIONS_WITH_LABEL,
    TERM_LABEL,
    VIOLATED_BY_LABEL,
} from "#configuration/strings/ontology.strings";
import { ARCH_ANCHOR, ARCH_CATEGORY_ANCHOR } from "#core/ids/ontology.ids";
import type { PrincipleCategoryView, PrincipleView } from "#types/ontology.types";
import type { Section, Subsection } from "#types/document.types";
import {
    chips,
    diagram,
    edgeLine,
    exemplarBlocks,
    glossary,
    labelled,
    linkList,
    linkRow,
    linked,
    localId,
    node,
    plainList,
    row,
} from "#domain/converters/ontology.converter";
import { ARCH_FACE } from "@govlab/constants";
import type { Block } from "#types/block.types";
import { CATEGORY_SECTION_ICON } from "#configuration/icons/ontology.icons";
import type { EdgeRef } from "#types/link.types";

const HEADER = "flowchart LR";
const SOLID = " --> ";
const DOTTED = " -.-> ";
const NEGATIVE = " --x ";

const facts = function facts(principle: PrincipleView): Block {
    return chips([
        linked(KIND_LABEL, principle.kind),
        labelled(SEVERITY_LABEL, principle.severity),
        principle.scope.length === 0 ? null : labelled(SCOPE_LABEL, linkList(principle.scope)),
        principle.aliases.length === 0 ? null : labelled(ALIASES_LABEL, plainList(principle.aliases)),
        linked(LAYER_LABEL, principle.layer),
    ]);
};

const relations = function relations(principle: PrincipleView): Block {
    return glossary([
        row(REQUIRES_LABEL, linkList(principle.edges.requires)),
        row(REINFORCES_LABEL, linkList(principle.edges.reinforces)),
        row(ENABLES_LABEL, linkList(principle.edges.enables)),
        row(TENSIONS_WITH_LABEL, linkList(principle.edges.tensionsWith)),
        row(CONFLICTS_WITH_LABEL, linkList(principle.edges.conflictsWith)),
        ...linkRow(REFERENCED_BY_LABEL, principle.referencedBy),
        ...linkRow(TERM_LABEL, principle.term === null ? [] : [principle.term]),
        ...linkRow(CONTRACTS_LABEL, principle.contracts),
        ...linkRow(TENSIONS_LABEL, principle.tensions),
    ]);
};

const descriptors = function descriptors(principle: PrincipleView): Block {
    return glossary([
        row(VIOLATED_BY_LABEL, linkList(principle.violatedBy)),
        row(DETECTED_BY_LABEL, linkList(principle.detectedBy)),
        row(MEASURED_BY_LABEL, linkList(principle.measuredBy)),
        row(REFACTORED_BY_LABEL, linkList(principle.refactoredBy)),
        row(ENFORCED_BY_LABEL, linkList(principle.enforcedBy)),
    ]);
};

const principleSubsection = function principleSubsection(principle: PrincipleView): Subsection {
    return {
        blocks: [
            facts(principle),
            relations(principle),
            descriptors(principle),
            ...exemplarBlocks(principle.exemplar, BEFORE_TITLE, AFTER_TITLE),
        ],
        id: ARCH_ANCHOR + principle.id,
        title: principle.name,
    };
};

const categoryDiagram = function categoryDiagram(group: PrincipleCategoryView): string {
    const members = new Set(group.principles.map((principle) => principle.id));
    const nodes = group.principles.map((principle) => node(principle.id, principle.name));
    const edges = group.principles.flatMap((principle) => {
        const arrows: [readonly EdgeRef[], string][] = [
            [principle.edges.requires, SOLID],
            [principle.edges.reinforces, SOLID],
            [principle.edges.enables, SOLID],
            [principle.edges.tensionsWith, DOTTED],
            [principle.edges.conflictsWith, NEGATIVE],
        ];
        return arrows.flatMap(([targets, arrow]) =>
            targets.flatMap((target) => {
                const id = localId(target, ARCH_FACE, members);
                return id === null || id === principle.id ? [] : [edgeLine(principle.id, arrow, id)];
            }),
        );
    });
    return diagram(HEADER, [...nodes, ...edges]);
};

const categorySection = function categorySection(group: PrincipleCategoryView): Section {
    return {
        blocks: [{ caption: CATEGORY_CAPTION, kind: "mermaid", text: categoryDiagram(group) }],
        icon: CATEGORY_SECTION_ICON,
        id: ARCH_CATEGORY_ANCHOR + group.id,
        intro: CATEGORY_INTRO,
        subsections: group.principles.map(principleSubsection),
        title: group.category,
    };
};

export const principleSections = function principleSections(
    groups: readonly PrincipleCategoryView[],
): readonly Section[] {
    return groups.map(categorySection);
};
```
