const langColorsRes = await fetch("https://cdn.jsdelivr.net/gh/anuraghazra/github-readme-stats@refs/heads/master/src/common/languageColors.json"); const langColors: Record = await langColorsRes.json(); type repo = { language: string } type repos = repo[] const getTopLangs = async (type: "users" | "orgs", name: string) => { const obj: Record = {} const repoResp = await fetch(`https://git.creations.works/api/v1/${type}/${name}/repos?limit=0`); const repos = await repoResp.json() as repos | { message: string }; if ("message" in repos) { throw new Error(repos.message); } for (const repo of repos) { const lang = repo.language; if (obj[lang] && lang !== "") { obj[lang]++; } else if (lang !== "") { obj[lang] = 1; } } return calculatePercent(obj); } const calculatePercent = (obj: Record) => { const totalHits = Object.values(obj).reduce((acc, curr) => acc + curr, 0); const percentages: Record = {}; for (const [category, hits] of Object.entries(obj)) { const percent = (hits / totalHits) * 100; percentages[category] = percent.toFixed(2); } return percentages; } const makeSVG = (data: Record) => { const svgContent = Object.entries(data) .map(([language, percentage], index) => { const color = langColors[language] || "#111111"; const circleY = 60 + (index * 25); // Adjust Y position for each language return `${language}: ${percentage}%`; }) .join(''); return `${svgContent}`; } Bun.serve({ async fetch(request, server) { const { searchParams } = new URL(request.url); const type = searchParams.get("type") as "users" | "orgs"; const name = searchParams.get("name") as string; if (!type) { return new Response("Please provide a type parameter, users or orgs", { status: 400 }); } if (type !== "users" && type !== "orgs") { return new Response("Type parameter must be either users or orgs", { status: 400 }); } if (!name) { return new Response("Please provide a name parameter", { status: 400 }); } const data = await getTopLangs(type, name); return new Response(makeSVG(data), { headers: { "Content-Type": "image/svg+xml" } }); }, })