Skip to content

Commit 118cc6f

Browse files
committed
feat: add role parameter refer anuraghazra#2459
1 parent 8108ba1 commit 118cc6f

File tree

5 files changed

+66
-47
lines changed

5 files changed

+66
-47
lines changed

api/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default async (req, res) => {
4848
border_color,
4949
rank_icon,
5050
show,
51+
role,
5152
} = req.query;
5253
res.setHeader("Content-Type", "image/svg+xml");
5354

@@ -94,6 +95,7 @@ export default async (req, res) => {
9495
showStats.includes("discussions_started"),
9596
showStats.includes("discussions_answered"),
9697
parseInt(commits_year, 10),
98+
parseArray(role),
9799
);
98100
const cacheSeconds = resolveCacheSeconds({
99101
requested: parseInt(cache_seconds, 10),

package-lock.json

Lines changed: 7 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common/ops.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,37 @@ const dateDiff = (d1, d2) => {
113113
return Math.round(diff / (1000 * 60));
114114
};
115115

116+
/**
117+
* Valid owner affiliations for GitHub GraphQL API.
118+
*/
119+
const VALID_OWNER_AFFILIATIONS = [
120+
"OWNER",
121+
"COLLABORATOR",
122+
"ORGANIZATION_MEMBER",
123+
];
124+
125+
/**
126+
* Parse owner affiliations from string array.
127+
*
128+
* @param {string[]} affiliations Array of affiliations to parse.
129+
* @returns {string[]} Parsed and validated affiliations. Defaults to ["OWNER"] if empty or invalid.
130+
*/
131+
const parseOwnerAffiliations = (affiliations) => {
132+
if (
133+
!affiliations ||
134+
!Array.isArray(affiliations) ||
135+
affiliations.length === 0
136+
) {
137+
return ["OWNER"];
138+
}
139+
140+
const validAffiliations = affiliations
141+
.map((a) => a.toUpperCase().trim())
142+
.filter((a) => VALID_OWNER_AFFILIATIONS.includes(a));
143+
144+
return validAffiliations.length > 0 ? validAffiliations : ["OWNER"];
145+
};
146+
116147
export {
117148
parseBoolean,
118149
parseArray,
@@ -121,4 +152,5 @@ export {
121152
chunkArray,
122153
parseEmojis,
123154
dateDiff,
155+
parseOwnerAffiliations,
124156
};

src/fetchers/stats.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import { CustomError, MissingParamError } from "../common/error.js";
1111
import { wrapTextMultiline } from "../common/fmt.js";
1212
import { request } from "../common/http.js";
1313

14+
import { parseOwnerAffiliations } from "../common/ops.js";
15+
1416
dotenv.config();
1517

1618
// GraphQL queries.
1719
const GRAPHQL_REPOS_FIELD = `
18-
repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
20+
repositories(first: 100, after: $after, ownerAffiliations: $ownerAffiliations, orderBy: {direction: DESC, field: STARGAZERS}) {
1921
totalCount
2022
nodes {
2123
name
@@ -31,15 +33,15 @@ const GRAPHQL_REPOS_FIELD = `
3133
`;
3234

3335
const GRAPHQL_REPOS_QUERY = `
34-
query userInfo($login: String!, $after: String) {
36+
query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
3537
user(login: $login) {
3638
${GRAPHQL_REPOS_FIELD}
3739
}
3840
}
3941
`;
4042

4143
const GRAPHQL_STATS_QUERY = `
42-
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $startTime: DateTime = null) {
44+
query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation], $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $startTime: DateTime = null) {
4345
user(login: $login) {
4446
name
4547
login
@@ -103,6 +105,7 @@ const fetcher = (variables, token) => {
103105
*
104106
* @param {object} variables Fetcher variables.
105107
* @param {string} variables.username GitHub username.
108+
* @param {string[]} variables.ownerAffiliations The owner affiliations to filter by. Default: ["OWNER"].
106109
* @param {boolean} variables.includeMergedPullRequests Include merged pull requests.
107110
* @param {boolean} variables.includeDiscussions Include discussions.
108111
* @param {boolean} variables.includeDiscussionsAnswers Include discussions answers.
@@ -113,6 +116,7 @@ const fetcher = (variables, token) => {
113116
*/
114117
const statsFetcher = async ({
115118
username,
119+
ownerAffiliations,
116120
includeMergedPullRequests,
117121
includeDiscussions,
118122
includeDiscussionsAnswers,
@@ -126,6 +130,7 @@ const statsFetcher = async ({
126130
login: username,
127131
first: 100,
128132
after: endCursor,
133+
ownerAffiliations,
129134
includeMergedPullRequests,
130135
includeDiscussions,
131136
includeDiscussionsAnswers,
@@ -222,6 +227,7 @@ const totalCommitsFetcher = async (username) => {
222227
* @param {boolean} include_discussions Include discussions.
223228
* @param {boolean} include_discussions_answers Include discussions answers.
224229
* @param {number|undefined} commits_year Year to count total commits
230+
* @param {string[]} owner_affiliations Owner affiliations. Default: ["OWNER"].
225231
* @returns {Promise<import("./types").StatsData>} Stats data.
226232
*/
227233
const fetchStats = async (
@@ -232,6 +238,7 @@ const fetchStats = async (
232238
include_discussions = false,
233239
include_discussions_answers = false,
234240
commits_year,
241+
owner_affiliations = [],
235242
) => {
236243
if (!username) {
237244
throw new MissingParamError(["username"]);
@@ -252,8 +259,11 @@ const fetchStats = async (
252259
rank: { level: "C", percentile: 100 },
253260
};
254261

262+
const ownerAffiliations = parseOwnerAffiliations(owner_affiliations);
263+
255264
let res = await statsFetcher({
256265
username,
266+
ownerAffiliations,
257267
includeMergedPullRequests: include_merged_pull_requests,
258268
includeDiscussions: include_discussions,
259269
includeDiscussionsAnswers: include_discussions_answers,

tests/calculateRank.test.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ describe("Test calculateRank", () => {
1919
});
2020

2121
it("beginner user gets B- rank", () => {
22-
expect(
23-
calculateRank({
24-
all_commits: false,
25-
commits: 125,
26-
prs: 25,
27-
issues: 10,
28-
reviews: 5,
29-
repos: 0,
30-
stars: 25,
31-
followers: 5,
32-
}),
33-
).toStrictEqual({ level: "B-", percentile: 65.02918514848255 });
22+
const result = calculateRank({
23+
all_commits: false,
24+
commits: 125,
25+
prs: 25,
26+
issues: 10,
27+
reviews: 5,
28+
repos: 0,
29+
stars: 25,
30+
followers: 5,
31+
});
32+
expect(result.level).toBe("B-");
33+
expect(result.percentile).toBeCloseTo(65.02918514848255, 10);
3434
});
3535

3636
it("median user gets B+ rank", () => {

0 commit comments

Comments
 (0)