From b99aadea82ff956b08b0e367a051794438d4c1ce Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Sat, 6 Sep 2025 08:04:30 +0530 Subject: [PATCH] Fix#564: Update sponsors command to handle new API response format (#565) Co-authored-by: Aman Varshney --- apps/cli/src/utils/sponsors.ts | 110 +++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 31 deletions(-) diff --git a/apps/cli/src/utils/sponsors.ts b/apps/cli/src/utils/sponsors.ts index a61fd57..dbddc4d 100644 --- a/apps/cli/src/utils/sponsors.ts +++ b/apps/cli/src/utils/sponsors.ts @@ -1,25 +1,49 @@ import { log, outro, spinner } from "@clack/prompts"; +import { consola } from "consola"; import pc from "picocolors"; -export interface SponsorEntry { - readonly sponsor: { - readonly login: string; - readonly name?: string | null; - readonly avatarUrl?: string | null; - readonly websiteUrl?: string | null; - readonly linkUrl?: string | null; - readonly type?: string; +type SponsorSummary = { + total_sponsors: number; + total_lifetime_amount: number; + total_current_monthly: number; + special_sponsors: number; + current_sponsors: number; + past_sponsors: number; + backers: number; + top_sponsor?: { + name: string; + amount: number; }; - readonly isOneTime: boolean; - readonly monthlyDollars?: number; - readonly tierName?: string; -} +}; -export const SPONSORS_JSON_URL = "https://sponsors.amanv.dev/sponsors.json"; +type Sponsor = { + name?: string; + githubId: string; + avatarUrl: string; + websiteUrl?: string; + githubUrl: string; + tierName?: string; + sinceWhen: string; + transactionCount: number; + totalProcessedAmount?: number; + formattedAmount?: string; +}; + +type SponsorEntry = { + generated_at: string; + summary: SponsorSummary; + specialSponsors: Sponsor[]; + sponsors: Sponsor[]; + pastSponsors: Sponsor[]; + backers: Sponsor[]; +}; + +export const SPONSORS_JSON_URL = + "https://sponsors.better-t-stack.dev/sponsors.json"; export async function fetchSponsors( url: string = SPONSORS_JSON_URL, -): Promise { +): Promise { const s = spinner(); s.start("Fetching sponsors…"); @@ -29,13 +53,14 @@ export async function fetchSponsors( throw new Error(`Failed to fetch sponsors: ${response.statusText}`); } - const sponsors = (await response.json()) as SponsorEntry[]; + const sponsors = (await response.json()) as SponsorEntry; s.stop("Sponsors fetched successfully!"); return sponsors; } -export function displaySponsors(sponsors: SponsorEntry[]) { - if (sponsors.length === 0) { +export function displaySponsors(sponsors: SponsorEntry) { + const { total_sponsors } = sponsors.summary; + if (total_sponsors === 0) { log.info("No sponsors found. You can be the first one! ✨"); outro( pc.cyan( @@ -45,24 +70,47 @@ export function displaySponsors(sponsors: SponsorEntry[]) { return; } - sponsors.forEach((entry: SponsorEntry, idx: number) => { - const sponsor = entry.sponsor; - const displayName = sponsor.name ?? sponsor.login; - const tier = entry.tierName ? ` (${entry.tierName})` : ""; + displaySponsorsBox(sponsors); - log.step(`${idx + 1}. ${pc.green(displayName)}${pc.yellow(tier)}`); - log.message(` ${pc.dim("GitHub:")} https://github.com/${sponsor.login}`); - - const website = sponsor.websiteUrl ?? sponsor.linkUrl; - if (website) { - log.message(` ${pc.dim("Website:")} ${website}`); - } - }); - - log.message(""); + if (total_sponsors - sponsors.specialSponsors.length > 0) { + log.message( + pc.blue( + `+${total_sponsors - sponsors.specialSponsors.length} more amazing sponsors.\n`, + ), + ); + } outro( pc.magenta( "Visit https://github.com/sponsors/AmanVarshney01 to become a sponsor.", ), ); } + +function displaySponsorsBox(sponsors: SponsorEntry) { + if (sponsors.specialSponsors.length === 0) { + return; + } + + let output = `${pc.bold(pc.cyan("-> Special Sponsors"))}\n\n`; + + sponsors.specialSponsors.forEach((sponsor: Sponsor, idx: number) => { + const displayName = sponsor.name ?? sponsor.githubId; + const tier = sponsor.tierName + ? ` ${pc.yellow(`(${sponsor.tierName})`)}` + : ""; + + output += `${pc.green(`• ${displayName}`)}${tier}\n`; + output += ` ${pc.dim("GitHub:")} https://github.com/${sponsor.githubId}\n`; + + const website = sponsor.websiteUrl ?? sponsor.githubUrl; + if (website) { + output += ` ${pc.dim("Website:")} ${website}\n`; + } + + if (idx < sponsors.specialSponsors.length - 1) { + output += "\n"; + } + }); + + consola.box(output); +}