import { NextApiRequest, NextApiResponse } from 'next' const AV_SIZE = 32 const PADDING = 4 const COLS = 16 type SponsorResult = { url: string; login: string } type QueryResult = { node: { sponsorEntity: { avatarUrl: string; login: string } } } function getXY(i: number) { return [(i % COLS) * (AV_SIZE + PADDING), Math.floor(i / COLS) * (AV_SIZE + PADDING)] } export default async function GetSponsors(req: NextApiRequest, res: NextApiResponse) { const sponsorInfo = await fetch('https://api.github.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'bearer ' + process.env.GITHUB_API_SECRET, }, body: JSON.stringify({ query: `{ viewer { sponsors(first: 0) { totalCount } sponsorshipsAsMaintainer(first: 100, orderBy: { field:CREATED_AT, direction:DESC }) { edges { node { sponsorEntity { ...on User { avatarUrl login } } } } } } }`, }), }).then((res) => res.json()) const totalCount: number = sponsorInfo.data.viewer.sponsors.totalCount const results = ( sponsorInfo.data.viewer.sponsorshipsAsMaintainer.edges as QueryResult[] ).map((edge) => ({ url: edge.node.sponsorEntity.avatarUrl?.replace(/&/g, '&') ?? '', login: edge.node.sponsorEntity.login, })) if (results.length % COLS <= 2) { results.pop() results.pop() results.pop() } // Avatars const avatars = results .map(({ url, login }, i) => { const [x, y] = getXY(i) return `${login}` }) .join('') // More text const [x, y] = getXY(results.length) const width = (AV_SIZE + PADDING) * 3 const more = ` ...and ${totalCount - 100} more!` const svgImage = ` ${avatars}${more}` // const html = ` //
// ${images.join(` // `)} //
` res .status(200) .setHeader('Cache-Control', 'max-age=604800') .setHeader('Content-Type', 'image/svg+xml') .send(svgImage) }