1import type { Database } from "bun:sqlite";2import { readFileSync } from "node:fs";3import { join } from "node:path";4import type { Hono } from "hono";5import { describeFile } from "../describe/describe.ts";6import { setting } from "../server/db.ts";7import { type Html, html } from "./html.ts";8import { cacheFor, notFound, type PageContext, page } from "./layout.ts";9import { renderParagraph, renderSiteMarkdown } from "./markdown.ts";1011const SITE_DIR = join(import.meta.dir, "../../docs/site");12131415161718export function registerDocsPages(app: Hono, ctx: PageContext): void {19 const docs = readFileSync(join(SITE_DIR, "docs.md"), "utf8");20 const docsBody = sitePage(docs, true);21 app.get("/docs", (c) => {22 cacheFor(c, false);23 return c.html(page(ctx, { title: "docs", path: "/docs", ...docsBody }));24 });25 app.get("/support", (c) => {26 if (setting(ctx.kepr, "support_off")) return notFound(c, ctx);27 cacheFor(c, false);28 const body = sitePage(supportText(ctx.kepr));29 return c.html(page(ctx, { title: "support", path: "/support", ...body }));30 });31}323334export function supportText(db: Database): string {35 return setting(db, "support_page") ?? readFileSync(join(SITE_DIR, "support.md"), "utf8");36}373839function sitePage(source: string, contents = false): { description: string; body: Html } {40 const intro = describeFile("page.md", source);41 const doc = renderSiteMarkdown(source);42 const article = html`<article class="site-doc markdown">${doc.html}</article>`;43 const links = doc.sections.map(({ id, title }) => html`<a href="#${id}">${title}</a>`);44 return {45 description: intro ? renderParagraph(intro, { repo: "", dir: "", at: null }).text : "",46 body: contents47 ? html`<div class="site-doc-layout">48<nav class="site-doc-nav mono" aria-label="sections">${links}</nav>49${article}50</div>`51 : article,52 };53}