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 { 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; };