domain/converters/kind.converter.ts
domain/converters/kind.converter.ts is a file in Bane's Lab Site. 161 lines of code and 14 definitions.
import {
CONCERNS_LABEL,
DISCRIMINATOR_LABEL,
DISTINGUISHES_LABEL,
FORCE_INTRO,
FORCE_TITLE,
KINDS_IN_RANGE_LABEL,
KIND_INTRO,
KIND_TITLE,
PRINCIPLES_OF_KIND_LABEL,
RANGE_CAPTION,
RANGE_INTRO,
RANGE_SECTION_TITLE,
SIGNATURES_LABEL,
TERMS_OF_KIND_LABEL,
VOCABULARY_SECTIONS,
} from "#configuration/strings/kind.strings";
import {
CONTRACTS_LABEL,
COVERAGE_TITLE,
PRINCIPLES_LABEL,
missingVocabularySection,
} from "#configuration/strings/ontology.strings";
import {
COVERAGE_SUBSECTION_ID,
FORCE_ANCHOR,
FORCE_SECTION_ID,
KIND_ANCHOR,
KIND_SECTION_ID,
RANGE_SECTION_ID,
RELATION_ANCHOR,
VOCABULARY_ANCHOR,
VOCABULARY_SECTION_PREFIX,
} from "#core/ids/ontology.ids";
import type { ForceView, KindView, RelationRangeView, VocabularyView } from "#types/ontology.types";
import { HYPHEN, SPACE, UNDERSCORE } from "#configuration/constants/document.constants";
import type { Section, Subsection } from "#types/document.types";
import {
chips,
glossary,
labeled,
linkList,
plainList,
row,
text,
wideRow,
} from "#domain/converters/ontology.converter";
import { diagram, edgeLine, node } from "#domain/converters/ontology.graph.converter";
import type { CoverageView } from "#types/coverage.types";
import { DEFINITION_LABEL } from "#configuration/strings/lexicon.strings";
import { EDGE_SOLID } from "#configuration/constants/diagram.constants";
import { KIND_SECTION_ICON } from "#configuration/icons/ontology.icons";
import type { SchemaInput } from "#types/kind.types";
import { coverageRow } from "#domain/converters/coverage.converter";
const HEADER = "flowchart LR";
const RELATION_PREFIX = "relation-";
const kindSubsection = function kindSubsection(kind: KindView): Subsection {
return {
blocks: [
chips([
labeled(PRINCIPLES_OF_KIND_LABEL, String(kind.principles)),
labeled(TERMS_OF_KIND_LABEL, String(kind.terms)),
]),
glossary([
row(DISCRIMINATOR_LABEL, kind.discriminator),
row(DISTINGUISHES_LABEL, kind.distinguishesFrom),
row(SIGNATURES_LABEL, plainList(kind.definitionSignatures)),
]),
],
id: KIND_ANCHOR + kind.kind,
title: kind.kind,
};
};
const kindSection = function kindSection(
kinds: readonly KindView[],
resolutionNote: string,
coverage: readonly CoverageView[],
): Section {
return {
blocks: [text(resolutionNote)],
icon: KIND_SECTION_ICON,
id: KIND_SECTION_ID,
intro: KIND_INTRO,
subsections: [
...kinds.map(kindSubsection),
{ blocks: [glossary(coverage.map(coverageRow))], id: COVERAGE_SUBSECTION_ID, title: COVERAGE_TITLE },
],
title: KIND_TITLE,
};
};
const rangeDiagram = function rangeDiagram(ranges: readonly RelationRangeView[], kinds: readonly KindView[]): string {
const relationNodes = ranges.map((range) => node(RELATION_PREFIX + range.relation, range.relation));
const kindNodes = kinds.map((kind) => node(kind.kind, kind.kind));
const edges = ranges.flatMap((range) =>
range.kinds.map((kind) => edgeLine(RELATION_PREFIX + range.relation, EDGE_SOLID, kind.label)),
);
return diagram(HEADER, [...relationNodes, ...kindNodes, ...edges]);
};
const rangeSection = function rangeSection(ranges: readonly RelationRangeView[], kinds: readonly KindView[]): Section {
return {
blocks: [{ caption: RANGE_CAPTION, kind: "mermaid", text: rangeDiagram(ranges, kinds) }],
icon: KIND_SECTION_ICON,
id: RANGE_SECTION_ID,
intro: RANGE_INTRO,
subsections: ranges.map((range) => ({
blocks: [glossary([row(KINDS_IN_RANGE_LABEL, linkList(range.kinds))])],
id: RELATION_ANCHOR + range.relation,
title: range.relation,
})),
title: RANGE_SECTION_TITLE,
};
};
const forceSubsection = function forceSubsection(force: ForceView): Subsection {
return {
blocks: [
glossary([
row(CONTRACTS_LABEL, linkList(force.contracts)),
row(PRINCIPLES_LABEL, linkList(force.principles)),
...(force.concerns.length === 0 ? [] : [row(CONCERNS_LABEL, plainList(force.concerns))]),
]),
],
id: FORCE_ANCHOR + force.id,
title: force.force.replaceAll(UNDERSCORE, SPACE),
};
};
const vocabularySection = function vocabularySection(vocabulary: VocabularyView): Section {
const copy = VOCABULARY_SECTIONS.get(vocabulary.id);
if (copy === undefined) {
throw new Error(missingVocabularySection(vocabulary.id));
}
return {
icon: KIND_SECTION_ICON,
id: VOCABULARY_SECTION_PREFIX + vocabulary.id,
intro: copy.intro,
subsections: vocabulary.entries.map((entry) => ({
blocks: [
glossary([wideRow(DEFINITION_LABEL, entry.definition), row(copy.records, linkList(entry.records))]),
],
id: VOCABULARY_ANCHOR + vocabulary.id + HYPHEN + entry.value,
title: entry.value,
})),
title: copy.title,
};
};
const forceSection = function forceSection(forces: readonly ForceView[]): Section {
return {
icon: KIND_SECTION_ICON,
id: FORCE_SECTION_ID,
intro: FORCE_INTRO,
subsections: forces.map(forceSubsection),
title: FORCE_TITLE,
};
};
export const kindSections = function kindSections(input: SchemaInput): readonly Section[] {
return [
kindSection(input.kinds, input.note, input.coverage),
...input.vocabularies.map(vocabularySection),
rangeSection(input.ranges, input.kinds),
forceSection(input.forces),
];
};