121 lines · 4.9 KB
import { env } from "cloudflare:workers";
import { all, first } from "./db";
import { branchSha, listRefs } from "./git/refs";
import { withStore } from "./git/store";
import { renderMarkdown } from "./markdown";
import { REPO_SELECT } from "./repos";
import type { RepoRow } from "~/lib/types";

const DAY_MS = 24 * 60 * 60 * 1000;
const GRAPH_WEEKS = 52;
const WEEK_DAYS = 7;
const README_NAMES = new Set(["readme.md", "readme.markdown"]);
const MAX_README_BYTES = 256 * 1024;
const README_CACHE_TTL_SECONDS = 60 * 60 * 24 * 7;
const decoder = new TextDecoder();

export type ContributionBreakdown = { commits: number; pulls: number; issues: number; reviews: number; other: number };

export type ContributionDay = {
  date: string;
  count: number;
  breakdown: ContributionBreakdown | null;
  repos: string[];
};

const MAX_DAY_REPOS = 3;

type Category = keyof ContributionBreakdown;

function categoryOf(kind: string): Category {
  if (kind === "push" || kind === "ref_created") return "commits";
  if (kind.startsWith("pull_")) return "pulls";
  if (kind.startsWith("issue_")) return "issues";
  if (kind === "comment" || kind.startsWith("review")) return "reviews";
  return "other";
}

/** Daily repository activity counts (public repos unless `includePrivate`) for roughly the last year, oldest first, aligned to whole weeks, with a per-day breakdown for hover cards. */
export async function contributionGraph(accountId: string, includePrivate: boolean): Promise<ContributionDay[]> {
  const now = Date.now();