personal-site/src/lib/ForgejoClient.ts

52 lines
1.8 KiB
TypeScript

import httpFetchClient from "@lib/HttpFetchClient";
const FORGEJO_BASE = "https://git.badblocks.dev";
const API = `${FORGEJO_BASE}/api/v1`;
const HEADERS = { Accept: "application/json" };
export interface ForgejoRepoDto {
name: string;
full_name: string;
description: string;
topics: string[];
stars_count: number;
forks_count: number;
updated_at: string;
language: string;
html_url: string;
archived: boolean;
default_branch: string;
}
export interface LastCommit { date: string; sha: string; message: string }
export const toIsoSeconds = (ts: string) =>
new Date(ts).toISOString().replace(/\.\d{3}Z$/, "");
const forgejoClient = {
searchByTopic: async (topic: string): Promise<ForgejoRepoDto[]> => {
const res = await httpFetchClient.get(
`${API}/repos/search?topic=true&q=${encodeURIComponent(topic)}&limit=50`, HEADERS);
if (!res?.ok) throw new Error("Forgejo search returned not-ok");
return res.data as ForgejoRepoDto[];
},
getLanguages: async (fullName: string): Promise<Record<string, number>> =>
httpFetchClient.get(`${API}/repos/${fullName}/languages`, HEADERS),
getLastCommit: async (fullName: string, branch: string): Promise<LastCommit | null> => {
try {
const res = await httpFetchClient.get(
`${API}/repos/${fullName}/branches/${encodeURIComponent(branch)}`, HEADERS);
const c = res?.commit;
if (!c?.timestamp) return null;
return {
date: toIsoSeconds(c.timestamp),
sha: String(c.id ?? "").slice(0, 7),
message: String(c.message ?? "").split("\n")[0].trim(),
};
} catch (error: any) {
if (error?.status === 404 || error?.statusCode === 404) return null;
throw error;
}
},
};
export default forgejoClient;