Repository: anuraghazra/github-readme-stats
Pull request #2100 (2022-10-03 09:23:19)

fix: fetch all repos for for the stats card
This fixed https://github.com/anuraghazra/github-readme-stats/issues/1177 only for the stats card part

vercel[bot]: @MatteoPierro is attempting to deploy a commit to the **github readme stats** Team on [Vercel](https://vercel.com).

A member of the Team first needs to [authorize it](https://vercel.com/git/authorize?team=github%20readme%20stats&type=github&job=%7B%22headInfo%22%3A%7B%22sha%22%3A%22d61893ee53177c81cafb9a4df132c7709e8afcd0%22%7D%2C%22id%22%3A%22QmP8a2qG8UsQLLqFQ77EMwg4o1R2An2iYXHxU4YTEyHmz1%22%2C%22org%22%3A%22anuraghazra%22%2C%22prId%22%3A2100%2C%22repo%22%3A%22github-readme-stats%22%7D).


rickstaa: Amazing! I will take a look later this week. We are trying to keep up with the great amount of PRs we receive because of the Hacktober fest 🔥 😅.
MatteoPierro: great. This is for the Hacktober fest as well  😅
rickstaa: > great. This is for the Hacktober fest as well sweat_smile

Ha great, you decided to be part of this fantastic event! 🚀 I am attaching the [hacktoberfest-accepted] label to all PR made in October, so all accepted PR should count.

Patch:
diff --git a/readme.md b/readme.md
index 2f18336..8130a33 100644
--- a/readme.md
+++ b/readme.md
@@ -6,7 +6,7 @@
   <p align="center">
     <a href="https://github.com/anuraghazra/github-readme-stats/actions">
       <img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
-    </a> 
+    </a>
     <a href="https://github.com/anuraghazra/github-readme-stats/graphs/contributors">
       <img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/anuraghazra/github-readme-stats" />
     </a>
@@ -64,18 +64,16 @@
 </p>
 <p align="center">Love the project? Please consider <a href="https://www.paypal.me/anuraghazra">donating</a> to help it improve!
 
-<p>
 <a href="https://indiafightscorona.giveindia.org">
-<img src="https://indiaspora.org/wp-content/uploads/2021/04/give-India-logo.png" alt="Give india logo" width="200" />
+  <img src="https://indiaspora.org/wp-content/uploads/2021/04/give-India-logo.png" alt="Give india logo" width="200" />
 </a>
 
-Are you considering supporting the project by donating? Please DON'T!!
+Are you considering supporting the project by donating? Please DO NOT!!
 
-Instead, Help India fight the 2nd deadly wave of COVID-19.
+Instead, Help India fight the second deadly wave of COVID-19.
 Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure.
 
-Visit <https://indiafightscorona.giveindia.org> and make a small donation to help us fight COVID and overcome this crisis.
-A small donation goes a long way. :heart:
+Visit <https://indiafightscorona.giveindia.org> and make a small donation to help us fight COVID and overcome this crisis. A small donation goes a long way. :heart:
 
 </p>
 
@@ -96,7 +94,7 @@ A small donation goes a long way. :heart:
 
 # GitHub Stats Card
 
-Copy-paste this into your markdown content, and that's it. Simple!
+Copy-paste this into your markdown content, and that is it. Simple!
 
 Change the `?username=` value to your GitHub username.
 
@@ -110,7 +108,7 @@ The implementation can be investigated at [src/calculateRank.js](./src/calculate
 
 ### Hiding individual stats
 
-To hide any specific stats, you can pass a query parameter `&hide=` with comma-separated values.
+You can pass a query parameter `&hide=` to hide any specific stats with comma-separated values.
 
 > Options: `&hide=stars,commits,prs,issues,contribs`
 
@@ -122,7 +120,7 @@ To hide any specific stats, you can pass a query parameter `&hide=` with comma-s
 
 You can add the count of all your private contributions to the total commits count by using the query parameter `&count_private=true`.
 
-_Note: If you are deploying this project yourself, the private contributions will be counted by default. Otherwise, you need to choose to share your private contribution counts._
+_Note: If you are deploying this project yourself, the private contributions will be counted by default. If you are using the public Vercel instance, you need to choose to [share your private contributions](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/showing-your-private-contributions-and-achievements-on-your-profile)._
 
 > Options: `&count_private=true`
 
@@ -142,15 +140,15 @@ To enable icons, you can pass `show_icons=true` in the query param, like so:
 
 With inbuilt themes, you can customize the look of the card without doing any [manual customization](#customization).
 
-Use `&theme=THEME_NAME` parameter like so :-
+Use `&theme=THEME_NAME` parameter like so :
 
 ```md
 ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical)
 ```
 
-#### All inbuilt themes:-
+#### All inbuilt themes
 
-dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
+Github readme stats comes with several built-in themes (e.g. `dark`, `radical`, `merko`, `gruvbox`, `tokyonight`, `onedark`, `cobalt`, `synthwave`, `highcontrast`, `dracula`).
 
 <img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stats Themes" width="600px"/>
 
@@ -158,9 +156,9 @@ You can look at a preview for [all available themes](./themes/README.md) or chec
 
 ### Customization
 
-You can customize the appearance of your `Stats Card` or `Repo Card` however you wish with URL params.
+You can customize the appearance of your `Stats Card` or `Repo Card` however you wish with URL parameters.
 
-#### Common Options:
+#### Common Options
 
 -   `title_color` - Card's title color _(hex color)_. Default: `2f80ed`.
 -   `text_color` - Body text color _(hex color)_. Default: `434d58`.
@@ -177,13 +175,13 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you
 
 ##### Gradient in bg_color
 
-You can provide multiple comma-separated values in the bg_color option to render a gradient, with the following format:
+You can provide multiple comma-separated values in the bg_color option to render a gradient with the following format:
 
     &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10
 
-> Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k, otherwise, it's 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours.
+> Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours.
 
-#### Stats Card Exclusive Options:
+#### Stats Card Exclusive Options
 
 -   `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`.
 -   `hide_title` - _(boolean)_. Default: `false`.
@@ -192,7 +190,7 @@ You can provide multiple comma-separated values in the bg_color option to render
 -   `show_icons` - _(boolean)_. Default: `false`.
 -   `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_. Default: `false`.
 -   `count_private` - Count private commits _(boolean)_. Default: `false`.
--   `line_height` - Sets the line-height between text _(number)_.  Default: `25`.
+-   `line_height` - Sets the line height between text _(number)_. Default: `25`.
 -   `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_. Default: `[] (blank array)`.
 -   `custom_title` - Sets a custom title for the card. Default:  `<username> Github Stats`.
 -   `text_bold` - Use bold text _(boolean)_. Default: `true`.
@@ -201,42 +199,42 @@ You can provide multiple comma-separated values in the bg_color option to render
 > Note on `hide_rank`:
 > When hide_rank=`true`, the minimum card width is 270 px + the title length and padding.
 
-#### Repo Card Exclusive Options:
+#### Repo Card Exclusive Options
 
--   `show_owner` - Show the repo's owner name _(boolean)_. Defaults to `false`.
+-   `show_owner` - Show the repo's owner name _(boolean)_. Default: `false`.
 
-#### Language Card Exclusive Options:
+#### Language Card Exclusive Options
 
--   `hide` - Hide the languages specified from the card _(Comma-separated values)_
--   `hide_title` - _(boolean)_. Defaults to `false`.
--   `layout` - Switch between two available layouts `default` & `compact`
--   `card_width` - Set the card's width manually _(number)_
--   `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_
--   `exclude_repo` - Exclude specified repositories _(Comma-separated values)_
--   `custom_title` - Sets a custom title for the card
+-   `hide` - Hide the languages specified from the card _(Comma-separated values)_. Default: `[] (blank array)`.
+-   `hide_title` - _(boolean)_. Default: `false`.
+-   `layout` - Switch between two available layouts `default` & `compact`. Default: `default`.
+-   `card_width` - Set the card's width manually _(number)_. Default `300`.
+-   `langs_count` - Show more languages on the card, between 1-10 _(number)_. Default `5`.
+-   `exclude_repo` - Exclude specified repositories _(Comma-separated values)_. Default: `[] (blank array)`.
+-   `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`.
 
 > :warning: **Important:**
-> Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
+> Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
 > (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.) You can use
 > [urlencoder.org](https://www.urlencoder.org/) to help you do this automatically.
 
-#### Wakatime Card Exclusive Options:
+#### Wakatime Card Exclusive Options
 
--   `hide` - Hide the languages specified from the card _(Comma-separated values)_
--   `hide_title` - _(boolean)_. Defaults to `false`.
--   `line_height` - Sets the line-height between text _(number)_. Default Value: `25`.
--   `hide_progress` - Hides the progress bar and percentage _(boolean)_
--   `custom_title` - Sets a custom title for the card
--   `layout` - Switch between two available layouts `default` & `compact`
--   `langs_count` - Limit the number of languages on the card, defaults to all reported languages
--   `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi)
--   `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options.
+-   `hide` - Hide the languages specified from the card _(Comma-separated values)_. Default: `[] (blank array)`.
+-   `hide_title` - _(boolean)_. Default `false`.
+-   `line_height` - Sets the line height between text _(number)_. Default `25`.
+-   `hide_progress` - Hides the progress bar and percentage _(boolean)_. Default `false`.
+-   `custom_title` - Sets a custom title for the card _(string)_. Default `Wakatime Stats`.
+-   `layout` - Switch between two available layouts `default` & `compact`.  Default `default`.
+-   `langs_count` - Limit the number of languages on the card, defaults to all reported languages _(number)_.
+-   `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) _(string)_. Default `Waka API`.
+-   `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. _(YYYY-MM, last_7_days, last_30_days, last_6_months, last_year, or all_time)_. Default `all_time`.
 
 * * *
 
 # GitHub Extra Pins
 
-GitHub extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile.
+GitHub extra pins allow you to pin more than six repositories in your profile using a GitHub readme profile.
 
 Yay! You are no longer limited to 6 pinned repositories.
 
@@ -262,7 +260,7 @@ Use [show_owner](#customization) variable to include the repo's owner username
 
 The top languages card shows a GitHub user's most frequently used top language.
 
-_NOTE: Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It's a new feature of github-readme-stats._
+_NOTE: Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It is a new feature of github-readme-stats._
 
 ### Usage
 
@@ -276,7 +274,7 @@ Endpoint: `api/top-langs?username=anuraghazra`
 
 ### Exclude individual repositories
 
-You can use `&exclude_repo=repo1,repo2` parameter to exclude individual repositories.
+You can use the `&exclude_repo=repo1,repo2` parameter to exclude individual repositories.
 
 ```md
 [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&exclude_repo=github-readme-stats,anuraghazra.github.io)](https://github.com/anuraghazra/github-readme-stats)
@@ -384,7 +382,7 @@ Choose from any of the [default themes](#themes)
 
 [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats)
 
--   Wakatime card
+-   WakaTime card
 
 [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod)](https://github.com/anuraghazra/github-readme-stats)
 
@@ -392,7 +390,7 @@ Choose from any of the [default themes](#themes)
 
 ### Quick Tip (Align The Repo Cards)
 
-You usually won't be able to layout the images side by side. To do that you can use this approach:
+By default, GitHub does not lay out the cards side by side. To do that, you can use this approach:
 
 ```html
 <a href="https://github.com/anuraghazra/github-readme-stats">
@@ -407,7 +405,7 @@ You usually won't be able to layout the images side by side. To do that you can
 
 #### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
 
-Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you don't have to worry about anything. Click on the deploy button to get started!
+Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Click on the deploy button to get started!
 
 NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we should be able to handle more than 5k requests and have no issues with downtime :D
 
@@ -416,32 +414,32 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
 <details>
  <summary><b> Guide on setting up Vercel  🔨 </b></summary>
 
-1.  Go to [vercel.com](https://vercel.com/)
-2.  Click on `Log in`
-    ![](https://files.catbox.moe/tct1wg.png)
-3.  Sign in with GitHub by pressing `Continue with GitHub`
-    ![](https://files.catbox.moe/btd78j.jpeg)
-4.  Sign in to GitHub and allow access to all repositories, if prompted
-5.  Fork this repo
-6.  After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10`
-7.  Go back to your [Vercel dashboard](https://vercel.com/dashboard)
-8.  Select `Import Project`
-    ![](https://files.catbox.moe/qckos0.png)
-9.  Select `Import Git Repository`. Select root and keep everything as is.
-    ![](https://files.catbox.moe/pqub9q.png)
-10. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats)
+1.  Go to [vercel.com](https://vercel.com/).
+2.  Click on `Log in`.
+    ![](https://files.catbox.moe/pcxk33.png)
+3.  Sign in with GitHub by pressing `Continue with GitHub`.
+    ![](https://files.catbox.moe/b9oxey.png)
+4.  Sign in to GitHub and allow access to all repositories if prompted.
+5.  Fork this repo.
+6.  After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10`.
+7.  Go back to your [Vercel dashboard](https://vercel.com/dashboard).
+8.  To import a project, click the `Add New...` button and select the `Project` option.
+    ![](https://files.catbox.moe/3n76fh.png)
+9.  Click the `Continue with GitHub` button, search for the required Git Repository and import it by clicking the `Import` button. Alternatively, you can import a Third-Party Git Repository using the `Import Third-Party Git Repository ->` link at the bottom of the page.
+    ![](https://files.catbox.moe/mg5p04.png)
+10. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats).
 11. Add the PAT as an environment variable named `PAT_1` (as shown).
-    ![](https://files.catbox.moe/0ez4g7.png)
+    ![](https://files.catbox.moe/0yclio.png)
 12. Click deploy, and you're good to go. See your domains to use the API!
 
 </details>
 
 ## :sparkling_heart: Support the project
 
-I open-source almost everything I can, and I try to reply to everyone needing help using these projects. Obviously,
+I open-source almost everything I can and try to reply to everyone needing help using these projects. Obviously,
 this takes time. You can use this service for free.
 
-However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it:-
+However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it:
 
 -   Giving proper credit when you use github-readme-stats on your readme, linking back to it :D
 -   Starring and sharing the project :rocket:
diff --git a/src/calculateRank.js b/src/calculateRank.js
index bbfece1..6c161f3 100644
--- a/src/calculateRank.js
+++ b/src/calculateRank.js
@@ -1,4 +1,14 @@
-// https://stackoverflow.com/a/5263759/10629172
+/**
+ * Calculates the probability of x taking on x or a value less than x in a normal distribution
+ * with mean and standard deviation.
+ *
+ * @see https://stackoverflow.com/a/5263759/10629172
+ *
+ * @param {string} mean
+ * @param {number} sigma
+ * @param {number} to
+ * @returns {number} Probability.
+ */
 function normalcdf(mean, sigma, to) {
   var z = (to - mean) / Math.sqrt(2 * sigma * sigma);
   var t = 1 / (1 + 0.3275911 * Math.abs(z));
@@ -16,6 +26,18 @@ function normalcdf(mean, sigma, to) {
   return (1 / 2) * (1 + sign * erf);
 }
 
+/**
+ * Calculates the users rank.
+ *
+ * @param {number} totalRepos
+ * @param {number} totalCommits
+ * @param {number} contributions
+ * @param {number} followers
+ * @param {number} prs
+ * @param {number} issues
+ * @param {number} stargazers
+ * @returns {{level: string, score: number}}} The users rank.
+ */
 function calculateRank({
   totalRepos,
   totalCommits,
diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js
index 4b0cd33..f880560 100644
--- a/src/cards/stats-card.js
+++ b/src/cards/stats-card.js
@@ -12,6 +12,19 @@ import {
 import { getStyles } from "../getStyles.js";
 import { statCardLocales } from "../translations.js";
 
+/**
+ * Create a stats card text item.
+ *
+ * @param {object[]} createTextNodeParams Object that contains the createTextNode parameters.
+ * @param {string} createTextNodeParams.label The label to display.
+ * @param {string} createTextNodeParams.value The value to display.
+ * @param {string} createTextNodeParams.id The id of the stat.
+ * @param {number} createTextNodeParams.index The index of the stat.
+ * @param {boolean} createTextNodeParams.showIcons Whether to show icons.
+ * @param {number} createTextNodeParams.shiftValuePos Number of pixels the value has to be shifted to the right.
+ * @param {boolean} createTextNodeParams.bold Whether to bold the label.
+ * @returns
+ */
 const createTextNode = ({
   icon,
   label,
diff --git a/src/common/retryer.js b/src/common/retryer.js
index c898ef3..859e94b 100644
--- a/src/common/retryer.js
+++ b/src/common/retryer.js
@@ -1,5 +1,14 @@
 import { CustomError, logger } from "./utils.js";
 
+/**
+ * Try to execute the fetcher function until it succeeds or the max number of retries is reached.
+ *
+ * @param {object[]} retryerParams Object that contains the createTextNode parameters.
+ * @param {object[]} retryerParams.fetcher The fetcher function.
+ * @param {object[]} retryerParams.variables Object with arguments to pass to the fetcher function.
+ * @param {number} retryerParams.retries How many times to retry.
+ * @returns Promise<retryer>
+ */
 const retryer = async (fetcher, variables, retries = 0) => {
   if (retries > 7) {
     throw new CustomError("Maximum retries exceeded", CustomError.MAX_RETRY);
diff --git a/src/common/utils.js b/src/common/utils.js
index 7660bbd..fc462d3 100644
--- a/src/common/utils.js
+++ b/src/common/utils.js
@@ -11,13 +11,13 @@ import { themes } from "../../themes/index.js";
  */
 const renderError = (message, secondaryMessage = "") => {
   return `
-    <svg width="495" height="120" viewBox="0 0 495 120" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg width="576.5" height="120" viewBox="0 0 576.5 120" fill="none" xmlns="http://www.w3.org/2000/svg">
     <style>
     .text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
     .small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #252525 }
     .gray { fill: #858585 }
     </style>
-    <rect x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
+    <rect x="0.5" y="0.5" width="575.5" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
     <text x="25" y="45" class="text">Something went wrong! file an issue at https://tiny.one/readme-stats</text>
     <text data-testid="message" x="25" y="55" class="text small">
       <tspan x="25" dy="18">${encodeHTML(message)}</tspan>
@@ -74,7 +74,10 @@ function parseBoolean(value) {
 }
 
 /**
- * @param {string} str
+ * Parse string to array of strings.
+ *
+ * @param {string} str The string to parse.
+ * @returns {string[]} The array of strings.
  */
 function parseArray(str) {
   if (!str) return [];
@@ -82,9 +85,12 @@ function parseArray(str) {
 }
 
 /**
- * @param {number} number
- * @param {number} min
- * @param {number} max
+ * Clamp the given number between the given range.
+ *
+ * @param {number} number The number to clamp.
+ * @param {number} min The minimum value.
+ * @param {number} max The maximum value.
+ * returns {number} The clamped number.
  */
 function clampValue(number, min, max) {
   // @ts-ignore
@@ -93,7 +99,10 @@ function clampValue(number, min, max) {
 }
 
 /**
- * @param {string[]} colors
+ * Check if the given string is a valid gradient.
+ *
+ * @param {string[]} colors Array of colors.
+ * returns {boolean} True if the given string is a valid gradient.
  */
 function isValidGradient(colors) {
   return isValidHexColor(colors[1]) && isValidHexColor(colors[2]);
diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js
index b9493ad..8f8a820 100644
--- a/src/fetchers/stats-fetcher.js
+++ b/src/fetchers/stats-fetcher.js
@@ -29,10 +29,10 @@ const fetcher = (variables, token) => {
             totalCommitContributions
             restrictedContributionsCount
           }
-          repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
+          repositoriesContributedTo(contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
             totalCount
           }
-          pullRequests(first: 1) {
+          pullRequests {
             totalCount
           }
           openIssues: issues(states: OPEN) {
@@ -44,14 +44,41 @@ const fetcher = (variables, token) => {
           followers {
             totalCount
           }
-          repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}) {
+          repositories(ownerAffiliations: OWNER) {
             totalCount
+          }
+        }
+      }
+      `,
+      variables,
+    },
+    {
+      Authorization: `bearer ${token}`,
+    },
+  );
+};
+
+/**
+ * @param {import('axios').AxiosRequestHeaders} variables
+ * @param {string} token
+ */
+const repositoriesFetcher = (variables, token) => {
+  return request(
+    {
+      query: `
+      query userInfo($login: String!, $after: String) {
+        user(login: $login) {
+          repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) {
             nodes {
               name
               stargazers {
                 totalCount
               }
             }
+            pageInfo {
+              hasNextPage
+              endCursor
+            }
           }
         }
       }
@@ -99,6 +126,43 @@ const totalCommitsFetcher = async (username) => {
   return 0;
 };
 
+/**
+ * Fetch all the stars for all the repositories of a given username
+ * @param {string} username
+ * @param {array} repoToHide
+ */
+const totalStarsFetcher = async (username, repoToHide) => {
+  let nodes = [];
+  let hasNextPage = true;
+  let endCursor = null;
+  while (hasNextPage) {
+    const variables = { login: username, first: 100, after: endCursor };
+    let res = await retryer(repositoriesFetcher, variables);
+
+    if (res.data.errors) {
+      logger.error(res.data.errors);
+      throw new CustomError(
+        res.data.errors[0].message || "Could not fetch user",
+        CustomError.USER_NOT_FOUND,
+      );
+    }
+
+    const allNodes = res.data.data.user.repositories.nodes;
+    const nodesWithStars = allNodes.filter(
+      (node) => node.stargazers.totalCount !== 0,
+    );
+    nodes.push(...nodesWithStars);
+    hasNextPage =
+      allNodes.length === nodesWithStars.length &&
+      res.data.data.user.repositories.pageInfo.hasNextPage;
+    endCursor = res.data.data.user.repositories.pageInfo.endCursor;
+  }
+
+  return nodes
+    .filter((data) => !repoToHide[data.name])
+    .reduce((prev, curr) => prev + curr.stargazers.totalCount, 0);
+};
+
 /**
  * @param {string} username
  * @param {boolean} count_private
@@ -166,13 +230,7 @@ async function fetchStats(
   stats.contributedTo = user.repositoriesContributedTo.totalCount;
 
   // Retrieve stars while filtering out repositories to be hidden
-  stats.totalStars = user.repositories.nodes
-    .filter((data) => {
-      return !repoToHide[data.name];
-    })
-    .reduce((prev, curr) => {
-      return prev + curr.stargazers.totalCount;
-    }, 0);
+  stats.totalStars = await totalStarsFetcher(username, repoToHide);
 
   stats.rank = calculateRank({
     totalCommits: stats.totalCommits,


Test patch:
diff --git a/tests/api.test.js b/tests/api.test.js
index b0dfc59..a6bb092 100644
--- a/tests/api.test.js
+++ b/tests/api.test.js
@@ -40,7 +40,20 @@ const data = {
       followers: { totalCount: 0 },
       repositories: {
         totalCount: 1,
+      },
+    },
+  },
+};
+
+const repositoriesData = {
+  data: {
+    user: {
+      repositories: {
         nodes: [{ stargazers: { totalCount: 100 } }],
+        pageInfo: {
+          hasNextPage: false,
+          cursor: "cursor",
+        },
       },
     },
   },
@@ -70,7 +83,11 @@ const faker = (query, data) => {
     setHeader: jest.fn(),
     send: jest.fn(),
   };
-  mock.onPost("https://api.github.com/graphql").reply(200, data);
+  mock
+    .onPost("https://api.github.com/graphql")
+    .replyOnce(200, data)
+    .onPost("https://api.github.com/graphql")
+    .replyOnce(200, repositoriesData);
 
   return { req, res };
 };
@@ -138,7 +155,6 @@ describe("Test /api/", () => {
 
   it("should have proper cache", async () => {
     const { req, res } = faker({}, data);
-    mock.onPost("https://api.github.com/graphql").reply(200, data);
 
     await api(req, res);
 
diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js
index f8eae98..9ccdcb2 100644
--- a/tests/fetchStats.test.js
+++ b/tests/fetchStats.test.js
@@ -19,13 +19,61 @@ const data = {
       followers: { totalCount: 100 },
       repositories: {
         totalCount: 5,
+      },
+    },
+  },
+};
+
+const firstRepositoriesData = {
+  data: {
+    user: {
+      repositories: {
         nodes: [
           { name: "test-repo-1", stargazers: { totalCount: 100 } },
           { name: "test-repo-2", stargazers: { totalCount: 100 } },
           { name: "test-repo-3", stargazers: { totalCount: 100 } },
+        ],
+        pageInfo: {
+          hasNextPage: true,
+          cursor: "cursor",
+        },
+      },
+    },
+  },
+};
+
+const secondRepositoriesData = {
+  data: {
+    user: {
+      repositories: {
+        nodes: [
           { name: "test-repo-4", stargazers: { totalCount: 50 } },
           { name: "test-repo-5", stargazers: { totalCount: 50 } },
         ],
+        pageInfo: {
+          hasNextPage: false,
+          cursor: "cursor",
+        },
+      },
+    },
+  },
+};
+
+const repositoriesWithZeroStarsData = {
+  data: {
+    user: {
+      repositories: {
+        nodes: [
+          { name: "test-repo-1", stargazers: { totalCount: 100 } },
+          { name: "test-repo-2", stargazers: { totalCount: 100 } },
+          { name: "test-repo-3", stargazers: { totalCount: 100 } },
+          { name: "test-repo-4", stargazers: { totalCount: 0 } },
+          { name: "test-repo-5", stargazers: { totalCount: 0 } },
+        ],
+        pageInfo: {
+          hasNextPage: true,
+          cursor: "cursor",
+        },
       },
     },
   },
@@ -44,14 +92,22 @@ const error = {
 
 const mock = new MockAdapter(axios);
 
+beforeEach(() => {
+  mock
+    .onPost("https://api.github.com/graphql")
+    .replyOnce(200, data)
+    .onPost("https://api.github.com/graphql")
+    .replyOnce(200, firstRepositoriesData)
+    .onPost("https://api.github.com/graphql")
+    .replyOnce(200, secondRepositoriesData);
+});
+
 afterEach(() => {
   mock.reset();
 });
 
 describe("Test fetchStats", () => {
   it("should fetch correct stats", async () => {
-    mock.onPost("https://api.github.com/graphql").reply(200, data);
-
     let stats = await fetchStats("anuraghazra");
     const rank = calculateRank({
       totalCommits: 100,
@@ -74,7 +130,38 @@ describe("Test fetchStats", () => {
     });
   });
 
+  it("should stop fetching when there are repos with zero stars", async () => {
+    mock.reset();
+    mock
+      .onPost("https://api.github.com/graphql")
+      .replyOnce(200, data)
+      .onPost("https://api.github.com/graphql")
+      .replyOnce(200, repositoriesWithZeroStarsData);
+
+    let stats = await fetchStats("anuraghazra");
+    const rank = calculateRank({
+      totalCommits: 100,
+      totalRepos: 5,
+      followers: 100,
+      contributions: 61,
+      stargazers: 300,
+      prs: 300,
+      issues: 200,
+    });
+
+    expect(stats).toStrictEqual({
+      contributedTo: 61,
+      name: "Anurag Hazra",
+      totalCommits: 100,
+      totalIssues: 200,
+      totalPRs: 300,
+      totalStars: 300,
+      rank,
+    });
+  });
+
   it("should throw error", async () => {
+    mock.reset();
     mock.onPost("https://api.github.com/graphql").reply(200, error);
 
     await expect(fetchStats("anuraghazra")).rejects.toThrow(
@@ -83,8 +170,6 @@ describe("Test fetchStats", () => {
   });
 
   it("should fetch and add private contributions", async () => {
-    mock.onPost("https://api.github.com/graphql").reply(200, data);
-
     let stats = await fetchStats("anuraghazra", true);
     const rank = calculateRank({
       totalCommits: 150,
@@ -108,7 +193,6 @@ describe("Test fetchStats", () => {
   });
 
   it("should fetch total commits", async () => {
-    mock.onPost("https://api.github.com/graphql").reply(200, data);
     mock
       .onGet("https://api.github.com/search/commits?q=author:anuraghazra")
       .reply(200, { total_count: 1000 });
@@ -136,7 +220,6 @@ describe("Test fetchStats", () => {
   });
 
   it("should exclude stars of the `test-repo-1` repository", async () => {
-    mock.onPost("https://api.github.com/graphql").reply(200, data);
     mock
       .onGet("https://api.github.com/search/commits?q=author:anuraghazra")
       .reply(200, { total_count: 1000 });