Compare commits

..
Author SHA1 Message Date
rickstaa 13a8edc0f6 test: another test 2023-07-19 09:53:18 +02:00
rickstaa 477c4500c8 Merge branch 'master' into pull_request_trigger_test 2023-07-19 09:52:41 +02:00
rickstaa d2a1362ac0 test: add dummy text for pr trigger test 2023-07-19 09:51:22 +02:00
36 changed files with 1325 additions and 2526 deletions
-15
View File
@@ -1,15 +0,0 @@
version: 2
updates:
# Maintain dependencies for NPM
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
# Maintain dependencies for GitHub Actions
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
-1
View File
@@ -7,7 +7,6 @@ documentation:
- readme.md - readme.md
- CONTRIBUTING.md - CONTRIBUTING.md
- CODE_OF_CONDUCT.md - CODE_OF_CONDUCT.md
- SECURITY.md
dependencies: dependencies:
- package.json - package.json
- package-lock.json - package-lock.json
+2 -2
View File
@@ -10,10 +10,10 @@ jobs:
if: github.repository == 'anuraghazra/github-readme-stats' if: github.repository == 'anuraghazra/github-readme-stats'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Deployment Prep - name: Deployment Prep
run: python ./.github/workflows/deploy-prep.py run: python ./.github/workflows/deploy-prep.py
- uses: stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a # v4.16.0 - uses: stefanzweifel/git-auto-commit-action@v4
with: with:
branch: vercel branch: vercel
create_branch: true create_branch: true
+2 -2
View File
@@ -17,10 +17,10 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
+2 -2
View File
@@ -26,10 +26,10 @@ jobs:
name: Close empty issues name: Close empty issues
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 # NOTE: Retrieve issue templates. - uses: actions/checkout@v3 # NOTE: Retrieve issue templates.
- name: Run empty issues closer action - name: Run empty issues closer action
uses: rickstaa/empty-issues-closer-action@09d48dba81e64a390dce550d643fb54cd1636d97 # v1.1.2 uses: rickstaa/empty-issues-closer-action@v1
env: env:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
with: with:
+3 -3
View File
@@ -29,10 +29,10 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
@@ -49,7 +49,7 @@ jobs:
CI: true CI: true
- name: Run Script - name: Run Script
uses: skx/github-action-tester@e29768ff4ff67be9d1fdbccd8836ab83233bebb1 # v0.10.0 uses: skx/github-action-tester@master
with: with:
script: ./scripts/push-theme-readme.sh script: ./scripts/push-theme-readme.sh
env: env:
+1 -1
View File
@@ -21,6 +21,6 @@ jobs:
if: github.repository == 'anuraghazra/github-readme-stats' if: github.repository == 'anuraghazra/github-readme-stats'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0 - uses: actions/labeler@v4
with: with:
repo-token: "${{ secrets.GITHUB_TOKEN }}" repo-token: "${{ secrets.GITHUB_TOKEN }}"
+3 -3
View File
@@ -21,12 +21,12 @@ jobs:
steps: steps:
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with: with:
persist-credentials: false persist-credentials: false
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0 uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
@@ -43,6 +43,6 @@ jobs:
# required for Code scanning alerts # required for Code scanning alerts
- name: "Upload SARIF results to code scanning" - name: "Upload SARIF results to code scanning"
uses: github/codeql-action/upload-sarif@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2 uses: github/codeql-action/upload-sarif@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
with: with:
sarif_file: results.sarif sarif_file: results.sarif
+3 -3
View File
@@ -30,15 +30,15 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
- uses: bahmutov/npm-install@c5482d70ec8706408996e31ac94075030694993f # v1.8.32 - uses: bahmutov/npm-install@v1
with: with:
useLockFile: false useLockFile: false
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 uses: actions/checkout@v3
- name: Cleanup - name: Cleanup
run: | run: |
+3 -12
View File
@@ -1,15 +1,6 @@
name: Close stale theme pull requests that have the 'invalid' label. name: Close stale theme pull requests that have the 'invalid' label.
on: on:
schedule: schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: "0 0 */7 * *" - cron: "0 0 */7 * *"
permissions: permissions:
@@ -36,15 +27,15 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
- uses: bahmutov/npm-install@c5482d70ec8706408996e31ac94075030694993f # v1.8.32 - uses: bahmutov/npm-install@v1
with: with:
useLockFile: false useLockFile: false
+3 -3
View File
@@ -18,10 +18,10 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
@@ -40,4 +40,4 @@ jobs:
npm run format:check npm run format:check
- name: Code Coverage - name: Code Coverage
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 uses: codecov/codecov-action@v3
+1 -10
View File
@@ -1,15 +1,6 @@
name: Update top issues dashboard name: Update top issues dashboard
on: on:
schedule: schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: "0 0 */3 * *" - cron: "0 0 */3 * *"
workflow_dispatch: workflow_dispatch:
@@ -34,7 +25,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Run top issues action - name: Run top issues action
uses: rickstaa/top-issues-action@c66e5d53ffc26f7ae020ff8454582884d4af4cdb # v1.3.32 uses: rickstaa/top-issues-action@v1
env: env:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
with: with:
+3 -12
View File
@@ -1,15 +1,6 @@
name: Update supported languages name: Update supported languages
on: on:
schedule: schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: "0 0 */30 * *" - cron: "0 0 */30 * *"
permissions: permissions:
@@ -36,10 +27,10 @@ jobs:
node-version: [18.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/checkout@v3
- name: Setup Node - name: Setup Node
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: npm cache: npm
@@ -53,7 +44,7 @@ jobs:
run: npm run generate-langs-json run: npm run generate-langs-json
- name: Create Pull Request if upstream language file is changed - name: Create Pull Request if upstream language file is changed
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2 uses: peter-evans/create-pull-request@v4
with: with:
commit-message: "refactor: update languages JSON" commit-message: "refactor: update languages JSON"
branch: "update_langs/patch" branch: "update_langs/patch"
+1 -2
View File
@@ -1,7 +1,6 @@
{ {
"recommendations": [ "recommendations": [
"yzhang.markdown-all-in-one", "yzhang.markdown-all-in-one",
"esbenp.prettier-vscode", "esbenp.prettier-vscode"
"dbaeumer.vscode-eslint"
] ]
} }
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"markdown.extension.toc.levels": "1..3", "markdown.extension.toc.levels": "1..3",
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode"
} }
+4 -4
View File
@@ -40,20 +40,20 @@ _(make sure you already have a [Vercel](https://vercel.com/) account)_
8. Run the command `vercel dev` to start a development server at <https://localhost:3000>. 8. Run the command `vercel dev` to start a development server at <https://localhost:3000>.
9. The cards will then be available from this local endpoint (i.e. `https://localhost:3000/api?username=anuraghazra`). 9. The cards will then be available from this local endpoint (i.e. `https://localhost:3000/api?username=anuraghazra`).
> [!NOTE]\ > **Note**
> You can debug the package code in [Vscode](https://code.visualstudio.com/) by using the [Node.js: Attach to process](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_setting-up-an-attach-configuration) debug option. You can also debug any tests using the [VSCode Jest extension](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest). For more information, see https://github.com/jest-community/vscode-jest/issues/912. > You can debug the package code in [Vscode](https://code.visualstudio.com/) by using the [Node.js: Attach to process](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_setting-up-an-attach-configuration) debug option. You can also debug any tests using the [VSCode Jest extension](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest). For more information, see https://github.com/jest-community/vscode-jest/issues/912.
## Themes Contribution ## Themes Contribution
GitHub Readme Stats supports custom theming, and you can also contribute new themes! GitHub Readme Stats supports custom theming, and you can also contribute new themes!
> [!NOTE]\ > **Note**
> If you are contributing your theme just because you are using it personally, then you can [customize the looks](./readme.md#customization) of your card with URL params instead. > If you are contributing your theme just because you are using it personally, then you can [customize the looks](./readme.md#customization) of your card with URL params instead.
> [!NOTE]\ > **Note**
> Keep in mind that we already have a vast collection of different themes. To keep their number manageable, we began to add only themes supported by the community. Your pull request with theme addition will be merged once we get enough positive feedback from the community in the form of thumbs up (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935#top-themes-prs)). Remember that you can also support themes of other contributors that you liked to speed up their merge. > Keep in mind that we already have a vast collection of different themes. To keep their number manageable, we began to add only themes supported by the community. Your pull request with theme addition will be merged once we get enough positive feedback from the community in the form of thumbs up (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935#top-themes-prs)). Remember that you can also support themes of other contributors that you liked to speed up their merge.
> [!NOTE]\ > **Note**
> Before submitting pull request, please make sure that your theme pass WCAG 2.0 level AA constrast ration test. You can use [this tool](https://webaim.org/resources/contrastchecker/) to check it. > Before submitting pull request, please make sure that your theme pass WCAG 2.0 level AA constrast ration test. You can use [this tool](https://webaim.org/resources/contrastchecker/) to check it.
To contribute your theme you need to edit the [themes/index.js](./themes/index.js) file and add it at the end of the file. To contribute your theme you need to edit the [themes/index.js](./themes/index.js) file and add it at the end of the file.
-39
View File
@@ -1,39 +0,0 @@
# GitHub Readme Stats Security Policies and Procedures <!-- omit in toc -->
This document outlines security procedures and general policies for the
GitHub Readme Stats project.
- [Reporting a Vulnerability](#reporting-a-vulnerability)
- [Disclosure Policy](#disclosure-policy)
## Reporting a Vulnerability
The GitHub Readme Stats team and community take all security vulnerabilities
seriously. Thank you for improving the security of our open source
software. We appreciate your efforts and responsible disclosure and will
make every effort to acknowledge your contributions.
Report security vulnerabilities by emailing the GitHub Readme Stats team at:
```
hazru.anurag@gmail.com
```
The lead maintainer will acknowledge your email within 24 hours, and will
send a more detailed response within 48 hours indicating the next steps in
handling your report. After the initial reply to your report, the security
team will endeavor to keep you informed of the progress towards a fix and
full announcement, and may ask for additional information or guidance.
Report security vulnerabilities in third-party modules to the person or
team maintaining the module.
## Disclosure Policy
When the security team receives a security bug report, they will assign it
to a primary handler. This person will coordinate the fix and release
process, involving the following steps:
* Confirm the problem.
* Audit code to find any potential similar problems.
* Prepare fixes and release them as fast as possible.
+1172 -2216
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -30,37 +30,37 @@
"format": "prettier --write .", "format": "prettier --write .",
"format:check": "prettier --check .", "format:check": "prettier --check .",
"prepare": "husky install", "prepare": "husky install",
"lint": "npx eslint --max-warnings 0 \"./src/**/*.js\" \"./scripts/**/*.js\" \"./tests/**/*.js\" \"./api/**/*.js\" \"./themes/**/*.js\"" "lint": "npx eslint --max-warnings 0 \"./src/**.js\" \"./scripts/**.js\" \"./tests/**.js\" \"./api/**.js\" \"./themes/**.js\""
}, },
"author": "Anurag Hazra", "author": "Anurag Hazra",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.9.1",
"@actions/github": "^5.1.1", "@actions/github": "^4.0.0",
"@testing-library/dom": "^9.3.1", "@testing-library/dom": "^8.17.1",
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.16.5",
"@uppercod/css-to-object": "^1.1.1", "@uppercod/css-to-object": "^1.1.1",
"axios-mock-adapter": "^1.21.5", "axios-mock-adapter": "^1.21.2",
"color-contrast-checker": "^2.1.0", "color-contrast-checker": "^2.1.0",
"eslint": "^8.46.0", "eslint": "^8.43.0",
"eslint-config-prettier": "^8.9.0", "eslint-config-prettier": "^8.8.0",
"hjson": "^3.2.2", "hjson": "^3.2.2",
"husky": "^8.0.3", "husky": "^8.0.0",
"jest": "^29.6.2", "jest": "^29.5.0",
"jest-environment-jsdom": "^29.6.2", "jest-environment-jsdom": "^29.5.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"lint-staged": "^13.2.3", "lint-staged": "^13.0.3",
"lodash.snakecase": "^4.1.1", "lodash.snakecase": "^4.1.1",
"parse-diff": "^0.11.1", "parse-diff": "^0.7.0",
"prettier": "^3.0.0" "prettier": "^2.1.2"
}, },
"dependencies": { "dependencies": {
"axios": "^1.4.0", "axios": "^1.4.0",
"dotenv": "^16.3.1", "dotenv": "^8.2.0",
"emoji-name-map": "^1.2.8", "emoji-name-map": "^1.2.8",
"github-username-regex": "^1.0.0", "github-username-regex": "^1.0.0",
"upgrade": "^1.1.0", "upgrade": "^1.1.0",
"word-wrap": "^1.2.5" "word-wrap": "^1.2.3"
}, },
"lint-staged": { "lint-staged": {
"*.{js,css,md}": "prettier --write" "*.{js,css,md}": "prettier --write"
+48 -46
View File
@@ -88,42 +88,42 @@ Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of
# Features <!-- omit in toc --> # Features <!-- omit in toc -->
- [GitHub Stats Card](#github-stats-card) * [GitHub Stats Card](#github-stats-card)
- [Hiding individual stats](#hiding-individual-stats) * [Hiding individual stats](#hiding-individual-stats)
- [Showing additional individual stats](#showing-additional-individual-stats) * [Showing additional individual stats](#showing-additional-individual-stats)
- [Showing icons](#showing-icons) * [Showing icons](#showing-icons)
- [Themes](#themes) * [Themes](#themes)
- [Customization](#customization) * [Customization](#customization)
- [GitHub Extra Pins](#github-extra-pins) * [GitHub Extra Pins](#github-extra-pins)
- [Usage](#usage) * [Usage](#usage)
- [Demo](#demo) * [Demo](#demo)
- [Top Languages Card](#top-languages-card) * [Top Languages Card](#top-languages-card)
- [Usage](#usage-1) * [Usage](#usage-1)
- [Language stats algorithm](#language-stats-algorithm) * [Language stats algorithm](#language-stats-algorithm)
- [Exclude individual repositories](#exclude-individual-repositories) * [Exclude individual repositories](#exclude-individual-repositories)
- [Hide individual languages](#hide-individual-languages) * [Hide individual languages](#hide-individual-languages)
- [Show more languages](#show-more-languages) * [Show more languages](#show-more-languages)
- [Compact Language Card Layout](#compact-language-card-layout) * [Compact Language Card Layout](#compact-language-card-layout)
- [Donut Chart Language Card Layout](#donut-chart-language-card-layout) * [Donut Chart Language Card Layout](#donut-chart-language-card-layout)
- [Donut Vertical Chart Language Card Layout](#donut-vertical-chart-language-card-layout) * [Donut Vertical Chart Language Card Layout](#donut-vertical-chart-language-card-layout)
- [Pie Chart Language Card Layout](#pie-chart-language-card-layout) * [Pie Chart Language Card Layout](#pie-chart-language-card-layout)
- [Hide Progress Bars](#hide-progress-bars) * [Hide Progress Bars](#hide-progress-bars)
- [Demo](#demo-1) * [Demo](#demo-1)
- [Wakatime Stats Card](#wakatime-stats-card) * [Wakatime Stats Card](#wakatime-stats-card)
- [Demo](#demo-2) * [Demo](#demo-2)
- [All Demos](#all-demos) * [All Demos](#all-demos)
- [Quick Tip (Align The Cards)](#quick-tip-align-the-cards) * [Quick Tip (Align The Cards)](#quick-tip-align-the-cards)
- [Deploy on your own](#deploy-on-your-own) * [Deploy on your own](#deploy-on-your-own)
- [On Vercel](#on-vercel) * [On Vercel](#on-vercel)
- [:film\_projector: Check Out Step By Step Video Tutorial By @codeSTACKr](#film_projector-check-out-step-by-step-video-tutorial-by-codestackr) * [:film\_projector: Check Out Step By Step Video Tutorial By @codeSTACKr](#film_projector-check-out-step-by-step-video-tutorial-by-codestackr)
- [On other platforms](#on-other-platforms) * [On other platforms](#on-other-platforms)
- [Disable rate limit protections](#disable-rate-limit-protections) * [Disable rate limit protections](#disable-rate-limit-protections)
- [Keep your fork up to date](#keep-your-fork-up-to-date) * [Keep your fork up to date](#keep-your-fork-up-to-date)
- [:sparkling\_heart: Support the project](#sparkling_heart-support-the-project) * [:sparkling\_heart: Support the project](#sparkling_heart-support-the-project)
# Important Notice <!-- omit in toc --> # Important Notice <!-- omit in toc -->
> [!IMPORTANT]\ > **Warning**
> Since the GitHub API only [allows 5k requests per hour per user account](https://docs.github.com/en/graphql/overview/resource-limitations), the public Vercel instance hosted on `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). We use caching to prevent this from happening (see https://github.com/anuraghazra/github-readme-stats#common-options). You can turn off these rate limit protections by deploying [your own Vercel instance](#disable-rate-limit-protections). > Since the GitHub API only [allows 5k requests per hour per user account](https://docs.github.com/en/graphql/overview/resource-limitations), the public Vercel instance hosted on `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). We use caching to prevent this from happening (see https://github.com/anuraghazra/github-readme-stats#common-options). You can turn off these rate limit protections by deploying [your own Vercel instance](#disable-rate-limit-protections).
# GitHub Stats Card # GitHub Stats Card
@@ -136,11 +136,11 @@ Change the `?username=` value to your GitHub username.
[![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) [![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats)
``` ```
> [!WARNING]\ > **Warning**
> By default, the stats card only shows statistics like stars, commits and pull requests from public repositories. To show private statistics on the stats card, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token. > By default, the stats card only shows statistics like stars, commits and pull requests from public repositories. To show private statistics on the stats card, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token.
> [!NOTE]\ > **Note**
> Available ranks are S (top 1%), A+ (12.5%), A (25%), A- (37.5%), B+ (50%), B (62.5%), B- (75%), C+ (87.5%) and C (everyone). This ranking scheme is based on the [Japanese academic grading](https://wikipedia.org/wiki/Academic_grading_in_Japan) system. The global percentile is calculated as a weighted sum of percentiles for each statistic (number of commits, pull requests, reviews, issues, stars and followers), based on the cumulative distribution function of the [exponential](https://wikipedia.org/wiki/exponential_distribution) and the [log-normal](https://wikipedia.org/wiki/Log-normal_distribution) distributions. The implementation can be investigated at [src/calculateRank.js](./src/calculateRank.js). The circle around the rank shows 100 minus the global percentile. > Available ranks are S (top 1%), A+ (12.5%), A (25%), A- (37.5%), B+ (50%), B (62.5%), B- (75%), C+ (87.5%) and C (everyone). This ranking scheme is based on the [Japanese academic grading](https://wikipedia.org/wiki/Academic_grading_in_Japan) system. The global percentile is calculated as a weighted sum of percentiles for each statistic (number of commits, pull requests, issues, stars and followers), based on the cumulative distribution function of the [exponential](https://wikipedia.org/wiki/exponential_distribution) and the [log-normal](https://wikipedia.org/wiki/Log-normal_distribution) distributions. The implementation can be investigated at [src/calculateRank.js](./src/calculateRank.js). The circle around the rank shows 100 minus the global percentile.
### Hiding individual stats ### Hiding individual stats
@@ -294,7 +294,7 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you
* `locale` - Sets the language in the card *(e.g. cn, de, es, etc.)*. Default: `en`. * `locale` - Sets the language in the card *(e.g. cn, de, es, etc.)*. Default: `en`.
* `border_radius` - Corner rounding on the card. Default: `4.5`. * `border_radius` - Corner rounding on the card. Default: `4.5`.
> [!WARNING]\ > **Warning**
> We use caching to decrease the load on our servers (see <https://github.com/anuraghazra/github-readme-stats/issues/1471#issuecomment-1271551425>). Our cards have a default cache of 4 hours (14400 seconds). Also, note that the cache is clamped to a minimum of 4 hours and a maximum of 24 hours. > We use caching to decrease the load on our servers (see <https://github.com/anuraghazra/github-readme-stats/issues/1471#issuecomment-1271551425>). Our cards have a default cache of 4 hours (14400 seconds). Also, note that the cache is clamped to a minimum of 4 hours and a maximum of 24 hours.
##### Gradient in bg\_color ##### Gradient in bg\_color
@@ -321,7 +321,7 @@ You can provide multiple comma-separated values in the bg\_color option to rende
* `number_format` - Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). Default: `short`. * `number_format` - Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). Default: `short`.
* `show` - Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started` or `discussions_answered`) *(Comma-separated values)*. Default: `[] (blank array)`. * `show` - Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started` or `discussions_answered`) *(Comma-separated values)*. Default: `[] (blank array)`.
> [!NOTE]\ > **Note**
> When hide\_rank=`true`, the minimum card width is 270 px + the title length and padding. > When hide\_rank=`true`, the minimum card width is 270 px + the title length and padding.
#### Repo Card Exclusive Options #### Repo Card Exclusive Options
@@ -342,7 +342,7 @@ You can provide multiple comma-separated values in the bg\_color option to rende
* `size_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 1. * `size_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 1.
* `count_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 0. * `count_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 0.
> [!WARNING]\ > **Warning**
> 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 > (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. > [urlencoder.org](https://www.urlencoder.org/) to help you do this automatically.
@@ -388,13 +388,13 @@ Use [show\_owner](#repo-card-exclusive-options) query option to include the repo
The top languages card shows a GitHub user's most frequently used languages. The top languages card shows a GitHub user's most frequently used languages.
> [!WARNING]\ > **Warning**
> By default, the language card shows language results only from public repositories. To include languages used in private repositories, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token. > By default, the language card shows language results only from public repositories. To include languages used in private repositories, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token.
> [!NOTE]\ > **Note**
> Top Languages does not indicate the user's 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. > Top Languages does not indicate the user's 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.
> [!WARNING]\ > **Warning**
> This card shows languages usage only inside your own non-forked repositories, not depending from who is the author of the commits. It does not include your contributions into another users/organizations repositories. Currently there are no way to get this data from GitHub API. If you want this behavior to be improved you can support [this feature request](https://github.com/orgs/community/discussions/18230) created by [@rickstaa](https://github.com/rickstaa) inside GitHub Community. > This card shows languages usage only inside your own non-forked repositories, not depending from who is the author of the commits. It does not include your contributions into another users/organizations repositories. Currently there are no way to get this data from GitHub API. If you want this behavior to be improved you can support [this feature request](https://github.com/orgs/community/discussions/18230) created by [@rickstaa](https://github.com/rickstaa) inside GitHub Community.
### Usage ### Usage
@@ -515,7 +515,7 @@ You can use the `&hide_progress=true` option to hide the percentages and the pro
# Wakatime Stats Card # Wakatime Stats Card
> [!WARNING]\ > **Warning**
> Please be aware that we currently only show data from Wakatime profiles that are public. You therefore have to make sure that **BOTH** `Display code time publicly` and `Display languages, editors, os, categories publicly` are enabled. > Please be aware that we currently only show data from Wakatime profiles that are public. You therefore have to make sure that **BOTH** `Display code time publicly` and `Display languages, editors, os, categories publicly` are enabled.
Change the `?username=` value to your [Wakatime](https://wakatime.com) username. Change the `?username=` value to your [Wakatime](https://wakatime.com) username.
@@ -653,10 +653,10 @@ By default, GitHub does not lay out the cards side by side. To do that, you can
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! 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]\ > **Note**
> Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58), we should be able to handle more than 5k requests and have fewer issues with downtime :grin:. > Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58), we should be able to handle more than 5k requests and have fewer issues with downtime :grin:.
> [!NOTE]\ > **Note**
> If you are on the [Pro (i.e. paid)](https://vercel.com/pricing) Vercel plan, the [maxDuration](https://vercel.com/docs/concepts/projects/project-configuration#value-definition) value found in the [Vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) can be increased when your Vercel instance frequently times out during the card request. You are advised to keep this value lower than `30` seconds to prevent high memory usage. > If you are on the [Pro (i.e. paid)](https://vercel.com/pricing) Vercel plan, the [maxDuration](https://vercel.com/docs/concepts/projects/project-configuration#value-definition) value found in the [Vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) can be increased when your Vercel instance frequently times out during the card request. You are advised to keep this value lower than `30` seconds to prevent high memory usage.
[![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats) [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
@@ -685,7 +685,7 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
## On other platforms ## On other platforms
> [!WARNING]\ > **Warning**
> This way of using GRS is not officially supported and was added to cater to some particular use cases where Vercel could not be used (e.g. [#2341](https://github.com/anuraghazra/github-readme-stats/discussions/2341)). The support for this method, therefore, is limited. > This way of using GRS is not officially supported and was added to cater to some particular use cases where Vercel could not be used (e.g. [#2341](https://github.com/anuraghazra/github-readme-stats/discussions/2341)). The support for this method, therefore, is limited.
<details> <details>
@@ -732,3 +732,5 @@ Thanks! :heart:
Contributions are welcome! <3 Contributions are welcome! <3
Made with :heart: and JavaScript. Made with :heart: and JavaScript.
test2
+11 -11
View File
@@ -29,10 +29,10 @@ const FAIL_TEXT = `
const THEME_CONTRIB_GUIDELINES = ` const THEME_CONTRIB_GUIDELINES = `
\rHi, thanks for the theme contribution. Please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). \rHi, thanks for the theme contribution. Please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution).
\r> [!WARNING]\ \r> **Warning**
\r> Keep in mind that we already have a vast collection of different themes. To keep their number manageable, we began to add only themes supported by the community. Your pull request with theme addition will be merged once we get enough positive feedback from the community in the form of thumbs up (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935#top-themes-prs)). Remember that you can also support themes of other contributors that you liked to speed up their merge. \r> Keep in mind that we already have a vast collection of different themes. To keep their number manageable, we began to add only themes supported by the community. Your pull request with theme addition will be merged once we get enough positive feedback from the community in the form of thumbs up (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935#top-themes-prs)). Remember that you can also support themes of other contributors that you liked to speed up their merge.
\r> [!NOTE]\ \r> **Note**
\r> Also, note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection, you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization). \r> Also, note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection, you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization).
`; `;
const COLOR_PROPS = { const COLOR_PROPS = {
@@ -164,14 +164,14 @@ const upsertComment = async (
) => { ) => {
let resp; let resp;
if (commentId !== undefined) { if (commentId !== undefined) {
resp = await octokit.rest.issues.updateComment({ resp = await octokit.issues.updateComment({
owner, owner,
repo, repo,
comment_id: commentId, comment_id: commentId,
body, body,
}); });
} else { } else {
resp = await octokit.rest.issues.createComment({ resp = await octokit.issues.createComment({
owner, owner,
repo, repo,
issue_number: issueNumber, issue_number: issueNumber,
@@ -200,7 +200,7 @@ const addReview = async (
reviewState, reviewState,
reason, reason,
) => { ) => {
await octokit.rest.pulls.createReview({ await octokit.pulls.createReview({
owner, owner,
repo, repo,
pull_number: prNumber, pull_number: prNumber,
@@ -220,7 +220,7 @@ const addReview = async (
* @returns {Promise<void>} Promise. * @returns {Promise<void>} Promise.
*/ */
const addLabel = async (octokit, prNumber, owner, repo, labels) => { const addLabel = async (octokit, prNumber, owner, repo, labels) => {
await octokit.rest.issues.addLabels({ await octokit.issues.addLabels({
owner, owner,
repo, repo,
issue_number: prNumber, issue_number: prNumber,
@@ -239,7 +239,7 @@ const addLabel = async (octokit, prNumber, owner, repo, labels) => {
* @returns {Promise<void>} Promise. * @returns {Promise<void>} Promise.
*/ */
const removeLabel = async (octokit, prNumber, owner, repo, label) => { const removeLabel = async (octokit, prNumber, owner, repo, label) => {
await octokit.rest.issues.removeLabel({ await octokit.issues.removeLabel({
owner, owner,
repo, repo,
issue_number: prNumber, issue_number: prNumber,
@@ -259,7 +259,7 @@ const removeLabel = async (octokit, prNumber, owner, repo, label) => {
* @returns {Promise<void>} Promise. * @returns {Promise<void>} Promise.
*/ */
const addRemoveLabel = async (octokit, prNumber, owner, repo, label, add) => { const addRemoveLabel = async (octokit, prNumber, owner, repo, label, add) => {
const res = await octokit.rest.pulls.get({ const res = await octokit.pulls.get({
owner, owner,
repo, repo,
pull_number: prNumber, pull_number: prNumber,
@@ -389,7 +389,7 @@ export const run = async () => {
// Retrieve the PR diff and preview-theme comment. // Retrieve the PR diff and preview-theme comment.
debug("Retrieve PR diff..."); debug("Retrieve PR diff...");
const res = await OCTOKIT.rest.pulls.get({ const res = await OCTOKIT.pulls.get({
owner: OWNER, owner: OWNER,
repo: REPO, repo: REPO,
pull_number: PULL_REQUEST_ID, pull_number: PULL_REQUEST_ID,
@@ -551,8 +551,8 @@ export const run = async () => {
\r${warnings.map((warning) => `- :warning: ${warning}.\n`).join("")} \r${warnings.map((warning) => `- :warning: ${warning}.\n`).join("")}
\ntitle_color: <code>#${titleColor}</code> | icon_color: <code>#${iconColor}</code> | text_color: <code>#${textColor}</code> | bg_color: <code>#${bgColor}</code>${ \ntitle_color: <code>#${titleColor}</code> | icon_color: <code>#${iconColor}</code> | text_color: <code>#${textColor}</code> | bg_color: <code>#${bgColor}</code>${
borderColor ? ` | border_color: <code>#${borderColor}</code>` : "" borderColor ? ` | border_color: <code>#${borderColor}</code>` : ""
} }
\r[Preview Link](${url}) \r[Preview Link](${url})
-6
View File
@@ -15,7 +15,6 @@ function log_normal_cdf(x) {
* @param {number} params.commits Number of commits. * @param {number} params.commits Number of commits.
* @param {number} params.prs The number of pull requests. * @param {number} params.prs The number of pull requests.
* @param {number} params.issues The number of issues. * @param {number} params.issues The number of issues.
* @param {number} params.reviews The number of reviews.
* @param {number} params.repos Total number of repos. * @param {number} params.repos Total number of repos.
* @param {number} params.stars The number of stars. * @param {number} params.stars The number of stars.
* @param {number} params.followers The number of followers. * @param {number} params.followers The number of followers.
@@ -26,7 +25,6 @@ function calculateRank({
commits, commits,
prs, prs,
issues, issues,
reviews,
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
repos, // unused repos, // unused
stars, stars,
@@ -38,8 +36,6 @@ function calculateRank({
PRS_WEIGHT = 3; PRS_WEIGHT = 3;
const ISSUES_MEDIAN = 25, const ISSUES_MEDIAN = 25,
ISSUES_WEIGHT = 1; ISSUES_WEIGHT = 1;
const REVIEWS_MEDIAN = 2,
REVIEWS_WEIGHT = 1;
const STARS_MEDIAN = 50, const STARS_MEDIAN = 50,
STARS_WEIGHT = 4; STARS_WEIGHT = 4;
const FOLLOWERS_MEDIAN = 10, const FOLLOWERS_MEDIAN = 10,
@@ -49,7 +45,6 @@ function calculateRank({
COMMITS_WEIGHT + COMMITS_WEIGHT +
PRS_WEIGHT + PRS_WEIGHT +
ISSUES_WEIGHT + ISSUES_WEIGHT +
REVIEWS_WEIGHT +
STARS_WEIGHT + STARS_WEIGHT +
FOLLOWERS_WEIGHT; FOLLOWERS_WEIGHT;
@@ -61,7 +56,6 @@ function calculateRank({
(COMMITS_WEIGHT * exponential_cdf(commits / COMMITS_MEDIAN) + (COMMITS_WEIGHT * exponential_cdf(commits / COMMITS_MEDIAN) +
PRS_WEIGHT * exponential_cdf(prs / PRS_MEDIAN) + PRS_WEIGHT * exponential_cdf(prs / PRS_MEDIAN) +
ISSUES_WEIGHT * exponential_cdf(issues / ISSUES_MEDIAN) + ISSUES_WEIGHT * exponential_cdf(issues / ISSUES_MEDIAN) +
REVIEWS_WEIGHT * exponential_cdf(reviews / REVIEWS_MEDIAN) +
STARS_WEIGHT * log_normal_cdf(stars / STARS_MEDIAN) + STARS_WEIGHT * log_normal_cdf(stars / STARS_MEDIAN) +
FOLLOWERS_WEIGHT * log_normal_cdf(followers / FOLLOWERS_MEDIAN)) / FOLLOWERS_WEIGHT * log_normal_cdf(followers / FOLLOWERS_MEDIAN)) /
TOTAL_WEIGHT; TOTAL_WEIGHT;
+1 -1
View File
@@ -62,7 +62,7 @@ const ICON_SIZE = 16;
* @returns {string} Icon with label SVG object. * @returns {string} Icon with label SVG object.
*/ */
const iconWithLabel = (icon, label, testid) => { const iconWithLabel = (icon, label, testid) => {
if (typeof label === "number" && label <= 0) return ""; if (label <= 0) return "";
const iconSvg = ` const iconSvg = `
<svg <svg
class="icon" class="icon"
+4 -9
View File
@@ -219,9 +219,8 @@ const renderStatsCard = (stats, options = {}) => {
"de", "de",
"nl", "nl",
"zh-tw", "zh-tw",
"uz",
]; ];
const isLongLocale = locale ? longLocales.includes(locale) : false; const isLongLocale = longLocales.includes(locale);
// filter out hidden stats defined by user & create the text nodes // filter out hidden stats defined by user & create the text nodes
const statItems = Object.keys(STATS) const statItems = Object.keys(STATS)
@@ -295,11 +294,7 @@ const renderStatsCard = (stats, options = {}) => {
: statItems.length : statItems.length
? RANK_CARD_DEFAULT_WIDTH ? RANK_CARD_DEFAULT_WIDTH
: RANK_ONLY_CARD_DEFAULT_WIDTH) + iconWidth; : RANK_ONLY_CARD_DEFAULT_WIDTH) + iconWidth;
let width = card_width let width = isNaN(card_width) ? defaultCardWidth : card_width;
? isNaN(card_width)
? defaultCardWidth
: card_width
: defaultCardWidth;
if (width < minCardWidth) { if (width < minCardWidth) {
width = minCardWidth; width = minCardWidth;
} }
@@ -356,8 +351,8 @@ const renderStatsCard = (stats, options = {}) => {
? "" ? ""
: `<g data-testid="rank-circle" : `<g data-testid="rank-circle"
transform="translate(${calculateRankXTranslation()}, ${ transform="translate(${calculateRankXTranslation()}, ${
height / 2 - 50 height / 2 - 50
})"> })">
<circle class="rank-circle-rim" cx="-10" cy="8" r="40" /> <circle class="rank-circle-rim" cx="-10" cy="8" r="40" />
<circle class="rank-circle" cx="-10" cy="8" r="40" /> <circle class="rank-circle" cx="-10" cy="8" r="40" />
<g class="rank-text"> <g class="rank-text">
+10 -12
View File
@@ -46,7 +46,7 @@ const getLongestLang = (arr) =>
* Convert degrees to radians. * Convert degrees to radians.
* *
* @param {number} angleInDegrees Angle in degrees. * @param {number} angleInDegrees Angle in degrees.
* @returns {number} Angle in radians. * @returns Angle in radians.
*/ */
const degreesToRadians = (angleInDegrees) => angleInDegrees * (Math.PI / 180.0); const degreesToRadians = (angleInDegrees) => angleInDegrees * (Math.PI / 180.0);
@@ -54,7 +54,7 @@ const degreesToRadians = (angleInDegrees) => angleInDegrees * (Math.PI / 180.0);
* Convert radians to degrees. * Convert radians to degrees.
* *
* @param {number} angleInRadians Angle in radians. * @param {number} angleInRadians Angle in radians.
* @returns {number} Angle in degrees. * @returns Angle in degrees.
*/ */
const radiansToDegrees = (angleInRadians) => angleInRadians / (Math.PI / 180.0); const radiansToDegrees = (angleInRadians) => angleInRadians / (Math.PI / 180.0);
@@ -234,7 +234,7 @@ const createProgressTextNode = ({ width, color, name, progress, index }) => {
* @param {object} props Function properties. * @param {object} props Function properties.
* @param {Lang} props.lang Programming language object. * @param {Lang} props.lang Programming language object.
* @param {number} props.totalSize Total size of all languages. * @param {number} props.totalSize Total size of all languages.
* @param {boolean=} props.hideProgress Whether to hide percentage. * @param {boolean} props.hideProgress Whether to hide percentage.
* @param {number} props.index Index of the programming language. * @param {number} props.index Index of the programming language.
* @returns {string} Compact layout programming language SVG node. * @returns {string} Compact layout programming language SVG node.
*/ */
@@ -259,7 +259,7 @@ const createCompactLangNode = ({ lang, totalSize, hideProgress, index }) => {
* @param {object} props Function properties. * @param {object} props Function properties.
* @param {Lang[]} props.langs Array of programming languages. * @param {Lang[]} props.langs Array of programming languages.
* @param {number} props.totalSize Total size of all languages. * @param {number} props.totalSize Total size of all languages.
* @param {boolean=} props.hideProgress Whether to hide percentage. * @param {boolean} props.hideProgress Whether to hide percentage.
* @returns {string} Programming languages SVG node. * @returns {string} Programming languages SVG node.
*/ */
const createLanguageTextNode = ({ langs, totalSize, hideProgress }) => { const createLanguageTextNode = ({ langs, totalSize, hideProgress }) => {
@@ -344,7 +344,7 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => {
* @param {Lang[]} langs Array of programming languages. * @param {Lang[]} langs Array of programming languages.
* @param {number} width Card width. * @param {number} width Card width.
* @param {number} totalLanguageSize Total size of all languages. * @param {number} totalLanguageSize Total size of all languages.
* @param {boolean=} hideProgress Whether to hide progress bar. * @param {boolean} hideProgress Whether to hide progress bar.
* @returns {string} Compact layout card SVG object. * @returns {string} Compact layout card SVG object.
*/ */
const renderCompactLayout = (langs, width, totalLanguageSize, hideProgress) => { const renderCompactLayout = (langs, width, totalLanguageSize, hideProgress) => {
@@ -738,13 +738,11 @@ const renderTopLanguages = (topLangs, options = {}) => {
hide, hide,
); );
let width = card_width let width = isNaN(card_width)
? isNaN(card_width) ? DEFAULT_CARD_WIDTH
? DEFAULT_CARD_WIDTH : card_width < MIN_CARD_WIDTH
: card_width < MIN_CARD_WIDTH ? MIN_CARD_WIDTH
? MIN_CARD_WIDTH : card_width;
: card_width
: DEFAULT_CARD_WIDTH;
let height = calculateNormalLayoutHeight(langs.length); let height = calculateNormalLayoutHeight(langs.length);
// returns theme based colors with proper overrides and defaults // returns theme based colors with proper overrides and defaults
+3 -10
View File
@@ -36,18 +36,13 @@ const noCodingActivityNode = ({ color, text }) => {
`; `;
}; };
/**
* @typedef {import('../fetchers/types').WakaTimeLang} WakaTimeLang
*/
/** /**
* Create compact WakaTime layout. * Create compact WakaTime layout.
* *
* @param {Object} args The function arguments. * @param {Object} args The function arguments.
* @param {WakaTimeLang} args.lang The languages array. * @param {import("../fetchers/types").WakaTimeLang} args.lang The languages array.
* @param {number} args.x The x position of the language node. * @param {number} args.x The x position of the language node.
* @param {number} args.y The y position of the language node. * @param {number} args.y The y position of the language node.
* @returns {string} The compact layout language SVG node.
*/ */
const createCompactLangNode = ({ lang, x, y }) => { const createCompactLangNode = ({ lang, x, y }) => {
const color = languageColors[lang.name] || "#858585"; const color = languageColors[lang.name] || "#858585";
@@ -66,9 +61,8 @@ const createCompactLangNode = ({ lang, x, y }) => {
* Create WakaTime language text node item. * Create WakaTime language text node item.
* *
* @param {Object} args The function arguments. * @param {Object} args The function arguments.
* @param {WakaTimeLang[]} args.langs The language objects. * @param {import("../fetchers/types").WakaTimeLang[]} args.langs The language objects.
* @param {number} args.y The y position of the language node. * @param {number} args.y The y position of the language node.
* @returns {string[]} The language text node items.
*/ */
const createLanguageTextNode = ({ langs, y }) => { const createLanguageTextNode = ({ langs, y }) => {
return langs.map((lang, index) => { return langs.map((lang, index) => {
@@ -99,7 +93,6 @@ const createLanguageTextNode = ({ langs, y }) => {
* @param {boolean} args.hideProgress Whether to hide the progress bar. * @param {boolean} args.hideProgress Whether to hide the progress bar.
* @param {string} args.progressBarColor The color of the progress bar. * @param {string} args.progressBarColor The color of the progress bar.
* @param {string} args.progressBarBackgroundColor The color of the progress bar background. * @param {string} args.progressBarBackgroundColor The color of the progress bar background.
* @returns {string} The text SVG node.
*/ */
const createTextNode = ({ const createTextNode = ({
id, id,
@@ -144,7 +137,7 @@ const createTextNode = ({
* Recalculating percentages so that, compact layout's progress bar does not break when * Recalculating percentages so that, compact layout's progress bar does not break when
* hiding languages. * hiding languages.
* *
* @param {WakaTimeLang[]} languages The languages array. * @param {import("../fetchers/types").WakaTimeLang[]} languages The languages array.
* @returns {void} The recalculated languages array. * @returns {void} The recalculated languages array.
*/ */
const recalculatePercentages = (languages) => { const recalculatePercentages = (languages) => {
+1 -1
View File
@@ -15,7 +15,7 @@ const icons = {
* Get rank icon * Get rank icon
* *
* @param {string} rankIcon - The rank icon type. * @param {string} rankIcon - The rank icon type.
* @param {string} rankLevel - The rank level. * @param {number} rankLevel - The rank level.
* @param {number} percentile - The rank percentile. * @param {number} percentile - The rank percentile.
* @returns {string} - The SVG code of the rank icon * @returns {string} - The SVG code of the rank icon
*/ */
+18 -41
View File
@@ -132,7 +132,7 @@ const isValidGradient = (colors) => {
* Retrieves a gradient if color has more than one valid hex codes else a single color. * Retrieves a gradient if color has more than one valid hex codes else a single color.
* *
* @param {string} color The color to parse. * @param {string} color The color to parse.
* @param {string | string[]} fallbackColor The fallback color. * @param {string} fallbackColor The fallback color.
* @returns {string | string[]} The gradient or color. * @returns {string | string[]} The gradient or color.
*/ */
const fallbackColor = (color, fallbackColor) => { const fallbackColor = (color, fallbackColor) => {
@@ -173,8 +173,8 @@ const request = (data, headers) => {
* @param {object} props Function properties. * @param {object} props Function properties.
* @param {string[]} props.items Array of items to layout. * @param {string[]} props.items Array of items to layout.
* @param {number} props.gap Gap between items. * @param {number} props.gap Gap between items.
* @param {"column" | "row"=} props.direction Direction to layout items. * @param {number[]?=} props.sizes Array of sizes for each item.
* @param {number[]=} props.sizes Array of sizes for each item. * @param {"column" | "row"?=} props.direction Direction to layout items.
* @returns {string[]} Array of items with proper layout. * @returns {string[]} Array of items with proper layout.
*/ */
const flexLayout = ({ items, gap, direction, sizes = [] }) => { const flexLayout = ({ items, gap, direction, sizes = [] }) => {
@@ -191,31 +191,18 @@ const flexLayout = ({ items, gap, direction, sizes = [] }) => {
}); });
}; };
/**
* Object containing card colors.
* @typedef {{
* titleColor: string | string[];
* iconColor: string | string[];
* textColor: string | string[];
* bgColor: string | string[];
* borderColor: string | string[];
* ringColor: string | string[];
* }} CardColors
*/
/** /**
* Returns theme based colors with proper overrides and defaults. * Returns theme based colors with proper overrides and defaults.
* *
* @param {Object} args Function arguments. * @param {Object} args Function arguments.
* @param {string=} args.title_color Card title color. * @param {string} args.title_color Card title color.
* @param {string=} args.text_color Card text color. * @param {string} args.text_color Card text color.
* @param {string=} args.icon_color Card icon color. * @param {string} args.icon_color Card icon color.
* @param {string=} args.bg_color Card background color. * @param {string} args.bg_color Card background color.
* @param {string=} args.border_color Card border color. * @param {string} args.border_color Card border color.
* @param {string=} args.ring_color Card ring color. * @param {string} args.ring_color Card ring color.
* @param {string=} args.theme Card theme. * @param {string} args.theme Card theme.
* @param {string=} args.fallbackTheme Fallback theme. * @param {string} args.fallbackTheme Fallback theme.
* @returns {CardColors} Card colors.
*/ */
const getCardColors = ({ const getCardColors = ({
title_color, title_color,
@@ -346,10 +333,8 @@ class CustomError extends Error {
*/ */
class MissingParamError extends Error { class MissingParamError extends Error {
/** /**
* Missing query parameter error constructor. * @param {string[]} missedParams
* * @param {string?=} secondaryMessage
* @param {string[]} missedParams An array of missing parameters names.
* @param {string=} secondaryMessage Optional secondary message to display.
*/ */
constructor(missedParams, secondaryMessage) { constructor(missedParams, secondaryMessage) {
const msg = `Missing params ${missedParams const msg = `Missing params ${missedParams
@@ -403,12 +388,7 @@ const measureText = (str, fontSize = 10) => {
); );
}; };
/** /** @param {string} name */
* Lowercase and trim string.
*
* @param {string} name String to lowercase and trim.
* @returns {string} Lowercased and trimmed string.
*/
const lowercaseTrim = (name) => name.toLowerCase().trim(); const lowercaseTrim = (name) => name.toLowerCase().trim();
/** /**
@@ -424,11 +404,9 @@ const chunkArray = (arr, perChunk) => {
const chunkIndex = Math.floor(index / perChunk); const chunkIndex = Math.floor(index / perChunk);
if (!resultArray[chunkIndex]) { if (!resultArray[chunkIndex]) {
// @ts-ignore
resultArray[chunkIndex] = []; // start a new chunk resultArray[chunkIndex] = []; // start a new chunk
} }
// @ts-ignore
resultArray[chunkIndex].push(item); resultArray[chunkIndex].push(item);
return resultArray; return resultArray;
@@ -449,11 +427,10 @@ const parseEmojis = (str) => {
}; };
/** /**
* Get diff in minutes between two dates. * Get diff in minutes
* * @param {Date} d1
* @param {Date} d1 First date. * @param {Date} d2
* @param {Date} d2 Second date. * @returns {number}
* @returns {number} Number of minutes between the two dates.
*/ */
const dateDiff = (d1, d2) => { const dateDiff = (d1, d2) => {
const date1 = new Date(d1); const date1 = new Date(d1);
-1
View File
@@ -259,7 +259,6 @@ const fetchStats = async (
all_commits: include_all_commits, all_commits: include_all_commits,
commits: stats.totalCommits, commits: stats.totalCommits,
prs: stats.totalPRs, prs: stats.totalPRs,
reviews: stats.totalReviews,
issues: stats.totalIssues, issues: stats.totalIssues,
repos: user.repositories.totalCount, repos: user.repositories.totalCount,
stars: stats.totalStars, stars: stats.totalStars,
+1 -10
View File
@@ -238,7 +238,7 @@ const statCardLocales = ({ name, apostrophe }) => {
"zh-tw": "审查的 PR 总数", "zh-tw": "审查的 PR 总数",
cs: "Celkový počet PR", cs: "Celkový počet PR",
de: "Insgesamt überprüfte PRs", de: "Insgesamt überprüfte PRs",
en: "Total PRs Reviewed", en: "Total PRs reviewed",
bn: "সর্বমোট পুনরালোচনা করা PR", bn: "সর্বমোট পুনরালোচনা করা PR",
es: "PR totales revisados", es: "PR totales revisados",
fr: "Nombre total de PR examinés", fr: "Nombre total de PR examinés",
@@ -353,7 +353,6 @@ const repoCardLocales = {
sk: "Šablóna", sk: "Šablóna",
tr: "Şablon", tr: "Şablon",
pl: "Szablony", pl: "Szablony",
uz: "Shablon",
vi: "Mẫu", vi: "Mẫu",
se: "Mall", se: "Mall",
}, },
@@ -384,7 +383,6 @@ const repoCardLocales = {
sk: "Archivované", sk: "Archivované",
tr: "Arşiv", tr: "Arşiv",
pl: "Zarchiwizowano", pl: "Zarchiwizowano",
uz: "Arxivlangan",
vi: "Đã Lưu Trữ", vi: "Đã Lưu Trữ",
se: "Arkiverade", se: "Arkiverade",
}, },
@@ -418,7 +416,6 @@ const langCardLocales = {
sk: "Najviac používané jazyky", sk: "Najviac používané jazyky",
tr: "En Çok Kullanılan Diller", tr: "En Çok Kullanılan Diller",
pl: "Najczęściej używane języki", pl: "Najczęściej używane języki",
uz: "Eng koʻp ishlatiladigan tillar",
vi: "Ngôn Ngữ Thường Sử Dụng", vi: "Ngôn Ngữ Thường Sử Dụng",
se: "Mest använda språken", se: "Mest använda språken",
}, },
@@ -449,7 +446,6 @@ const langCardLocales = {
sk: "Žiadne údaje o jazykoch.", sk: "Žiadne údaje o jazykoch.",
tr: "Dil verisi yok.", tr: "Dil verisi yok.",
pl: "Brak danych dotyczących języków.", pl: "Brak danych dotyczących języków.",
uz: "Til haqida ma'lumot yo'q.",
vi: "Không có dữ liệu ngôn ngữ.", vi: "Không có dữ liệu ngôn ngữ.",
se: "Inga språkdata.", se: "Inga språkdata.",
}, },
@@ -483,7 +479,6 @@ const wakatimeCardLocales = {
sk: "Wakatime štatistika", sk: "Wakatime štatistika",
tr: "Waketime İstatistikler", tr: "Waketime İstatistikler",
pl: "Statystyki Wakatime", pl: "Statystyki Wakatime",
uz: "Wakatime statistikasi",
vi: "Thống Kê Wakatime", vi: "Thống Kê Wakatime",
se: "Wakatime statistik", se: "Wakatime statistik",
}, },
@@ -514,7 +509,6 @@ const wakatimeCardLocales = {
sk: "Minulý rok", sk: "Minulý rok",
tr: "Geçen yıl", tr: "Geçen yıl",
pl: "W zeszłym roku", pl: "W zeszłym roku",
uz: "O'tgan yil",
vi: "Năm ngoái", vi: "Năm ngoái",
se: "Förra året", se: "Förra året",
}, },
@@ -545,7 +539,6 @@ const wakatimeCardLocales = {
sk: "Posledných 7 dní", sk: "Posledných 7 dní",
tr: "Son 7 gün", tr: "Son 7 gün",
pl: "Ostatnie 7 dni", pl: "Ostatnie 7 dni",
uz: "O'tgan 7 kun",
vi: "7 ngày qua", vi: "7 ngày qua",
se: "Senaste 7 dagarna", se: "Senaste 7 dagarna",
}, },
@@ -576,7 +569,6 @@ const wakatimeCardLocales = {
sk: "Profil používateľa Wakatime nie je verejný", sk: "Profil používateľa Wakatime nie je verejný",
tr: "Wakatime kullanıcı profili herkese açık değil", tr: "Wakatime kullanıcı profili herkese açık değil",
pl: "Profil użytkownika Wakatime nie jest publiczny", pl: "Profil użytkownika Wakatime nie jest publiczny",
uz: "Wakatime foydalanuvchi profili ochiq emas",
vi: "Hồ sơ người dùng Wakatime không công khai", vi: "Hồ sơ người dùng Wakatime không công khai",
se: "Wakatime användarprofil inte offentlig", se: "Wakatime användarprofil inte offentlig",
}, },
@@ -609,7 +601,6 @@ const wakatimeCardLocales = {
sk: "Používateľ neposkytuje verejne podrobné štatistiky kódu", sk: "Používateľ neposkytuje verejne podrobné štatistiky kódu",
tr: "Kullanıcı ayrıntılı kod istatistiklerini herkese açık olarak paylaşmıyor", tr: "Kullanıcı ayrıntılı kod istatistiklerini herkese açık olarak paylaşmıyor",
pl: "Użytkownik nie udostępnia publicznie szczegółowych statystyk kodu", pl: "Użytkownik nie udostępnia publicznie szczegółowych statystyk kodu",
uz: "Foydalanuvchi umumiy ko`d statistikasini ochiq ravishda almashmaydi",
vi: "Người dùng không chia sẻ thống kê mã chi tiết công khai", vi: "Người dùng không chia sẻ thống kê mã chi tiết công khai",
se: "Användaren delar inte offentligt detaljerad kodstatistik", se: "Användaren delar inte offentligt detaljerad kodstatistik",
}, },
-1
View File
@@ -24,7 +24,6 @@ stats.rank = calculateRank({
all_commits: false, all_commits: false,
commits: stats.totalCommits, commits: stats.totalCommits,
prs: stats.totalPRs, prs: stats.totalPRs,
reviews: stats.totalReviews,
issues: stats.totalIssues, issues: stats.totalIssues,
repos: 1, repos: 1,
stars: stats.totalStars, stars: stats.totalStars,
+6 -13
View File
@@ -10,7 +10,6 @@ describe("Test calculateRank", () => {
commits: 0, commits: 0,
prs: 0, prs: 0,
issues: 0, issues: 0,
reviews: 0,
repos: 0, repos: 0,
stars: 0, stars: 0,
followers: 0, followers: 0,
@@ -25,12 +24,11 @@ describe("Test calculateRank", () => {
commits: 125, commits: 125,
prs: 25, prs: 25,
issues: 10, issues: 10,
reviews: 5,
repos: 0, repos: 0,
stars: 25, stars: 25,
followers: 5, followers: 5,
}), }),
).toStrictEqual({ level: "B-", percentile: 65.02918514848255 }); ).toStrictEqual({ level: "B-", percentile: 69.333868386557 });
}); });
it("median user gets B+ rank", () => { it("median user gets B+ rank", () => {
@@ -40,12 +38,11 @@ describe("Test calculateRank", () => {
commits: 250, commits: 250,
prs: 50, prs: 50,
issues: 25, issues: 25,
reviews: 10,
repos: 0, repos: 0,
stars: 50, stars: 50,
followers: 10, followers: 10,
}), }),
).toStrictEqual({ level: "B+", percentile: 46.09375 }); ).toStrictEqual({ level: "B+", percentile: 50 });
}); });
it("average user gets B+ rank (include_all_commits)", () => { it("average user gets B+ rank (include_all_commits)", () => {
@@ -55,12 +52,11 @@ describe("Test calculateRank", () => {
commits: 1000, commits: 1000,
prs: 50, prs: 50,
issues: 25, issues: 25,
reviews: 10,
repos: 0, repos: 0,
stars: 50, stars: 50,
followers: 10, followers: 10,
}), }),
).toStrictEqual({ level: "B+", percentile: 46.09375 }); ).toStrictEqual({ level: "B+", percentile: 50 });
}); });
it("advanced user gets A rank", () => { it("advanced user gets A rank", () => {
@@ -70,12 +66,11 @@ describe("Test calculateRank", () => {
commits: 500, commits: 500,
prs: 100, prs: 100,
issues: 50, issues: 50,
reviews: 20,
repos: 0, repos: 0,
stars: 200, stars: 200,
followers: 40, followers: 40,
}), }),
).toStrictEqual({ level: "A", percentile: 20.841471354166664 }); ).toStrictEqual({ level: "A", percentile: 22.72727272727273 });
}); });
it("expert user gets A+ rank", () => { it("expert user gets A+ rank", () => {
@@ -85,12 +80,11 @@ describe("Test calculateRank", () => {
commits: 1000, commits: 1000,
prs: 200, prs: 200,
issues: 100, issues: 100,
reviews: 40,
repos: 0, repos: 0,
stars: 800, stars: 800,
followers: 160, followers: 160,
}), }),
).toStrictEqual({ level: "A+", percentile: 5.575988339442828 }); ).toStrictEqual({ level: "A+", percentile: 6.082887700534744 });
}); });
it("sindresorhus gets S rank", () => { it("sindresorhus gets S rank", () => {
@@ -100,11 +94,10 @@ describe("Test calculateRank", () => {
commits: 1300, commits: 1300,
prs: 1500, prs: 1500,
issues: 4500, issues: 4500,
reviews: 1000,
repos: 0, repos: 0,
stars: 600000, stars: 600000,
followers: 50000, followers: 50000,
}), }),
).toStrictEqual({ level: "S", percentile: 0.4578556547153667 }); ).toStrictEqual({ level: "S", percentile: 0.49947889605312934 });
}); });
}); });
+1 -2
View File
@@ -16,14 +16,13 @@ const USER = "catelinemnemosyne";
const STATS_DATA = { const STATS_DATA = {
name: "Cateline Mnemosyne", name: "Cateline Mnemosyne",
totalPRs: 2, totalPRs: 2,
totalReviews: 0,
totalCommits: 8, totalCommits: 8,
totalIssues: 1, totalIssues: 1,
totalStars: 1, totalStars: 1,
contributedTo: 1, contributedTo: 1,
rank: { rank: {
level: "C", level: "C",
percentile: 98.06929469995667, percentile: 97.89377603631637,
}, },
}; };
-7
View File
@@ -108,7 +108,6 @@ describe("Test fetchStats", () => {
all_commits: false, all_commits: false,
commits: 100, commits: 100,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 300, stars: 300,
@@ -142,7 +141,6 @@ describe("Test fetchStats", () => {
all_commits: false, all_commits: false,
commits: 100, commits: 100,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 300, stars: 300,
@@ -182,7 +180,6 @@ describe("Test fetchStats", () => {
all_commits: true, all_commits: true,
commits: 1000, commits: 1000,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 300, stars: 300,
@@ -213,7 +210,6 @@ describe("Test fetchStats", () => {
all_commits: true, all_commits: true,
commits: 1000, commits: 1000,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 200, stars: 200,
@@ -242,7 +238,6 @@ describe("Test fetchStats", () => {
all_commits: false, all_commits: false,
commits: 100, commits: 100,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 400, stars: 400,
@@ -271,7 +266,6 @@ describe("Test fetchStats", () => {
all_commits: false, all_commits: false,
commits: 100, commits: 100,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 300, stars: 300,
@@ -300,7 +294,6 @@ describe("Test fetchStats", () => {
all_commits: false, all_commits: false,
commits: 100, commits: 100,
prs: 300, prs: 300,
reviews: 50,
issues: 200, issues: 200,
repos: 5, repos: 5,
stars: 300, stars: 300,
-7
View File
@@ -430,13 +430,6 @@ export const themes = {
border_color: "ffffff", border_color: "ffffff",
bg_color: "000000", bg_color: "000000",
}, },
ocean_breeze: {
"title_color": "0d6efd",
"icon_color": "0d6efd",
"text_color": "333333",
"bg_color": "f0f6fc",
"border_color": "d1d5da",
}
}; };
export default themes; export default themes;