Recipe: GitHub API

Map GET /repos/{owner}/{repo}/commits directly into Commit[]. No live demo here — production usage needs auth (rate limits) and the REST endpoint paginates at 100 per page.

import type { Commit } from "@/components/git-graph/types";

type GitHubCommit = {
  sha: string;
  parents: { sha: string }[];
  commit: {
    author: { name: string; email: string; date: string };
    message: string;
  };
  author: { avatar_url: string } | null;
};

export async function fetchCommits(owner: string, repo: string): Promise<Commit[]> {
  const res = await fetch(
    `https://api.github.com/repos/${owner}/${repo}/commits?per_page=100`,
    { headers: { Accept: "application/vnd.github+json" } },
  );
  if (!res.ok) throw new Error(`GitHub API: ${res.status}`);
  const data = (await res.json()) as GitHubCommit[];

  return data.map((c) => ({
    sha: c.sha,
    parents: c.parents.map((p) => p.sha),
    author: {
      name: c.commit.author.name,
      email: c.commit.author.email,
      ...(c.author?.avatar_url ? { avatarUrl: c.author.avatar_url } : {}),
    },
    // Headline only — <GitGraph> renders one line per commit.
    message: c.commit.message.split("\n", 1)[0] ?? "",
    timestamp: c.commit.author.date,
  }));
}

Caveats