import type { GitHubRepoData } from "@/types"; export function parseGitHubUrl(url: string): { owner: string; repo: string } | null { const trimmed = url.trim(); const patterns = [ /github\.com\/([^/\s]+)\/([^/\s#?]+)/i, /^([^/\s]+)\/([^/\s]+)$/, ]; for (const pattern of patterns) { const match = trimmed.match(pattern); if (match) { return { owner: match[1].replace(/\.git$/, ""), repo: match[2].replace(/\.git$/, ""), }; } } return null; } async function githubFetch(path: string): Promise { const headers: Record = { Accept: "application/vnd.github+json", "User-Agent": "caption-studio", }; // ponytail: a placeholder token 401s every request — treat it as absent const token = process.env.GITHUB_TOKEN?.trim(); if (token && token.length > 20) { headers.Authorization = `Bearer ${token}`; } return fetch(`https://api.github.com${path}`, { headers }); } export async function fetchRepoData(url: string): Promise { const parsed = parseGitHubUrl(url); if (!parsed) throw new Error("Invalid GitHub repo URL"); const { owner, repo } = parsed; const repoRes = await githubFetch(`/repos/${owner}/${repo}`); if (!repoRes.ok) { throw new Error( `GitHub repo fetch failed (${repoRes.status}): ${owner}/${repo}`, ); } const repoData = await repoRes.json(); let readme = ""; const readmeRes = await githubFetch(`/repos/${owner}/${repo}/readme`); if (readmeRes.ok) { readme = await readmeRes.text(); if (readme.length > 4000) readme = readme.slice(0, 4000) + "..."; } return { owner, repo, fullName: repoData.full_name as string, htmlUrl: repoData.html_url as string, description: (repoData.description as string) || "", stars: (repoData.stargazers_count as number) || 0, language: (repoData.language as string) || "Unknown", topics: (repoData.topics as string[]) || [], readme, }; }