Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default async (req, res) => {
border_color,
rank_icon,
show,
include_transferred_repos,
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");

Expand Down Expand Up @@ -100,6 +101,7 @@ export default async (req, res) => {
showStats.includes("discussions_started"),
showStats.includes("discussions_answered"),
parseInt(commits_year, 10),
parseBoolean(include_transferred_repos),
);

let cacheSeconds = clampValue(
Expand Down
11 changes: 10 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ You can specify a year and fetch only the commits that were made in that year by
![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&commits_year=2020)
```

### Including transferred repositories

If you have transferred repositories to organizations, you can include their stars in your stats by using the `&include_transferred_repos=true` parameter. This helps maintain accurate star counts for repositories that were originally created by you but have since been transferred to an organization.

```md
![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&include_transferred_repos=true)
```

### Themes

With inbuilt themes, you can customize the look of the card without doing any [manual customization](#customization).
Expand Down Expand Up @@ -374,7 +382,8 @@ If we don't support your language, please consider contributing! You can find mo
| `ring_color` | Color of the rank circle. | string (hex color) | `2f80ed` |
| `number_format` | Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). | enum | `short` |
| `show` | Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`). | string (comma-separated values) | `null` |
| `commits_year` | Filters and counts only commits made in the specified year | integer _(YYYY)_ | `<current year> (one year to date)`.
| `commits_year` | Filters and counts only commits made in the specified year | integer _(YYYY)_ | `<current year> (one year to date)` |
| `include_transferred_repos` | Includes repositories that were transferred to organizations in star count. This helps maintain star counts for repositories that were originally created by the user but have since been transferred to an organization. | boolean | `false` |

> [!NOTE]\
> When hide\_rank=`true`, the minimum card width is 270 px + the title length and padding.
Expand Down
4 changes: 2 additions & 2 deletions src/cards/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ const renderStatsCard = (stats, options = {}) => {
STATS.prs_merged_percentage = {
icon: icons.prs_merged_percentage,
label: i18n.t("statcard.prs-merged-percentage"),
value: mergedPRsPercentage.toFixed(2),
value: totalPRs === 0 ? "N/A" : mergedPRsPercentage.toFixed(2),
id: "prs_merged_percentage",
unitSymbol: "%",
unitSymbol: totalPRs === 0 ? "" : "%",
};
}

Expand Down
29 changes: 21 additions & 8 deletions src/fetchers/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ import {
dotenv.config();

// GraphQL queries.
const GRAPHQL_REPOS_FIELD = `
repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
const getReposField = (includeTransferred = false) => {
const ownerAffiliations = includeTransferred
? "[OWNER, COLLABORATOR]"
: "OWNER";
return `
repositories(first: 100, ownerAffiliations: ${ownerAffiliations}, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
totalCount
nodes {
name
Expand All @@ -30,16 +34,17 @@ const GRAPHQL_REPOS_FIELD = `
}
}
`;
};

const GRAPHQL_REPOS_QUERY = `
const getReposQuery = (includeTransferred = false) => `
query userInfo($login: String!, $after: String) {
user(login: $login) {
${GRAPHQL_REPOS_FIELD}
${getReposField(includeTransferred)}
}
}
`;

const GRAPHQL_STATS_QUERY = `
const getStatsQuery = (includeTransferred = false) => `
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $startTime: DateTime = null) {
user(login: $login) {
name
Expand Down Expand Up @@ -74,7 +79,7 @@ const GRAPHQL_STATS_QUERY = `
repositoryDiscussionComments(onlyAnswers: true) @include(if: $includeDiscussionsAnswers) {
totalCount
}
${GRAPHQL_REPOS_FIELD}
${getReposField(includeTransferred)}
}
}
`;
Expand All @@ -91,7 +96,10 @@ const GRAPHQL_STATS_QUERY = `
* @returns {Promise<AxiosResponse>} Axios response.
*/
const fetcher = (variables, token) => {
const query = variables.after ? GRAPHQL_REPOS_QUERY : GRAPHQL_STATS_QUERY;
const includeTransferred = variables.includeTransferred || false;
const query = variables.after
? getReposQuery(includeTransferred)
: getStatsQuery(includeTransferred);
return request(
{
query,
Expand Down Expand Up @@ -122,6 +130,7 @@ const statsFetcher = async ({
includeDiscussions,
includeDiscussionsAnswers,
startTime,
includeTransferred,
}) => {
let stats;
let hasNextPage = true;
Expand All @@ -135,6 +144,7 @@ const statsFetcher = async ({
includeDiscussions,
includeDiscussionsAnswers,
startTime,
includeTransferred,
};
let res = await retryer(fetcher, variables);
if (res.data.errors) {
Expand Down Expand Up @@ -233,6 +243,7 @@ const fetchStats = async (
include_discussions = false,
include_discussions_answers = false,
commits_year,
include_transferred_repos = false,
) => {
if (!username) {
throw new MissingParamError(["username"]);
Expand All @@ -259,6 +270,7 @@ const fetchStats = async (
includeDiscussions: include_discussions,
includeDiscussionsAnswers: include_discussions_answers,
startTime: commits_year ? `${commits_year}-01-01T00:00:00Z` : undefined,
includeTransferred: include_transferred_repos,
});

// Catch GraphQL errors.
Expand Down Expand Up @@ -297,7 +309,8 @@ const fetchStats = async (
if (include_merged_pull_requests) {
stats.totalPRsMerged = user.mergedPullRequests.totalCount;
stats.mergedPRsPercentage =
(user.mergedPullRequests.totalCount / user.pullRequests.totalCount) * 100;
(user.mergedPullRequests.totalCount / user.pullRequests.totalCount) *
100 || 0;
}
stats.totalReviews = user.reviews.totalPullRequestReviewContributions;
stats.totalIssues = user.openIssues.totalCount + user.closedIssues.totalCount;
Expand Down