core/loaders/chapter.loader.ts
core/loaders/chapter.loader.ts is a file in Bane's Lab Content. 104 lines of code and 19 definitions.
import { ATTRIBUTION_COPYRIGHT, ATTRIBUTION_WORK } from "#configuration/strings/chapter.strings";
import type {
Attribution,
ChapterShape,
ChapterSource,
PageSources,
ShapeInput,
ShapeRenderer,
} from "#types/chapter.types";
import { CREATIVE_COMMONS_LICENSE, METHODOLOGY_AUTHOR } from "@banes-lab/web/configuration/strings/page.strings.ts";
import {
FOLDER_SEPARATOR,
MARKDOWN_EXTENSION,
REPOSITORY_SHAPE,
WIKI_SHAPE,
} from "#configuration/constants/chapter.constants";
import { README_PAGES, REPOSITORY_PAGES, TEACHING_PAGES } from "#configuration/constants/readme.constants";
import { existsSync, readFileSync } from "node:fs";
import { payloadFileOf, readPagePayload } from "#core/loaders/payload.loader";
import type { PagePayload } from "#types/leak.types";
import { UTF8 } from "#configuration/constants/source.constants";
import { absolutePath } from "@ssot/paths";
import { readmeInputsOf } from "#core/loaders/readme.loader";
import { renderChapters } from "#core/renderers/chapter.renderer";
import { renderWiki } from "#core/renderers/wiki.renderer";
export const shapeOf = function shapeOf(value: string | null): ChapterShape | null {
if (value === null || value === REPOSITORY_SHAPE) {
return REPOSITORY_SHAPE;
}
return value === WIKI_SHAPE ? WIKI_SHAPE : null;
};
export const rendererFor = function rendererFor(shape: ChapterShape): ShapeRenderer {
if (shape === WIKI_SHAPE) {
return renderWiki;
}
return renderChapters;
};
const readTwin = function readTwin(file: string): string | null {
return existsSync(file) ? readFileSync(file, UTF8) : null;
};
export const twinFilesOf = function twinFilesOf(payload: PagePayload): string[] {
const pageTwin = absolutePath("builds.web", payload.page + MARKDOWN_EXTENSION);
if (payload.tabs.length === 0) {
return [pageTwin];
}
return payload.tabs.map((tab, index) =>
index === 0
? pageTwin
: absolutePath("builds.web", payload.page + FOLDER_SEPARATOR + tab.id + MARKDOWN_EXTENSION),
);
};
export const chapterSourcesOf = function chapterSourcesOf(payload: PagePayload): ChapterSource[] | null {
const files = twinFilesOf(payload);
const sources: ChapterSource[] = [];
for (const [index, file] of files.entries()) {
const markdown = readTwin(file);
if (markdown === null) {
return null;
}
const tab = payload.tabs[index];
sources.push(
tab === undefined
? { first: true, label: payload.label, markdown, tab: payload.page }
: { first: index === 0, label: tab.label, markdown, tab: tab.id },
);
}
return sources;
};
export const pageSourcesOf = function pageSourcesOf(page: string): PageSources | null {
const payload = readPagePayload(page);
const sources = payload === null ? null : chapterSourcesOf(payload);
return payload === null || sources === null ? null : { label: payload.label, page, sources };
};
export const pagesFor = function pagesFor(shape: ChapterShape): readonly string[] {
return shape === WIKI_SHAPE ? TEACHING_PAGES : REPOSITORY_PAGES;
};
export const shapeInputOf = function shapeInputOf(shape: ChapterShape): ShapeInput | null {
const pages = pagesFor(shape).map(pageSourcesOf);
const present = pages.filter((page): page is PageSources => page !== null);
if (present.length !== pages.length) {
return null;
}
return { pages: present, readme: shape === REPOSITORY_SHAPE ? readmeInputsOf() : null };
};
export const attributionOf = function attributionOf(): Attribution {
return {
author: METHODOLOGY_AUTHOR,
copyright: ATTRIBUTION_COPYRIGHT,
coveredBy: CREATIVE_COMMONS_LICENSE.lead,
licenseName: CREATIVE_COMMONS_LICENSE.name,
licenseUrl: CREATIVE_COMMONS_LICENSE.href,
work: ATTRIBUTION_WORK,
};
};
export const surfaceFolder = function surfaceFolder(shape: ChapterShape): string {
return shape === WIKI_SHAPE ? absolutePath("methodology.wiki") : absolutePath("methodology");
};
export const surfaceInputFiles = function surfaceInputFiles(shape: ChapterShape): string[] {
const pages = shape === REPOSITORY_SHAPE ? [...pagesFor(shape), ...README_PAGES] : pagesFor(shape);
return [...new Set(pages)].flatMap((page) => {
const payload = readPagePayload(page);
return [payloadFileOf(page), ...(payload === null ? [] : twinFilesOf(payload))];
});
};