Skip to content

Commit f344673

Browse files
committed
feat: parse role parameter
1 parent d363f5b commit f344673

File tree

4 files changed

+46
-21
lines changed

4 files changed

+46
-21
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,3 @@ vercel_token
1010
# IDE
1111
.vscode
1212
*.code-workspace
13-
14-
.vercel

src/common/utils.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,16 @@ const CONSTANTS = {
300300
ONE_DAY: 86400,
301301
};
302302

303+
const OWNER_AFFILIATIONS = ["OWNER", "COLLABORATOR", "ORGANIZATION_MEMBER"];
304+
303305
const SECONDARY_ERROR_MESSAGES = {
304306
MAX_RETRY:
305307
"Please add an env variable called PAT_1 with your github token in vercel",
306308
USER_NOT_FOUND: "Make sure the provided username is not an organization",
307309
GRAPHQL_ERROR: "Please try again later",
310+
INVALID_AFFILIATION: `Invalid owner affiliations. Valid values are: ${OWNER_AFFILIATIONS.join(
311+
", ",
312+
)}`,
308313
};
309314

310315
/**
@@ -324,6 +329,7 @@ class CustomError extends Error {
324329
static MAX_RETRY = "MAX_RETRY";
325330
static USER_NOT_FOUND = "USER_NOT_FOUND";
326331
static GRAPHQL_ERROR = "GRAPHQL_ERROR";
332+
static INVALID_AFFILIATION = "INVALID_AFFILIATION";
327333
}
328334

329335
/**
@@ -423,6 +429,36 @@ const parseEmojis = (str) => {
423429
return toEmoji.get(emoji) || "";
424430
});
425431
};
432+
/**
433+
* Parse owner affiliations.
434+
*
435+
* @param {string[]} affiliations
436+
* @returns {string[]} Parsed affiliations.
437+
*
438+
* @throws {CustomError} If affiliations contains invalid values.
439+
*/
440+
const parseOwnerAffiliations = (affiliations) => {
441+
// Set default value for ownerAffiliations.
442+
// NOTE: Done here since parseArray() will always return an empty array even nothing
443+
//was specified.
444+
affiliations =
445+
affiliations && affiliations.length > 0
446+
? affiliations.map((affiliation) => affiliation.toUpperCase())
447+
: ["OWNER"];
448+
449+
// Check if ownerAffiliations contains valid values.
450+
if (
451+
affiliations.some(
452+
(affiliation) => !OWNER_AFFILIATIONS.includes(affiliation),
453+
)
454+
) {
455+
throw new CustomError(
456+
"Invalid query parameter",
457+
CustomError.INVALID_AFFILIATION,
458+
);
459+
}
460+
return affiliations;
461+
};
426462

427463
export {
428464
ERROR_CARD_LENGTH,
@@ -441,10 +477,12 @@ export {
441477
wrapTextMultiline,
442478
logger,
443479
CONSTANTS,
480+
OWNER_AFFILIATIONS,
444481
CustomError,
445482
MissingParamError,
446483
measureText,
447484
lowercaseTrim,
448485
chunkArray,
449486
parseEmojis,
487+
parseOwnerAffiliations,
450488
};

src/fetchers/stats-fetcher.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import {
1010
MissingParamError,
1111
request,
1212
wrapTextMultiline,
13+
parseOwnerAffiliations,
1314
} from "../common/utils.js";
1415

1516
dotenv.config();
1617

1718
// GraphQL queries.
1819
const GRAPHQL_REPOS_FIELD = `
19-
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}) {
2021
totalCount
2122
nodes {
2223
name
@@ -40,7 +41,7 @@ const GRAPHQL_REPOS_QUERY = `
4041
`;
4142

4243
const GRAPHQL_STATS_QUERY = `
43-
query userInfo($login: String!, $after: String) {
44+
query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
4445
user(login: $login) {
4546
name
4647
login
@@ -92,6 +93,7 @@ const fetcher = (variables, token) => {
9293
* Fetch stats information for a given username.
9394
*
9495
* @param {string} username Github username.
96+
* @param {string[]} ownerAffiliations The owner affiliations to filter by. Default: OWNER.
9597
* @returns {Promise<import('../common/types').StatsFetcher>} GraphQL Stats object.
9698
*
9799
* @description This function supports multi-page fetching if the 'FETCH_MULTI_PAGE_STARS' environment variable is set to true.
@@ -105,7 +107,7 @@ const statsFetcher = async (username, ownerAffiliations) => {
105107
login: username,
106108
first: 100,
107109
after: endCursor,
108-
ownerAffiliations: [ownerAffiliations],
110+
ownerAffiliations: ownerAffiliations,
109111
};
110112
let res = await retryer(fetcher, variables);
111113
if (res.data.errors) return res;
@@ -202,14 +204,7 @@ const fetchStats = async (
202204
contributedTo: 0,
203205
rank: { level: "C", score: 0 },
204206
};
205-
206-
// Set default value for ownerAffiliations.
207-
// NOTE: Done here since parseArray() will always return an empty array even nothing
208-
//was specified.
209-
ownerAffiliations =
210-
ownerAffiliations && ownerAffiliations.length > 0
211-
? ownerAffiliations
212-
: ["OWNER"];
207+
ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
213208

214209
let res = await statsFetcher(username, ownerAffiliations);
215210

src/fetchers/top-languages-fetcher.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
MissingParamError,
77
request,
88
wrapTextMultiline,
9+
parseOwnerAffiliations,
910
} from "../common/utils.js";
1011

1112
/**
@@ -61,14 +62,7 @@ const fetchTopLanguages = async (
6162
ownerAffiliations = [],
6263
) => {
6364
if (!username) throw new MissingParamError(["username"]);
64-
65-
// Set default value for ownerAffiliations.
66-
// NOTE: Done here since parseArray() will always return an empty array even nothing
67-
//was specified.
68-
ownerAffiliations =
69-
ownerAffiliations && ownerAffiliations.length > 0
70-
? ownerAffiliations
71-
: ["OWNER"];
65+
ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
7266

7367
const res = await retryer(fetcher, { login: username, ownerAffiliations });
7468

0 commit comments

Comments
 (0)