This repository's site, in Chrome
What the browser checks share. They build the site from HEAD with the renderer in dist/, and
serve it to a page in the Chrome installed on the machine, so nothing is downloaded. The page
asks for http://site/…, and each request is answered from the built files as a static host
would answer it, so no server runs.
// The checks also run code in the page, so they're typed with the DOM.
/// <reference lib="dom" />
import { execFileSync } from "node:child_process";
import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, relative } from "node:path";
import { type Browser, chromium, type Page } from "playwright-core";
/** The built site, a browser, and a way to open a page on it. */
export interface Site {
/** Every page, as the path a reader would ask for. */
pages: string[];
browser: Browser;
/** A new tab that answers `http://site/…` from the built files. */
newPage(): Promise<Page>;
close(): Promise<void>;
}
export async function openSite(): Promise<Site> {
const dir = mkdtempSync(join(tmpdir(), "prose-site-"));
execFileSync("node", ["dist/cli.js", "build", ".", "--out", dir], { stdio: "ignore" });
const browser = await chromium.launch({ channel: "chrome" });
return {
pages: pages(dir),
browser,
async newPage() {
const page = await browser.newPage();
await page.route("http://site/**", (route) => {
const file = fileFor(dir, new URL(route.request().url()).pathname);
return file ? route.fulfill({ path: file }) : route.fulfill({ status: 404 });
});
return page;
},
async close() {
await browser.close();
rmSync(dir, { recursive: true, force: true });
},
};
}
/** Every page in the site. A redirect, like a folder's `README.md` to the folder, isn't a page,
* and its target is a page anyway. */
function pages(dir: string, root = dir): string[] {
return readdirSync(dir).flatMap((name) => {
const path = join(dir, name);
if (statSync(path).isDirectory()) return name === "assets" ? [] : pages(path, root);
if (!name.endsWith(".html") || name === "404.html") return [];
if (readFileSync(path, "utf8").includes('http-equiv="refresh"')) return [];
return [
"/" +
relative(root, path)
.replace(/(^|\/)index\.html$/, "$1")
.replace(/\.html$/, ""),
];
});
}
/** The site's file for a request, as a static host would find it. */
function fileFor(site: string, pathname: string): string | undefined {
const base = join(site, decodeURIComponent(pathname));
return [base, `${base}.html`, join(base, "index.html")].find(
(file) => existsSync(file) && statSync(file).isFile(),
);
}