const axios = require("axios"); require("dotenv").config(); async function fetchStats(username) { const res = await axios({ url: "https://api.github.com/graphql", method: "post", headers: { Authorization: `bearer ${process.env.GITHUB_TOKEN}`, }, data: { query: ` query userInfo($login: String!) { user(login: $login) { name repositoriesContributedTo(first: 100, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) { totalCount } contributionsCollection { totalCommitContributions } pullRequests(first: 100) { totalCount } issues(first: 100) { totalCount } repositories(first: 100) { nodes { stargazers { totalCount } } } } } `, variables: { login: username, }, }, }); const stats = { name: "", totalPRs: 0, totalCommits: 0, totalIssues: 0, totalStars: 0, contributedTo: 0, }; if (res.data.error) return stats; const user = res.data.data.user; stats.name = user.name; stats.totalIssues = user.issues.totalCount; stats.totalCommits = user.contributionsCollection.totalCommitContributions; stats.totalPRs = user.pullRequests.totalCount; stats.contributedTo = user.repositoriesContributedTo.totalCount; stats.totalStars = user.repositories.nodes.reduce((prev, curr) => { return prev + curr.stargazers.totalCount; }, 0); return stats; } const renderSVG = (stats, options) => { const { name, totalStars, totalCommits, totalIssues, totalPRs, contributedTo, } = stats; const { hide, show_icons, hide_border } = options || {}; const STAT_MAP = { stars: ` Total Stars: ${totalStars} `, commits: ` 🕗 Total Commits: ${totalCommits} `, prs: ` 🔀 Total PRs: ${totalPRs} `, issues: ` Total Issues: ${totalIssues} `, contribs: ` 📕 Contributed to: ${contributedTo} repos `, }; const statItems = Object.keys(STAT_MAP) .filter((key) => !hide.includes(key)) .map((key) => STAT_MAP[key]); const height = 45 + (statItems.length + 1) * 25; return ` ${ !hide_border && `` } ${name}'s GitHub Stats ${statItems} `; }; module.exports = async (req, res) => { const username = req.query.username; const hide = req.query.hide; const hide_border = req.query.hide_border; const show_icons = req.query.show_icons; let { name, totalPRs, totalCommits, totalStars, totalIssues, contributedTo, } = await fetchStats(username); res.setHeader("Content-Type", "image/svg+xml"); res.send( renderSVG( { name, totalStars, totalCommits, totalIssues, totalPRs, contributedTo, }, { hide: JSON.parse(hide || "[]"), show_icons, hide_border } ) ); };