import type { FlatTemplatable, Templatable } from "tempstream"; import { tempstream } from "tempstream"; import type { Readable } from "stream"; import type { BaseContext } from "koa"; import { toKebabCase } from "js-convert-case"; import { DEFAULT_HTML_LANG } from "./config.js"; import { default_navbar } from "./routes/common/navbar.js"; export const defaultHead = ( ctx: BaseContext, title: string, options: HTMLOptions ) => /* HTML */ `${title} ยท ${ctx.$app.manifest.name} ${options.morphing ? `` : ""} ${options.preserveScroll ? `` : ""}`; export type HTMLOptions = { preserveScroll?: boolean; morphing?: boolean; navbar?: (ctx: BaseContext) => FlatTemplatable; autoRefreshCSS?: boolean; disableCopyEvent?: boolean; language?: string; }; export default function html( ctx: BaseContext, title: string, body: Templatable, htmlOptions: HTMLOptions = {}, makeHead: ( ctx: BaseContext, title: string, options: HTMLOptions ) => Templatable = defaultHead ): Readable { ctx.set("content-type", "text/html;charset=utf-8"); const controllers: string[] = []; if (htmlOptions.autoRefreshCSS) { controllers.push("refresh-styles"); controllers.push("refresh-on-ts-changes"); } return tempstream/* HTML */ ` ${makeHead(ctx, title, htmlOptions)} ${(htmlOptions?.navbar || default_navbar)(ctx)} ${body} ${htmlOptions.disableCopyEvent ? /* HTML */ "" : ""} `; }