forked from mirrored/github-readme-stats
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3705f73b97 | ||
|
|
99571df33f | ||
|
|
9575f2ea95 | ||
|
|
03d7f85d77 | ||
|
|
075add2e59 | ||
|
|
d4b16d2935 | ||
|
|
5bfccb0faf |
+10
-9
@@ -48,8 +48,8 @@
|
|||||||
// "dot-notation": "warn",
|
// "dot-notation": "warn",
|
||||||
// "eqeqeq": [ "error", "smart" ],
|
// "eqeqeq": [ "error", "smart" ],
|
||||||
// "guard-for-in": "warn",
|
// "guard-for-in": "warn",
|
||||||
"no-alert": "error",
|
// "no-alert": "error",
|
||||||
"no-caller": "error",
|
// "no-caller": "error",
|
||||||
// "no-case-declarations": "warn",
|
// "no-case-declarations": "warn",
|
||||||
// "no-div-regex": "warn",
|
// "no-div-regex": "warn",
|
||||||
// "no-else-return": "warn",
|
// "no-else-return": "warn",
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
// "init-declarations": [ "error", "always" ],
|
// "init-declarations": [ "error", "always" ],
|
||||||
// "no-catch-shadow": "warn",
|
// "no-catch-shadow": "warn",
|
||||||
"no-delete-var": "error",
|
// "no-delete-var": "error",
|
||||||
// "no-label-var": "error",
|
// "no-label-var": "error",
|
||||||
// "no-shadow-restricted-names": "error",
|
// "no-shadow-restricted-names": "error",
|
||||||
// "no-shadow": "warn",
|
// "no-shadow": "warn",
|
||||||
@@ -150,12 +150,12 @@
|
|||||||
// "arrow-body-style": [ "error", "always" ],
|
// "arrow-body-style": [ "error", "always" ],
|
||||||
// "arrow-parens": [ "error", "always" ],
|
// "arrow-parens": [ "error", "always" ],
|
||||||
// "arrow-spacing": [ "error", { "before": true, "after": true }],
|
// "arrow-spacing": [ "error", { "before": true, "after": true }],
|
||||||
"constructor-super": "error",
|
// "constructor-super": "error",
|
||||||
// "generator-star-spacing": [ "error", "before" ],
|
// "generator-star-spacing": [ "error", "before" ],
|
||||||
// "no-arrow-condition": "error",
|
// "no-arrow-condition": "error",
|
||||||
"no-class-assign": "error",
|
// "no-class-assign": "error",
|
||||||
"no-const-assign": "error",
|
// "no-const-assign": "error",
|
||||||
"no-dupe-class-members": "error",
|
// "no-dupe-class-members": "error",
|
||||||
"no-this-before-super": "error",
|
"no-this-before-super": "error",
|
||||||
// "no-var": "warn",
|
// "no-var": "warn",
|
||||||
"object-shorthand": [ "warn" ],
|
"object-shorthand": [ "warn" ],
|
||||||
@@ -217,13 +217,14 @@
|
|||||||
"MethodDefinition": true,
|
"MethodDefinition": true,
|
||||||
"ClassDeclaration": false
|
"ClassDeclaration": false
|
||||||
}
|
}
|
||||||
}],
|
}]
|
||||||
// "semi-spacing": [ "warn", { "before": false, "after": true }],
|
// "semi-spacing": [ "warn", { "before": false, "after": true }],
|
||||||
// "semi": [ "error", "always" ],
|
// "semi": [ "error", "always" ],
|
||||||
// "sort-vars": "off",
|
// "sort-vars": "off",
|
||||||
"keyword-spacing": ["error", { "before": true, "after": true }]
|
// "space-after-keywords": [ "warn", "always" ],
|
||||||
// "space-before-blocks": [ "warn", "always" ],
|
// "space-before-blocks": [ "warn", "always" ],
|
||||||
// "space-before-function-paren": [ "warn", "never" ],
|
// "space-before-function-paren": [ "warn", "never" ],
|
||||||
|
// "space-before-keywords": [ "warn", "always" ],
|
||||||
// "space-in-parens": [ "warn", "never" ],
|
// "space-in-parens": [ "warn", "never" ],
|
||||||
// "space-infix-ops": [ "warn", { "int32Hint": true } ],
|
// "space-infix-ops": [ "warn", { "int32Hint": true } ],
|
||||||
// "space-return-throw-case": "error",
|
// "space-return-throw-case": "error",
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
commit-message:
|
|
||||||
prefix: "build(deps)"
|
|
||||||
prefix-development: "build(deps-dev)"
|
|
||||||
reviewers:
|
|
||||||
- "qwerty541"
|
|
||||||
|
|
||||||
# Maintain dependencies for GitHub Actions
|
# Maintain dependencies for GitHub Actions
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
@@ -18,8 +13,3 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
commit-message:
|
|
||||||
prefix: "ci(deps)"
|
|
||||||
prefix-development: "ci(deps-dev)"
|
|
||||||
reviewers:
|
|
||||||
- "qwerty541"
|
|
||||||
|
|||||||
+43
-86
@@ -1,95 +1,52 @@
|
|||||||
themes:
|
themes: themes/index.js
|
||||||
- changed-files:
|
doc-translation: docs/*
|
||||||
- any-glob-to-any-file:
|
|
||||||
- themes/index.js
|
|
||||||
|
|
||||||
doc-translation:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- docs/*
|
|
||||||
|
|
||||||
card-i18n:
|
card-i18n:
|
||||||
- changed-files:
|
- src/translations.js
|
||||||
- any-glob-to-any-file:
|
- src/common/I18n.js
|
||||||
- src/translations.js
|
|
||||||
- src/common/I18n.js
|
|
||||||
|
|
||||||
documentation:
|
documentation:
|
||||||
- changed-files:
|
- readme.md
|
||||||
- any-glob-to-any-file:
|
- CONTRIBUTING.md
|
||||||
- readme.md
|
- CODE_OF_CONDUCT.md
|
||||||
- CONTRIBUTING.md
|
- SECURITY.md
|
||||||
- CODE_OF_CONDUCT.md
|
|
||||||
- SECURITY.md
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- changed-files:
|
- package.json
|
||||||
- any-glob-to-any-file:
|
- package-lock.json
|
||||||
- package.json
|
|
||||||
- package-lock.json
|
|
||||||
|
|
||||||
lang-card:
|
lang-card:
|
||||||
- changed-files:
|
- api/top-langs.js
|
||||||
- any-glob-to-any-file:
|
- src/cards/top-languages-card.js
|
||||||
- api/top-langs.js
|
- src/fetchers/top-languages-fetcher.js
|
||||||
- src/cards/top-languages-card.js
|
- tests/fetchTopLanguages.test.js
|
||||||
- src/fetchers/top-languages-fetcher.js
|
- tests/renderTopLanguagesCard.test.js
|
||||||
- tests/fetchTopLanguages.test.js
|
- tests/top-langs.test.js
|
||||||
- tests/renderTopLanguagesCard.test.js
|
|
||||||
- tests/top-langs.test.js
|
|
||||||
|
|
||||||
repo-card:
|
repo-card:
|
||||||
- changed-files:
|
- api/pin.js
|
||||||
- any-glob-to-any-file:
|
- src/cards/repo-card.js
|
||||||
- api/pin.js
|
- src/fetchers/repo-fetcher.js
|
||||||
- src/cards/repo-card.js
|
- tests/fetchRepo.test.js
|
||||||
- src/fetchers/repo-fetcher.js
|
- tests/renderRepoCard.test.js
|
||||||
- tests/fetchRepo.test.js
|
- tests/pin.test.js
|
||||||
- tests/renderRepoCard.test.js
|
|
||||||
- tests/pin.test.js
|
|
||||||
|
|
||||||
stats-card:
|
stats-card:
|
||||||
- changed-files:
|
- api/index.js
|
||||||
- any-glob-to-any-file:
|
- src/cards/stats-card.js
|
||||||
- api/index.js
|
- src/fetchers/stats-fetcher.js
|
||||||
- src/cards/stats-card.js
|
- tests/fetchStats.test.js
|
||||||
- src/fetchers/stats-fetcher.js
|
- tests/renderStatsCard.test.js
|
||||||
- tests/fetchStats.test.js
|
- tests/api.test.js
|
||||||
- tests/renderStatsCard.test.js
|
|
||||||
- tests/api.test.js
|
|
||||||
|
|
||||||
wakatime-card:
|
wakatime-card:
|
||||||
- changed-files:
|
- api/wakatime.js
|
||||||
- any-glob-to-any-file:
|
- src/cards/wakatime-card.js
|
||||||
- api/wakatime.js
|
- src/fetchers/wakatime-fetcher.js
|
||||||
- src/cards/wakatime-card.js
|
- tests/fetchWakatime.test.js
|
||||||
- src/fetchers/wakatime-fetcher.js
|
- tests/renderWakatimeCard.test.js
|
||||||
- tests/fetchWakatime.test.js
|
|
||||||
- tests/renderWakatimeCard.test.js
|
|
||||||
- tests/wakatime.test.js
|
|
||||||
|
|
||||||
gist-card:
|
gist-card:
|
||||||
- changed-files:
|
- api/gist.js
|
||||||
- any-glob-to-any-file:
|
- src/cards/gist-card.js
|
||||||
- api/gist.js
|
- src/fetchers/gist-fetcher.js
|
||||||
- src/cards/gist-card.js
|
- tests/fetchGist.test.js
|
||||||
- src/fetchers/gist-fetcher.js
|
- tests/renderGistCard.test.js
|
||||||
- tests/fetchGist.test.js
|
- tests/gist.test.js
|
||||||
- tests/renderGistCard.test.js
|
ranks: src/calculateRank.js
|
||||||
- tests/gist.test.js
|
|
||||||
|
|
||||||
ranks:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- src/calculateRank.js
|
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
- changed-files:
|
- .github/workflows/*
|
||||||
- any-glob-to-any-file:
|
- scripts/*
|
||||||
- .github/workflows/*
|
infrastructure: .eslintrc.json
|
||||||
- scripts/*
|
|
||||||
|
|
||||||
infrastructure:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- .eslintrc.json
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
|||||||
@@ -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@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- 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@8621497c8c39c72f3e2a999a26b4ca1b5058a842 # v5.0.1
|
- uses: stefanzweifel/git-auto-commit-action@8756aa072ef5b4a080af5dc8fef36c5d586e521d # v5.0.0
|
||||||
with:
|
with:
|
||||||
branch: vercel
|
branch: vercel
|
||||||
create_branch: true
|
create_branch: true
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
+2
-2
@@ -27,10 +27,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# NOTE: Retrieve issue templates.
|
# NOTE: Retrieve issue templates.
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Run empty issues closer action
|
- name: Run empty issues closer action
|
||||||
uses: rickstaa/empty-issues-closer-action@e96914613221511279ca25f50fd4acc85e331d99 # v1.1.74
|
uses: rickstaa/empty-issues-closer-action@af151e679df0e3b59cda0e10c43010556d6c5bff # v1.1.35
|
||||||
env:
|
env:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
@@ -29,10 +29,10 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
@@ -21,7 +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@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
- uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
sync-labels: true
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ permissions: read-all
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analysis:
|
analysis:
|
||||||
if: github.repository == 'anuraghazra/github-readme-stats'
|
|
||||||
name: Scorecard analysis
|
name: Scorecard analysis
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@@ -22,12 +21,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
@@ -36,7 +35,7 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|||||||
@@ -30,15 +30,15 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
- uses: bahmutov/npm-install@e5c7e14408aa6089501de32bd16123b41738047e # v1.10.2
|
- uses: bahmutov/npm-install@2509f13e8485d88340a789a3f7ca11aaac47c9fc # v1.8.36
|
||||||
with:
|
with:
|
||||||
useLockFile: false
|
useLockFile: false
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Cleanup
|
- name: Cleanup
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+3
-3
@@ -36,15 +36,15 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
- uses: bahmutov/npm-install@e5c7e14408aa6089501de32bd16123b41738047e # v1.10.2
|
- uses: bahmutov/npm-install@2509f13e8485d88340a789a3f7ca11aaac47c9fc # v1.8.36
|
||||||
with:
|
with:
|
||||||
useLockFile: false
|
useLockFile: false
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
@@ -44,4 +44,4 @@ jobs:
|
|||||||
npm run format:check
|
npm run format:check
|
||||||
|
|
||||||
- name: Code Coverage
|
- name: Code Coverage
|
||||||
uses: codecov/codecov-action@4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0 # v3.1.5
|
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
|
||||||
|
|||||||
@@ -34,7 +34,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@7e8dda5d5ae3087670f9094b9724a9a091fc3ba1 # v1.3.101
|
uses: rickstaa/top-issues-action@36df2af30c15ddf48558931420138890ed1b1708 # v1.3.61
|
||||||
env:
|
env:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ jobs:
|
|||||||
node-version: [18.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: npm
|
cache: npm
|
||||||
@@ -53,7 +53,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@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
|
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
|
||||||
with:
|
with:
|
||||||
commit-message: "refactor: update languages JSON"
|
commit-message: "refactor: update languages JSON"
|
||||||
branch: "update_langs/patch"
|
branch: "update_langs/patch"
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm test
|
npm test
|
||||||
npm run lint
|
npm run lint
|
||||||
npx lint-staged
|
npx lint-staged
|
||||||
|
|||||||
+2
-18
@@ -27,15 +27,7 @@ export default async (req, res) => {
|
|||||||
res.setHeader("Content-Type", "image/svg+xml");
|
res.setHeader("Content-Type", "image/svg+xml");
|
||||||
|
|
||||||
if (locale && !isLocaleAvailable(locale)) {
|
if (locale && !isLocaleAvailable(locale)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong", "Language not found"));
|
||||||
renderError("Something went wrong", "Language not found", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -91,14 +83,6 @@ export default async (req, res) => {
|
|||||||
CONSTANTS.ERROR_CACHE_SECONDS
|
CONSTANTS.ERROR_CACHE_SECONDS
|
||||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
); // Use lower cache period for errors.
|
); // Use lower cache period for errors.
|
||||||
return res.send(
|
return res.send(renderError(err.message, err.secondaryMessage));
|
||||||
renderError(err.message, err.secondaryMessage, {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-27
@@ -42,27 +42,11 @@ export default async (req, res) => {
|
|||||||
res.setHeader("Content-Type", "image/svg+xml");
|
res.setHeader("Content-Type", "image/svg+xml");
|
||||||
|
|
||||||
if (blacklist.includes(username)) {
|
if (blacklist.includes(username)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locale && !isLocaleAvailable(locale)) {
|
if (locale && !isLocaleAvailable(locale)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong", "Language not found"));
|
||||||
renderError("Something went wrong", "Language not found", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -127,14 +111,6 @@ export default async (req, res) => {
|
|||||||
CONSTANTS.ERROR_CACHE_SECONDS
|
CONSTANTS.ERROR_CACHE_SECONDS
|
||||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
); // Use lower cache period for errors.
|
); // Use lower cache period for errors.
|
||||||
return res.send(
|
return res.send(renderError(err.message, err.secondaryMessage));
|
||||||
renderError(err.message, err.secondaryMessage, {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-29
@@ -3,6 +3,7 @@ import { blacklist } from "../src/common/blacklist.js";
|
|||||||
import {
|
import {
|
||||||
clampValue,
|
clampValue,
|
||||||
CONSTANTS,
|
CONSTANTS,
|
||||||
|
getBase64URIFromImage,
|
||||||
parseBoolean,
|
parseBoolean,
|
||||||
renderError,
|
renderError,
|
||||||
} from "../src/common/utils.js";
|
} from "../src/common/utils.js";
|
||||||
@@ -24,33 +25,17 @@ export default async (req, res) => {
|
|||||||
locale,
|
locale,
|
||||||
border_radius,
|
border_radius,
|
||||||
border_color,
|
border_color,
|
||||||
description_lines_count,
|
show_image,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
res.setHeader("Content-Type", "image/svg+xml");
|
res.setHeader("Content-Type", "image/svg+xml");
|
||||||
|
|
||||||
if (blacklist.includes(username)) {
|
if (blacklist.includes(username)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locale && !isLocaleAvailable(locale)) {
|
if (locale && !isLocaleAvailable(locale)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong", "Language not found"));
|
||||||
renderError("Something went wrong", "Language not found", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -85,6 +70,10 @@ export default async (req, res) => {
|
|||||||
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
repoData.stringifiedRepoImage = await getBase64URIFromImage(
|
||||||
|
repoData.openGraphImageUrl,
|
||||||
|
);
|
||||||
|
|
||||||
return res.send(
|
return res.send(
|
||||||
renderRepoCard(repoData, {
|
renderRepoCard(repoData, {
|
||||||
hide_border: parseBoolean(hide_border),
|
hide_border: parseBoolean(hide_border),
|
||||||
@@ -97,7 +86,7 @@ export default async (req, res) => {
|
|||||||
border_color,
|
border_color,
|
||||||
show_owner: parseBoolean(show_owner),
|
show_owner: parseBoolean(show_owner),
|
||||||
locale: locale ? locale.toLowerCase() : null,
|
locale: locale ? locale.toLowerCase() : null,
|
||||||
description_lines_count,
|
show_image: parseBoolean(show_image),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -107,14 +96,6 @@ export default async (req, res) => {
|
|||||||
CONSTANTS.ERROR_CACHE_SECONDS
|
CONSTANTS.ERROR_CACHE_SECONDS
|
||||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
); // Use lower cache period for errors.
|
); // Use lower cache period for errors.
|
||||||
return res.send(
|
return res.send(renderError(err.message, err.secondaryMessage));
|
||||||
renderError(err.message, err.secondaryMessage, {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-18
@@ -37,15 +37,7 @@ export default async (req, res) => {
|
|||||||
res.setHeader("Content-Type", "image/svg+xml");
|
res.setHeader("Content-Type", "image/svg+xml");
|
||||||
|
|
||||||
if (blacklist.includes(username)) {
|
if (blacklist.includes(username)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locale && !isLocaleAvailable(locale)) {
|
if (locale && !isLocaleAvailable(locale)) {
|
||||||
@@ -113,14 +105,6 @@ export default async (req, res) => {
|
|||||||
CONSTANTS.ERROR_CACHE_SECONDS
|
CONSTANTS.ERROR_CACHE_SECONDS
|
||||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
); // Use lower cache period for errors.
|
); // Use lower cache period for errors.
|
||||||
return res.send(
|
return res.send(renderError(err.message, err.secondaryMessage));
|
||||||
renderError(err.message, err.secondaryMessage, {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-22
@@ -30,22 +30,12 @@ export default async (req, res) => {
|
|||||||
api_domain,
|
api_domain,
|
||||||
border_radius,
|
border_radius,
|
||||||
border_color,
|
border_color,
|
||||||
display_format,
|
|
||||||
disable_animations,
|
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
res.setHeader("Content-Type", "image/svg+xml");
|
res.setHeader("Content-Type", "image/svg+xml");
|
||||||
|
|
||||||
if (locale && !isLocaleAvailable(locale)) {
|
if (locale && !isLocaleAvailable(locale)) {
|
||||||
return res.send(
|
return res.send(renderError("Something went wrong", "Language not found"));
|
||||||
renderError("Something went wrong", "Language not found", {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -85,8 +75,6 @@ export default async (req, res) => {
|
|||||||
locale: locale ? locale.toLowerCase() : null,
|
locale: locale ? locale.toLowerCase() : null,
|
||||||
layout,
|
layout,
|
||||||
langs_count,
|
langs_count,
|
||||||
display_format,
|
|
||||||
disable_animations: parseBoolean(disable_animations),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -96,14 +84,6 @@ export default async (req, res) => {
|
|||||||
CONSTANTS.ERROR_CACHE_SECONDS
|
CONSTANTS.ERROR_CACHE_SECONDS
|
||||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||||
); // Use lower cache period for errors.
|
); // Use lower cache period for errors.
|
||||||
return res.send(
|
return res.send(renderError(err.message, err.secondaryMessage));
|
||||||
renderError(err.message, err.secondaryMessage, {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -1,11 +1,12 @@
|
|||||||
import "dotenv/config";
|
|
||||||
import statsCard from "./api/index.js";
|
import statsCard from "./api/index.js";
|
||||||
import repoCard from "./api/pin.js";
|
import repoCard from "./api/pin.js";
|
||||||
import langCard from "./api/top-langs.js";
|
import langCard from "./api/top-langs.js";
|
||||||
import wakatimeCard from "./api/wakatime.js";
|
import wakatimeCard from "./api/wakatime.js";
|
||||||
import gistCard from "./api/gist.js";
|
import gistCard from "./api/gist.js";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
|
import dotenv from "dotenv";
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
const app = express();
|
const app = express();
|
||||||
app.listen(process.env.port || 9000);
|
app.listen(process.env.port || 9000);
|
||||||
|
|
||||||
|
|||||||
Generated
+1323
-415
File diff suppressed because it is too large
Load Diff
+11
-11
@@ -29,7 +29,7 @@
|
|||||||
"generate-langs-json": "node scripts/generate-langs-json",
|
"generate-langs-json": "node scripts/generate-langs-json",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"format:check": "prettier --check .",
|
"format:check": "prettier --check .",
|
||||||
"prepare": "husky",
|
"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\"",
|
||||||
"bench": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.bench.config.js"
|
"bench": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.bench.config.js"
|
||||||
},
|
},
|
||||||
@@ -38,27 +38,27 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
"@testing-library/dom": "^10.1.0",
|
"@testing-library/dom": "^9.3.3",
|
||||||
"@testing-library/jest-dom": "^6.4.5",
|
"@testing-library/jest-dom": "^6.1.4",
|
||||||
"@uppercod/css-to-object": "^1.1.1",
|
"@uppercod/css-to-object": "^1.1.1",
|
||||||
"axios-mock-adapter": "^1.22.0",
|
"axios-mock-adapter": "^1.22.0",
|
||||||
"color-contrast-checker": "^2.1.0",
|
"color-contrast-checker": "^2.1.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.52.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"hjson": "^3.2.2",
|
"hjson": "^3.2.2",
|
||||||
"husky": "^9.0.11",
|
"husky": "^8.0.3",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-bench": "^29.7.1",
|
"jest-bench": "^29.4.1",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"lint-staged": "^15.2.2",
|
"lint-staged": "^15.0.2",
|
||||||
"lodash.snakecase": "^4.1.1",
|
"lodash.snakecase": "^4.1.1",
|
||||||
"parse-diff": "^0.11.1",
|
"parse-diff": "^0.11.1",
|
||||||
"prettier": "^3.2.5"
|
"prettier": "^3.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.1",
|
"axios": "^1.5.1",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.3.1",
|
||||||
"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",
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">Please note that documentation translations may be outdated; try to use English documentation if possible.</p>
|
<p align="center">Please note that documentation translations may be outdated, try to use english documentation if possible.</p>
|
||||||
|
|
||||||
<p align="center">Love the project? Please consider <a href="https://www.paypal.me/anuraghazra">donating</a> to help it improve!</p>
|
<p align="center">Love the project? Please consider <a href="https://www.paypal.me/anuraghazra">donating</a> to help it improve!</p>
|
||||||
|
|
||||||
@@ -73,11 +73,11 @@
|
|||||||
<img src="https://cfstatic.give.do/logo.png" alt="Give india logo" width="200" />
|
<img src="https://cfstatic.give.do/logo.png" alt="Give india logo" width="200" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
Are you considering supporting the project by donating to me? Please DO NOT!!!
|
Are you considering supporting the project by donating to me? Please DO NOT!!
|
||||||
|
|
||||||
<img src="https://cfstatic.give.do/910ede2a-7892-43fe-8c8a-dea45e96d950.webp" alt="Picture of Coromandel Express train tragedy" width="35%">
|
<img src="https://cfstatic.give.do/910ede2a-7892-43fe-8c8a-dea45e96d950.webp" alt="Picture of Coromandel Express train tragedy" width="35%">
|
||||||
|
|
||||||
India has recently suffered one of the most devastating train accidents, and your help will be immensely valuable for the people who were affected by this tragedy.
|
India just suffered one of the most devastating train accident and your help will be immensely valuable for the people who were affected by this tragedy.
|
||||||
|
|
||||||
Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of-the-coromandel-express-train-tragedy-in-odisha-donate-now) and make a small donation to help the people in need. A small donation goes a long way. :heart:
|
Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of-the-coromandel-express-train-tragedy-in-odisha-donate-now) and make a small donation to help the people in need. A small donation goes a long way. :heart:
|
||||||
|
|
||||||
@@ -129,11 +129,11 @@ Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of
|
|||||||
<img alt="Uptime Badge" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fgithub-readme-stats-git-monitoring-github-readme-stats-team.vercel.app%2Fapi%2Fstatus%2Fup%3Ftype%3Dshields">
|
<img alt="Uptime Badge" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fgithub-readme-stats-git-monitoring-github-readme-stats-team.vercel.app%2Fapi%2Fstatus%2Fup%3Ftype%3Dshields">
|
||||||
|
|
||||||
> [!IMPORTANT]\
|
> [!IMPORTANT]\
|
||||||
> We're a small team, and to prioritize, we rely on upvotes :+1:. We use the Top Issues dashboard for tracking community demand (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935)). Do not hesitate to upvote the issues and pull requests you are interested in. We will work on the most upvoted first.
|
> We're a small team, and to prioritize, we rely on upvotes :+1:. We use Top issues dashboard for tracking community demand (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935)). Do not hesitate to upvote the issues and pull requests you are interested in. We will work on the most upvoted first.
|
||||||
|
|
||||||
# GitHub Stats Card
|
# GitHub Stats Card
|
||||||
|
|
||||||
Copy and paste this into your markdown, 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.
|
Change the `?username=` value to your GitHub username.
|
||||||
|
|
||||||
@@ -142,10 +142,10 @@ Change the `?username=` value to your GitHub username.
|
|||||||
```
|
```
|
||||||
|
|
||||||
> [!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](https://github.com/anuraghazra/github-readme-stats/blob/master/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, 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](https://github.com/anuraghazra/github-readme-stats/blob/master/src/calculateRank.js). The circle around the rank shows 100 minus the global percentile.
|
||||||
|
|
||||||
### Hiding individual stats
|
### Hiding individual stats
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ GitHub Readme Stats comes with several built-in themes (e.g. `dark`, `radical`,
|
|||||||
|
|
||||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stats Themes" width="600px"/>
|
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stats Themes" width="600px"/>
|
||||||
|
|
||||||
You can look at a preview for [all available themes](themes/README.md) or checkout the [theme config file](themes/index.js). Please note that we paused the addition of new themes to decrease maintenance efforts; all pull requests related to new themes will be closed.
|
You can look at a preview for [all available themes](themes/README.md) or checkout the [theme config file](themes/index.js). Please note that we paused addition of new themes to decrease maintenance efforts, all pull requests related to new themes will be closed.
|
||||||
|
|
||||||
#### Responsive Card Theme
|
#### Responsive Card Theme
|
||||||
|
|
||||||
@@ -288,18 +288,16 @@ You can customize the appearance of all your cards however you wish with URL par
|
|||||||
|
|
||||||
#### Common Options
|
#### Common Options
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `title_color` - Card's title color *(hex color)*. Default: `2f80ed`.
|
||||||
| --- | --- | --- | --- |
|
* `text_color` - Body text color *(hex color)*. Default: `434d58`.
|
||||||
| `title_color` | Card's title color. | string (hex color) | `2f80ed` |
|
* `icon_color` - Icons color if available *(hex color)*. Default: `4c71f2`.
|
||||||
| `text_color` | Body text color. | string (hex color) | `434d58` |
|
* `border_color` - Card's border color *(hex color)*. Default: `e4e2e2` (Does not apply when `hide_border` is enabled).
|
||||||
| `icon_color` | Icons color if available. | string (hex color) | `4c71f2` |
|
* `bg_color` - Card's background color *(hex color)* **or** a gradient in the form of *angle,start,end*. Default: `fffefe`
|
||||||
| `border_color` | Card's border color. Does not apply when `hide_border` is enabled. | string (hex color) | `e4e2e2` |
|
* `hide_border` - Hides the card's border *(boolean)*. Default: `false`
|
||||||
| `bg_color` | Card's background color. | string (hex color or a gradient in the form of *angle,start,end*) | `fffefe` |
|
* `theme` - Name of the theme, choose from [all available themes](themes/README.md). Default: `default` theme.
|
||||||
| `hide_border` | Hides the card's border. | boolean | `false` |
|
* `cache_seconds` - Sets the cache header manually *(min: 21600, max: 86400)*. Default: `21600 seconds (6 hours)`.
|
||||||
| `theme` | Name of the theme, choose from [all available themes](themes/README.md). | enum | `default` |
|
* `locale` - Sets the language in the card, you can check full list of available locales [here](#available-locales). Default: `en`.
|
||||||
| `cache_seconds` | Sets the cache header manually (min: 21600, max: 86400). | integer | `21600` |
|
* `border_radius` - Corner rounding on the card. Default: `4.5`.
|
||||||
| `locale` | Sets the language in the card, you can check full list of available locales [here](#available-locales). | enum | `en` |
|
|
||||||
| `border_radius` | Corner rounding on the card. | number | `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 6 hours (21600 seconds). Also, note that the cache is clamped to a minimum of 6 hours and a maximum of 24 hours. If you want the data on your statistics card to be updated more often you can [deploy your own instance](#deploy-on-your-own) and set [environment variable](#disable-rate-limit-protections) `CACHE_SECONDS` to a value of your choosing.
|
> 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 6 hours (21600 seconds). Also, note that the cache is clamped to a minimum of 6 hours and a maximum of 24 hours. If you want the data on your statistics card to be updated more often you can [deploy your own instance](#deploy-on-your-own) and set [environment variable](#disable-rate-limit-protections) `CACHE_SECONDS` to a value of your choosing.
|
||||||
@@ -366,55 +364,47 @@ If we don't support your language, please consider contributing! You can find mo
|
|||||||
|
|
||||||
#### Stats Card Exclusive Options
|
#### Stats Card Exclusive Options
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `hide` - Hides the [specified items](#hiding-individual-stats) from stats *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| --- | --- | --- | --- |
|
* `hide_title` - *(boolean)*. Default: `false`.
|
||||||
| `hide` | Hides the [specified items](#hiding-individual-stats) from stats. | string (comma-separated values) | `null` |
|
* `card_width` - Sets the card's width manually *(number)*. Default: `500px (approx.)`.
|
||||||
| `hide_title` | Hides the title of your stats card. | boolean | `false` |
|
* `hide_rank` - *(boolean)* hides the rank and automatically resizes the card width. Default: `false`.
|
||||||
| `card_width` | Sets the card's width manually. | number | `500px (approx.)` |
|
* `rank_icon` - Shows alternative rank icon (i.e. `github`, `percentile` or `default`). Default: `default`.
|
||||||
| `hide_rank` | Hides the rank and automatically resizes the card width. | boolean | `false` |
|
* `show_icons` - *(boolean)*. Default: `false`.
|
||||||
| `rank_icon` | Shows alternative rank icon (i.e. `github`, `percentile` or `default`). | enum | `default` |
|
* `include_all_commits` - Counts total commits instead of just the current year commits *(boolean)*. Default: `false`.
|
||||||
| `show_icons` | Shows icons near all stats. | boolean | `false` |
|
* `line_height` - Sets the line height between text *(number)*. Default: `25`.
|
||||||
| `include_all_commits` | Count total commits instead of just the current year commits. | boolean | `false` |
|
* `exclude_repo` - Excludes stars from specified repositories *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| `line_height` | Sets the line height between text. | integer | `25` |
|
* `custom_title` - Sets a custom title for the card. Default: `<username> GitHub Stats`.
|
||||||
| `exclude_repo` | Excludes specified repositories. | string (comma-separated values) | `null` |
|
* `text_bold` - Uses bold text *(boolean)*. Default: `true`.
|
||||||
| `custom_title` | Sets a custom title for the card. | string | `<username> GitHub Stats` |
|
* `disable_animations` - Disables all animations in the card *(boolean)*. Default: `false`.
|
||||||
| `text_bold` | Uses bold text. | boolean | `true` |
|
* `ring_color` - Color of the rank circle *(hex color)*. Defaults to the theme ring color if it exists and otherwise the title color.
|
||||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
* `number_format` - Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). Default: `short`.
|
||||||
| `ring_color` | Color of the rank circle. | string (hex color) | `2f80ed` |
|
* `show` - Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`) *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| `number_format` | Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). | enum | `short` |
|
|
||||||
| `show` | Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`). | string (comma-separated values) | `null` |
|
|
||||||
|
|
||||||
> [!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
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `show_owner` - Shows the repo's owner name *(boolean)*. Default: `false`.
|
||||||
| --- | --- | --- | --- |
|
* `show_image` - Shows the repo's social preview image *(boolean)*. Default: `false`.
|
||||||
| `show_owner` | Shows the repo's owner name. | boolean | `false` |
|
|
||||||
| `description_lines_count` | Manually set the number of lines for the description. Specified value will be clamped between 1 and 3. If this parameter is not specified, the number of lines will be automatically adjusted according to the actual length of the description. | number | `null` |
|
|
||||||
|
|
||||||
#### Gist Card Exclusive Options
|
#### Gist Card Exclusive Options
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `show_owner` - Shows the gist's owner name *(boolean)*. Default: `false`.
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| `show_owner` | Shows the gist's owner name. | boolean | `false` |
|
|
||||||
|
|
||||||
#### Language Card Exclusive Options
|
#### Language Card Exclusive Options
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `hide` - Hides the languages specified from the card *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| --- | --- | --- | --- |
|
* `hide_title` - *(boolean)*. Default: `false`.
|
||||||
| `hide` | Hides the [specified languages](#hide-individual-languages) from card. | string (comma-separated values) | `null` |
|
* `layout` - Switches between five available layouts `normal` & `compact` & `donut` & `donut-vertical` & `pie`. Default: `normal`.
|
||||||
| `hide_title` | Hides the title of your card. | boolean | `false` |
|
* `card_width` - Sets the card's width manually *(number)*. Default `300`.
|
||||||
| `layout` | Switches between five available layouts `normal` & `compact` & `donut` & `donut-vertical` & `pie`. | enum | `normal` |
|
* `langs_count` - Shows more languages on the card, between 1-20 *(number)*. Default: `5` for `normal` and `donut`, `6` for other layouts.
|
||||||
| `card_width` | Sets the card's width manually. | number | `300` |
|
* `exclude_repo` - Excludes specified repositories *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| `langs_count` | Shows more languages on the card, between 1-20. | integer | `5` for `normal` and `donut`, `6` for other layouts |
|
* `custom_title` - Sets a custom title for the card *(string)*. Default `Most Used Languages`.
|
||||||
| `exclude_repo` | Excludes specified repositories. | string (comma-separated values) | `null` |
|
* `disable_animations` - Disables all animations in the card *(boolean)*. Default: `false`.
|
||||||
| `custom_title` | Sets a custom title for the card. | string | `Most Used Languages` |
|
* `hide_progress` - Uses the compact layout option, hides percentages, and removes the bars. Default: `false`.
|
||||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
* `size_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 1.
|
||||||
| `hide_progress` | Uses the compact layout option, hides percentages, and removes the bars. | boolean | `false` |
|
* `count_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 0.
|
||||||
| `size_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `1` |
|
|
||||||
| `count_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `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)
|
||||||
@@ -423,18 +413,14 @@ If we don't support your language, please consider contributing! You can find mo
|
|||||||
|
|
||||||
#### WakaTime Card Exclusive Options
|
#### WakaTime Card Exclusive Options
|
||||||
|
|
||||||
| Name | Description | Type | Default value |
|
* `hide` - Hides the languages specified from the card *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||||
| --- | --- | --- | --- |
|
* `hide_title` - *(boolean)*. Default `false`.
|
||||||
| `hide` | Hides the languages specified from the card. | string (comma-separated values) | `null` |
|
* `line_height` - Sets the line height between text *(number)*. Default `25`.
|
||||||
| `hide_title` | Hides the title of your card. | boolean | `false` |
|
* `hide_progress` - Hides the progress bar and percentage *(boolean)*. Default `false`.
|
||||||
| `line_height` | Sets the line height between text. | integer | `25` |
|
* `custom_title` - Sets a custom title for the card *(string)*. Default `WakaTime Stats`.
|
||||||
| `hide_progress` | Hides the progress bar and percentage. | boolean | `false` |
|
* `layout` - Switches between two available layouts `default` & `compact`. Default `default`.
|
||||||
| `custom_title` | Sets a custom title for the card. | string | `WakaTime Stats` |
|
* `langs_count` - Limits the number of languages on the card, defaults to all reported languages *(number)*.
|
||||||
| `layout` | Switches between two available layouts `default` & `compact`. | enum | `default` |
|
* `api_domain` - Sets 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`.
|
||||||
| `langs_count` | Limits the number of languages on the card, defaults to all reported languages. | integer | `null` |
|
|
||||||
| `api_domain` | Sets 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 | `wakatime.com` |
|
|
||||||
| `display_format` | Sets the WakaTime stats display format. Choose `time` to display time-based stats or `percent` to show percentages. | enum | `time` |
|
|
||||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -462,6 +448,11 @@ Use [show\_owner](#repo-card-exclusive-options) query option to include the repo
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
Use [show\_image](#repo-card-exclusive-options) query option to include the repo's social preview image header
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# GitHub Gist Pins
|
# GitHub Gist Pins
|
||||||
|
|
||||||
GitHub gist pins allow you to pin gists in your GitHub profile using a GitHub readme profile.
|
GitHub gist pins allow you to pin gists in your GitHub profile using a GitHub readme profile.
|
||||||
@@ -495,10 +486,10 @@ The top languages card shows a GitHub user's most frequently used languages.
|
|||||||
> 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 language usage only inside your own non-forked repositories, not depending on who the author of the commits is. 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.
|
||||||
|
|
||||||
> [!WARNING]\
|
> [!WARNING]\
|
||||||
> Currently this card shows data only about first 100 repositories. This is because GitHub API limitations which cause downtimes of public instances (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). In future this behavior will be improved by releasing GitHub action or providing environment variables for user's own instances.
|
> Currently this card shows data only about first 100 repositories. This is because GitHub API limitations which cause downtimes of public instance (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). In future this behavior will be improved by releasing GitHub action or providing environment variable for user's own instances.
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
@@ -815,7 +806,7 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
|
|||||||
|
|
||||||
Github Readme Stats contains several Vercel environment variables that can be used to remove the rate limit protections:
|
Github Readme Stats contains several Vercel environment variables that can be used to remove the rate limit protections:
|
||||||
|
|
||||||
* `CACHE_SECONDS`: This environment variable takes precedence over our cache minimum and maximum values and can circumvent these values for self-hosted Vercel instances.
|
* `CACHE_SECONDS`: This environment variable takes precedence over our cache minimum and maximum values and can circumvent these values for self Hosted Vercel instances.
|
||||||
|
|
||||||
See [the Vercel documentation](https://vercel.com/docs/concepts/projects/environment-variables) on adding these environment variables to your Vercel instance.
|
See [the Vercel documentation](https://vercel.com/docs/concepts/projects/environment-variables) on adding these environment variables to your Vercel instance.
|
||||||
|
|
||||||
@@ -830,9 +821,9 @@ 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
|
* Giving proper credit when you use github-readme-stats on your readme, linking back to it :D
|
||||||
* Starring and sharing the project. :rocket:
|
* Starring and sharing the project :rocket:
|
||||||
* [](https://www.paypal.me/anuraghazra) - You can make a one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea:
|
* [](https://www.paypal.me/anuraghazra) - You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea:
|
||||||
|
|
||||||
Thanks! :heart:
|
Thanks! :heart:
|
||||||
|
|
||||||
|
|||||||
+9
-21
@@ -12,13 +12,10 @@ import {
|
|||||||
wrapTextMultiline,
|
wrapTextMultiline,
|
||||||
iconWithLabel,
|
iconWithLabel,
|
||||||
createLanguageNode,
|
createLanguageNode,
|
||||||
clampValue,
|
|
||||||
} from "../common/utils.js";
|
} from "../common/utils.js";
|
||||||
import { repoCardLocales } from "../translations.js";
|
import { repoCardLocales } from "../translations.js";
|
||||||
|
|
||||||
const ICON_SIZE = 16;
|
const ICON_SIZE = 16;
|
||||||
const DESCRIPTION_LINE_WIDTH = 59;
|
|
||||||
const DESCRIPTION_MAX_LINES = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repository description and wraps it to fit the card width.
|
* Retrieves the repository description and wraps it to fit the card width.
|
||||||
@@ -64,6 +61,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
isTemplate,
|
isTemplate,
|
||||||
starCount,
|
starCount,
|
||||||
forkCount,
|
forkCount,
|
||||||
|
stringifiedRepoImage,
|
||||||
} = repo;
|
} = repo;
|
||||||
const {
|
const {
|
||||||
hide_border = false,
|
hide_border = false,
|
||||||
@@ -76,34 +74,23 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
border_radius,
|
border_radius,
|
||||||
border_color,
|
border_color,
|
||||||
locale,
|
locale,
|
||||||
description_lines_count,
|
show_image = false,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const lineHeight = 10;
|
const lineHeight = 10;
|
||||||
const header = show_owner ? nameWithOwner : name;
|
const header = show_owner ? nameWithOwner : name;
|
||||||
const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified";
|
const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified";
|
||||||
const langColor = (primaryLanguage && primaryLanguage.color) || "#333";
|
const langColor = (primaryLanguage && primaryLanguage.color) || "#333";
|
||||||
const descriptionMaxLines = description_lines_count
|
|
||||||
? clampValue(description_lines_count, 1, DESCRIPTION_MAX_LINES)
|
|
||||||
: DESCRIPTION_MAX_LINES;
|
|
||||||
|
|
||||||
const desc = parseEmojis(description || "No description provided");
|
const desc = parseEmojis(description || "No description provided");
|
||||||
const multiLineDescription = wrapTextMultiline(
|
const multiLineDescription = wrapTextMultiline(desc);
|
||||||
desc,
|
const descriptionLines = multiLineDescription.length;
|
||||||
DESCRIPTION_LINE_WIDTH,
|
|
||||||
descriptionMaxLines,
|
|
||||||
);
|
|
||||||
const descriptionLinesCount = description_lines_count
|
|
||||||
? clampValue(description_lines_count, 1, DESCRIPTION_MAX_LINES)
|
|
||||||
: multiLineDescription.length;
|
|
||||||
|
|
||||||
const descriptionSvg = multiLineDescription
|
const descriptionSvg = multiLineDescription
|
||||||
.map((line) => `<tspan dy="1.2em" x="25">${encodeHTML(line)}</tspan>`)
|
.map((line) => `<tspan dy="1.2em" x="25">${encodeHTML(line)}</tspan>`)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
const height =
|
const height =
|
||||||
(descriptionLinesCount > 1 ? 120 : 110) +
|
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||||
descriptionLinesCount * lineHeight;
|
|
||||||
|
|
||||||
const i18n = new I18n({
|
const i18n = new I18n({
|
||||||
locale,
|
locale,
|
||||||
@@ -156,6 +143,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
height,
|
height,
|
||||||
border_radius,
|
border_radius,
|
||||||
colors,
|
colors,
|
||||||
|
stringifiedRepoImage: show_image ? stringifiedRepoImage : "",
|
||||||
});
|
});
|
||||||
|
|
||||||
card.disableAnimations();
|
card.disableAnimations();
|
||||||
@@ -175,9 +163,9 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
? // @ts-ignore
|
? // @ts-ignore
|
||||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||||
: isArchived
|
: isArchived
|
||||||
? // @ts-ignore
|
? // @ts-ignore
|
||||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
<text class="description" x="25" y="-5">
|
<text class="description" x="25" y="-5">
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ const createTextNode = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates progress along the boundary of the circle, i.e. its circumference.
|
* Calculates progress along the boundary of the circle i.e it's circumference.
|
||||||
*
|
*
|
||||||
* @param {number} value The rank value to calculate progress for.
|
* @param {number} value The rank value to calculate progress for.
|
||||||
* @returns {number} Progress value.
|
* @returns {number} Progress value.
|
||||||
@@ -412,8 +412,8 @@ const renderStatsCard = (stats, options = {}) => {
|
|||||||
custom_title
|
custom_title
|
||||||
? custom_title
|
? custom_title
|
||||||
: statItems.length
|
: statItems.length
|
||||||
? i18n.t("statcard.title")
|
? i18n.t("statcard.title")
|
||||||
: i18n.t("statcard.ranktitle"),
|
: i18n.t("statcard.ranktitle"),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -431,14 +431,14 @@ const renderStatsCard = (stats, options = {}) => {
|
|||||||
Infinity,
|
Infinity,
|
||||||
)
|
)
|
||||||
: statItems.length
|
: statItems.length
|
||||||
? RANK_CARD_MIN_WIDTH
|
? RANK_CARD_MIN_WIDTH
|
||||||
: RANK_ONLY_CARD_MIN_WIDTH) + iconWidth;
|
: RANK_ONLY_CARD_MIN_WIDTH) + iconWidth;
|
||||||
const defaultCardWidth =
|
const defaultCardWidth =
|
||||||
(hide_rank
|
(hide_rank
|
||||||
? CARD_DEFAULT_WIDTH
|
? CARD_DEFAULT_WIDTH
|
||||||
: 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 = card_width
|
||||||
? isNaN(card_width)
|
? isNaN(card_width)
|
||||||
? defaultCardWidth
|
? defaultCardWidth
|
||||||
@@ -518,7 +518,7 @@ const renderStatsCard = (stats, options = {}) => {
|
|||||||
if (key === "commits") {
|
if (key === "commits") {
|
||||||
return `${i18n.t("statcard.commits")} ${
|
return `${i18n.t("statcard.commits")} ${
|
||||||
include_all_commits ? "" : `in ${new Date().getFullYear()}`
|
include_all_commits ? "" : `in ${new Date().getFullYear()}`
|
||||||
} : ${STATS[key].value}`;
|
} : ${totalStars}`;
|
||||||
}
|
}
|
||||||
return `${STATS[key].label}: ${STATS[key].value}`;
|
return `${STATS[key].label}: ${STATS[key].value}`;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -755,8 +755,8 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
|||||||
? 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;
|
: DEFAULT_CARD_WIDTH;
|
||||||
let height = calculateNormalLayoutHeight(langs.length);
|
let height = calculateNormalLayoutHeight(langs.length);
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-4
@@ -32,7 +32,7 @@ export type StatCardOptions = CommonOptions & {
|
|||||||
|
|
||||||
export type RepoCardOptions = CommonOptions & {
|
export type RepoCardOptions = CommonOptions & {
|
||||||
show_owner: boolean;
|
show_owner: boolean;
|
||||||
description_lines_count: number;
|
show_image: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TopLangOptions = CommonOptions & {
|
export type TopLangOptions = CommonOptions & {
|
||||||
@@ -46,7 +46,7 @@ export type TopLangOptions = CommonOptions & {
|
|||||||
hide_progress: boolean;
|
hide_progress: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WakaTimeOptions = CommonOptions & {
|
type WakaTimeOptions = CommonOptions & {
|
||||||
hide_title: boolean;
|
hide_title: boolean;
|
||||||
hide: string[];
|
hide: string[];
|
||||||
line_height: string;
|
line_height: string;
|
||||||
@@ -54,8 +54,6 @@ export type WakaTimeOptions = CommonOptions & {
|
|||||||
custom_title: string;
|
custom_title: string;
|
||||||
layout: "compact" | "normal";
|
layout: "compact" | "normal";
|
||||||
langs_count: number;
|
langs_count: number;
|
||||||
display_format: "time" | "percent";
|
|
||||||
disable_animations: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GistCardOptions = CommonOptions & {
|
export type GistCardOptions = CommonOptions & {
|
||||||
|
|||||||
@@ -39,20 +39,6 @@ const noCodingActivityNode = ({ color, text }) => {
|
|||||||
* @typedef {import('../fetchers/types').WakaTimeLang} WakaTimeLang
|
* @typedef {import('../fetchers/types').WakaTimeLang} WakaTimeLang
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Format language value.
|
|
||||||
*
|
|
||||||
* @param {Object} args The function arguments.
|
|
||||||
* @param {WakaTimeLang} args.lang The language object.
|
|
||||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
|
||||||
* @returns {string} The formatted language value.
|
|
||||||
*/
|
|
||||||
const formatLanguageValue = ({ display_format, lang }) => {
|
|
||||||
return display_format === "percent"
|
|
||||||
? `${lang.percent.toFixed(2).toString()} %`
|
|
||||||
: lang.text;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create compact WakaTime layout.
|
* Create compact WakaTime layout.
|
||||||
*
|
*
|
||||||
@@ -60,18 +46,16 @@ const formatLanguageValue = ({ display_format, lang }) => {
|
|||||||
* @param {WakaTimeLang} args.lang The languages array.
|
* @param {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.
|
||||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
|
||||||
* @returns {string} The compact layout language SVG node.
|
* @returns {string} The compact layout language SVG node.
|
||||||
*/
|
*/
|
||||||
const createCompactLangNode = ({ lang, x, y, display_format }) => {
|
const createCompactLangNode = ({ lang, x, y }) => {
|
||||||
const color = languageColors[lang.name] || "#858585";
|
const color = languageColors[lang.name] || "#858585";
|
||||||
const value = formatLanguageValue({ display_format, lang });
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<g transform="translate(${x}, ${y})">
|
<g transform="translate(${x}, ${y})">
|
||||||
<circle cx="5" cy="6" r="5" fill="${color}" />
|
<circle cx="5" cy="6" r="5" fill="${color}" />
|
||||||
<text data-testid="lang-name" x="15" y="10" class='lang-name'>
|
<text data-testid="lang-name" x="15" y="10" class='lang-name'>
|
||||||
${lang.name} - ${value}
|
${lang.name} - ${lang.text}
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
`;
|
`;
|
||||||
@@ -83,24 +67,21 @@ const createCompactLangNode = ({ lang, x, y, display_format }) => {
|
|||||||
* @param {Object} args The function arguments.
|
* @param {Object} args The function arguments.
|
||||||
* @param {WakaTimeLang[]} args.langs The language objects.
|
* @param {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.
|
||||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
|
||||||
* @returns {string[]} The language text node items.
|
* @returns {string[]} The language text node items.
|
||||||
*/
|
*/
|
||||||
const createLanguageTextNode = ({ langs, y, display_format }) => {
|
const createLanguageTextNode = ({ langs, y }) => {
|
||||||
return langs.map((lang, index) => {
|
return langs.map((lang, index) => {
|
||||||
if (index % 2 === 0) {
|
if (index % 2 === 0) {
|
||||||
return createCompactLangNode({
|
return createCompactLangNode({
|
||||||
lang,
|
lang,
|
||||||
x: 25,
|
x: 25,
|
||||||
y: 12.5 * index + y,
|
y: 12.5 * index + y,
|
||||||
display_format,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return createCompactLangNode({
|
return createCompactLangNode({
|
||||||
lang,
|
lang,
|
||||||
x: 230,
|
x: 230,
|
||||||
y: 12.5 + 12.5 * index,
|
y: 12.5 + 12.5 * index,
|
||||||
display_format,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -237,8 +218,6 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
langs_count = languages.length,
|
langs_count = languages.length,
|
||||||
border_radius,
|
border_radius,
|
||||||
border_color,
|
border_color,
|
||||||
display_format = "time",
|
|
||||||
disable_animations,
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const shouldHideLangs = Array.isArray(hide) && hide.length > 0;
|
const shouldHideLangs = Array.isArray(hide) && hide.length > 0;
|
||||||
@@ -332,7 +311,6 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
? createLanguageTextNode({
|
? createLanguageTextNode({
|
||||||
y: 25,
|
y: 25,
|
||||||
langs: filteredLanguages,
|
langs: filteredLanguages,
|
||||||
display_format,
|
|
||||||
}).join("")
|
}).join("")
|
||||||
: noCodingActivityNode({
|
: noCodingActivityNode({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -352,7 +330,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
return createTextNode({
|
return createTextNode({
|
||||||
id: language.name,
|
id: language.name,
|
||||||
label: language.name,
|
label: language.name,
|
||||||
value: formatLanguageValue({ display_format, lang: language }),
|
value: language.text,
|
||||||
index,
|
index,
|
||||||
percent: language.percent,
|
percent: language.percent,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -404,10 +382,6 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (disable_animations) {
|
|
||||||
card.disableAnimations();
|
|
||||||
}
|
|
||||||
|
|
||||||
card.setHideBorder(hide_border);
|
card.setHideBorder(hide_border);
|
||||||
card.setHideTitle(hide_title);
|
card.setHideTitle(hide_title);
|
||||||
card.setCSS(
|
card.setCSS(
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ class Card {
|
|||||||
* @param {string?=} args.customTitle Card custom title.
|
* @param {string?=} args.customTitle Card custom title.
|
||||||
* @param {string?=} args.defaultTitle Card default title.
|
* @param {string?=} args.defaultTitle Card default title.
|
||||||
* @param {string?=} args.titlePrefixIcon Card title prefix icon.
|
* @param {string?=} args.titlePrefixIcon Card title prefix icon.
|
||||||
|
* @param {string?=} args.stringifiedRepoImage Card preview image.
|
||||||
|
* @param {number?=} args.imageHeight Card preview image.
|
||||||
* @param {object?=} args.colors Card colors arguments.
|
* @param {object?=} args.colors Card colors arguments.
|
||||||
* @param {string} args.colors.titleColor Card title color.
|
* @param {string} args.colors.titleColor Card title color.
|
||||||
* @param {string} args.colors.textColor Card text color.
|
* @param {string} args.colors.textColor Card text color.
|
||||||
@@ -27,6 +29,8 @@ class Card {
|
|||||||
customTitle,
|
customTitle,
|
||||||
defaultTitle = "",
|
defaultTitle = "",
|
||||||
titlePrefixIcon,
|
titlePrefixIcon,
|
||||||
|
stringifiedRepoImage = "",
|
||||||
|
imageHeight = 200,
|
||||||
}) {
|
}) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@@ -36,6 +40,9 @@ class Card {
|
|||||||
|
|
||||||
this.border_radius = border_radius;
|
this.border_radius = border_radius;
|
||||||
|
|
||||||
|
this.imageHeight = imageHeight;
|
||||||
|
this.stringifiedRepoImage = stringifiedRepoImage;
|
||||||
|
|
||||||
// returns theme based colors with proper overrides and defaults
|
// returns theme based colors with proper overrides and defaults
|
||||||
this.colors = colors;
|
this.colors = colors;
|
||||||
this.title =
|
this.title =
|
||||||
@@ -51,6 +58,10 @@ class Card {
|
|||||||
this.animations = true;
|
this.animations = true;
|
||||||
this.a11yTitle = "";
|
this.a11yTitle = "";
|
||||||
this.a11yDesc = "";
|
this.a11yDesc = "";
|
||||||
|
if (this.stringifiedRepoImage) {
|
||||||
|
this.height += this.imageHeight;
|
||||||
|
this.paddingY += this.imageHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,6 +210,21 @@ class Card {
|
|||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} Renders social preview image
|
||||||
|
*/
|
||||||
|
renderImage = () => {
|
||||||
|
if (!this.stringifiedRepoImage) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return `
|
||||||
|
<g data-testid="card-image" transform="translate(0, 0)">
|
||||||
|
<image x="0" y="0" width="${this.width}" height="${this.imageHeight}"
|
||||||
|
href="${this.stringifiedRepoImage}">
|
||||||
|
</image>
|
||||||
|
</g>`;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} body The inner body of the card.
|
* @param {string} body The inner body of the card.
|
||||||
* @returns {string} The rendered card.
|
* @returns {string} The rendered card.
|
||||||
@@ -264,6 +290,7 @@ class Card {
|
|||||||
>
|
>
|
||||||
${body}
|
${body}
|
||||||
</g>
|
</g>
|
||||||
|
${this.renderImage()}
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@
|
|||||||
"BlitzBasic": "#00FFAE",
|
"BlitzBasic": "#00FFAE",
|
||||||
"BlitzMax": "#cd6400",
|
"BlitzMax": "#cd6400",
|
||||||
"Bluespec": "#12223c",
|
"Bluespec": "#12223c",
|
||||||
"Bluespec BH": "#12223c",
|
|
||||||
"Boo": "#d4bec1",
|
"Boo": "#d4bec1",
|
||||||
"Boogie": "#c80fa0",
|
"Boogie": "#c80fa0",
|
||||||
"Brainfuck": "#2F2530",
|
"Brainfuck": "#2F2530",
|
||||||
@@ -130,8 +129,6 @@
|
|||||||
"Easybuild": "#069406",
|
"Easybuild": "#069406",
|
||||||
"Ecere Projects": "#913960",
|
"Ecere Projects": "#913960",
|
||||||
"Ecmarkup": "#eb8131",
|
"Ecmarkup": "#eb8131",
|
||||||
"Edge": "#0dffe0",
|
|
||||||
"EdgeQL": "#31A7FF",
|
|
||||||
"EditorConfig": "#fff1f2",
|
"EditorConfig": "#fff1f2",
|
||||||
"Eiffel": "#4d6977",
|
"Eiffel": "#4d6977",
|
||||||
"Elixir": "#6e4a7e",
|
"Elixir": "#6e4a7e",
|
||||||
@@ -172,8 +169,8 @@
|
|||||||
"Game Maker Language": "#71b417",
|
"Game Maker Language": "#71b417",
|
||||||
"Gemfile.lock": "#701516",
|
"Gemfile.lock": "#701516",
|
||||||
"Gemini": "#ff6900",
|
"Gemini": "#ff6900",
|
||||||
"Genero 4gl": "#63408e",
|
"Genero": "#63408e",
|
||||||
"Genero per": "#d8df39",
|
"Genero Forms": "#d8df39",
|
||||||
"Genie": "#fb855d",
|
"Genie": "#fb855d",
|
||||||
"Genshi": "#951531",
|
"Genshi": "#951531",
|
||||||
"Gentoo Ebuild": "#9400ff",
|
"Gentoo Ebuild": "#9400ff",
|
||||||
@@ -184,8 +181,6 @@
|
|||||||
"Git Config": "#F44D27",
|
"Git Config": "#F44D27",
|
||||||
"Git Revision List": "#F44D27",
|
"Git Revision List": "#F44D27",
|
||||||
"Gleam": "#ffaff3",
|
"Gleam": "#ffaff3",
|
||||||
"Glimmer JS": "#F5835F",
|
|
||||||
"Glimmer TS": "#3178c6",
|
|
||||||
"Glyph": "#c1ac7f",
|
"Glyph": "#c1ac7f",
|
||||||
"Gnuplot": "#f0a9f0",
|
"Gnuplot": "#f0a9f0",
|
||||||
"Go": "#00ADD8",
|
"Go": "#00ADD8",
|
||||||
@@ -197,7 +192,6 @@
|
|||||||
"Gosu": "#82937f",
|
"Gosu": "#82937f",
|
||||||
"Grace": "#615f8b",
|
"Grace": "#615f8b",
|
||||||
"Gradle": "#02303a",
|
"Gradle": "#02303a",
|
||||||
"Gradle Kotlin DSL": "#02303a",
|
|
||||||
"Grammatical Framework": "#ff0000",
|
"Grammatical Framework": "#ff0000",
|
||||||
"GraphQL": "#e10098",
|
"GraphQL": "#e10098",
|
||||||
"Graphviz (DOT)": "#2596be",
|
"Graphviz (DOT)": "#2596be",
|
||||||
@@ -316,7 +310,6 @@
|
|||||||
"Modelica": "#de1d31",
|
"Modelica": "#de1d31",
|
||||||
"Modula-2": "#10253f",
|
"Modula-2": "#10253f",
|
||||||
"Modula-3": "#223388",
|
"Modula-3": "#223388",
|
||||||
"Mojo": "#ff4c1f",
|
|
||||||
"Monkey C": "#8D6747",
|
"Monkey C": "#8D6747",
|
||||||
"MoonScript": "#ff4585",
|
"MoonScript": "#ff4585",
|
||||||
"Motoko": "#fbb03b",
|
"Motoko": "#fbb03b",
|
||||||
@@ -383,7 +376,6 @@
|
|||||||
"PicoLisp": "#6067af",
|
"PicoLisp": "#6067af",
|
||||||
"PigLatin": "#fcd7de",
|
"PigLatin": "#fcd7de",
|
||||||
"Pike": "#005390",
|
"Pike": "#005390",
|
||||||
"Pip Requirements": "#FFD343",
|
|
||||||
"PlantUML": "#fbbd16",
|
"PlantUML": "#fbbd16",
|
||||||
"PogoScript": "#d80074",
|
"PogoScript": "#d80074",
|
||||||
"Polar": "#ae81ff",
|
"Polar": "#ae81ff",
|
||||||
@@ -392,7 +384,6 @@
|
|||||||
"PostScript": "#da291c",
|
"PostScript": "#da291c",
|
||||||
"PowerBuilder": "#8f0f8d",
|
"PowerBuilder": "#8f0f8d",
|
||||||
"PowerShell": "#012456",
|
"PowerShell": "#012456",
|
||||||
"Praat": "#c8506d",
|
|
||||||
"Prisma": "#0c344b",
|
"Prisma": "#0c344b",
|
||||||
"Processing": "#0096D8",
|
"Processing": "#0096D8",
|
||||||
"Procfile": "#3B2F63",
|
"Procfile": "#3B2F63",
|
||||||
@@ -431,11 +422,9 @@
|
|||||||
"Red": "#f50000",
|
"Red": "#f50000",
|
||||||
"Regular Expression": "#009a00",
|
"Regular Expression": "#009a00",
|
||||||
"Ren'Py": "#ff7f7f",
|
"Ren'Py": "#ff7f7f",
|
||||||
"Rez": "#FFDAB3",
|
|
||||||
"Ring": "#2D54CB",
|
"Ring": "#2D54CB",
|
||||||
"Riot": "#A71E49",
|
"Riot": "#A71E49",
|
||||||
"RobotFramework": "#00c0b5",
|
"RobotFramework": "#00c0b5",
|
||||||
"Roc": "#7c38f5",
|
|
||||||
"Roff": "#ecdebe",
|
"Roff": "#ecdebe",
|
||||||
"Roff Manpage": "#ecdebe",
|
"Roff Manpage": "#ecdebe",
|
||||||
"Rouge": "#cc0088",
|
"Rouge": "#cc0088",
|
||||||
@@ -468,7 +457,6 @@
|
|||||||
"Slash": "#007eff",
|
"Slash": "#007eff",
|
||||||
"Slice": "#003fa2",
|
"Slice": "#003fa2",
|
||||||
"Slim": "#2b2b2b",
|
"Slim": "#2b2b2b",
|
||||||
"Slint": "#2379F4",
|
|
||||||
"SmPL": "#c94949",
|
"SmPL": "#c94949",
|
||||||
"Smalltalk": "#596706",
|
"Smalltalk": "#596706",
|
||||||
"Smarty": "#f0c040",
|
"Smarty": "#f0c040",
|
||||||
@@ -487,8 +475,7 @@
|
|||||||
"SugarSS": "#2fcc9f",
|
"SugarSS": "#2fcc9f",
|
||||||
"SuperCollider": "#46390b",
|
"SuperCollider": "#46390b",
|
||||||
"Svelte": "#ff3e00",
|
"Svelte": "#ff3e00",
|
||||||
"Sway": "#00F58C",
|
"Sway": "#dea584",
|
||||||
"Sweave": "#198ce7",
|
|
||||||
"Swift": "#F05138",
|
"Swift": "#F05138",
|
||||||
"SystemVerilog": "#DAE1C2",
|
"SystemVerilog": "#DAE1C2",
|
||||||
"TI Program": "#A0AA87",
|
"TI Program": "#A0AA87",
|
||||||
@@ -503,16 +490,12 @@
|
|||||||
"Tcl": "#e4cc98",
|
"Tcl": "#e4cc98",
|
||||||
"TeX": "#3D6117",
|
"TeX": "#3D6117",
|
||||||
"Terra": "#00004c",
|
"Terra": "#00004c",
|
||||||
"Terraform Template": "#7b42bb",
|
|
||||||
"TextGrid": "#c8506d",
|
|
||||||
"TextMate Properties": "#df66e4",
|
"TextMate Properties": "#df66e4",
|
||||||
"Textile": "#ffe7ac",
|
"Textile": "#ffe7ac",
|
||||||
"Thrift": "#D12127",
|
"Thrift": "#D12127",
|
||||||
"Toit": "#c2c9fb",
|
|
||||||
"Turing": "#cf142b",
|
"Turing": "#cf142b",
|
||||||
"Twig": "#c1d026",
|
"Twig": "#c1d026",
|
||||||
"TypeScript": "#3178c6",
|
"TypeScript": "#3178c6",
|
||||||
"Typst": "#239dad",
|
|
||||||
"Unified Parallel C": "#4e3617",
|
"Unified Parallel C": "#4e3617",
|
||||||
"Unity3D Asset": "#222c37",
|
"Unity3D Asset": "#222c37",
|
||||||
"Uno": "#9933cc",
|
"Uno": "#9933cc",
|
||||||
|
|||||||
+77
-75
@@ -39,6 +39,61 @@ class CustomError extends Error {
|
|||||||
static WAKATIME_ERROR = "WAKATIME_ERROR";
|
static WAKATIME_ERROR = "WAKATIME_ERROR";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Script parameters.
|
||||||
|
const ERROR_CARD_LENGTH = 576.5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode string as HTML.
|
||||||
|
*
|
||||||
|
* @see https://stackoverflow.com/a/48073476/10629172
|
||||||
|
*
|
||||||
|
* @param {string} str String to encode.
|
||||||
|
* @returns {string} Encoded string.
|
||||||
|
*/
|
||||||
|
const encodeHTML = (str) => {
|
||||||
|
return str
|
||||||
|
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
|
||||||
|
return "&#" + i.charCodeAt(0) + ";";
|
||||||
|
})
|
||||||
|
.replace(/\u0008/gim, "");
|
||||||
|
};
|
||||||
|
|
||||||
|
const UPSTREAM_API_ERRORS = [
|
||||||
|
TRY_AGAIN_LATER,
|
||||||
|
SECONDARY_ERROR_MESSAGES.MAX_RETRY,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders error message on the card.
|
||||||
|
*
|
||||||
|
* @param {string} message Main error message.
|
||||||
|
* @param {string} secondaryMessage The secondary error message.
|
||||||
|
* @returns {string} The SVG markup.
|
||||||
|
*/
|
||||||
|
const renderError = (message, secondaryMessage = "") => {
|
||||||
|
return `
|
||||||
|
<svg width="${ERROR_CARD_LENGTH}" height="120" viewBox="0 0 ${ERROR_CARD_LENGTH} 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="${
|
||||||
|
ERROR_CARD_LENGTH - 1
|
||||||
|
}" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
|
||||||
|
<text x="25" y="45" class="text">Something went wrong!${
|
||||||
|
UPSTREAM_API_ERRORS.includes(secondaryMessage)
|
||||||
|
? ""
|
||||||
|
: " 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>
|
||||||
|
<tspan x="25" dy="18" class="gray">${secondaryMessage}</tspan>
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto layout utility, allows us to layout things vertically or horizontally with
|
* Auto layout utility, allows us to layout things vertically or horizontally with
|
||||||
* proper gaping.
|
* proper gaping.
|
||||||
@@ -325,81 +380,6 @@ const getCardColors = ({
|
|||||||
return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor };
|
return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Script parameters.
|
|
||||||
const ERROR_CARD_LENGTH = 576.5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode string as HTML.
|
|
||||||
*
|
|
||||||
* @see https://stackoverflow.com/a/48073476/10629172
|
|
||||||
*
|
|
||||||
* @param {string} str String to encode.
|
|
||||||
* @returns {string} Encoded string.
|
|
||||||
*/
|
|
||||||
const encodeHTML = (str) => {
|
|
||||||
return str
|
|
||||||
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
|
|
||||||
return "&#" + i.charCodeAt(0) + ";";
|
|
||||||
})
|
|
||||||
.replace(/\u0008/gim, "");
|
|
||||||
};
|
|
||||||
|
|
||||||
const UPSTREAM_API_ERRORS = [
|
|
||||||
TRY_AGAIN_LATER,
|
|
||||||
SECONDARY_ERROR_MESSAGES.MAX_RETRY,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders error message on the card.
|
|
||||||
*
|
|
||||||
* @param {string} message Main error message.
|
|
||||||
* @param {string} secondaryMessage The secondary error message.
|
|
||||||
* @param {object} options Function options.
|
|
||||||
* @returns {string} The SVG markup.
|
|
||||||
*/
|
|
||||||
const renderError = (message, secondaryMessage = "", options = {}) => {
|
|
||||||
const {
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
theme = "default",
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
// returns theme based colors with proper overrides and defaults
|
|
||||||
const { titleColor, textColor, bgColor, borderColor } = getCardColors({
|
|
||||||
title_color,
|
|
||||||
text_color,
|
|
||||||
icon_color: "",
|
|
||||||
bg_color,
|
|
||||||
border_color,
|
|
||||||
ring_color: "",
|
|
||||||
theme,
|
|
||||||
});
|
|
||||||
|
|
||||||
return `
|
|
||||||
<svg width="${ERROR_CARD_LENGTH}" height="120" viewBox="0 0 ${ERROR_CARD_LENGTH} 120" fill="${bgColor}" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<style>
|
|
||||||
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor} }
|
|
||||||
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
|
||||||
.gray { fill: #858585 }
|
|
||||||
</style>
|
|
||||||
<rect x="0.5" y="0.5" width="${
|
|
||||||
ERROR_CARD_LENGTH - 1
|
|
||||||
}" height="99%" rx="4.5" fill="${bgColor}" stroke="${borderColor}"/>
|
|
||||||
<text x="25" y="45" class="text">Something went wrong!${
|
|
||||||
UPSTREAM_API_ERRORS.includes(secondaryMessage)
|
|
||||||
? ""
|
|
||||||
: " 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>
|
|
||||||
<tspan x="25" dy="18" class="gray">${secondaryMessage}</tspan>
|
|
||||||
</text>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split text over multiple lines based on the card width.
|
* Split text over multiple lines based on the card width.
|
||||||
*
|
*
|
||||||
@@ -589,6 +569,27 @@ const dateDiff = (d1, d2) => {
|
|||||||
return Math.round(diff / (1000 * 60));
|
return Math.round(diff / (1000 * 60));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getBase64URIFromImage = async (imageURL) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(imageURL, {
|
||||||
|
responseType: "arraybuffer",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
const base64Image = Buffer.from(response.data, "binary").toString(
|
||||||
|
"base64",
|
||||||
|
);
|
||||||
|
const mimeType = response.headers["content-type"];
|
||||||
|
return `data:${mimeType};base64,${base64Image}`;
|
||||||
|
} else {
|
||||||
|
throw new Error("Failed to fetch the image.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ERROR_CARD_LENGTH,
|
ERROR_CARD_LENGTH,
|
||||||
renderError,
|
renderError,
|
||||||
@@ -615,4 +616,5 @@ export {
|
|||||||
chunkArray,
|
chunkArray,
|
||||||
parseEmojis,
|
parseEmojis,
|
||||||
dateDiff,
|
dateDiff,
|
||||||
|
getBase64URIFromImage,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const fetcher = (variables, token) => {
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
forkCount
|
forkCount
|
||||||
|
openGraphImageUrl
|
||||||
}
|
}
|
||||||
query getRepo($login: String!, $repo: String!) {
|
query getRepo($login: String!, $repo: String!) {
|
||||||
user(login: $login) {
|
user(login: $login) {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const fetchTopLanguages = async (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw new CustomError(
|
throw new CustomError(
|
||||||
"Something went wrong while trying to retrieve the language data using the GraphQL API.",
|
"Something went while trying to retrieve the language data using the GraphQL API.",
|
||||||
CustomError.GRAPHQL_ERROR,
|
CustomError.GRAPHQL_ERROR,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
@@ -22,6 +22,7 @@ export type RepositoryData = {
|
|||||||
};
|
};
|
||||||
forkCount: number;
|
forkCount: number;
|
||||||
starCount: number;
|
starCount: number;
|
||||||
|
stringifiedRepoImage: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StatsData = {
|
export type StatsData = {
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ exports[`Test Render WakaTime Card should render correctly with compact layout 1
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
</svg>
|
</svg>
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
@@ -302,6 +303,7 @@ exports[`Test Render WakaTime Card should render correctly with compact layout w
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
</svg>
|
</svg>
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|||||||
+1
-18
@@ -120,21 +120,6 @@ describe("Test /api/", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render error card in same theme as requested card", async () => {
|
|
||||||
const { req, res } = faker({ theme: "merko" }, error);
|
|
||||||
|
|
||||||
await api(req, res);
|
|
||||||
|
|
||||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
|
||||||
expect(res.send).toBeCalledWith(
|
|
||||||
renderError(
|
|
||||||
error.errors[0].message,
|
|
||||||
"Make sure the provided username is not an organization",
|
|
||||||
{ theme: "merko" },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should get the query options", async () => {
|
it("should get the query options", async () => {
|
||||||
const { req, res } = faker(
|
const { req, res } = faker(
|
||||||
{
|
{
|
||||||
@@ -306,9 +291,7 @@ describe("Test /api/", () => {
|
|||||||
await api(req, res);
|
await api(req, res);
|
||||||
|
|
||||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||||
expect(res.send).toBeCalledWith(
|
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render error card when wrong locale is provided", async () => {
|
it("should render error card when wrong locale is provided", async () => {
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import { benchmarkSuite } from "jest-bench";
|
|
||||||
import gist from "../../api/gist.js";
|
|
||||||
import axios from "axios";
|
|
||||||
import MockAdapter from "axios-mock-adapter";
|
|
||||||
import { jest } from "@jest/globals";
|
|
||||||
|
|
||||||
const gist_data = {
|
|
||||||
data: {
|
|
||||||
viewer: {
|
|
||||||
gist: {
|
|
||||||
description:
|
|
||||||
"List of countries and territories in English and Spanish: name, continent, capital, dial code, country codes, TLD, and area in sq km. Lista de países y territorios en Inglés y Español: nombre, continente, capital, código de teléfono, códigos de país, dominio y área en km cuadrados. Updated 2023",
|
|
||||||
owner: {
|
|
||||||
login: "Yizack",
|
|
||||||
},
|
|
||||||
stargazerCount: 33,
|
|
||||||
forks: {
|
|
||||||
totalCount: 11,
|
|
||||||
},
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
name: "countries.json",
|
|
||||||
language: {
|
|
||||||
name: "JSON",
|
|
||||||
},
|
|
||||||
size: 85858,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mock = new MockAdapter(axios);
|
|
||||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
|
||||||
|
|
||||||
benchmarkSuite("test /api/gist", {
|
|
||||||
["simple request"]: async () => {
|
|
||||||
const req = {
|
|
||||||
query: {
|
|
||||||
id: "bbfce31e0217a3689c8d961a356cb10d",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const res = {
|
|
||||||
setHeader: jest.fn(),
|
|
||||||
send: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
await gist(req, res);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
import { benchmarkSuite } from "jest-bench";
|
|
||||||
import pin from "../../api/pin.js";
|
|
||||||
import axios from "axios";
|
|
||||||
import MockAdapter from "axios-mock-adapter";
|
|
||||||
import { jest } from "@jest/globals";
|
|
||||||
|
|
||||||
const data_repo = {
|
|
||||||
repository: {
|
|
||||||
username: "anuraghazra",
|
|
||||||
name: "convoychat",
|
|
||||||
stargazers: {
|
|
||||||
totalCount: 38000,
|
|
||||||
},
|
|
||||||
description: "Help us take over the world! React + TS + GraphQL Chat App",
|
|
||||||
primaryLanguage: {
|
|
||||||
color: "#2b7489",
|
|
||||||
id: "MDg6TGFuZ3VhZ2UyODc=",
|
|
||||||
name: "TypeScript",
|
|
||||||
},
|
|
||||||
forkCount: 100,
|
|
||||||
isTemplate: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const data_user = {
|
|
||||||
data: {
|
|
||||||
user: { repository: data_repo.repository },
|
|
||||||
organization: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mock = new MockAdapter(axios);
|
|
||||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
|
||||||
|
|
||||||
benchmarkSuite("test /api/pin", {
|
|
||||||
["simple request"]: async () => {
|
|
||||||
const req = {
|
|
||||||
query: {
|
|
||||||
username: "anuraghazra",
|
|
||||||
repo: "convoychat",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const res = {
|
|
||||||
setHeader: jest.fn(),
|
|
||||||
send: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
await pin(req, res);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
+1
-1
@@ -89,7 +89,7 @@ describe("Card", () => {
|
|||||||
"200",
|
"200",
|
||||||
);
|
);
|
||||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||||
"width",
|
"height",
|
||||||
"200",
|
"200",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
+8
-11
@@ -14,20 +14,19 @@ import { expect, describe, beforeAll, test } from "@jest/globals";
|
|||||||
|
|
||||||
const REPO = "curly-fiesta";
|
const REPO = "curly-fiesta";
|
||||||
const USER = "catelinemnemosyne";
|
const USER = "catelinemnemosyne";
|
||||||
const STATS_CARD_USER = "e2eninja";
|
|
||||||
const GIST_ID = "372cef55fd897b31909fdeb3a7262758";
|
const GIST_ID = "372cef55fd897b31909fdeb3a7262758";
|
||||||
|
|
||||||
const STATS_DATA = {
|
const STATS_DATA = {
|
||||||
name: "E2ENinja",
|
name: "Cateline Mnemosyne",
|
||||||
totalPRs: 1,
|
totalPRs: 2,
|
||||||
totalReviews: 0,
|
totalReviews: 0,
|
||||||
totalCommits: 3,
|
totalCommits: 8,
|
||||||
totalIssues: 1,
|
totalIssues: 1,
|
||||||
totalStars: 1,
|
totalStars: 1,
|
||||||
contributedTo: 0,
|
contributedTo: 1,
|
||||||
rank: {
|
rank: {
|
||||||
level: "C",
|
level: "C",
|
||||||
percentile: 98.73972605284538,
|
percentile: 98.06929469995667,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,17 +116,15 @@ describe("Fetch Cards", () => {
|
|||||||
|
|
||||||
// Check if the Vercel preview instance stats card function is up and running.
|
// Check if the Vercel preview instance stats card function is up and running.
|
||||||
await expect(
|
await expect(
|
||||||
axios.get(`${VERCEL_PREVIEW_URL}/api?username=${STATS_CARD_USER}`),
|
axios.get(`${VERCEL_PREVIEW_URL}/api?username=${USER}`),
|
||||||
).resolves.not.toThrow();
|
).resolves.not.toThrow();
|
||||||
|
|
||||||
// Get local stats card.
|
// Get local stats card.
|
||||||
const localStatsCardSVG = renderStatsCard(STATS_DATA, {
|
const localStatsCardSVG = renderStatsCard(STATS_DATA);
|
||||||
include_all_commits: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the Vercel preview stats card response.
|
// Get the Vercel preview stats card response.
|
||||||
const serverStatsSvg = await axios.get(
|
const serverStatsSvg = await axios.get(
|
||||||
`${VERCEL_PREVIEW_URL}/api?username=${STATS_CARD_USER}&include_all_commits=true&${CACHE_BURST_STRING}`,
|
`${VERCEL_PREVIEW_URL}/api?username=${USER}&${CACHE_BURST_STRING}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Check if stats card from deployment matches the stats card from local.
|
// Check if stats card from deployment matches the stats card from local.
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ describe("FetchTopLanguages", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow(
|
await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow(
|
||||||
"Something went wrong while trying to retrieve the language data using the GraphQL API.",
|
"Something went while trying to retrieve the language data using the GraphQL API.",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ const wakaTimeData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe("WakaTime fetcher", () => {
|
describe("WakaTime fetcher", () => {
|
||||||
it("should fetch correct WakaTime data", async () => {
|
it("should fetch correct wakatime data", async () => {
|
||||||
const username = "anuraghazra";
|
const username = "anuraghazra";
|
||||||
mock
|
mock
|
||||||
.onGet(
|
.onGet(
|
||||||
|
|||||||
+1
-3
@@ -155,9 +155,7 @@ describe("Test /api/pin", () => {
|
|||||||
await pin(req, res);
|
await pin(req, res);
|
||||||
|
|
||||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||||
expect(res.send).toBeCalledWith(
|
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render error card if wrong locale provided", async () => {
|
it("should render error card if wrong locale provided", async () => {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const data_repo = {
|
|||||||
},
|
},
|
||||||
starCount: 38000,
|
starCount: 38000,
|
||||||
forkCount: 100,
|
forkCount: 100,
|
||||||
|
stringifiedRepoImage: "data:image/png;base64,base64/image/string",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,33 +341,20 @@ describe("Test renderRepoCard", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have correct height with specified `description_lines_count` parameter", () => {
|
it("should render repo's social preview image, when show_image is true", () => {
|
||||||
// Testing short description
|
|
||||||
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
||||||
description_lines_count: 1,
|
show_image: true,
|
||||||
});
|
});
|
||||||
expect(document.querySelector("svg")).toHaveAttribute("height", "120");
|
|
||||||
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
|
||||||
description_lines_count: 3,
|
|
||||||
});
|
|
||||||
expect(document.querySelector("svg")).toHaveAttribute("height", "150");
|
|
||||||
|
|
||||||
// Testing long description
|
expect(queryByTestId(document.body, "card-image")).toBeInTheDocument();
|
||||||
const longDescription =
|
expect(
|
||||||
"A tool that will make a lot of iPhone/iPad developers' life easier. It shares your app over-the-air in a WiFi network. Bonjour is used and no configuration is needed.";
|
queryByTestId(document.body, "card-image").children[0],
|
||||||
document.body.innerHTML = renderRepoCard(
|
).toHaveAttribute("href", data_repo.repository.stringifiedRepoImage);
|
||||||
{ ...data_repo.repository, description: longDescription },
|
});
|
||||||
{
|
|
||||||
description_lines_count: 3,
|
it("should not render repo's social preview image by default", () => {
|
||||||
},
|
document.body.innerHTML = renderRepoCard(data_repo.repository);
|
||||||
);
|
|
||||||
expect(document.querySelector("svg")).toHaveAttribute("height", "150");
|
expect(queryByTestId(document.body, "card-image")).not.toBeInTheDocument();
|
||||||
document.body.innerHTML = renderRepoCard(
|
|
||||||
{ ...data_repo.repository, description: longDescription },
|
|
||||||
{
|
|
||||||
description_lines_count: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
expect(document.querySelector("svg")).toHaveAttribute("height", "120");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -387,9 +387,7 @@ describe("Test renderStatsCard", () => {
|
|||||||
document.querySelector(
|
document.querySelector(
|
||||||
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
|
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
|
||||||
).textContent,
|
).textContent,
|
||||||
).toMatchInlineSnapshot(
|
).toMatchInlineSnapshot(`"累计提交数(commit) (2023):"`);
|
||||||
`"累计提交数(commit) (${new Date().getFullYear()}):"`,
|
|
||||||
);
|
|
||||||
expect(
|
expect(
|
||||||
document.querySelector(
|
document.querySelector(
|
||||||
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
|
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
|
||||||
|
|||||||
@@ -183,9 +183,7 @@ describe("Test /api/top-langs", () => {
|
|||||||
await topLangs(req, res);
|
await topLangs(req, res);
|
||||||
|
|
||||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||||
expect(res.send).toBeCalledWith(
|
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||||
renderError("Something went wrong", "This username is blacklisted"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render error card if wrong locale provided", async () => {
|
it("should render error card if wrong locale provided", async () => {
|
||||||
|
|||||||
@@ -1,123 +0,0 @@
|
|||||||
import { jest } from "@jest/globals";
|
|
||||||
import "@testing-library/jest-dom";
|
|
||||||
import axios from "axios";
|
|
||||||
import MockAdapter from "axios-mock-adapter";
|
|
||||||
import wakatime from "../api/wakatime.js";
|
|
||||||
import { renderWakatimeCard } from "../src/cards/wakatime-card.js";
|
|
||||||
import { expect, it, describe, afterEach } from "@jest/globals";
|
|
||||||
|
|
||||||
const wakaTimeData = {
|
|
||||||
data: {
|
|
||||||
categories: [
|
|
||||||
{
|
|
||||||
digital: "22:40",
|
|
||||||
hours: 22,
|
|
||||||
minutes: 40,
|
|
||||||
name: "Coding",
|
|
||||||
percent: 100,
|
|
||||||
text: "22 hrs 40 mins",
|
|
||||||
total_seconds: 81643.570077,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
daily_average: 16095,
|
|
||||||
daily_average_including_other_language: 16329,
|
|
||||||
days_including_holidays: 7,
|
|
||||||
days_minus_holidays: 5,
|
|
||||||
editors: [
|
|
||||||
{
|
|
||||||
digital: "22:40",
|
|
||||||
hours: 22,
|
|
||||||
minutes: 40,
|
|
||||||
name: "VS Code",
|
|
||||||
percent: 100,
|
|
||||||
text: "22 hrs 40 mins",
|
|
||||||
total_seconds: 81643.570077,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
holidays: 2,
|
|
||||||
human_readable_daily_average: "4 hrs 28 mins",
|
|
||||||
human_readable_daily_average_including_other_language: "4 hrs 32 mins",
|
|
||||||
human_readable_total: "22 hrs 21 mins",
|
|
||||||
human_readable_total_including_other_language: "22 hrs 40 mins",
|
|
||||||
id: "random hash",
|
|
||||||
is_already_updating: false,
|
|
||||||
is_coding_activity_visible: true,
|
|
||||||
is_including_today: false,
|
|
||||||
is_other_usage_visible: true,
|
|
||||||
is_stuck: false,
|
|
||||||
is_up_to_date: true,
|
|
||||||
languages: [
|
|
||||||
{
|
|
||||||
digital: "0:19",
|
|
||||||
hours: 0,
|
|
||||||
minutes: 19,
|
|
||||||
name: "Other",
|
|
||||||
percent: 1.43,
|
|
||||||
text: "19 mins",
|
|
||||||
total_seconds: 1170.434361,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
digital: "0:01",
|
|
||||||
hours: 0,
|
|
||||||
minutes: 1,
|
|
||||||
name: "TypeScript",
|
|
||||||
percent: 0.1,
|
|
||||||
text: "1 min",
|
|
||||||
total_seconds: 83.293809,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
digital: "0:00",
|
|
||||||
hours: 0,
|
|
||||||
minutes: 0,
|
|
||||||
name: "YAML",
|
|
||||||
percent: 0.07,
|
|
||||||
text: "0 secs",
|
|
||||||
total_seconds: 54.975151,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
operating_systems: [
|
|
||||||
{
|
|
||||||
digital: "22:40",
|
|
||||||
hours: 22,
|
|
||||||
minutes: 40,
|
|
||||||
name: "Mac",
|
|
||||||
percent: 100,
|
|
||||||
text: "22 hrs 40 mins",
|
|
||||||
total_seconds: 81643.570077,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
percent_calculated: 100,
|
|
||||||
range: "last_7_days",
|
|
||||||
status: "ok",
|
|
||||||
timeout: 15,
|
|
||||||
total_seconds: 80473.135716,
|
|
||||||
total_seconds_including_other_language: 81643.570077,
|
|
||||||
user_id: "random hash",
|
|
||||||
username: "anuraghazra",
|
|
||||||
writes_only: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mock = new MockAdapter(axios);
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
mock.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Test /api/wakatime", () => {
|
|
||||||
it("should test the request", async () => {
|
|
||||||
const username = "anuraghazra";
|
|
||||||
const req = { query: { username } };
|
|
||||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
|
||||||
mock
|
|
||||||
.onGet(
|
|
||||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
|
||||||
)
|
|
||||||
.reply(200, wakaTimeData);
|
|
||||||
|
|
||||||
await wakatime(req, res);
|
|
||||||
|
|
||||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
|
||||||
expect(res.send).toBeCalledWith(renderWakatimeCard(wakaTimeData.data, {}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
+4
-6
@@ -12,7 +12,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
|||||||
|
|
||||||
## Stats
|
## Stats
|
||||||
|
|
||||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and WakaTime Card.
|
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
|
||||||
|
|
||||||
| | | |
|
| | | |
|
||||||
| :--: | :--: | :--: |
|
| :--: | :--: | :--: |
|
||||||
@@ -40,11 +40,11 @@ Use `?theme=THEME_NAME` parameter like so:
|
|||||||
| `rose_pine` ![rose_pine][rose_pine] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha] |
|
| `rose_pine` ![rose_pine][rose_pine] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha] |
|
||||||
| `date_night` ![date_night][date_night] | `one_dark_pro` ![one_dark_pro][one_dark_pro] | `rose` ![rose][rose] |
|
| `date_night` ![date_night][date_night] | `one_dark_pro` ![one_dark_pro][one_dark_pro] | `rose` ![rose][rose] |
|
||||||
| `holi` ![holi][holi] | `neon` ![neon][neon] | `blue_navy` ![blue_navy][blue_navy] |
|
| `holi` ![holi][holi] | `neon` ![neon][neon] | `blue_navy` ![blue_navy][blue_navy] |
|
||||||
| `calm_pink` ![calm_pink][calm_pink] | `ambient_gradient` ![ambient_gradient][ambient_gradient] | [Add your theme][add-theme] |
|
| `calm_pink` ![calm_pink][calm_pink] | | [Add your theme][add-theme] |
|
||||||
|
|
||||||
## Repo Card
|
## Repo Card
|
||||||
|
|
||||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and WakaTime Card.
|
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
|
||||||
|
|
||||||
| | | |
|
| | | |
|
||||||
| :--: | :--: | :--: |
|
| :--: | :--: | :--: |
|
||||||
@@ -72,7 +72,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
|||||||
| `rose_pine` ![rose_pine][rose_pine_repo] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte_repo] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha_repo] |
|
| `rose_pine` ![rose_pine][rose_pine_repo] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte_repo] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha_repo] |
|
||||||
| `date_night` ![date_night][date_night_repo] | `one_dark_pro` ![one_dark_pro][one_dark_pro_repo] | `rose` ![rose][rose_repo] |
|
| `date_night` ![date_night][date_night_repo] | `one_dark_pro` ![one_dark_pro][one_dark_pro_repo] | `rose` ![rose][rose_repo] |
|
||||||
| `holi` ![holi][holi_repo] | `neon` ![neon][neon_repo] | `blue_navy` ![blue_navy][blue_navy_repo] |
|
| `holi` ![holi][holi_repo] | `neon` ![neon][neon_repo] | `blue_navy` ![blue_navy][blue_navy_repo] |
|
||||||
| `calm_pink` ![calm_pink][calm_pink_repo] | `ambient_gradient` ![ambient_gradient][ambient_gradient_repo] | [Add your theme][add-theme] |
|
| `calm_pink` ![calm_pink][calm_pink_repo] | | [Add your theme][add-theme] |
|
||||||
|
|
||||||
|
|
||||||
[default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default
|
[default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default
|
||||||
@@ -149,7 +149,6 @@ Use `?theme=THEME_NAME` parameter like so:
|
|||||||
[neon]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=neon
|
[neon]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=neon
|
||||||
[blue_navy]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=blue_navy
|
[blue_navy]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=blue_navy
|
||||||
[calm_pink]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=calm_pink
|
[calm_pink]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=calm_pink
|
||||||
[ambient_gradient]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=ambient_gradient
|
|
||||||
|
|
||||||
|
|
||||||
[default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default
|
[default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default
|
||||||
@@ -226,7 +225,6 @@ Use `?theme=THEME_NAME` parameter like so:
|
|||||||
[neon_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=neon
|
[neon_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=neon
|
||||||
[blue_navy_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=blue_navy
|
[blue_navy_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=blue_navy
|
||||||
[calm_pink_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=calm_pink
|
[calm_pink_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=calm_pink
|
||||||
[ambient_gradient_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=ambient_gradient
|
|
||||||
|
|
||||||
|
|
||||||
[add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js
|
[add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js
|
||||||
|
|||||||
@@ -456,12 +456,6 @@ export const themes = {
|
|||||||
border_color: "e1bc29",
|
border_color: "e1bc29",
|
||||||
bg_color: "2b2d40",
|
bg_color: "2b2d40",
|
||||||
},
|
},
|
||||||
ambient_gradient: {
|
|
||||||
title_color: "ffffff",
|
|
||||||
text_color: "ffffff",
|
|
||||||
icon_color: "ffffff",
|
|
||||||
bg_color: "35,4158d0,c850c0,ffcc70",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default themes;
|
export default themes;
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"functions": {
|
"functions": {
|
||||||
"api/*.js": {
|
"api/*.js": {
|
||||||
"memory": 128,
|
"memory": 128,
|
||||||
"maxDuration": 30
|
"maxDuration": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redirects": [
|
"redirects": [
|
||||||
|
|||||||
Reference in New Issue
Block a user