108 lines · 4.0 KB
import { env } from "cloudflare:workers";
import { isTakenDown } from "~/lib/account-disable";
import type { AccountCardData, RepoCardData } from "~/lib/og";
import { accountOgPath, cardLanguages, repoOgPath, siteOgPath } from "~/lib/og";
import { parseLanguages } from "~/lib/languages";
import { parseTopics } from "~/lib/topics";
import type { RepoRow } from "~/lib/types";
import { first } from "../db";
import { repoDb } from "../scoped-db";
import { repoTakenDown } from "../repos";
import { isScratchRepo } from "../sites/config";

const CARD_TOPICS = 5;

/** Only what an anonymous visitor can see: public, not hidden, not taken down. Anything else gets the site card. */
export function repoCardVisible(
  repo: Pick<RepoRow, "visibility" | "hidden_at" | "owner_disabled_at" | "owner_disabled_reason" | "owner_id">,
): boolean {
  return repo.visibility === "public" && !repo.hidden_at && !repoTakenDown(repo) && !isScratchRepo(repo);
}

export async function repoCardData(repo: RepoRow): Promise<RepoCardData> {
  const [owner, release] = await Promise.all([
    first<{ avatar_key: string | null }>("SELECT avatar_key FROM accounts WHERE id = ?", repo.owner_id),
    repoDb(repo.id).first<{ tag: string }>(
      "SELECT tag FROM releases WHERE repo_id = ? AND draft = 0 ORDER BY COALESCE(published_at, created_at) DESC LIMIT 1",
      repo.id,
    ),
  ]);
  return {
    owner: repo.owner_name,
    name: repo.name,
    description: repo.description,
    stars: repo.stars_count,
    forks: repo.forks_count,
    openIssues: repo.open_issues_count,
    openPulls: repo.open_pulls_count,
    avatarKey: owner?.avatar_key ?? null,
    latestRelease: release?.tag ?? null,
    topics: parseTopics(repo.topics).slice(0, CARD_TOPICS),