${html``}${html`${release.hidden ? "hidden" : "shown"}`}${html`${plural(total, "download")}`}${release.downloads.map( ([platform, n]) => html`${platform} ${n}`, )}
import type { Context, Hono } from "hono";
import { MAX_CHARS } from "../issues/spam.ts";
import { openMirror } from "../mirror/store.ts";
import { html } from "../pages/html.ts";
import { plural } from "../pages/layout.ts";
import { type OperatorRelease, operatorReleases, setRelease } from "../releases/releases.ts";
import { type AdminContext, adminPage, formField, notice, textFields } from "./console.ts";
import { allRepos, findRepo } from "./store.ts";
/**
* ยง24's Releases section: versions with download counts, displayed notes and hiding. Everything
* lives in kepr.db; nothing is deleted, since the bucket key is read-only.
*/
export function registerReleases(app: Hono, ctx: AdminContext): void {
app.get("/admin/releases", (c) => c.html(releasesPage(c, ctx, "")));
app.post("/admin/releases/:repo/:version", async (c) => {
const repo = findRepo(ctx.kepr, c.req.param("repo"));
const release =
repo &&
operatorReleases(ctx.kepr, openMirror(ctx.mirrorDir, repo.name), repo.name).find(
(r) => r.version === c.req.param("version"),
);
if (!repo || !release) return c.notFound();
const fields = await textFields(c);
const notes = (fields.notes ?? "").replace(/\r\n/g, "\n");
if (notes.length > MAX_CHARS) {
const error = `${repo.name} ${release.version}: notes are over ${MAX_CHARS.toLocaleString("en-US")} characters.`;
return c.html(releasesPage(c, ctx, error), 400);
}
// Notes equal to the record's are no override, so a later record edit would show through.
const override = notes === release.recordNotes ? null : notes;
setRelease(ctx.kepr, repo.name, release.version, fields.hidden === "1", override);
return c.redirect(`/admin/releases#${repo.name}-${release.version}`, 303);
});
}
function releasesPage(c: Context, ctx: AdminContext, error: string): string {
const sections = allRepos(ctx.kepr).flatMap((repo) => {
const releases = operatorReleases(ctx.kepr, openMirror(ctx.mirrorDir, repo.name), repo.name);
if (releases.length === 0) return [];
return html`${repo.name}
${releases.map((release) => releaseForm(c, repo.name, release))}
no releases in the bucket yet
` }`; return adminPage(c, ctx, "releases", body); } function releaseForm(c: Context, repo: string, release: OperatorRelease) { const total = release.downloads.reduce((sum, [, n]) => sum + n, 0); const id = `${repo}-${release.version}`; return html`${html``}${html`${release.hidden ? "hidden" : "shown"}`}${html`${plural(total, "download")}`}${release.downloads.map( ([platform, n]) => html`${platform} ${n}`, )}