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 => { 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> => httpFetchClient.get(`${API}/repos/${fullName}/languages`, HEADERS), getLastCommit: async (fullName: string, branch: string): Promise => { 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;