2025-01-22 09:03:37 +01:00
|
|
|
import * as fs from "node:fs";
|
|
|
|
import * as posix from "node:path/posix";
|
2025-01-22 04:54:03 +01:00
|
|
|
import { prettify, htmlDocument } from "antihtml";
|
2025-01-22 09:03:37 +01:00
|
|
|
import { pages } from "./content/pages.js";
|
|
|
|
import type { Page } from "./content/types.js";
|
|
|
|
import { resolveRefs } from "./utils/resolve-refs.js";
|
|
|
|
|
|
|
|
function pageToHtml(page: Page) {
|
|
|
|
if (!page.ref.startsWith("/")) {
|
|
|
|
throw new Error(`ref "${page.ref}" for "${page.title}" is not absolute.`);
|
|
|
|
}
|
|
|
|
return htmlDocument(
|
|
|
|
prettify(
|
|
|
|
resolveRefs(
|
|
|
|
page.content,
|
|
|
|
posix.dirname(page.ref),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2025-01-21 07:56:15 +01:00
|
|
|
|
2025-02-01 16:25:45 +01:00
|
|
|
function assembleResources() {
|
|
|
|
const webDir = "public";
|
|
|
|
const resources = new Map<string, string | Page>();
|
|
|
|
for (const entry of fs.readdirSync(webDir, { recursive: true, withFileTypes: true })) {
|
|
|
|
if (!entry.isFile())
|
|
|
|
continue;
|
|
|
|
const parentPath = entry.parentPath.replace(/\\/g, "/");
|
|
|
|
const ref = `${parentPath.slice(webDir.length)}/${entry.name}`;
|
|
|
|
resources.set(ref, `${parentPath}/${entry.name}`);
|
|
|
|
}
|
|
|
|
for (const page of pages) {
|
|
|
|
if (resources.has(page.ref)) {
|
|
|
|
const existing = resources.get(page.ref)!;
|
|
|
|
const other = typeof existing === "string" ? "a static resource" : `"${existing.title}"`;
|
|
|
|
throw new Error(`ref "${page.ref}" is taken up by both "${page.title}" and ${other}`)
|
|
|
|
}
|
|
|
|
resources.set(page.ref, page);
|
|
|
|
}
|
|
|
|
return resources;
|
2025-01-21 07:56:15 +01:00
|
|
|
}
|
|
|
|
|
2025-02-01 16:25:45 +01:00
|
|
|
function build() {
|
|
|
|
const outDir = "build/web";
|
|
|
|
const dirsCreated = new Set<string>()
|
|
|
|
for (const [ref, resource] of assembleResources()) {
|
|
|
|
const refDir = `${outDir}${posix.dirname(ref)}`;
|
|
|
|
if (!dirsCreated.has(refDir)) {
|
|
|
|
fs.mkdirSync(refDir, { recursive: true });
|
2025-01-22 04:54:03 +01:00
|
|
|
}
|
2025-02-01 16:25:45 +01:00
|
|
|
console.log(`writing ${outDir}${ref}`);
|
|
|
|
let content;
|
|
|
|
if (typeof resource === "string") {
|
|
|
|
content = fs.readFileSync(resource);
|
|
|
|
} else {
|
|
|
|
content = pageToHtml(resource);
|
|
|
|
}
|
|
|
|
fs.writeFileSync(`${outDir}${ref}`, content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function printUsage() {
|
|
|
|
console.log("Usage: cli.js <cmd>");
|
|
|
|
console.log(" build - Copy resources and generated pages to build directory.");
|
|
|
|
}
|
|
|
|
|
|
|
|
function main(runtime: string, script: string, args: string[]) {
|
|
|
|
if (!args.length) {
|
|
|
|
printUsage();
|
|
|
|
process.exitCode = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const [command, ...commandArgs] = args;
|
|
|
|
if (command === "build") {
|
|
|
|
build();
|
|
|
|
} else {
|
|
|
|
console.log(`Error: Unkown sub-command ${command}`);
|
|
|
|
printUsage();
|
|
|
|
process.exitCode = 1;
|
2025-01-22 04:54:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-01 16:25:45 +01:00
|
|
|
const [runtime, script, ...args] = process.argv;
|
|
|
|
main(runtime, script, args)
|