core/loaders/panel.loader.ts

core/loaders/panel.loader.ts is a file in Bane's Lab Content. 59 lines of code and 11 definitions.

import {
    CHAPTER_LAYOUT,
    CHAPTER_PANEL_LAYOUTS,
    PANEL_KINDS,
    PAYLOAD_BLOCKS_KEY,
    PAYLOAD_LAYOUT_KEY,
    PAYLOAD_SUBSECTIONS_KEY,
    TAG_FIELD_BY_KIND,
} from "#configuration/constants/panel.constants";
import {
    PAYLOAD_ID_KEY,
    PAYLOAD_KIND_KEY,
    PAYLOAD_SECTIONS_KEY,
    WORD_SEPARATOR,
} from "#configuration/constants/leak.constants";
import type { PanelSection, PayloadPanel } from "#types/panel.types";
import { contentOf, listAt, tabsIn } from "#core/selectors/payload.selector";
import { payloadFileOf } from "#core/loaders/payload.loader";
import { readJsonOrNull } from "#core/persistence/report.persistence";
import { stringsOf } from "#core/converters/section.converter";

const isPanel = function isPanel(block: Record<string, unknown>): boolean {
    return typeof block[PAYLOAD_KIND_KEY] === "string" && PANEL_KINDS.has(block[PAYLOAD_KIND_KEY]);
};

const panelOf = function panelOf(block: Record<string, unknown>): PayloadPanel {
    const kind = typeof block[PAYLOAD_KIND_KEY] === "string" ? block[PAYLOAD_KIND_KEY] : "";
    const tag = block[TAG_FIELD_BY_KIND.get(kind) ?? ""];
    return { kind, tag: typeof tag === "string" && tag.length > 0 ? tag : null };
};

const blocksOf = function blocksOf(section: Record<string, unknown>): Record<string, unknown>[] {
    return [
        ...listAt(section, PAYLOAD_BLOCKS_KEY),
        ...listAt(section, PAYLOAD_SUBSECTIONS_KEY).flatMap((sub) => listAt(sub, PAYLOAD_BLOCKS_KEY)),
    ];
};

const sectionOf = function sectionOf(section: Record<string, unknown>): PanelSection {
    const id = section[PAYLOAD_ID_KEY];
    return {
        id: typeof id === "string" ? id : "",
        panels: blocksOf(section).filter(isPanel).map(panelOf),
        prose: stringsOf(section, isPanel).join(WORD_SEPARATOR),
    };
};

export const isChapterTab = function isChapterTab(tab: Record<string, unknown>): boolean {
    const layout = tab[PAYLOAD_LAYOUT_KEY];
    return layout === undefined || (typeof layout === "string" && CHAPTER_PANEL_LAYOUTS.has(layout));
};

export const readPanelSections = function readPanelSections(page: string): PanelSection[] | null {
    const content = contentOf(readJsonOrNull(payloadFileOf(page)));
    if (content === null) {
        return null;
    }
    if (content[PAYLOAD_LAYOUT_KEY] !== CHAPTER_LAYOUT) {
        return [];
    }
    return tabsIn(content)
        .filter(isChapterTab)
        .flatMap((tab) => listAt(tab, PAYLOAD_SECTIONS_KEY))
        .map(sectionOf);
};