Files
website/src/lib/server/gitea.ts
T

39 lines
1.3 KiB
TypeScript

const timeZone = 'America/New_York';
interface HeatmapEntry {
timestamp: number;
contributions: number;
}
export interface GiteaProfile {
baseUrl: string;
username: string;
profileUrl: string;
}
export function parseGiteaProfile(profileUrl: string | undefined): GiteaProfile | null {
if (!profileUrl) return null;
const url = new URL(profileUrl);
const username = url.pathname.split('/').filter(Boolean)[0];
return username ? { baseUrl: url.origin, username, profileUrl } : null;
}
function easternDate(timestampSeconds: number): string {
return new Intl.DateTimeFormat('en-CA', { timeZone, year: 'numeric', month: '2-digit', day: '2-digit' }).format(
new Date(timestampSeconds * 1000)
);
}
export async function fetchGiteaDailyCounts({ baseUrl, username }: GiteaProfile): Promise<Map<string, number>> {
const response = await fetch(`${baseUrl}/api/v1/users/${username}/heatmap`, { headers: { Accept: 'application/json' } });
if (!response.ok) throw new Error(`Gitea heatmap returned ${response.status}`);
const entries: HeatmapEntry[] = await response.json();
const dailyCounts = new Map<string, number>();
for (const { timestamp, contributions } of entries) {
const date = easternDate(timestamp);
dailyCounts.set(date, (dailyCounts.get(date) ?? 0) + contributions);
}
return dailyCounts;
}