Skip to content

Commit 77dce1a

Browse files
Fix supporters data pagination and dedup regressions
- serialize GraphQL cursor correctly for first-page fetches - remove duplicate sponsorEntity fallback and centralize sponsor mapping - deduplicate GitHub sponsors across sponsorship and activity sources - prefer OpenCollective profile links with website fallback in UI Assisted-by: Codex Co-authored-by: Aviv Keller <me@aviv.sh>
1 parent 29829ce commit 77dce1a

File tree

2 files changed

+24
-25
lines changed

2 files changed

+24
-25
lines changed

apps/site/components/Common/Supporters/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ type SupportersListProps = {
1111

1212
const SupportersList: FC<SupportersListProps> = ({ supporters }) => (
1313
<div className="flex max-w-full flex-wrap items-center justify-center gap-1">
14-
{supporters.map(({ name, image, url }) => (
14+
{supporters.map(({ name, image, profile, url }) => (
1515
<Avatar
1616
nickname={name}
1717
fallback={getAcronymFromString(name)}
1818
image={image}
1919
key={name}
20-
url={url}
20+
url={profile || url}
2121
/>
2222
))}
2323
</div>

apps/site/next-data/generators/supportersData.mjs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,25 @@ async function fetchGithubSponsorsData() {
4646
}
4747

4848
const sponsors = [];
49+
const seenSponsorKeys = new Set();
50+
51+
const addSponsor = node => {
52+
const s = node.sponsor || node.sponsorEntity; // support different field names
53+
const key = s?.id ?? s?.login ?? s?.url ?? s?.name ?? s?.avatarUrl;
54+
if (key && seenSponsorKeys.has(key)) {
55+
return;
56+
}
57+
if (key) {
58+
seenSponsorKeys.add(key);
59+
}
60+
61+
sponsors.push({
62+
name: s?.name || s?.login || null,
63+
image: s?.avatarUrl || null,
64+
url: s?.url || null,
65+
source: 'github',
66+
});
67+
};
4968

5069
// Fetch sponsorship pages
5170
let cursor = null;
@@ -64,17 +83,7 @@ async function fetchGithubSponsorsData() {
6483
}
6584

6685
const { nodes, pageInfo } = nodeRes;
67-
const mapped = nodes.map(n => {
68-
const s = n.sponsor || n.sponsorEntity || n.sponsorEntity; // support different field names
69-
return {
70-
name: s?.name || s?.login || null,
71-
image: s?.avatarUrl || null,
72-
url: s?.url || null,
73-
source: 'github',
74-
};
75-
});
76-
77-
sponsors.push(...mapped);
86+
nodes.forEach(addSponsor);
7887

7988
if (!pageInfo.hasNextPage) {
8089
break;
@@ -96,17 +105,7 @@ async function fetchGithubSponsorsData() {
96105
}
97106

98107
const { nodes } = nodeRes;
99-
const mapped = nodes.map(n => {
100-
const s = n.sponsor || n.sponsorEntity || n.sponsorEntity; // support different field names
101-
return {
102-
name: s?.name || s?.login || null,
103-
image: s?.avatarUrl || null,
104-
url: s?.url || null,
105-
source: 'github',
106-
};
107-
});
108-
109-
sponsors.push(...mapped);
108+
nodes.forEach(addSponsor);
110109

111110
return sponsors;
112111
}
@@ -115,7 +114,7 @@ function sponsorshipsQuery(cursor = null) {
115114
return `
116115
query {
117116
organization(login: "nodejs") {
118-
sponsorshipsAsMaintainer (first: 100, includePrivate: false, after: "${cursor}", activeOnly: false) {
117+
sponsorshipsAsMaintainer (first: 100, includePrivate: false, after: ${JSON.stringify(cursor)}, activeOnly: false) {
119118
nodes {
120119
sponsor: sponsorEntity {
121120
...on User {

0 commit comments

Comments
 (0)