import { readFile, writeFile, mkdir, cp, rm } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { resolve } from "node:path"; import { styles, modules } from "./manifest.mjs"; import { sectionOrder } from "../src/scripts/section-order.mjs"; import { publishSource } from "./publish-source.mjs"; export const root = fileURLToPath(new URL("../", import.meta.url)); export async function build(destination = resolve(root, "dist")) { const source = resolve(root, "src"); const shell = await readFile(resolve(source, "page.html"), "utf8"); if (shell.split("").length !== 2) throw new Error( "Page template must have exactly one section insertion point.", ); const sections = await Promise.all( sectionOrder.map((name) => readFile(resolve(source, "sections", `${name}.html`), "utf8"), ), ); const css = await Promise.all( styles.map( async (name) => `/* ${name} */\n${await readFile(resolve(source, "styles", name), "utf8")}`, ), ); // Read all inputs before replacing generated output; authored source is never written. await rm(destination, { recursive: true, force: true }); await mkdir(resolve(destination, "scripts"), { recursive: true }); await Promise.all( modules.map((name) => cp( resolve(source, "scripts", name), resolve(destination, "scripts", name), ), ), ); await cp(resolve(root, "assets"), resolve(destination, "assets"), { recursive: true, }); await writeFile( resolve(destination, "index.html"), shell .replace("", sections.join("\n")) .replace( "", ' \n', ), ); await writeFile(resolve(destination, "app.css"), css.join("\n")); await publishSource(root, destination); return destination; } if ( process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url) ) { build() .then(() => console.log( `Built ${sectionOrder.length} sections and readable source to dist/`, ), ) .catch((error) => { console.error(error); process.exitCode = 1; }); }