Files
elysium/apps/api/src/routes/about.ts
T
hikari d1d1f70c75 chore: fix lint, ensure full CI pipeline passes, add verify checklist
- Fix strict-boolean-expressions in 7 route files (runtime body validation)
- Fix no-unnecessary-condition in profile.ts and offlineProgress.ts (defensive null checks)
- Extend v8 ignore next-N counts in game.ts to reach 100% coverage
- Add CI requirements to CLAUDE.md (lint + build + test must pass before commit)
- Add manual verification checklist (verify.md)
- Remove progress.md
2026-03-08 13:59:38 -07:00

58 lines
1.7 KiB
TypeScript

/**
* @file About route providing API version and release information.
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
/* eslint-disable stylistic/max-len -- URL cannot be shortened */
/* eslint-disable require-atomic-updates -- Simple cache; race condition is acceptable */
import { Hono } from "hono";
import type { AboutResponse, GiteaRelease } from "@elysium/types";
// eslint-disable-next-line capitalized-comments -- v8 ignore
/* v8 ignore next -- @preserve */
const apiVersion = process.env.npm_package_version ?? "unknown";
const giteaReleasesUrl = "https://git.nhcarrigan.com/api/v1/repos/nhcarrigan-ideation/elysium/releases";
const cacheTtlMs = 5 * 60 * 1000;
interface ReleasesCache {
data: Array<GiteaRelease>;
timestamp: number;
}
let releasesCache: ReleasesCache = { data: [], timestamp: 0 };
const fetchReleases = async(): Promise<Array<GiteaRelease>> => {
const now = Date.now();
if (releasesCache.data.length > 0 && now - releasesCache.timestamp < cacheTtlMs) {
return releasesCache.data;
}
try {
const response = await fetch(giteaReleasesUrl);
if (!response.ok) {
return releasesCache.data;
}
const rawData: unknown = await response.json();
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- External API response */
const data = rawData as Array<GiteaRelease>;
releasesCache = { data: data, timestamp: now };
return releasesCache.data;
} catch {
return releasesCache.data;
}
};
const aboutRouter = new Hono();
aboutRouter.get("/", async(context) => {
const releases = await fetchReleases();
const body: AboutResponse = {
apiVersion,
releases,
};
return context.json(body);
});
export { aboutRouter };