diff --git a/scripts/generate-og-images.mjs b/scripts/generate-og-images.mjs index 7cbc9ddcd..988d8a57c 100644 --- a/scripts/generate-og-images.mjs +++ b/scripts/generate-og-images.mjs @@ -6,6 +6,7 @@ import satori from 'satori'; import sharp from 'sharp'; import imageSize from 'image-size'; import { Resvg } from '@resvg/resvg-js'; +import { getRepositoryRank } from '../src/lib/github'; const ALL_ROADMAP_DIR = path.join(process.cwd(), '/src/data/roadmaps'); const ALL_BEST_PRACTICE_DIR = path.join( @@ -28,6 +29,11 @@ const alreadyGeneratedImages = await fs.readdir( }, ); +async function updateRank() { + const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap'); + document.getElementById('repo-rank').innerText = `${repoRank} most starred GitHub project`; +} + async function getAllRoadmaps() { const allRoadmapDirNames = await fs.readdir(ALL_ROADMAP_DIR); @@ -142,6 +148,8 @@ async function getAllBestPracticeImageIds() { } async function generateResourceOpenGraph() { + await updateRank(); + const allRoadmaps = (await getAllRoadmaps()).filter( (roadmap) => !alreadyGeneratedImages.includes(`roadmaps/${roadmap.id}.png`), ); @@ -371,8 +379,8 @@ function getRoadmapDefaultTemplate({ title, description }) { /> -
- 6th most starred GitHub project +
+ Loading...
diff --git a/src/components/OpenSourceBanner.astro b/src/components/OpenSourceBanner.astro index b04427c88..42905aec0 100644 --- a/src/components/OpenSourceBanner.astro +++ b/src/components/OpenSourceBanner.astro @@ -1,10 +1,12 @@ --- -import { getFormattedStars } from '../lib/github'; +import { getFormattedStars, getRepositoryRank } from '../lib/github'; import Icon from './AstroIcon.astro'; import { getDiscordInfo } from '../lib/discord'; import OpenSourceStat from './OpenSourceStat.astro'; -const starCount = await getFormattedStars('kamranahmedse/developer-roadmap'); +const repoName = 'kamranahmedse/developer-roadmap'; +const starCount = await getFormattedStars(repoName); +const repoRank = await getRepositoryRank(repoName); const discordInfo = await getDiscordInfo(); --- @@ -16,7 +18,7 @@ const discordInfo = await getDiscordInfo(); href='https://github.com/search?o=desc&q=stars%3A%3E100000&s=stars&type=Repositories' target='_blank' class='font-medium text-gray-600 underline underline-offset-2 hover:text-black' - >6th most starred project on GitHub{repoRank} most starred project on GitHub and is visited by hundreds of thousands of developers every month.

diff --git a/src/components/OpenSourceStat.astro b/src/components/OpenSourceStat.astro index 54d9ca814..36dee7ac9 100644 --- a/src/components/OpenSourceStat.astro +++ b/src/components/OpenSourceStat.astro @@ -1,6 +1,7 @@ --- import { ChevronUp } from 'lucide-react'; import Icon from './AstroIcon.astro'; +import { getRepositoryRank } from '../lib/github'; export interface Props { value: string; text: string; @@ -11,6 +12,8 @@ const { value, text } = Astro.props; const isGitHubStars = text.toLowerCase() === 'github stars'; const isRegistered = text.toLowerCase() === 'registered users'; const isDiscordMembers = text.toLowerCase() === 'discord members'; + +const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap'); ---
- Rank 6th + Rank {repoRank}  out of 28M!

) diff --git a/src/lib/github.ts b/src/lib/github.ts index 26e7988a8..ffe36c467 100644 --- a/src/lib/github.ts +++ b/src/lib/github.ts @@ -32,3 +32,42 @@ export async function getFormattedStars( return formatter.format(stars); } + +const defaultRanking = "7th"; +let ranking: string; + +export async function getRepositoryRank( + repo = 'kamranahmedse/developer-roadmap', +): Promise { + try { + const response = await fetch(`https://api.github.com/search/repositories?q=stars:>100000&o=desc&s=stars`); + const json = await response.json(); + const repositories = json.items || []; + for (let rank = 1; rank <= repositories.length; rank++) { + if (repositories[rank - 1].full_name.toLowerCase() === repo.toLowerCase()) { + ranking = `${rank}${getOrdinalSuffix(rank)}`; + } + } + } catch (e) { + console.log('Failed to fetch ranking'); + ranking = defaultRanking; + } + + return ranking; +} + +function getOrdinalSuffix(rank: number): string { + if (11 <= rank % 100 && rank % 100 <= 13) { + return 'th'; + } + switch (rank % 10) { + case 1: + return 'st'; + case 2: + return 'nd'; + case 3: + return 'rd'; + default: + return 'th'; + } +} \ No newline at end of file diff --git a/src/pages/about.astro b/src/pages/about.astro index c78a314ee..1371bb140 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -1,5 +1,8 @@ --- import BaseLayout from '../layouts/BaseLayout.astro'; +import { getRepositoryRank } from '../lib/github.ts'; + +const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap'); --- @@ -73,7 +76,7 @@ import BaseLayout from '../layouts/BaseLayout.astro'; href='https://github.com/search?o=desc&q=stars%3A%3E100000&s=stars&type=Repositories' target='_blank' class='font-bold underline' - >the 6th most starred opensource project on GitHubthe {repoRank} most starred opensource project on GitHub and gets visited by hundreds of thousands of developers every month. We also have newsletter with 150,000+ developers. All the roadmaps are created and reviewed by community and several subject matter experts.