= {
'X-GitHub-Api-Version': '2022-11-28',
- },
- })
- return res.data
+ }
+ if (process.env.CONTRIBUTORS_PAT) {
+ headers['Authorization'] = `Bearer ${process.env.CONTRIBUTORS_PAT}`
+ }
+ const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/collaborators`, {
+ headers,
+ })
+ if (!res.ok) {
+ throw new Error(`GitHub API returned ${res.status}`)
+ }
+ return await res.json()
+ } catch (error) {
+ // Fallback when GitHub API is not accessible or auth fails
+ console.warn('Failed to fetch GitHub contributors, using fallback', error)
+ return Array.from({ length: 50 }).map((_, i) => ({
+ login: `contributor${i}`,
+ html_url: 'https://github.com',
+ avatar_url: '',
+ }))
+ }
}
const cachedFetchContributors = cache(fetchContributors)
@@ -72,7 +89,7 @@ export async function Backers({
repo: string
limit: number
}) {
- const backers = (await fetchBackers(repo)).slice(0, limit)
+ const backers = (await cachedFetchBackers(repo)).slice(0, limit)
return (
@@ -97,24 +114,30 @@ export async function Backers({
}
async function fetchBackers(repo: string) {
- const res = await fetch(`https://opencollective.com/${repo}/members/users.json`)
- const backers: {
- profile: string
- name: string
- image: string
- totalAmountDonated: number
- }[] = await res.json()
+ try {
+ const res = await fetch(`https://opencollective.com/${repo}/members/users.json`)
+ const backers: {
+ profile: string
+ name: string
+ image: string
+ totalAmountDonated: number
+ }[] = await res.json()
- const backersMap = new Map(backers.map((backer) => [backer.name, backer]))
- backersMap.forEach((backer) => {
- const existingBacker = backersMap.get(backer.name)
- if (existingBacker && backer.totalAmountDonated >= existingBacker.totalAmountDonated) {
- backersMap.set(backer.name, backer) // replace with the backer with the highest donation
- }
- })
- const uniqueBackers = Array.from(backersMap.values())
+ const backersMap = new Map(backers.map((backer) => [backer.name, backer]))
+ backersMap.forEach((backer) => {
+ const existingBacker = backersMap.get(backer.name)
+ if (existingBacker && backer.totalAmountDonated >= existingBacker.totalAmountDonated) {
+ backersMap.set(backer.name, backer) // replace with the backer with the highest donation
+ }
+ })
+ const uniqueBackers = Array.from(backersMap.values())
- return uniqueBackers.sort((a, b) => b.totalAmountDonated - a.totalAmountDonated)
+ return uniqueBackers.sort((a, b) => b.totalAmountDonated - a.totalAmountDonated)
+ } catch (error) {
+ // Fallback when OpenCollective API is not accessible
+ console.warn('Failed to fetch OpenCollective backers, using empty array', error)
+ return []
+ }
}
const cachedFetchBackers = cache(fetchBackers)
diff --git a/tsconfig.json b/tsconfig.json
index 3686cd15..0e8f4eee 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,7 +10,7 @@
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
- "jsx": "preserve",
+ "jsx": "react-jsx",
"baseUrl": "src",
"incremental": true,
"allowJs": true,
@@ -24,6 +24,12 @@
"@/*": ["./*"]
}
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
"exclude": ["node_modules", "docs"]
}