import { CONFIGURATION_CONTAINER, CONSTANTS_CONCERN, GRAPH_EXPORT_SUFFIX, } from "#configuration/constants/coverage.constants"; import { absolutePath, relativePath } from "@ssot/paths"; import { concernSuffix, folderFor } from "@ssot/govlab/shared/manifests/taxonomy.manifest.ts"; import type { ContentGraph } from "#types/coverage.types"; import { containerPath } from "@ssot/govlab/shared/resolvers/container.resolver.ts"; import { pathToFileURL } from "node:url"; import { readdirSync } from "node:fs"; const isRecord = function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null; }; const isGraph = function isGraph(value: unknown): value is ContentGraph { return isRecord(value) && typeof value["page"] === "string" && isRecord(value["sections"]); }; const graphsOf = function graphsOf(module: Record): ContentGraph[] { return Object.entries(module).flatMap(([name, value]) => name.endsWith(GRAPH_EXPORT_SUFFIX) && isGraph(value) ? [value] : [], ); }; const constantsFolder = function constantsFolder(): string { const container = containerPath(CONFIGURATION_CONTAINER, relativePath("app.member")); return absolutePath("app.root", container, folderFor(CONSTANTS_CONCERN) ?? ""); }; const loadModule = async function loadModule(file: string): Promise { const loaded: unknown = await import(pathToFileURL(file).href); return isRecord(loaded) ? graphsOf(loaded) : []; }; export const loadContentGraphs = async function loadContentGraphs(): Promise { const folder = constantsFolder(); const suffix = concernSuffix(CONSTANTS_CONCERN); const files = readdirSync(folder) .filter((name) => name.endsWith(suffix)) .sort((a, b) => a.localeCompare(b)) .map((name) => `${folder}/${name}`); const loaded = await Promise.all(files.map(loadModule)); return loaded.flat(); };