import type { Database } from "bun:sqlite";
import { beforeAll, describe, expect, test } from "bun:test";
import { mkdtemp, unlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Hono } from "hono";
import { openBucket } from "../src/bucket/reader.ts";
import { syncAll } from "../src/bucket/sync.ts";
import { openMirror } from "../src/mirror/store.ts";
import { createApp } from "../src/server/app.ts";
import { openKeprDb } from "../src/server/db.ts";
import { makeRepos } from "./fixture.ts";
let app: Hono;
let kepr: Database;
let dataDir: string;
let alphaSaves: { id: string; message: string; is_checkpoint: boolean }[];
let vaultSave: string;
const body = async (path: string) => (await app.request(path)).text();
// alpha (public): a save, a checkpoint holding a draft no real save keeps, then a second save.
// vault (private): one save whose message, category, language and ID must never show.
beforeAll(async () => {
const repos = await makeRepos(["alpha", "vault"]);
const root = join(repos.bucketDir, "..");
await writeFile(join(root, "work/alpha/draft.txt"), "a draft only a checkpoint holds\n");
repos.koh("alpha", "checkpoint", "checkpoint message never shown");
await unlink(join(root, "work/alpha/draft.txt"));
await writeFile(join(root, "work/alpha/README.md"), "# alpha\n\nThe alpha project, grown.\n");
await writeFile(join(root, "work/alpha/main.ts"), "export const a = 1;\n");
repos.koh("alpha", "save", "grow alpha");
await writeFile(join(root, "work/vault/main.zig"), "const x = 1;\n");
repos.koh("vault", "save", "vault message");
alphaSaves = JSON.parse(repos.koh("alpha", "log", "--json")).saves;
vaultSave = JSON.parse(repos.koh("vault", "log", "--json")).head_id;
dataDir = await mkdtemp(join(tmpdir(), "kepr-front-"));
kepr = openKeprDb(dataDir);
const bucket = openBucket({ kind: "folder", path: repos.bucketDir });
await syncAll({
bucket,
kepr,
mirrorDir: join(dataDir, "mirror"),
tarballDir: join(dataDir, "tarballs"),
});
kepr.run("UPDATE repos SET public = 1, category = 'tools' WHERE name = 'alpha'");
kepr.run("UPDATE repos SET category = 'secretcat' WHERE name = 'vault'");
for (const [key, value] of [
["handle", "ada"],
["tagline", "A library of small tools."],
["bio", "Writes small tools."],
["location", "Lisbon"],
["link", "https://ada.example"],
["building_since", "may 2026"],
]) {
kepr.query("INSERT INTO settings (key, value) VALUES (?, ?)").run(key, value);
}
kepr.run(
`INSERT INTO issues (repo, number, title, body, type, filed_at, hidden) VALUES
('alpha', 1, 'a', 'b', 'bug', 1, 0), ('alpha', 2, 'c', 'd', 'bug', 1, 1),
('vault', 1, 'e', 'f', 'bug', 1, 0)`,
);
kepr.run(
`INSERT INTO downloads (repo, version, platform, count) VALUES
('alpha', '1.0.0', 'linux-x86_64', 7), ('alpha', '0.9.0', 'linux-x86_64', 100),
('vault', '1.0.0', 'linux-x86_64', 1000)`,
);
kepr.run("INSERT INTO release_settings (repo, version, hidden) VALUES ('alpha', '0.9.0', 1)");
app = createApp(
{
domain: "kepr.example",
dataDir,
adminPasswordHash: "$argon2id$x",
bucket: { kind: "folder", path: repos.bucketDir },
},
kepr,
);
});
const checkpoint = () => alphaSaves.find((save) => save.is_checkpoint)?.id as string;
const realSaves = () => alphaSaves.filter((save) => !save.is_checkpoint);
describe("front page", () => {
test("counts distinct objects of public repos' real saves only", async () => {
// alpha's real saves hold .kohignore, two READMEs and main.ts; its mirror also holds the
// draft only the checkpoint kept, and the private repo's objects are elsewhere.
const mirror = openMirror(join(dataDir, "mirror"), "alpha");
expect(mirror.query("SELECT COUNT(*) AS n FROM objects").get()).toEqual({ n: 5 });
expect(await body("/")).toContain("The library knows
4 things.");
});
test("the ticker, cloud and cards show public saves, never checkpoints or private repos", async () => {
const html = await body("/");
expect(html).toContain('