core/converters/record.page.converter.ts

core/converters/record.page.converter.ts is a file in Bane's Lab Build Scripts. 133 lines of code and 38 definitions.

import {
    CANONICAL_LABEL,
    CLOSURE_LABEL,
    CLOSURE_LINK_LABEL,
    FORMED_BY_LABEL,
    RECORD_LABEL,
    SCOPE_LABEL,
    SEVERITY_LABEL,
} from "@banes-lab/web/strings/ontology.strings";
import type { Identity, Link } from "#types/catalog.types";
import type { RecordData, RecordLeaf, RecordPageInput, RecordSubjectCounts } from "#types/record.types";
import type { RecordFact, RecordLink, RecordPlacement, RecordSubject } from "@banes-lab/web/types/page.types.js";
import { SITE_NAME, TITLE_SEPARATOR } from "@banes-lab/web/strings/page.strings";
import { missingAlternate, recordDescription } from "#configuration/strings/page.strings";
import { MARKDOWN_EXTENSION } from "#configuration/constants/site.constants";
import { RECORDS_SEGMENT } from "#configuration/constants/catalog.constants";
import { recordText } from "#core/selectors/record.selector";

const SLASH = "/";
const FRAGMENT = "#";
const HYPHEN = "-";
const SPACE = " ";
const RECORD_PREFIX = SLASH + RECORDS_SEGMENT + SLASH;

const isRecordLeaf = function isRecordLeaf(path: string): boolean {
    return path.startsWith(RECORD_PREFIX) && path.endsWith(MARKDOWN_EXTENSION);
};

export const recordPathOf = function recordPathOf(identity: Identity): string {
    const { markdown } = identity.address;
    if (markdown === null || !isRecordLeaf(markdown)) {
        throw new Error(missingAlternate(identity.ref));
    }
    return markdown.slice(0, -MARKDOWN_EXTENSION.length);
};

export const pageLinkOf = function pageLinkOf(site: string, link: Link): RecordLink {
    const local = link.markdown?.startsWith(site) === true ? link.markdown.slice(site.length) : null;
    if (local !== null && isRecordLeaf(local)) {
        return { label: link.label, path: site + local.slice(0, -MARKDOWN_EXTENSION.length) };
    }
    return { label: link.label, path: link.href };
};

const tabPathOf = function tabPathOf(identity: Identity): string {
    const href = identity.href ?? SLASH;
    const cut = href.indexOf(FRAGMENT);
    return cut === -1 ? href : href.slice(0, cut);
};

const anchorOf = function anchorOf(identity: Identity): string | null {
    const href = identity.href ?? "";
    const cut = href.indexOf(FRAGMENT);
    return cut === -1 ? null : href.slice(cut + FRAGMENT.length);
};

const kindLabel = function kindLabel(kind: string): string {
    return kind.split(HYPHEN).join(SPACE);
};

const headingOf = function headingOf(subject: Pick<RecordSubject, "code" | "name">): string {
    return subject.code === null ? subject.name : `${subject.name} (${subject.code})`;
};

const countsOf = function countsOf(values: readonly string[]): ReadonlyMap<string, number> {
    return values.reduce((counts, value) => counts.set(value, (counts.get(value) ?? 0) + 1), new Map<string, number>());
};

const isShared = function isShared(counts: ReadonlyMap<string, number>, value: string): boolean {
    return (counts.get(value) ?? 0) > 1;
};

const distinctSubject = function distinctSubject(subject: RecordSubject, shared: RecordSubjectCounts): RecordSubject {
    const kind = kindLabel(subject.kind);
    const {label} = subject.collection;
    const title = isShared(shared.titles, subject.title)
        ? [headingOf(subject), kind, label, SITE_NAME].join(TITLE_SEPARATOR)
        : subject.title;
    const description = isShared(shared.descriptions, subject.description)
        ? recordDescription(headingOf(subject), kind, label, subject.summary)
        : subject.description;
    return { ...subject, description, title };
};

export const distinctPages = function distinctPages(leaves: readonly RecordLeaf[]): readonly RecordLeaf[] {
    const shared = {
        descriptions: countsOf(leaves.map((leaf) => leaf.page.description)),
        titles: countsOf(leaves.map((leaf) => leaf.page.title)),
    };
    return leaves.map((leaf) => ({ ...leaf, page: distinctSubject(leaf.page, shared) }));
};

const textFact = function textFact(data: RecordData, label: string, key: string): RecordFact | null {
    const value = recordText(data, key);
    return value === null ? null : { label, value: { label: value, path: null } };
};

const factsOf = function factsOf(data: RecordData, tabTitle: string): readonly RecordFact[] {
    const closure = recordText(data, "closure");
    const facts = [
        { label: RECORD_LABEL, value: { label: data.ref, path: null } },
        textFact(data, SEVERITY_LABEL, "severity"),
        textFact(data, SCOPE_LABEL, "scope"),
        textFact(data, FORMED_BY_LABEL, "formedBy"),
        data.href === null ? null : { label: CANONICAL_LABEL, value: { label: tabTitle, path: data.href } },
        closure === null ? null : { label: CLOSURE_LABEL, value: { label: CLOSURE_LINK_LABEL, path: closure } },
    ];
    return facts.filter((fact): fact is RecordFact => fact !== null);
};

const placementOf = function placementOf(data: RecordData, site: string): RecordPlacement | null {
    if (data.up === null) {
        return null;
    }
    const { next, previous } = data.siblings ?? { next: null, previous: null };
    return {
        next: next === null ? null : pageLinkOf(site, next),
        previous: previous === null ? null : pageLinkOf(site, previous),
        up: pageLinkOf(site, data.up),
    };
};

export const recordSubjectOf = function recordSubjectOf(input: RecordPageInput): RecordSubject {
    const { identity, record, site } = input;
    const tabPath = tabPathOf(identity);
    const tabTitle = input.tabLabel(tabPath);
    const name = headingOf(record);
    const path = recordPathOf(identity);
    return {
        aliases: input.aliases,
        alternates: { json: identity.address.json, markdown: path + MARKDOWN_EXTENSION },
        code: record.code,
        collection: { label: tabTitle, path: tabPath },
        description: record.summary ?? recordDescription(name, kindLabel(record.kind), tabTitle, null),
        facts: factsOf(input.data, tabTitle),
        kind: record.kind,
        layer: input.layer === null ? null : pageLinkOf(site, input.layer),
        name: record.name,
        path,
        placement: placementOf(input.data, site),
        relations: input.relations.map((relation) => ({
            links: relation.links.map((link) => pageLinkOf(site, link)),
            relation: relation.relation,
        })),
        section: anchorOf(identity),
        summary: record.summary,
        title: name + TITLE_SEPARATOR + tabTitle + TITLE_SEPARATOR + SITE_NAME,
    };
};