core/persistence/chapter.persistence.ts
core/persistence/chapter.persistence.ts is a file in Bane's Lab Content. 34 lines of code and 9 definitions.
import { FOLDER_SEPARATOR, MARKDOWN_EXTENSION } from "#configuration/constants/chapter.constants";
import { existsSync, readdirSync, rmSync } from "node:fs";
import type { Chapter } from "#types/chapter.types";
import { join } from "node:path";
import { persistText } from "#core/persistence/report.persistence";
const folderOf = function folderOf(file: string): string {
const slash = file.lastIndexOf(FOLDER_SEPARATOR);
return slash === -1 ? "" : file.slice(0, slash);
};
const markdownIn = function markdownIn(out: string, folder: string): string[] {
const target = join(out, folder);
if (!existsSync(target)) {
return [];
}
return readdirSync(target, { withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name.endsWith(MARKDOWN_EXTENSION))
.map((entry) => (folder.length === 0 ? entry.name : folder + FOLDER_SEPARATOR + entry.name));
};
export const staleChaptersOf = function staleChaptersOf(out: string, chapters: readonly Chapter[]): string[] {
const rendered = new Set(chapters.map((chapter) => chapter.file));
const folders = [...new Set(chapters.map((chapter) => folderOf(chapter.file)))];
return folders.flatMap((folder) => markdownIn(out, folder)).filter((file) => !rendered.has(file));
};
export const persistChapters = async function persistChapters(
out: string,
chapters: readonly Chapter[],
): Promise<string[]> {
const stale = staleChaptersOf(out, chapters);
for (const file of stale) {
rmSync(join(out, file));
}
await Promise.all(chapters.map(async (chapter) => persistText(join(out, chapter.file), chapter.body)));
return stale;
};