From 19291076fd16ee8417bbd1f526b9d9d2904c1fb5 Mon Sep 17 00:00:00 2001 From: Simeon Radivoev Date: Thu, 7 May 2026 02:33:52 +0300 Subject: [PATCH] fix: Used github releases download count --- src/components/Stats.astro | 17 +++------ src/scripts/getters.ts | 74 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/components/Stats.astro b/src/components/Stats.astro index bd492ad..9843514 100644 --- a/src/components/Stats.astro +++ b/src/components/Stats.astro @@ -11,6 +11,7 @@ import { emulators, appContributorsData, storeContributorsData, + totalDownloads, } from "../scripts/getters"; --- @@ -29,7 +30,9 @@ import {
- 10+ + {totalDownloads}+
Downloads
@@ -72,15 +75,3 @@ import { - - diff --git a/src/scripts/getters.ts b/src/scripts/getters.ts index 31a490f..f254764 100644 --- a/src/scripts/getters.ts +++ b/src/scripts/getters.ts @@ -32,6 +32,80 @@ export const releaseData = await fetch( return { tag_name: "unknown" }; }); +async function getTotalDownloads(owner: string, repo: string): Promise { + let totalDownloads = 0; + let cursor: string | null = null; + let hasNextPage = true; + + while (hasNextPage) { + const res = await fetch("https://api.github.com/graphql", { + method: "POST", + headers: { + ...githubHeaders.headers, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + query: `{ + repository(owner: "${owner}", name: "${repo}") { + releases(first: 100${cursor ? `, after: "${cursor}"` : ""}) { + pageInfo { + hasNextPage + endCursor + } + nodes { + releaseAssets(first: 100) { + nodes { + downloadCount + } + } + } + } + } + }`, + }), + }); + + if (!res.ok) { + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + } + + const json: any = await res.json(); + + if (json.errors) { + throw new Error( + `GraphQL error: ${json.errors.map((e: any) => e.message).join(", ")}`, + ); + } + + const releases = json.data?.repository?.releases; + + if (!releases) { + throw new Error( + `Repository ${owner}/${repo} not found or not accessible`, + ); + } + + for (const release of releases.nodes) { + for (const asset of release.releaseAssets.nodes) { + totalDownloads += asset.downloadCount; + } + } + + hasNextPage = releases.pageInfo.hasNextPage; + cursor = releases.pageInfo.endCursor; + } + + return totalDownloads; +} + +export const totalDownloads = await getTotalDownloads( + "simeonradivoev", + "gameflow-deck", +).catch((e) => { + console.error(e); + return 0; +}); + export const appContributorsData = await fetch( "https://api.github.com/repos/simeonradivoev/gameflow-deck/contributors", githubHeaders,