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, ): boolean { return repo.visibility === "public" && !repo.hidden_at && !repoTakenDown(repo) && !isScratchRepo(repo); } export async function repoCardData(repo: RepoRow): Promise { 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), languages: cardLanguages(parseLanguages(repo.languages)), }; } /** The card path a repository page advertises; private, hidden and taken-down repositories advertise the site card. */ export async function repoOgImage(repo: RepoRow): Promise { return repoCardVisible(repo) ? repoOgPath(await repoCardData(repo)) : siteOgPath(); } type AccountRow = { id: string; name: string; kind: "user" | "org"; display_name: string | null; bio: string | null; avatar_key: string | null; disabled_at: number | null; disabled_reason: string | null; }; export async function accountCardData(name: string): Promise { const account = await first( "SELECT id, name, kind, display_name, bio, avatar_key, disabled_at, disabled_reason FROM accounts WHERE name = ?", name, ); if (!account || isTakenDown(account)) return null; const repos = await first<{ count: number }>( "SELECT COUNT(*) AS count FROM repos WHERE owner_id = ? AND visibility = 'public' AND hidden_at IS NULL", account.id, ); return { name: account.name, kind: account.kind, displayName: account.display_name, bio: account.bio, avatarKey: account.avatar_key, publicRepos: repos?.count ?? 0, }; } export async function accountOgImage(name: string): Promise { const card = await accountCardData(name); return card ? accountOgPath(card) : siteOgPath(); } const AVATAR_PIXELS = 360; /** The owner's avatar as a PNG data URI; null (initial tile) when there is none or it can't be read. */ export async function avatarDataUri(key: string | null): Promise { if (!key) return null; try { const object = await env.BUCKET.get(`avatars/${key}`); if (!object) return null; const transformed = await env.IMAGES.input(object.body) .transform({ width: AVATAR_PIXELS, height: AVATAR_PIXELS, fit: "cover" }) .output({ format: "image/png" }); const bytes = new Uint8Array(await transformed.response().arrayBuffer()); let binary = ""; for (let index = 0; index < bytes.length; index += 0x8000) { binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000)); } return `data:image/png;base64,${btoa(binary)}`; } catch (error) { console.warn("OG avatar unavailable", key, error); return null; } }