mirror of
https://github.com/Heretek-AI/ompweb.git
synced 2026-11-07 22:42:14 -10:00
react-markdown, remark-gfm/math, rehype-raw/sanitize/katex, mermaid, mammoth, and katex were in devDependencies but imported at runtime (MarkdownBody, FileViewer, lib/markdown, MermaidBlock, files route), so global installs missed them. Also takes safe minor upgrades (next 16.3.4, react 19.2.8, base-ui 1.7, lucide 1.39, tailwind 4.3.3) and clears six lint warnings.
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
const RELEASES_API_URL = "https://api.github.com/repos/kahme247/ompweb/releases/tags/";
|
|
const FETCH_TIMEOUT_MS = 5_000;
|
|
export const MAX_BODY_BYTES = 64 * 1024;
|
|
|
|
export interface GitHubReleaseNotes {
|
|
version: string;
|
|
body: string;
|
|
htmlUrl: string;
|
|
}
|
|
|
|
/** Only allow github.com release URLs so the dialog never links off-site. */
|
|
export function isSafeReleaseUrl(url: string): boolean {
|
|
try {
|
|
return new URL(url).hostname.toLowerCase() === "github.com";
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function getGitHubReleaseNotes(version: string): Promise<GitHubReleaseNotes | null> {
|
|
const tag = `v${version}`;
|
|
let response: Response;
|
|
try {
|
|
response = await fetch(`${RELEASES_API_URL}${encodeURIComponent(tag)}`, {
|
|
cache: "no-store",
|
|
headers: { Accept: "application/vnd.github+json", "User-Agent": "@kahme247/ompweb", "X-GitHub-Api-Version": "2022-11-28" },
|
|
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
});
|
|
} catch {
|
|
return null;
|
|
}
|
|
if (!response.ok) return null;
|
|
let release: Record<string, unknown>;
|
|
try {
|
|
release = await response.json() as Record<string, unknown>;
|
|
} catch {
|
|
return null;
|
|
}
|
|
if (release.tag_name !== tag || release.draft !== false) return null;
|
|
if (typeof release.body !== "string" || release.body.length === 0) return null;
|
|
if (release.body.length > MAX_BODY_BYTES || Buffer.byteLength(release.body, "utf8") > MAX_BODY_BYTES) return null;
|
|
if (typeof release.html_url !== "string" || !isSafeReleaseUrl(release.html_url)) return null;
|
|
return { version, body: release.body, htmlUrl: release.html_url };
|
|
}
|