Merge remote-tracking branch 'rickstaa/add_role_param' into organization-filter
This commit is contained in:
@@ -38,6 +38,7 @@ export default async (req, res) => {
|
||||
disable_animations,
|
||||
border_radius,
|
||||
number_format,
|
||||
role,
|
||||
border_color,
|
||||
rank_icon,
|
||||
show,
|
||||
@@ -102,6 +103,7 @@ export default async (req, res) => {
|
||||
username,
|
||||
parseBoolean(include_all_commits),
|
||||
parseArray(exclude_repo),
|
||||
parseArray(role),
|
||||
showStats.includes("prs_merged") ||
|
||||
showStats.includes("prs_merged_percentage"),
|
||||
showStats.includes("discussions_started"),
|
||||
|
||||
@@ -31,6 +31,7 @@ export default async (req, res) => {
|
||||
locale,
|
||||
border_radius,
|
||||
border_color,
|
||||
role,
|
||||
disable_animations,
|
||||
hide_progress,
|
||||
} = req.query;
|
||||
@@ -69,6 +70,7 @@ export default async (req, res) => {
|
||||
parseArray(exclude_repo),
|
||||
size_weight,
|
||||
count_weight,
|
||||
parseArray(role),
|
||||
);
|
||||
|
||||
let cacheSeconds = parseInt(
|
||||
|
||||
@@ -4,6 +4,8 @@ import toEmoji from "emoji-name-map";
|
||||
import wrap from "word-wrap";
|
||||
import { themes } from "../../themes/index.js";
|
||||
|
||||
const OWNER_AFFILIATIONS = ["OWNER", "COLLABORATOR", "ORGANIZATION_MEMBER"];
|
||||
|
||||
const TRY_AGAIN_LATER = "Please try again later";
|
||||
|
||||
const SECONDARY_ERROR_MESSAGES = {
|
||||
@@ -15,6 +17,9 @@ const SECONDARY_ERROR_MESSAGES = {
|
||||
GRAPHQL_ERROR: TRY_AGAIN_LATER,
|
||||
GITHUB_REST_API_ERROR: TRY_AGAIN_LATER,
|
||||
WAKATIME_USER_NOT_FOUND: "Make sure you have a public WakaTime profile",
|
||||
INVALID_AFFILIATION: `Invalid owner affiliations. Valid values are: ${OWNER_AFFILIATIONS.join(
|
||||
", ",
|
||||
)}`,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -37,6 +42,7 @@ class CustomError extends Error {
|
||||
static GRAPHQL_ERROR = "GRAPHQL_ERROR";
|
||||
static GITHUB_REST_API_ERROR = "GITHUB_REST_API_ERROR";
|
||||
static WAKATIME_ERROR = "WAKATIME_ERROR";
|
||||
static INVALID_AFFILIATION = "INVALID_AFFILIATION";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -598,6 +604,36 @@ const parseEmojis = (str) => {
|
||||
return toEmoji.get(emoji) || "";
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Parse owner affiliations.
|
||||
*
|
||||
* @param {string[]} affiliations
|
||||
* @returns {string[]} Parsed affiliations.
|
||||
*
|
||||
* @throws {CustomError} If affiliations contains invalid values.
|
||||
*/
|
||||
const parseOwnerAffiliations = (affiliations) => {
|
||||
// Set default value for ownerAffiliations.
|
||||
// NOTE: Done here since parseArray() will always return an empty array even nothing
|
||||
//was specified.
|
||||
affiliations =
|
||||
affiliations && affiliations.length > 0
|
||||
? affiliations.map((affiliation) => affiliation.toUpperCase())
|
||||
: ["OWNER"];
|
||||
|
||||
// Check if ownerAffiliations contains valid values.
|
||||
if (
|
||||
affiliations.some(
|
||||
(affiliation) => !OWNER_AFFILIATIONS.includes(affiliation),
|
||||
)
|
||||
) {
|
||||
throw new CustomError(
|
||||
"Invalid query parameter",
|
||||
CustomError.INVALID_AFFILIATION,
|
||||
);
|
||||
}
|
||||
return affiliations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get diff in minutes between two dates.
|
||||
@@ -633,11 +669,13 @@ export {
|
||||
wrapTextMultiline,
|
||||
logger,
|
||||
CONSTANTS,
|
||||
OWNER_AFFILIATIONS,
|
||||
CustomError,
|
||||
MissingParamError,
|
||||
measureText,
|
||||
lowercaseTrim,
|
||||
chunkArray,
|
||||
parseEmojis,
|
||||
parseOwnerAffiliations,
|
||||
dateDiff,
|
||||
};
|
||||
|
||||
@@ -11,13 +11,14 @@ import {
|
||||
MissingParamError,
|
||||
request,
|
||||
wrapTextMultiline,
|
||||
parseOwnerAffiliations,
|
||||
} from "../common/utils.js";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
// GraphQL queries.
|
||||
const GRAPHQL_REPOS_FIELD = `
|
||||
repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
|
||||
repositories(first: 100, after: $after, ownerAffiliations: $ownerAffiliations, orderBy: {direction: DESC, field: STARGAZERS}) {
|
||||
totalCount
|
||||
nodes {
|
||||
name
|
||||
@@ -33,15 +34,15 @@ const GRAPHQL_REPOS_FIELD = `
|
||||
`;
|
||||
|
||||
const GRAPHQL_REPOS_QUERY = `
|
||||
query userInfo($login: String!, $after: String) {
|
||||
user(login: $login) {
|
||||
query userInfo($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
|
||||
user(login: $login, ownerAffiliations: $ownerAffiliations) {
|
||||
${GRAPHQL_REPOS_FIELD}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const GRAPHQL_STATS_QUERY = `
|
||||
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!) {
|
||||
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $ownerAffiliations: [RepositoryAffiliation]) {
|
||||
user(login: $login) {
|
||||
name
|
||||
login
|
||||
@@ -110,6 +111,7 @@ const fetcher = (variables, token) => {
|
||||
* @param {boolean} variables.includeMergedPullRequests Include merged pull requests.
|
||||
* @param {boolean} variables.includeDiscussions Include discussions.
|
||||
* @param {boolean} variables.includeDiscussionsAnswers Include discussions answers.
|
||||
* @param {string[]} ownerAffiliations The owner affiliations to filter by. Default: OWNER.
|
||||
* @returns {Promise<AxiosResponse>} Axios response.
|
||||
*
|
||||
* @description This function supports multi-page fetching if the 'FETCH_MULTI_PAGE_STARS' environment variable is set to true.
|
||||
@@ -119,6 +121,7 @@ const statsFetcher = async ({
|
||||
includeMergedPullRequests,
|
||||
includeDiscussions,
|
||||
includeDiscussionsAnswers,
|
||||
ownerAffiliations,
|
||||
}) => {
|
||||
let stats;
|
||||
let hasNextPage = true;
|
||||
@@ -131,6 +134,7 @@ const statsFetcher = async ({
|
||||
includeMergedPullRequests,
|
||||
includeDiscussions,
|
||||
includeDiscussionsAnswers,
|
||||
ownerAffiliations: ownerAffiliations,
|
||||
};
|
||||
let res = await retryer(fetcher, variables);
|
||||
if (res.data.errors) {
|
||||
@@ -282,6 +286,7 @@ const fetchRepoUserStats = async (
|
||||
* @param {string} username GitHub username.
|
||||
* @param {boolean} include_all_commits Include all commits.
|
||||
* @param {string[]} exclude_repo Repositories to exclude.
|
||||
* @param {string[]} ownerAffiliations Owner affiliations. Default: OWNER.
|
||||
* @param {boolean} include_merged_pull_requests Include merged pull requests.
|
||||
* @param {boolean} include_discussions Include discussions.
|
||||
* @param {boolean} include_discussions_answers Include discussions answers.
|
||||
@@ -291,6 +296,7 @@ const fetchStats = async (
|
||||
username,
|
||||
include_all_commits = false,
|
||||
exclude_repo = [],
|
||||
ownerAffiliations = [],
|
||||
include_merged_pull_requests = false,
|
||||
include_discussions = false,
|
||||
include_discussions_answers = false,
|
||||
@@ -325,12 +331,14 @@ const fetchStats = async (
|
||||
totalIssuesCommented: 0,
|
||||
rank: { level: "C", percentile: 100 },
|
||||
};
|
||||
ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
|
||||
|
||||
let res = await statsFetcher({
|
||||
username,
|
||||
includeMergedPullRequests: include_merged_pull_requests,
|
||||
includeDiscussions: include_discussions,
|
||||
includeDiscussionsAnswers: include_discussions_answers,
|
||||
ownerAffiliations,
|
||||
});
|
||||
|
||||
// Catch GraphQL errors.
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
MissingParamError,
|
||||
request,
|
||||
wrapTextMultiline,
|
||||
parseOwnerAffiliations,
|
||||
} from "../common/utils.js";
|
||||
|
||||
/**
|
||||
@@ -24,10 +25,10 @@ const fetcher = (variables, token) => {
|
||||
return request(
|
||||
{
|
||||
query: `
|
||||
query userInfo($login: String!) {
|
||||
query userInfo($login: String!, $ownerAffiliations: [RepositoryAffiliation]) {
|
||||
user(login: $login) {
|
||||
# fetch only owner repos & not forks
|
||||
repositories(ownerAffiliations: OWNER, isFork: false, first: 100) {
|
||||
# do not fetch forks
|
||||
repositories(ownerAffiliations: $ownerAffiliations, isFork: false, first: 100) {
|
||||
nodes {
|
||||
name
|
||||
languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
|
||||
@@ -60,7 +61,8 @@ const fetcher = (variables, token) => {
|
||||
* Fetch top languages for a given username.
|
||||
*
|
||||
* @param {string} username GitHub username.
|
||||
* @param {string[]} exclude_repo List of repositories to exclude.
|
||||
* @param {string[]} exclude_repo List of repositories to exclude. Default: [].
|
||||
* @param {string[]} ownerAffiliations The owner affiliations to filter by. Default: OWNER.
|
||||
* @param {number} size_weight Weightage to be given to size.
|
||||
* @param {number} count_weight Weightage to be given to count.
|
||||
* @returns {Promise<TopLangData>} Top languages data.
|
||||
@@ -70,12 +72,14 @@ const fetchTopLanguages = async (
|
||||
exclude_repo = [],
|
||||
size_weight = 1,
|
||||
count_weight = 0,
|
||||
ownerAffiliations = [],
|
||||
) => {
|
||||
if (!username) {
|
||||
throw new MissingParamError(["username"]);
|
||||
}
|
||||
ownerAffiliations = parseOwnerAffiliations(ownerAffiliations);
|
||||
|
||||
const res = await retryer(fetcher, { login: username });
|
||||
const res = await retryer(fetcher, { login: username, ownerAffiliations });
|
||||
|
||||
if (res.data.errors) {
|
||||
logger.error(res.data.errors);
|
||||
|
||||
Reference in New Issue
Block a user