Compare commits
128
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0156fa568 | ||
|
|
b901d3a1d6 | ||
|
|
5a136eccdf | ||
|
|
5a1af30d40 | ||
|
|
243107cc7e | ||
|
|
f3516ee6b4 | ||
|
|
facf095ff4 | ||
|
|
6cfe47130a | ||
|
|
bc8ec8068e | ||
|
|
7062f601b7 | ||
|
|
bfe297d20d | ||
|
|
940aa649fe | ||
|
|
f4cbac043c | ||
|
|
eaa7bf50bb | ||
|
|
49f00cd7b2 | ||
|
|
3a61d18f41 | ||
|
|
719e74c7f5 | ||
|
|
8acd429d44 | ||
|
|
20463f6365 | ||
|
|
366cc48853 | ||
|
|
ce8660c825 | ||
|
|
3a3d8d2c5e | ||
|
|
53c49404bf | ||
|
|
66836db71b | ||
|
|
6f7e35468c | ||
|
|
d7089af346 | ||
|
|
394fef948b | ||
|
|
67b434dc79 | ||
|
|
e7dcda0ee8 | ||
|
|
1412a8dbe0 | ||
|
|
e18f57be3e | ||
|
|
8dca589a13 | ||
|
|
f0b89d0f72 | ||
|
|
56e3745a5c | ||
|
|
416f027fae | ||
|
|
a4486d0327 | ||
|
|
65cdb1877f | ||
|
|
b0362c4e12 | ||
|
|
60511778ff | ||
|
|
3b0f1b11a0 | ||
|
|
074e22017e | ||
|
|
34b5dcb181 | ||
|
|
0833e8531d | ||
|
|
be285cb33e | ||
|
|
3c7220e4f7 | ||
|
|
d8d724c664 | ||
|
|
df447eee55 | ||
|
|
f38224a8b6 | ||
|
|
027655f023 | ||
|
|
bd0ef4afc1 | ||
|
|
9dde51951b | ||
|
|
d685d4d9df | ||
|
|
8854c6d6cb | ||
|
|
f741ec0073 | ||
|
|
826f0201aa | ||
|
|
457848225b | ||
|
|
1f22b6938c | ||
|
|
f7f8ee7ba0 | ||
|
|
3206c68f71 | ||
|
|
12ec9fd715 | ||
|
|
596897f9af | ||
|
|
2fa229ac7e | ||
|
|
51ba2d206a | ||
|
|
f82a89fbc0 | ||
|
|
b4882408c6 | ||
|
|
5076d88a34 | ||
|
|
243dd0f204 | ||
|
|
45cb505a5b | ||
|
|
11757dba42 | ||
|
|
68198d8b16 | ||
|
|
d929e8b20a | ||
|
|
b8330a88e1 | ||
|
|
3bdcf3d61f | ||
|
|
845e90b42e | ||
|
|
59e295f35b | ||
|
|
8be88461b4 | ||
|
|
9bd1bad491 | ||
|
|
1f79d503bd | ||
|
|
1b23175fa6 | ||
|
|
9e8d4aeb38 | ||
|
|
ef57cc7dcf | ||
|
|
f0a0dfe51c | ||
|
|
c1438fe7c5 | ||
|
|
7f220bb072 | ||
|
|
57cf490e3e | ||
|
|
6d1b1e220c | ||
|
|
662ae95b02 | ||
|
|
e38df2932c | ||
|
|
64d1fb46c3 | ||
|
|
753f0b9fec | ||
|
|
f50938c908 | ||
|
|
6d5a828542 | ||
|
|
463564382a | ||
|
|
e32ab3f973 | ||
|
|
2812ce0fd3 | ||
|
|
f9b14c9442 | ||
|
|
7b509d3128 | ||
|
|
f355f48bb4 | ||
|
|
4c0518616f | ||
|
|
3a9ded0a09 | ||
|
|
7973805cf7 | ||
|
|
a7d56c3a04 | ||
|
|
13d9da68ff | ||
|
|
9624cf6acd | ||
|
|
7a8510641c | ||
|
|
bd13399e7f | ||
|
|
aa44bd7615 | ||
|
|
c2adcfd6fe | ||
|
|
17c33cd322 | ||
|
|
1c4cb84916 | ||
|
|
d394add560 | ||
|
|
5ed75e11be | ||
|
|
03f55e809e | ||
|
|
63ba6e6601 | ||
|
|
dc3e9a59f2 | ||
|
|
8284be105d | ||
|
|
6c16020c53 | ||
|
|
8a8ff5b390 | ||
|
|
4b01b4187c | ||
|
|
c3de4675c5 | ||
|
|
ad87824f3c | ||
|
|
bc7a9857a9 | ||
|
|
4a8fd03d8d | ||
|
|
7c104cf8c5 | ||
|
|
b50555ad9a | ||
|
|
411d8f1ffa | ||
|
|
938df3f7ea | ||
|
|
92dcc89a3d |
+1
-1
@@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ["https://www.paypal.me/anuraghazra"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
custom: ["https://www.paypal.me/anuraghazra", "https://www.buymeacoffee.com/anuraghazra"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
themes: themes/index.js
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Generate Theme Readme
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "themes/index.js"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: "12.x"
|
||||
|
||||
- name: npm install, generate readme
|
||||
run: |
|
||||
npm install
|
||||
npm run theme-readme-gen
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- name: Run Script
|
||||
uses: skx/github-action-tester@master
|
||||
with:
|
||||
script: ./scripts/push-theme-readme.sh
|
||||
env:
|
||||
CI: true
|
||||
PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
|
||||
GH_REPO: ${{ secrets.GH_REPO }}
|
||||
@@ -0,0 +1,11 @@
|
||||
name: "Pull Request Labeler"
|
||||
on:
|
||||
- pull_request_target
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v2
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Theme preview
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- master
|
||||
- theme-preview-script
|
||||
- "themes/index.js"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: "12.x"
|
||||
|
||||
- name: npm install, preview theme
|
||||
run: |
|
||||
npm install
|
||||
npm run preview-theme
|
||||
env:
|
||||
CI: true
|
||||
PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -34,3 +34,6 @@ jobs:
|
||||
run: |
|
||||
npm install
|
||||
npm run test
|
||||
|
||||
- name: Code Coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
|
||||
@@ -2,3 +2,6 @@
|
||||
.env
|
||||
node_modules
|
||||
package-lock.json
|
||||
*.lock
|
||||
.vscode/
|
||||
coverage
|
||||
|
||||
+2
-1
@@ -1,2 +1,3 @@
|
||||
.env
|
||||
package-lock.json
|
||||
package-lock.json
|
||||
coverage
|
||||
@@ -0,0 +1,75 @@
|
||||
# Contributing to [github-readme-stats](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
|
||||
|
||||
- Reporting a issue
|
||||
- Discussing the current state of the code
|
||||
- Submitting a fix
|
||||
- Proposing new features
|
||||
- Becoming a maintainer
|
||||
|
||||
## All Changes Happen Through Pull Requests
|
||||
|
||||
Pull requests are the best way to propose changes. We actively welcome your pull requests:
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
1. If you've added code that should be tested, add some tests' example.
|
||||
1. If you've changed APIs, update the documentation.
|
||||
1. Issue that pull request!
|
||||
|
||||
## Local Development
|
||||
|
||||
To run & test github-readme-stats you need to follow few simple steps :-
|
||||
_(make sure you already have a [vercel](https://vercel.com/) account)_
|
||||
|
||||
1. Install [Vercel CLI](https://vercel.com/download)
|
||||
1. Fork the repository and clone the code to your local machine
|
||||
1. Run the command "vercel" in the root and follow the steps there
|
||||
1. Create a `.env` file in the root of the directory
|
||||
1. In the .env file add a new variable named "PAT" with your [github Personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token)
|
||||
1. Run the command "vercel dev" to start a development server at https://localhost:3000
|
||||
|
||||
## Themes Contribution
|
||||
|
||||
GitHub Readme Stats supports custom theming and you can also contribute new themes!
|
||||
|
||||
All you need to do is edit [themes/index.js](./themes/index.js) file and add your theme at the end of the file.
|
||||
|
||||
While creating the Pull request to add a new theme **don't forget to add a screenshot of how your theme looks**, you can also test how it looks using custom url parameters like `title_color`, `icon_color`, `bg_color`, `text_color`
|
||||
|
||||
> NOTE: If you are contributing your theme just because you are using it personally, then you can [customize the looks](./readme.md#customization) of your card with URL params instead.
|
||||
|
||||
## Any contributions you make will be under the MIT Software License
|
||||
|
||||
In short, when you submit changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
|
||||
|
||||
## Report issues/bugs using GitHub's [issues](https://github.com/anuraghazra/github-readme-stats/issues)
|
||||
|
||||
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/anuraghazra/github-readme-stats/issues/new/choose); it's that easy!
|
||||
|
||||
### Bug Reports
|
||||
|
||||
**Great Bug Reports** tend to have:
|
||||
|
||||
- A quick summary and/or background
|
||||
- Steps to reproduce
|
||||
- Be specific!
|
||||
- Share the snapshot, if possible.
|
||||
- GitHub Readme Stats' live link
|
||||
- What actually happens
|
||||
- What you expected would happen
|
||||
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
|
||||
|
||||
People _love_ thorough bug reports. I'm not even kidding.
|
||||
|
||||
### Feature Request
|
||||
|
||||
**Great Feature Requests** tend to have:
|
||||
|
||||
- A quick idea summary
|
||||
- What & why you wanted to add the specific feature
|
||||
- Additional Context like images, links to resources to implement the feature etc etc.
|
||||
|
||||
## License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under its [MIT License](./LICENSE).
|
||||
+19
-6
@@ -2,11 +2,12 @@ require("dotenv").config();
|
||||
const {
|
||||
renderError,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
} = require("../src/utils");
|
||||
const fetchStats = require("../src/fetchStats");
|
||||
const renderStatsCard = require("../src/renderStatsCard");
|
||||
} = require("../src/common/utils");
|
||||
const fetchStats = require("../src/fetchers/stats-fetcher");
|
||||
const renderStatsCard = require("../src/cards/stats-card");
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const {
|
||||
@@ -16,6 +17,8 @@ module.exports = async (req, res) => {
|
||||
hide_border,
|
||||
hide_rank,
|
||||
show_icons,
|
||||
count_private,
|
||||
include_all_commits,
|
||||
line_height,
|
||||
title_color,
|
||||
icon_color,
|
||||
@@ -29,9 +32,18 @@ module.exports = async (req, res) => {
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
try {
|
||||
stats = await fetchStats(username);
|
||||
stats = await fetchStats(
|
||||
username,
|
||||
parseBoolean(count_private),
|
||||
parseBoolean(include_all_commits)
|
||||
);
|
||||
} catch (err) {
|
||||
return res.send(renderError(err.message));
|
||||
return res.send(
|
||||
renderError(
|
||||
err.message,
|
||||
"Make sure the provided username is not an organization"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const cacheSeconds = clampValue(
|
||||
@@ -44,11 +56,12 @@ module.exports = async (req, res) => {
|
||||
|
||||
res.send(
|
||||
renderStatsCard(stats, {
|
||||
hide: JSON.parse(hide || "[]"),
|
||||
hide: parseArray(hide),
|
||||
show_icons: parseBoolean(show_icons),
|
||||
hide_title: parseBoolean(hide_title),
|
||||
hide_border: parseBoolean(hide_border),
|
||||
hide_rank: parseBoolean(hide_rank),
|
||||
include_all_commits: parseBoolean(include_all_commits),
|
||||
line_height,
|
||||
title_color,
|
||||
icon_color,
|
||||
|
||||
+5
-4
@@ -4,9 +4,10 @@ const {
|
||||
parseBoolean,
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
} = require("../src/utils");
|
||||
const fetchRepo = require("../src/fetchRepo");
|
||||
const renderRepoCard = require("../src/renderRepoCard");
|
||||
logger,
|
||||
} = require("../src/common/utils");
|
||||
const fetchRepo = require("../src/fetchers/repo-fetcher");
|
||||
const renderRepoCard = require("../src/cards/repo-card");
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const {
|
||||
@@ -28,7 +29,7 @@ module.exports = async (req, res) => {
|
||||
try {
|
||||
repoData = await fetchRepo(username, repo);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
logger.error(err);
|
||||
return res.send(renderError(err.message));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
require("dotenv").config();
|
||||
const {
|
||||
renderError,
|
||||
clampValue,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
CONSTANTS,
|
||||
} = require("../src/common/utils");
|
||||
const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher");
|
||||
const renderTopLanguages = require("../src/cards/top-languages-card");
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const {
|
||||
username,
|
||||
hide,
|
||||
hide_title,
|
||||
hide_border,
|
||||
card_width,
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
cache_seconds,
|
||||
layout,
|
||||
} = req.query;
|
||||
let topLangs;
|
||||
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
try {
|
||||
topLangs = await fetchTopLanguages(username);
|
||||
} catch (err) {
|
||||
return res.send(renderError(err.message));
|
||||
}
|
||||
|
||||
const cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.THIRTY_MINUTES, 10),
|
||||
CONSTANTS.THIRTY_MINUTES,
|
||||
CONSTANTS.ONE_DAY
|
||||
);
|
||||
|
||||
res.setHeader("Cache-Control", `public, max-age=${cacheSeconds}`);
|
||||
|
||||
res.send(
|
||||
renderTopLanguages(topLangs, {
|
||||
hide_title: parseBoolean(hide_title),
|
||||
hide_border: parseBoolean(hide_border),
|
||||
card_width: parseInt(card_width, 10),
|
||||
hide: parseArray(hide),
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
layout,
|
||||
})
|
||||
);
|
||||
};
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
codecov:
|
||||
require_ci_to_pass: yes
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 5
|
||||
patch: false
|
||||
@@ -1,27 +1,51 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="Github Readme Stats" />
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">在你的 README 中 获取动态生成的 GitHub 统计信息!</p>
|
||||
<p align="center">在你的 README 中获取动态生成的 GitHub 统计信息!</p>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#demo">查看 Demo</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">报告 bug</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">报告 bug</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">请求增加功能</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">请求增加功能</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">喜欢这个项目?请考虑<a href="https://www.paypal.me/anuraghazra">捐赠</a>来帮助它完善!
|
||||
@@ -30,55 +54,70 @@
|
||||
|
||||
- [GitHub 统计卡片](#GitHub-统计卡片)
|
||||
- [GitHub 更多置顶](#GitHub-更多置顶)
|
||||
- [热门语言卡片](#热门语言卡片)
|
||||
- [主题](#主题)
|
||||
- [自定义](#自定义)
|
||||
- [自己部署](#自己部署)
|
||||
|
||||
# GitHub 统计卡片
|
||||
|
||||
将这行代码复制到你的 markdown 文件中,简单如此!
|
||||
将这行代码复制到你的 markdown 文件中,就是如此简单!
|
||||
|
||||
更改 `?username=` 的值为你的 GitHub 用户名。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
_Note: 排名基于用户的统计信息计算得出,详见 [src/calculateRank.js](./src/calculateRank.js)_
|
||||
_注: 等级基于用户的统计信息计算得出,详见 [src/calculateRank.js](./src/calculateRank.js)_
|
||||
|
||||
### 隐藏个人统计信息
|
||||
### 隐藏个别统计项
|
||||
|
||||
想要隐藏某项统计信息,你可以调用参数 `?hide=`,并调用 你想要隐藏的项目 组成的数组。
|
||||
想要隐藏指定统计信息,你可以调用参数 `?hide=`,其值用 `,` 分隔。
|
||||
|
||||
> 选项:`&hide=["stars","prs","issues","contribs"]`
|
||||
> 选项:`&hide=stars,commits,prs,issues,contribs`
|
||||
|
||||
```md
|
||||

|
||||

|
||||
```
|
||||
|
||||
### 将私人项目贡献添加到总提交计数中
|
||||
|
||||
你可以使用参数 `?count_private=true` 把私人贡献计数添加到总提交计数中。
|
||||
|
||||
_注:如果你是自己部署本项目,私人贡献将会默认被计数,如果不是自己部署,你需要分享你的私人贡献计数。_
|
||||
|
||||
> Options: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### 显示图标
|
||||
|
||||
想要显示图标,你可以调用 `show_icons=true` 参数,如下:
|
||||
如果想要显示图标,你可以调用 `show_icons=true` 参数,如下:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### 主题
|
||||
|
||||
你可以通过现有的主题进行卡片个性化,省去[手动自定义](#自定义)的麻烦。
|
||||
|
||||
调用 `?theme=THEME_NAME` 参数,如下:
|
||||
通过调用 `?theme=THEME_NAME` 参数,像这样:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
#### 所有现有主题:
|
||||
#### 所有现有主题
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="Github Readme Stat Themes" width="600px"/>
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
在 [theme config 文件](./themes/index.js) 中查看更多主题,或者 **贡献新的主题** :D
|
||||
在 [theme config 文件](./themes/index.js) 中查看更多主题,或者你可以 **贡献新的主题** :D
|
||||
|
||||
### 自定义
|
||||
|
||||
@@ -86,51 +125,25 @@ dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontr
|
||||
|
||||
自定义选项:
|
||||
|
||||
| Option | type | description | Stats Card (default) | Repo Card (default) |
|
||||
| ----------- | --------- | ------------------------------------ | -------------------- | ------------------- |
|
||||
| title_color | hex color | 标题颜色 | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | 字体颜色 | 333 | 333 |
|
||||
| icon_color | hex color | 图标颜色 | 4c71f2 | 586069 |
|
||||
| bg_color | hex color | 卡片背景颜色 | FFFEFE | FFFEFE |
|
||||
| line_height | number | 文字行高 | 30 | N/A |
|
||||
| hide_rank | boolean | 隐藏评分等级 | false | N/A |
|
||||
| hide_title | boolean | 隐藏卡片标题 | false | N/A |
|
||||
| hide_border | boolean | 隐藏卡片边框 | false | N/A |
|
||||
| show_owner | boolean | 显示 Repo 卡片所属账户用户名 | N/A | false |
|
||||
| show_icons | boolean | 显示图标 | false | N/A |
|
||||
| theme | string | 设置主题 | 'default' | 'default_repocard' |
|
||||
| Option | type | description | Stats Card (default) | Repo Card (default) | Top Lang Card (default) |
|
||||
| ------------- | --------- | ---------------------------- | -------------------- | ------------------- | ----------------------- |
|
||||
| title_color | hex color | 标题颜色 | 2f80ed | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | 字体颜色 | 333 | 333 | 333 |
|
||||
| icon_color | hex color | 图标颜色 | 4c71f2 | 586069 | 586069 |
|
||||
| bg_color | hex color | 卡片背景颜色 | FFFEFE | FFFEFE | FFFEFE |
|
||||
| line_height | number | 文字行高 | 30 | N/A | N/A |
|
||||
| hide | CSV | 隐藏指定统计项 | undfined | N/A | undefined |
|
||||
| hide_rank | boolean | 隐藏评分等级 | false | N/A | N/A |
|
||||
| hide_title | boolean | 隐藏卡片标题 | false | N/A | false |
|
||||
| hide_border | boolean | 隐藏卡片边框 | false | N/A | N/A |
|
||||
| show_owner | boolean | 显示 Repo 卡片所属账户用户名 | N/A | false | N/A |
|
||||
| show_icons | boolean | 显示图标 | false | N/A | N/A |
|
||||
| theme | string | 设置主题 | 'default' | 'default_repocard' | 'default' |
|
||||
| cache_seconds | number | 手动设置自定义缓存控制 | 1800 | 1800 | 1800 |
|
||||
| count_private | boolean | 统计私人贡献计数 | false | N/A | N/A |
|
||||
| layout | string | 布局方式 | N/A | N/A | 'default' |
|
||||
|
||||
---
|
||||
|
||||
### Demo
|
||||
|
||||
- 默认
|
||||
|
||||

|
||||
|
||||
- 隐藏特定数据
|
||||
|
||||

|
||||
|
||||
- 显示图标
|
||||
|
||||

|
||||
|
||||
- 主题
|
||||
|
||||
从 [默认主题](#主题) 中进行选择
|
||||
|
||||

|
||||
|
||||
- 自定义添加卡片
|
||||
|
||||

|
||||
|
||||
- 自定义 Repo 卡片
|
||||
|
||||

|
||||
|
||||
---
|
||||
> 注意缓存:Repo 卡片默认缓存 30 分钟,如果 fork 数和 star 数小于 1k ,则默认为 2 小时。缓存被限制为最少 30 分钟,最长 24 小时。
|
||||
|
||||
# GitHub 更多置顶
|
||||
|
||||
@@ -156,6 +169,82 @@ Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# 热门语言卡片
|
||||
|
||||
热门语言卡片显示了 GitHub 用户常用的编程语言。
|
||||
|
||||
_注意:热门语言并不表示我的技能水平或类似的水平,它是用户在 GitHub 上拥有最多代码的一项指标,它是 github-readme-stats 的新功能_
|
||||
|
||||
### 使用细则
|
||||
|
||||
将此代码复制粘贴到您的`README.md`文件中,并修改链接。
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 隐藏特定语言
|
||||
|
||||
可以使用`?hide=语言1,语言2`参数来隐藏指定的语言。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 紧凑的语言卡片布局
|
||||
|
||||
你可以使用 `&layout=compact` 参数来改变卡片的样式。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- 紧凑布局
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### 全部 Demo
|
||||
|
||||
- 默认
|
||||
|
||||

|
||||
|
||||
- 隐藏特定数据
|
||||
|
||||

|
||||
|
||||
- 显示图标
|
||||
|
||||

|
||||
|
||||
- 主题
|
||||
|
||||
从 [默认主题](#主题) 中进行选择
|
||||
|
||||

|
||||
|
||||
- 自定义统计卡片
|
||||
|
||||

|
||||
|
||||
- 自定义代码库卡片
|
||||
|
||||

|
||||
|
||||
- 热门语言
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### 提示 (对齐 Repo 卡片)
|
||||
|
||||
你通常无法将图片靠边显示。为此,您可以使用以下方法:
|
||||
@@ -174,7 +263,7 @@ Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
因为 GitHub 的 API 每个小时只允许 5 千次请求,我的 `https://github-readme-stats.vercel.app/api` 很有可能会触发限制
|
||||
如果你将其托管在自己的 Vercel 服务器上,那么你就不必为此担心。点击 deploy 按钮来开始你的部署!
|
||||
|
||||
注意: 从 [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) 开始,我们应该能够处理超过 5千 的请求,并且不会出现宕机问题 :D
|
||||
注意: 从 [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) 开始,我们应该能够处理超过 5 千 的请求,并且不会出现宕机问题 :D
|
||||
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
@@ -196,6 +285,7 @@ Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
1. 选择 root 并将所有内容保持不变,并且只需添加名为 PAT_1 的环境变量(如图所示),其中将包含一个个人访问令牌(PAT),你可以在[这里](https://github.com/settings/tokens/new)轻松创建(保留默认,并且只需要命名下,名字随便)
|
||||

|
||||
1. 点击 deploy,这就完成了,查看你的域名就可使用 API 了!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: 支持这个项目
|
||||
@@ -0,0 +1,274 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">Zeige dynamisch generierte GitHub-Statistiken in deinen Readmes!</p>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">Du magst das Projekt? Wie wäre es mit einer kleinen <a href="https://www.paypal.me/anuraghazra">Spende</a> um es weiterhin am Leben zu erhalten?
|
||||
|
||||
# Funktionalitäten
|
||||
|
||||
- [GitHub Stats Card](#github-stats-card)
|
||||
- [GitHub Extra Pins](#github-extra-pins)
|
||||
- [Top Programmiersprachen Card](#top-programmiersprachen-card)
|
||||
- [Erscheinungsbild/Themes](#erscheinungsbildthemes)
|
||||
- [Anpassungen](#anpassungenpersonalisierung)
|
||||
- [Selber betreiben](#betreibe-es-auf-deiner-eigenen-vercel-instanz)
|
||||
|
||||
# GitHub Stats Card
|
||||
|
||||
Kopiere einfach folgendes in dein Markdown und das wars. Echt simpel!
|
||||
|
||||
Passe den Wert des URL-Paramters `?username=` so an, dass dort dein GitHub Username steht.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
_Hinweis: Die Berechnung des Ranges basiert auf den jeweiligen Benutzerstatistiken, siehe [src/calculateRank.js](./src/calculateRank.js)_
|
||||
|
||||
### Verbergen individueller Statistiken
|
||||
|
||||
Um eine spezifische Statistik auszublenden, kann dem Query-Parameter `?hide=` ein Array an Dingen die nicht angezeigt werden sollen übergeben werden.
|
||||
|
||||
> Optionen: `&hide=["stars","commits","prs","issues","contribs"]`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Icons anzeigen
|
||||
|
||||
Um Icons anzuzeigen kann der URL-Paramter `show_icons=true` wie folgt verwendet werden:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Erscheinungsbild/Themes
|
||||
|
||||
Mithilfe der eingebauten Themes kann das Aussehen der Karten verändern werden ohne manuelle Anpassungen vornehmen zu müssen.
|
||||
|
||||
Benutze den `?theme=THEME_NAME`-Parameter wie folgt :-
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
#### Alle eingebauten Themes :-
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
Du kannst dir eine Vorschau [aller verfügbaren Themes](./themes/README.md) ansehen oder die [theme config Datei](./themes/index.js) auschecken.
|
||||
Außerdem **kannst du neue Themes beisteuern** wenn du möchtest, contributions sind gern gesehen :D
|
||||
|
||||
### Anpassungen/Personalisierung
|
||||
|
||||
Du kannst das Erscheinungsbild deiner `Stats Card` oder `Repo Card`, mithilfe von URL-Parametern, nach deinen Vorlieben anpassen.
|
||||
|
||||
Anpassungsoptionen:
|
||||
|
||||
| Option | Type | Beschreibung | Statistiken (default) | Repo (default) | Top Programmiersprachen (default) |
|
||||
| ---------------- | --------- | ---------------------------------------------------- | --------------------- | ------------------ | --------------------------------- |
|
||||
| title_color | hex color | Titelfarbe | 2f80ed | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | Textkörperfarbe | 333 | 333 | 333 |
|
||||
| icon_color | hex color | Iconfarbe | 4c71f2 | 586069 | 586069 |
|
||||
| bg_color | hex color | Hintergrundfarbe | FFFEFE | FFFEFE | FFFEFE |
|
||||
| line_height | number | kontrolliert die Zeilenhöhe zwischen dem Text | 30 | N/A | N/A |
|
||||
| hide_rank | boolean | blendet das Ranking aus | false | N/A | N/A |
|
||||
| hide_title | boolean | blendet den Statistik-Titel aus | false | N/A | false |
|
||||
| hide_border | boolean | blendet den Rahmen aus | false | N/A | N/A |
|
||||
| show_owner | boolean | zeigt den Namen des Besitzers in der Repo-Karte | N/A | false | N/A |
|
||||
| show_icons | boolean | zeige Icons an | false | N/A | N/A |
|
||||
| theme | string | setze eingebaute themes | 'default' | 'default_repocard' | 'default' |
|
||||
| cache_seconds | number | manuelles setzen der Cachezeiten | 1800 | 1800 | 1800 |
|
||||
| hide_langs_below | number | verberge Sprachen unter einem bestimmten Schwellwert | N/A | N/A | undefined |
|
||||
|
||||
> Hinweis bzgl. des Caches: Wenn die Anzahl der Forks und Stars geringer als 1Tsd ist, haben die Repo-Cards eine default Cachezeit von 30 Minuten (1800 Sekunden), ansonsten beträgt diese 2 Stunden (7200 Sekunden). Außerdem ist der Cache auf eine Minimum von 30 Minuten und ein Maximum von 24 Stunden begrenzt.
|
||||
|
||||
# GitHub Extra Pins
|
||||
|
||||
GitHub extra pins ermöglicht es, mit Hilfe eines GitHub-Readme-Profiles, mehr als 6 Repositories in deinen Profil anzuzeigen.
|
||||
|
||||
Und Bääm! Du bist nicht mehr auf 6 pinned Repositories limitiert.
|
||||
|
||||
### Benutzung
|
||||
|
||||
Füge diesen Code in deine Readme-Datei ein und passe die Links an.
|
||||
|
||||
Endpunkt: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Beispiele
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
Benutze die [show_owner](#anpassungenpersonalisierung) Variable, um den Usernamen des Repo Eigentümers anzuzeigen.
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# Top Programmiersprachen Card
|
||||
|
||||
Die Top Programmiersprachen Card visualisiert die am meisten benutzten Programmiersprachen eines GitHub-Nutzers.
|
||||
|
||||
_HINWEIS: Die Top Programmiersprachen treffen keine Aussage über persönliche Fähigkeiten oder der gleichen, es ist lediglich eine auf den GitHub-Statistiken des Nutzers basierende Kennzahl welche Programmiersprache wie häufig verwendet wurde._
|
||||
|
||||
### Benutzung
|
||||
|
||||
Füge diesen Code in deine Readme-Datei ein und passe die Links an.
|
||||
|
||||
Endpunkt: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Verberge Programmiersprachen unter einem bestimmten Schwellwert
|
||||
|
||||
Benutze den `?hide_langs_below=NUMBER` URL-Parameter um Programmiersprachen unter einem bestimmten prozentualen Schwellwert auszublenden.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Beispiel
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Alle Beispiele
|
||||
|
||||
- Default
|
||||
|
||||

|
||||
|
||||
- Ausblenden bestimmter Statistiken
|
||||
|
||||

|
||||
|
||||
- Icons anzeigen
|
||||
|
||||

|
||||
|
||||
- Erscheinungsbild/Themes
|
||||
|
||||
Choose from any of the [default themes](#themes)
|
||||
|
||||

|
||||
|
||||
- Stats Card anpassen
|
||||
|
||||

|
||||
|
||||
- Repo Card anpassen
|
||||
|
||||

|
||||
|
||||
- Top Programmiersprachen
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Kleiner Tip (Ausrichten der Repo Cards)
|
||||
|
||||
Üblicherweise ist es in `.md`-Dateien nicht möglich Bilder nebeneinander anzuzeigen. Um dies zu erreichen kann folgender Ansatz gewählt werden:
|
||||
|
||||
```md
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/convoychat">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
|
||||
</a>
|
||||
```
|
||||
|
||||
## Betreibe es auf deiner eigenen Vercel-Instanz
|
||||
|
||||
Da die GitHub API nur 5tsd Aufrufe pro Stunde zulässt, kann es passieren, dass meine `https://github-readme-stats.vercel.app/api` dieses Limit erreicht.
|
||||
Wenn du es auf deinem eigenen Vercel-Server hostest, brauchst du dich darum nicht zu kümmern. Klicke auf den Deploy-Button um loszulegen!
|
||||
|
||||
Hinweis: Seit [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) sollte es möglich sein mehr als 5tsd Aufrufe pro Stunde ohne Downtimes zu verkraften :D
|
||||
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<details>
|
||||
<summary>Anleitung zum Einrichten von Vercel</summary>
|
||||
|
||||
1. Gehe zu [vercel.com](https://vercel.com/)
|
||||
1. Klicke auf `Log in`
|
||||

|
||||
1. Melde dich mit deinem GitHub-account an, indem du `Continue with GitHub` klickst
|
||||

|
||||
1. Verbinde dich mit GitHub und erlaube den Zugriff auf alle Repositories, wenn gefordert
|
||||
1. Forke dieses Repository
|
||||
1. Gehe zurück zu deinem [Vercel dashboard](https://vercel.com/dashboard)
|
||||
1. Klick `Import Project`
|
||||

|
||||
1. Klick `Import Git Repository`
|
||||

|
||||
1. Wähle root und füge eine Umgebungsvariable namens PAT_1 (siehe Abbildung) die als Wert deinen persönlichen Access Token (PAT) hat hinzu, den du einfach [hier](https://github.com/settings/tokens/new) erzeugen kannst (lasse alles wie es ist, vergebe einen beliebigen Namen)
|
||||

|
||||
1. Klicke deploy, und das wars. Besuche deine domains um die API zu benutzen!
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: Unterstütze das Projekt
|
||||
|
||||
Ich versuche alles was ich kann als Open-Source zur Verfügung zu stellen, als auch jedem der Hilfe bei der Benutzung dieses Projektes braucht zu antworten. Natürlich beansprucht sowas Zeit und Du kannst diesen Dienst kostenlos benutzen.
|
||||
|
||||
Dennoch, wenn Du dieses Projekt benutzt und damit zufrieden bist oder mich einfach nur motivieren möchtest weiterhin daran zu arbeiten, gibt es verschiedene Sachen die Du machen kannst:-
|
||||
|
||||
- Erwähne und verlinke das Projekt in deiner Readme wenn du es benutzt :D
|
||||
- Geb dem Projekt einen Stern hier auf GitHub und teile es :rocket:
|
||||
- [](https://www.paypal.me/anuraghazra) - Du kannst einmalige Spenden via PayPal tätigen. Ich kaufe mir wahrscheinlich einen ~~Kaffee~~ Tee davon. :tea:
|
||||
|
||||
Vielen Dank! :heart:
|
||||
|
||||
---
|
||||
|
||||
Mitarbeit an dem Projekt is immer Willkommen! <3
|
||||
|
||||
Gebaut mit :heart: und JavaScript.
|
||||
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="Github Readme Stats" />
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">¡Obtén tus estadísticas de GitHub generadas dinámicamente en tu README!</p>
|
||||
</p>
|
||||
@@ -14,14 +14,35 @@
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#ejemplo">Ve un ejemplo</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">Reporta un bug</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Reporta un bug</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">Solicita una mejora</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Solicita una mejora</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">¿Te gusta este proyecto? ¡Por favor considera <a href="https://www.paypal.me/anuraghazra">donar</a> para ayudar a mejorarlo!
|
||||
@@ -29,7 +50,7 @@
|
||||
# Características
|
||||
|
||||
- [Tarjeta de estadísticas de GitHub](#tarjeta-de-estadísticas-de-github)
|
||||
- [Pins extra de GitHub](#pins-extra-de-github)
|
||||
- [Pins adicionales de GitHub](#pines-adicionales-de-github)
|
||||
- [Temas](#temas)
|
||||
- [Personalización](#personalización)
|
||||
- [Despliega por tu cuenta](#despliega-tu-propia-instancia-de-vercel)
|
||||
@@ -56,6 +77,18 @@ Para ocultar alguna estadística específica, puedes utilizar el parámetro `?hi
|
||||

|
||||
```
|
||||
|
||||
### Agregar contribuciones privadas al total de commits contados
|
||||
|
||||
Puede agregar el recuento de todas sus contribuciones privadas al recuento total de confirmaciones utilizando el parámetro de consulta `?count_private=true`.
|
||||
|
||||
_Nota: Si está desplegando este proyecto usted mismo, las contribuciones privadas se contarán de manera predeterminada; de lo contrario, deberá elegir compartir sus recuentos de contribuciones privadas._
|
||||
|
||||
> Opciones: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Mostrar íconos
|
||||
|
||||
Para habilitar los íconos, puedes utilizar `show_icons=true` como parámetro, de esta manera:
|
||||
@@ -74,75 +107,65 @@ Utiliza el parámetro `?theme=THEME_NAME`, de esta manera:
|
||||

|
||||
```
|
||||
|
||||
#### Todos los temas incorporados:
|
||||
#### Todos los temas incorporados
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="Github Readme Stat Themes" width="600px"/>
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
Puedes ver una vista previa de [todos los temas disponibles](./themes/README.md) o ver el [archivo de configuración](./themes/index.js) del tema y también **puedes contribuir con nuevos temas** si lo deseas: D
|
||||
Puedes ver una vista previa de [todos los temas disponibles](./themes/README.md) o ver el [archivo de configuración](./themes/index.js) del tema y también **puedes contribuir con nuevos temas** si lo deseas :D
|
||||
|
||||
### Personalización
|
||||
|
||||
Puedes personalizar el aspecto de tu `Stats Card` o `Repo Card` de la manera que desees con los parámetros URL.
|
||||
|
||||
Opciones de personalización:
|
||||
#### Opciones Comunes:
|
||||
|
||||
| Option | type | description | Stats Card (default) | Repo Card (default) |
|
||||
| ----------- | --------- | ----------------------------- | -------------------- | ------------------- |
|
||||
| title_color | hex color | color del título | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | color del contenido | 333 | 333 |
|
||||
| icon_color | hex color | color del ícono | 4c71f2 | 586069 |
|
||||
| bg_color | hex color | color de fondo | FFFEFE | FFFEFE |
|
||||
| line_height | number | controla el line_height | 30 | N/A |
|
||||
| hide_rank | boolean | oculta la clasificación | false | N/A |
|
||||
| hide_title | boolean | oculta el título | false | N/A |
|
||||
| hide_border | boolean | oculta el borde | false | N/A |
|
||||
| show_owner | boolean | muestra el propietario | N/A | false |
|
||||
| show_icons | boolean | muestra los íconos | false | N/A |
|
||||
| theme | string | establece un tema incorporado | 'default' | 'default_repocard' |
|
||||
- `title_color` - Color del título _(hex color)_
|
||||
- `text_color` - Color del contenido _(hex color)_
|
||||
- `icon_color` - Color de icono si esta disponible _(hex color)_
|
||||
- `bg_color` - Color de fondo _(hex color)_
|
||||
- `theme` - Nombre del tema, elige uno de [todos los temas disponible ](./themes/README.md)
|
||||
- `cache_seconds` - Cache _(min: 1800, max: 86400)_
|
||||
|
||||
> Nota sobre la caché: las tarjetas de Repo tienen un caché predeterminado de 30 minutos (1800 segundos) si el recuento forks y el recuento de estrellas es inferior a 1k; de lo contrario, son 2 horas (7200). También tenga en cuenta que el caché está sujeto a un mínimo de 30 minutos y un máximo de 24 horas
|
||||
|
||||
#### Opciones exclusivas de la tarjeta de estadísticas:
|
||||
|
||||
- `hide` - Ocultar los elementos especificados de las estadísticas _ (valores separados por comas) _
|
||||
- `hide_title` - _(boolean)_
|
||||
- `hide_rank` - _(boolean)_
|
||||
- `show_icons` - _(boolean)_
|
||||
- `include_all_commits` - Cuente los commits totales en lugar de solo los commits del año actual _(boolean)_
|
||||
- `count_private` - Cuenta los commits privadas _(boolean)_
|
||||
- `line_height` - Establece el alto de línea entre texto _(number)_
|
||||
|
||||
#### Opciones exclusivas de la tarjeta Repo:
|
||||
|
||||
- `show_owner` - Mostrar el nombre del propietario del repositorio _(boolean)_
|
||||
|
||||
#### Opciones exclusivas de la tarjeta de lenguajes:
|
||||
|
||||
- `hide` - Ocultar los lenguajes especificados de la tarjeta _(valores separados por comas)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `layout` - Cambiar entre dos diseños disponibles `default` & `compact`
|
||||
- `card_width` - Establecer el ancho de la tarjeta manualmente _(number)_
|
||||
|
||||
> :warning: **Importante:**
|
||||
> Los nombres de los idiomas deben tener escape de uri, como se especifica en [Código porciento](https://es.wikipedia.org/wiki/C%C3%B3digo_porciento)
|
||||
> (es decir: `c++` debería convertirse en `c%2B%2B`,`jupyter notebook` debería convertirse en `jupyter%20notebook`, etc.)
|
||||
|
||||
---
|
||||
|
||||
### Ejemplo
|
||||
# Pines adicionales de GitHub
|
||||
|
||||
- Predeterminado
|
||||
Los pines adicionales de GitHub le permiten fijar más de 6 repositorios en su perfil utilizando un readme de perfil de GitHub.
|
||||
|
||||

|
||||
|
||||
- Ocultando estadísticas específicas
|
||||
|
||||

|
||||
|
||||
- Mostrando íconos
|
||||
|
||||

|
||||
|
||||
- Temas
|
||||
|
||||
Elige uno de los [temas predeterminados](#temas)
|
||||
|
||||

|
||||
|
||||
- Personalizando la tarjeta de estadísticas
|
||||
|
||||

|
||||
|
||||
- Personalizando la tarjeta de repositorio
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# Pins extra de GitHub
|
||||
|
||||
Los pins extra de GitHub te permiten anclar más de 6 repositorios en tu perfil utilizando el archivo README.md.
|
||||
|
||||
¡Bien! Ya no estás limitado a 6 repositorios anclados.
|
||||
Yey! Ya no está limitado a 6 repositorios anclados.
|
||||
|
||||
### Utilización
|
||||
|
||||
Copia y pega este código en tu README.md y cambia los links.
|
||||
Copie y pegue este código en su archivo Léame y cambie los enlaces.
|
||||
|
||||
Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
@@ -158,9 +181,89 @@ Utiliza la variable [show_owner](#customización) para incluir el nombre de usua
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
### Pequeño consejo (alinear las tarjetas de repositorios)
|
||||
# Tarjeta de lenguajes principales
|
||||
|
||||
Usualmente no serías capaz de alinear las imágenes una al lado de otra. Para lograrlo, puedes realizar esto:
|
||||
La tarjeta de lenguajes principales muestra los lenguajes principales del usuario de github que se han utilizado principalmente.
|
||||
|
||||
_NOTA: los lenguajes principales no indican mi nivel de habilidad o algo así, es una métrica de github de los lenguajes que tengo más código en github, es una nueva característica de github-readme-stats_
|
||||
|
||||
### Utilización
|
||||
|
||||
Copie y pegue este código en su readme y cambie los enlaces.
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Ocultar lenguajes individuales
|
||||
|
||||
Puede usar el parámetro `? Hide = language1, language2` para ocultar lenguajes individuales.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Diseño de tarjeta de lenguaje compacta
|
||||
|
||||
Puede usar la opción `& layout = compact` para cambiar el diseño de la tarjeta.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Ejemplo
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- Diseño compacto
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Todos los ejemplos
|
||||
|
||||
- Por Defecto
|
||||
|
||||

|
||||
|
||||
- Ocultar estadísticas específicas
|
||||
|
||||

|
||||
|
||||
- Mostrando iconos
|
||||
|
||||

|
||||
|
||||
- Incluir todos los Commits
|
||||
|
||||

|
||||
|
||||
- Temas
|
||||
|
||||
Elija entre cualquiera de los [temas predeterminados](#themes)
|
||||
|
||||

|
||||
|
||||
- Personalizando tarjeta de estadísticas
|
||||
|
||||

|
||||
|
||||
- Personalizar la tarjeta de repositorio
|
||||
|
||||

|
||||
|
||||
- Lenguajes Principales
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Consejo rápido (alinee las tarjetas de repositorio)
|
||||
|
||||
Por lo general, no podrá diseñar las imágenes una al lado de la otra. Para hacerlo, puede usar este enfoque:
|
||||
|
||||
```md
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats">
|
||||
@@ -195,8 +298,9 @@ Nota: debido a esto [#58](https://github.com/anuraghazra/github-readme-stats/pul
|
||||
1. Selecciona `Import Git Repository`
|
||||

|
||||
1. Selecciona "root" y matén todo como está, simplemente añade tu variable de entorno llamada PAT_1 (como se muestra), la cual contendrá un token de acceso personal (PAT), el cual puedes crear fácilmente [aquí](https://github.com/settings/tokens/new) (mantén todo como está, simplemente asígnale un nombre, puede ser cualquiera que desees)
|
||||

|
||||

|
||||
1. Clickea "Deploy" y ya está listo. ¡Ve tus dominios para usar la API!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: Apoya al proyecto
|
||||
@@ -0,0 +1,308 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">あなたのREADMEに動的に生成されたGitHubの統計情報を載せましょう!</p>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#demo">View Demo</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Report Bug</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Request Feature</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">このプロジェクトを気に入っていただけましたか?<br>もしよろしければ、プロジェクトのさらなる改善のために<a href="https://www.paypal.me/anuraghazra">寄付</a>を検討して頂けると嬉しいです!</p>
|
||||
|
||||
# Features
|
||||
|
||||
- [GitHub Stats Card](#github-stats-card)
|
||||
- [GitHub Extra Pins](#github-extra-pins)
|
||||
- [Top Languages Card](#top-languages-card)
|
||||
- [Themes](#themes)
|
||||
- [Customization](#customization)
|
||||
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
||||
|
||||
# GitHub Stats Card
|
||||
|
||||
以下の構文をコピーして、あなたの Markdown ファイルに貼り付けるだけです。
|
||||
簡単ですね!
|
||||
|
||||
`?username=` の値は、あなたの GitHub アカウントのユーザー名に変更してください。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
_Note: カードに表示されるランクはユーザの統計情報に基づいて計算されています。詳しくは、[src/calculateRank.js](./src/calculateRank.js)を見てください。_
|
||||
|
||||
### Hiding individual stats
|
||||
|
||||
クエリパラメータ `?hide=` にカンマ区切りの値を渡すことで、特定の統計情報を隠すことができます。
|
||||
|
||||
> Options: `&hide=stars,commits,prs,issues,contribs`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Adding private contributions count to total commits count
|
||||
|
||||
クエリパラメータ `?count_private=true` を使用することで、private contributions の数をコミット総数に追加することができます。
|
||||
|
||||
_Note: このプロジェクトを自分でデプロイしている場合、デフォルトでは非公開の貢献がカウントされます。_
|
||||
|
||||
> Options: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Showing icons
|
||||
|
||||
クエリパラメータ `?show_icons=true` を使用することで、アイコンが表示が有効になります。
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Themes
|
||||
|
||||
内蔵されているテーマを使用することで、任意の[手動のカスタマイズ](#customization)を行うことなく、カードの外観をカスタマイズすることができます。
|
||||
|
||||
`?theme=THEME_NAME` は以下のように使います。
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
#### All inbuilt themes :-
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
用意されている全てのテーマの[プレビュー](./themes/README.md)や[設定ファイル](./themes/index.js)を見ることができます。もしよろしければ、**新しいテーマを投稿してみてください** (´∀` )
|
||||
|
||||
### Customization
|
||||
|
||||
`Stats Card` や `Repo Card` の外観を URL パラメーターを使って好きなようにカスタマイズすることができます。
|
||||
|
||||
Customization Options:
|
||||
|
||||
| Option | type | description | Stats Card (default) | Repo Card (default) | Top Lang Card (default) |
|
||||
| ------------- | --------- | -------------------------------------------- | -------------------- | ------------------- | ----------------------- |
|
||||
| title_color | hex color | タイトルの色 | 2f80ed | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | 文字の色 | 333 | 333 | 333 |
|
||||
| icon_color | hex color | アイコンの色 | 4c71f2 | 586069 | 586069 |
|
||||
| bg_color | hex color | カードの背景色 | FFFEFE | FFFEFE | FFFEFE |
|
||||
| line_height | number | 字間距離 | 30 | N/A | N/A |
|
||||
| hide | CSV | 項目の非表示 | undefined | N/A | undefined |
|
||||
| hide_rank | boolean | ranking の非表示 | false | N/A | N/A |
|
||||
| hide_title | boolean | タイトルの非表示 | false | N/A | false |
|
||||
| hide_border | boolean | 枠線の非表示 | false | N/A | N/A |
|
||||
| show_owner | boolean | オーナー名の表示 | N/A | false | N/A |
|
||||
| show_icons | boolean | アイコンの表示 | false | N/A | N/A |
|
||||
| theme | string | 用意されているテーマ | 'default' | 'default_repocard' | 'default' |
|
||||
| cache_seconds | number | キャッシュコントロール | 1800 | 1800 | 1800 |
|
||||
| count_private | boolean | private contributions 数をコミット総数に追加 | false | N/A | N/A |
|
||||
| layout | string | レイアウトのオプション選択 | N/A | N/A | 'default' |
|
||||
|
||||
> キャッシュに関する注意点: Repo cards のデフォルトのキャッシュは、フォーク数とスター数が 1k 未満の場合は 30 分(1800 秒) で、それ以外の場合は 2 時間(7200) です。また、キャッシュは最低でも 30 分、最大でも 24 時間に制限されていることに注意してください。
|
||||
|
||||
# GitHub Extra Pins
|
||||
|
||||
GitHub extra pins を使うと、GitHub の readme プロフィールを使って、自分のプロフィールに 6 つ以上のリポジトリをピン留めすることができます。
|
||||
|
||||
イェーイ! もはや 6 つのピン留めされたリポジトリに制限されることはありません。
|
||||
|
||||
### Usage
|
||||
|
||||
以下のコードをあなたの readme にコピー & ペーストし、リンクを変更してください。
|
||||
|
||||
Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
リポジトリのオーナーのユーザー名を含める場合は、show_owner 変数を使用します。
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# Top Languages Card
|
||||
|
||||
Top languages card には、その GitHub ユーザーが最も利用している Top languages が表示されます。
|
||||
|
||||
_NOTE: Top languages は、ユーザのスキルレベルを示すものではなく、GitHub 上でどの言語で最も多くのコードを書いているかを示す GitHub の指標です。_
|
||||
|
||||
### Usage
|
||||
|
||||
以下のコードをあなたの readme にコピー & ペーストし、リンクを変更してください。
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Hide individual languages
|
||||
|
||||
クエリパラメータ `?hide=language1,language2` 使用することで、個々の言語を非表示にすることができます。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Compact Language Card Layout
|
||||
|
||||
クエリパラメータ `&layout=compact` を使用することで、カードのデザインを変更することができます。
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- Compact layout
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### All Demos
|
||||
|
||||
- Default
|
||||
|
||||

|
||||
|
||||
- Hiding specific stats
|
||||
|
||||

|
||||
|
||||
- Showing icons
|
||||
|
||||

|
||||
|
||||
- Themes
|
||||
|
||||
任意の[テーマ](#themes)を選択できます。
|
||||
|
||||

|
||||
|
||||
- Customizing stats card
|
||||
|
||||

|
||||
|
||||
- Customizing repo card
|
||||
|
||||

|
||||
|
||||
- Top languages
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Quick Tip (Align The Repo Cards)
|
||||
|
||||
通常、画像を並べてレイアウトすることはできません。そのためには、次のような方法があります。
|
||||
|
||||
```md
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/convoychat">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
|
||||
</a>
|
||||
```
|
||||
|
||||
## Deploy on your own Vercel instance
|
||||
|
||||
GitHub API は 1 時間あたり 5k リクエストしか受け付けていないので、私の `https://github-readme-stats.vercel.app/api` がレートリミッターを超えてしまう可能性があります。自分の Vercel サーバーでホストしているのであれば、何も心配する必要はありません。デプロイボタンをクリックして始めましょう!
|
||||
|
||||
NOTE: [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) 以降は 5k 以上のリクエストに対応できるようになり、ダウンタイムの問題もなくなりました (´∀` )
|
||||
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<details>
|
||||
<summary>Vercelの設定ガイド</summary>
|
||||
|
||||
1. [vercel.com](https://vercel.com/)に行きます。
|
||||
1. `Log in`をクリックします。
|
||||

|
||||
1. `Continue with GitHub` を押して GitHub にサインインします。
|
||||

|
||||
1. GitHub にサインインし、すべてのリポジトリへのアクセスを許可します。
|
||||
1. このリポジトリをフォークします。
|
||||
1. [Vercel dashboard](https://vercel.com/dashboard)に戻ります。
|
||||
1. `Import Project` を選択します。
|
||||

|
||||
1. `Import Git Repository` を選択します。
|
||||

|
||||
1. root を選択して、すべてをそのままにしておき、PAT_1 という名前の環境変数を(下図のように)追加します。これには個人アクセストークン (PAT) が含まれており、[ここ](https://github.com/settings/tokens/new)で簡単に作成することができます (すべてをそのままにしておいて、何かに名前を付けてください。)
|
||||

|
||||
1. デプロイをクリックすれば完了です。API を使用するためにあなたのドメインを参照してください!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: Support the project
|
||||
|
||||
私はできる限りのことをオープンソースで行い、これらのプロジェクトを利用して支援を必要としている皆さんに返信するようにしています。もちろんです。
|
||||
これは時間がかかります。無料でご利用いただけます。
|
||||
|
||||
しかし、もしあなたがこのプロジェクトを使っていて、それに満足しているのであれば、あるいは単に私にものを作り続けることを奨励したいのであれば、いくつかの方法があります。
|
||||
|
||||
- あなたの readme で github-readme-stats を使用して適切なクレジットを付与し、それにリンクします (´∀` )
|
||||
- 主演とプロジェクトの共有 :rocket:
|
||||
- [](https://www.paypal.me/anuraghazra) - PayPal を介して 1 回限りの寄付を行うことができます。私はおそらく ~~コーヒー~~ お茶買うでしょう。 :tea:
|
||||
|
||||
Thanks! :heart:
|
||||
|
||||
---
|
||||
|
||||
Contributions を歓迎します! <3
|
||||
|
||||
このプロジェクトは :heart: と JavaScript で作られています。
|
||||
@@ -0,0 +1,332 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">동적으로 생성된 Github의 통계를 여러분의 README에 올려보세요!</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#demo">View Demo</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Report Bug</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Request Feature</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">이 프로젝트가 마음에 드나요? 괜찮으시다면 더 나은 개선을 위해 <a href="https://www.paypal.me/anuraghazra">기부</a>를 고려해주세요!
|
||||
|
||||
# Features
|
||||
|
||||
- [GitHub Stats Card](#github-stats-card)
|
||||
- [GitHub Extra Pins](#github-extra-pins)
|
||||
- [상위 언어 카드](#상위-언어-카드)
|
||||
- [테마](#테마)
|
||||
- [사용자정의](#사용자정의)
|
||||
- [직접 배포하기](#자체-Vercel-인스턴스에-배포하기)
|
||||
|
||||
# GitHub Stats Card
|
||||
|
||||
아래 코드를 복사해서 당신의 마크다운 파일에 넣으면 됩니다. 간단합니다!
|
||||
|
||||
`?username=` 영역의 값은 당신의 Github 계정의 이름으로 바꿔주세요.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
_참고: 순위는 사용자의 통계를 기반으로 계산됩니다. [src/calculateRank.js](./src/calculateRank.js) 참고_
|
||||
|
||||
### 개별 통계 숨기기
|
||||
|
||||
특정 통계를 숨기려면 콤마로 구분된 값을 `?hide=` 쿼리 파라미터 값으로 나열하면 됩니다.
|
||||
|
||||
> 예시: `&hide=stars,commits,prs,issues,contribs`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### 총 커밋 수에 private 컨트리뷰트 개수 추가하기
|
||||
|
||||
`?count_private=true` 쿼리 파라미터를 사용하면 총 커밋 수에 private 컨트리뷰트 개수를 추가할 수 있습니다.
|
||||
|
||||
\_참고: 이 프로젝트를 직접 배포하는 경우 private 컨트리뷰트는 기본적으로 계산된다. 그렇지 않은 경우 private 컨트리뷰트 개수를 추가하도록 설정해야 합니다.
|
||||
|
||||
_Note: If you are deploying this project yourself, the private contributions will be counted by default otherwise you need to chose to share your private contribution counts._
|
||||
|
||||
> 예시: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### 아이콘 표기
|
||||
|
||||
아이콘을 활성화하려면 다음과 같이 `show_icons=true` 쿼리 파라미터를 사용하세요.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### 테마
|
||||
|
||||
내장된 테마를 사용하여 수동 [사용자정의](#사용자정의)할 필요 없이 카드의 모양을 커스터마이징할 수 있습니다.
|
||||
|
||||
아래와 같이 `?theme=THEME_NAME` 파라미터를 사용하세요. :-
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
#### 모든 내장된 테마 :-
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
[사용 가능한 모든 테마](./themes/README.md)의 미리보기와 [테마 설정 파일](./themes/index.js)을 확인할 수 있습니다. 괜찮으시다면 **새로운 테마를 만드셔서, 코드를 기여** 해주세요 :D
|
||||
|
||||
### 사용자정의
|
||||
|
||||
URL 파라미터를 사용하여 원하는대로 `Stats Card` 또는 `Repo Card` 모양을 사용자 정의할 수 있습니다.
|
||||
|
||||
#### Common Options:
|
||||
|
||||
- `title_color` - 카드 제목 색상 _(hex color)_
|
||||
- `text_color` - 본문 글자 색상 _(hex color)_
|
||||
- `icon_color` - 아이콘 색상(활성화된 경우) _(hex color)_
|
||||
- `bg_color` - 카드 배경 색상 _(hex color)_
|
||||
- `theme` - 테마의 이름, [사용 가능한 모든 테마](./themes/README.md)에서 선택
|
||||
- `cache_seconds` - 캐시 헤더를 수동으로 설정 _(min: 1800, max: 86400)_
|
||||
|
||||
> 캐시 관련 참고: Repo 카드는 fork 개수와 star 카운트가 1천 개 미만인 경우 기본 캐시가 30분(1800초)이고, 그렇지 않은 경우 2시간(7200초) 입니다. 또한 캐시는 최소 30분 및 최대 24시간으로 고정됩니다.
|
||||
|
||||
#### Stats Card의 제외 옵션:
|
||||
|
||||
- `hide` - 통계에서 특정 항목을 제외한다. _(콤마로 구분된 값)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `hide_rank` - _(boolean)_
|
||||
- `show_icons` - _(boolean)_
|
||||
- `include_all_commits` - 현재 년도 대신 전체 커밋 개수 카운트 _(boolean)_
|
||||
- `count_private` - private 커밋도 카운트 _(boolean)_
|
||||
- `line_height` - 글자 사이의 line-height 값 설정(자간) _(number)_
|
||||
|
||||
#### Repo Card의 제외 옵션:
|
||||
|
||||
- `show_owner` - repo의 소유자 이름 표기 _(boolean)_
|
||||
|
||||
#### Language Card의 제외 옵션:
|
||||
|
||||
- `hide` - 카드에서 특정 언어 숨기기 _(콤마로 구분된 값)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `layout` - `default` & `compact` 레이아웃 간의 전환
|
||||
- `card_width` - 카드의 너비를 수동으로 설정 _(숫자)_
|
||||
|
||||
> :warning: **중요:**
|
||||
> 언어 이름은 URI 이스케이프 처리되어야 합니다. [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)를 참고하세요.
|
||||
> (i.e: `c++` 는 `c%2B%2B`, `jupyter notebook` 는 `jupyter%20notebook`, etc.)
|
||||
|
||||
---
|
||||
|
||||
# GitHub Extra Pins
|
||||
|
||||
GitHub extra pins을 사용하면 Github readme 프로필에 6개 이상의 저장소를 고정할 수 있습니다.
|
||||
그렇습니다! 더 이상 고정된 6개의 저장소로 제한되지 않습니다.
|
||||
|
||||
GitHub extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile.
|
||||
|
||||
Yey! You are no longer limited to 6 pinned repositories.
|
||||
|
||||
### 사용법
|
||||
|
||||
이 코드를 복사해서 readme에 넣고 링크를 변경해주세요.
|
||||
|
||||
Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 데모
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
[show_owner](#사용자정의) 값을 사용하여 저장소 소유자 이름을 포함할 수 있습니다.
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# 상위 언어 카드
|
||||
|
||||
상위 언어 카드는 그 Github 사용자가 가장 많이 사용하고 있는 언어가 표시됩니다.
|
||||
|
||||
_참고: Top languages는 사용자의 기술 수준을 나타내는 것이 아니라 GitHub에서 어떤 언어로 코드를 많이 작성하는지 나타내는 Github 지표이며 github-readme-stats의 새로운 기능입니다._
|
||||
|
||||
### 사용법
|
||||
|
||||
이 코드를 복사해서 readme에 넣고 링크를 변경해주세요.
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 개별 언어 숨기기
|
||||
|
||||
`?hide=language1,language2` 파라미터를 사용하여 특정 언어를 숨길 수 있습니다.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 컴팩트 언어 카드 레이아웃
|
||||
|
||||
`&layout=compact` 파라미터를 사용하여 카드의 디자인을 변경할 수 있습니다.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### 데모
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- 컴팩트 레이아웃
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### 모든 데모
|
||||
|
||||
- 기본 설정
|
||||
|
||||

|
||||
|
||||
- 특정 통계 숨김
|
||||
|
||||

|
||||
|
||||
- 아이콘 표기
|
||||
|
||||

|
||||
|
||||
- 모든 커밋 표기
|
||||
|
||||

|
||||
|
||||
- 테마
|
||||
|
||||
[default themes](#테마)에서 선택
|
||||
|
||||

|
||||
|
||||
- Stats 카드 사용자 정의
|
||||
|
||||

|
||||
|
||||
- Repo 카드 사용자 정의
|
||||
|
||||

|
||||
|
||||
- 상위 언어
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### 꿀팁 (Repo 카드 정렬)
|
||||
|
||||
일반적으로 사진을 나란히 배치할 수 없습니다. 따라서 다음과 같은 방법을 사용할 수 있습니다.
|
||||
|
||||
```md
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/convoychat">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
|
||||
</a>
|
||||
```
|
||||
|
||||
## 자체 Vercel 인스턴스에 배포하기
|
||||
|
||||
Github API는 시간당 5k 요청만을 허용하기 때문에, 이 `https://github-readme-stats.vercel.app/api`이 제한에 도달할 수 있습니다.
|
||||
물론 자신의 Vercel 서버에서 호스팅하는 것이라면 아무것도 걱정할 필요가 없습니다. 시작하려면 배포 버튼을 클릭하세요!
|
||||
|
||||
참고: [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) 이슈 이후로는 5k 이상의 요청을 처리할 수 있게 되어, 다운 타임의 문제가 발생하지 않습니다 :D
|
||||
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<details>
|
||||
<summary><b> Guide on setting up Vercel 🔨 </b></summary>
|
||||
|
||||
1. [vercel.com](https://vercel.com/)에 접속하세요.
|
||||
1. `Log in` 클릭합니다.
|
||||

|
||||
1. `Continue with GitHub` 를 클릭하여 Github로 로그인하세요.
|
||||

|
||||
1. Github에 로그인하고 메시지가 표시되면 모든 저장소에 대한 접근을 허용합니다.
|
||||
1. 이 저장소를 fork 합니다.
|
||||
1. [Vercel dashboard](https://vercel.com/dashboard)로 돌아갑니다.
|
||||
1. `Import Project` 를 선택합니다.
|
||||

|
||||
1. `Import Git Repository` 를 선택합니다.
|
||||

|
||||
1. 루트를 선택한 다음에 다른 것들은 그대로 두고 PAT_1 이라는 환경 변수(아래처럼)를 추가합니다. 여기에는 개인 접근 토큰(PAT)이 포함되며, 토큰은 [여기](https://github.com/settings/tokens/new)에서 쉽게 만들 수 있습니다. (모두 그대로 두고, 이름만 지정하면 됩니다.)
|
||||

|
||||
1. 배포를 클릭하면 완료됩니다. API를 사용하기 위해 당신의 도메인을 참조하세요!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: 프로젝트 후원
|
||||
|
||||
저는 제가 할 수 있는 거의 모든 것을 오픈소스로 제공하고, 이 프로젝트를 사용하면서 도움이 필요한 분들에게 회신하려고 합니다.
|
||||
분명한 것은, 이는 시간이 걸리는 일입니다. 하지만 여러분은 이 서비스를 무료로 사용할 수 있습니다.
|
||||
|
||||
하지만 여러분이 이 프로젝트를 사용하고 거기에 만족한다면, 아니면 제가 하는 활동을 격려하고자 싶다면 몇가지 방법이 있습니다. :-
|
||||
|
||||
- readme에서 github-readme-stats를 사용하고 다시 링크해주세요 :D
|
||||
- star를 눌러주거나 이 프로젝트를 공유해주세요. :rocket:
|
||||
- [](https://www.paypal.me/anuraghazra) - PayPal을 통해서 일회성 기부를 할 수 있습니다. 저는 아마 ~~커피~~ 차를 살겁니다.
|
||||
|
||||
고맙습니다! :heart:
|
||||
|
||||
---
|
||||
|
||||
코드 기여는 환영합니다!
|
||||
|
||||
:heart: and JavaScript로 만들어졌습니다.
|
||||
@@ -0,0 +1,326 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">Adicione suas estatísticas no GitHub geradas dinamicamente em seus readmes!</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Testes aprovados" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Apoiado%20por-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Apoiado%20por-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#demo">Ver demonstração</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Reportar erros</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Solicitar recursos</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">Gostou do projeto? Por favor considere <a href="https://www.paypal.me/anuraghazra">fazer uma doação</a> para ajudar a melhorá-lo!
|
||||
|
||||
# Características
|
||||
|
||||
- [Cartão de estatísticas do GitHub](#cartão-de-estatísticas-do-github)
|
||||
- [Pins extras do GitHub](#pins-extras-do-github)
|
||||
- [Cartão de principais linguagens de programação](#cartão-de-principais-linguagens-de-programação)
|
||||
- [Temas](#temas)
|
||||
- [Personalização](#personalização)
|
||||
- [Faça suas próprias implantações](#faça-suas-próprias-implantações)
|
||||
|
||||
# Cartão de estatísticas do GitHub
|
||||
|
||||
Copie e cole isso no seu conteúdo de remarcação e é isso. Simples!
|
||||
|
||||
Mude o valor de `?username=` para o seu nome de usuário no GitHub.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
_Nota: As classificações são baseadas nas estatísticas do usuário, veja [src/calculateRank.js](./src/calculateRank.js)_
|
||||
|
||||
### Ocultando estatísticas específicas
|
||||
|
||||
Para ocultar estatísticas individualmente, você pode passar um parâmetro de consulta `?hide=` com valores separados por vírgula.
|
||||
|
||||
> Opções: `&hide=stars,commits,prs,issues,contribs`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Adicionando contagem de contribuições privadas à contagem total de commits
|
||||
|
||||
Adicione a contagem de todas as suas contribuições privadas à contagem total de confirmações usando o parâmetro de consulta `?count_private=true`.
|
||||
|
||||
_Nota: Se você estiver implantando este projeto, as contribuições privadas serão contadas por padrão; caso contrário, você precisará compartilhar suas contagens de contribuições privadas._
|
||||
|
||||
> Opções: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Exibindo ícones
|
||||
|
||||
Para habilitar ícones, basta utilizar o parâmetro `show_icons=true` na sua requisição, da seguinte forma:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Temas
|
||||
|
||||
Com temas predefinidos, pode personalizar a aparência dos cartões sem precisar fazer nenhuma [configuração manual](#personalização).
|
||||
|
||||
Utilize o parâmetro `?theme=THEME_NAME`, da seguinte forma:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
#### Todos os temas predefinidos :
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat Themes" width="600px"/>
|
||||
|
||||
Visualize [todos o temas disponíveis](./themes/README.md) ou o [arquivo de configuração de tema](./themes/index.js), além de **também poder contribuir com novos temas**, se desejar :D
|
||||
|
||||
### Personalização
|
||||
|
||||
Personalize a aparência do seu `Stats Card` ou `Repo Card` da maneira que desejar com os parâmetros de URL.
|
||||
|
||||
#### Opções comuns
|
||||
|
||||
- `title_color` - Cor do título do cartão _(hex color)_
|
||||
- `text_color` - Cor de texto do conteúdo _(hex color)_
|
||||
- `icon_color` - Cor dos ícones (se disponível) _(hex color)_
|
||||
- `bg_color` - Cor de fundo do cartão _(hex color)_
|
||||
- `theme` - Nome do tema, escolha em [todos os temas disponíveis](./themes/README.md)
|
||||
- `cache_seconds` - Defina o cabeçalho do cache manualmente _(min: 1800, max: 86400)_
|
||||
|
||||
> Nota sobre o cache: Cartões de repositório tem um cache padrão de 30 minutos (1800 segundos), se o número a contagem de forks e contagem de estrelas é menor que 1 mil o padrão é 2 horas (7200). Note também que o cache é limitado a um mínimo de 30 minutos e um máximo de 24 horas.
|
||||
|
||||
#### Opções exclusivas do cartão de estatísticas:
|
||||
|
||||
- `hide` - Oculta itens específicos das estatísticas _(Valores separados por vírgulas)_
|
||||
- `hide_title` - Ocutar o título _(boolean)_
|
||||
- `hide_rank` - Ocultar a classificação _(boolean)_
|
||||
- `show_icons` - Mostrar ícones _(boolean)_
|
||||
- `include_all_commits` - Contabiliza todos os commits ao invés de apenas os atual ano _(boolean)_
|
||||
- `count_private` - Contabiliza commits privados _(boolean)_
|
||||
- `line_height` - Define a altura do espaçamento entre o texto _(number)_
|
||||
|
||||
#### Opções exclusivas do cartão de repositórios:
|
||||
|
||||
- `show_owner` - Exibir o nome da pessoa a quem o repositório pertence _(boolean)_
|
||||
|
||||
#### Opções exclusivas do cartão de linguagens:
|
||||
|
||||
- `hide` - Oculta linguagens específicas _(Valores separados por vírgulas)_
|
||||
- `hide_title` - Oculta o título _(boolean)_
|
||||
- `layout` - Alterna entre os dois layouts disponíveis `default` & `compact`
|
||||
- `card_width` - Define a largura do cartão manualmente _(number)_
|
||||
|
||||
> :warning: **Importante:**
|
||||
> Nomes de linguagens devem ser uma sequência escapada de URI, como específicado em [Codificação por cento](https://pt.wikipedia.org/wiki/Codificação_por_cento)
|
||||
> (Isso é: `c++` deve se tornar `c%2B%2B`, `jupyter notebook` deve se tornar `jupyter%20notebook`, etc.)
|
||||
|
||||
---
|
||||
|
||||
# Pins extras do GitHub
|
||||
|
||||
Os Pins extras do GitHub permitem fixar mais de 6 repositórios no seu perfil usando um perfil README.me do GitHub.
|
||||
|
||||
Uhu! Você não está mais limitado a 6 repositórios fixados.
|
||||
|
||||
### Utilização
|
||||
|
||||
Copie e cole esse código no seu README.md e altere os atributos.
|
||||
|
||||
Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demonstração
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
Utilize a variável [show_owner](#personalização) para incluir o nome de usuário do proprietária do repositório
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# Cartão de principais linguagens de programação
|
||||
|
||||
Exibe uma métrica de linguagens de programação mais usadas pelo usuário do GitHub.
|
||||
|
||||
_Nota: As principais linguagens de programação não fazem declarações sobre habilidades pessoais ou similares, é apenas uma figura-chave com base nas estatísticas do GitHub do usuário indicando a frequência com que cada uma foi utilizada._
|
||||
|
||||
### Utilização
|
||||
|
||||
Copie e cole esse código no seu README.md e altere os atributos.
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Ocultar linguagens individualmente
|
||||
|
||||
Utilize o parâmetro `?hide=language1,language2` para ocultar linguagens específicas.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Layout de cartão de linguagens compacto
|
||||
|
||||
Utilize a opção `&layout=compact` para mudar o layout do cartão.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demonstração
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- Layout compacto
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Todas as demonstrações
|
||||
|
||||
- Padronizado
|
||||
|
||||

|
||||
|
||||
- Ocultando estatísticas específicas
|
||||
|
||||

|
||||
|
||||
- Mostrando ícones
|
||||
|
||||

|
||||
|
||||
- Incluir todos os commits
|
||||
|
||||

|
||||
|
||||
- Temas
|
||||
|
||||
Escolha entre um dos [temas predefinidos](#temas)
|
||||
|
||||

|
||||
|
||||
- Personalizando o cartão de estatísticas
|
||||
|
||||

|
||||
|
||||
- Customizando o cartão de repositório
|
||||
|
||||

|
||||
|
||||
- Principais linguagens
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Dica (Alinhandos os cartões de repositório)
|
||||
|
||||
Por padrão, você não poderá organizar as imagens lado a lado. Para fazer isso, você pode usar a seguinte abordagem:
|
||||
|
||||
```md
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/convoychat">
|
||||
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
|
||||
</a>
|
||||
```
|
||||
|
||||
## Implante em sua própria instância do Vercel
|
||||
|
||||
Como a API do GitHub permite apenas 5 mil solicitações por hora, é possível que minha `https://github-readme-stats.vercel.app/api` atinja a cota limite. Se hospedar em seu próprio servidor Vercel, não precisará se preocupar com nada. Clique no botão de implantação para começar!
|
||||
|
||||
Nota: Desde [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) há possibilidade de lidar com mais de 5 mil chamadas por hora, sem interrupções :D
|
||||
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<details>
|
||||
<summary>Guia de configuração do Vercel</summary>
|
||||
|
||||
1. Acesse [vercel.com](https://vercel.com/)
|
||||
1. Clique em `Login`
|
||||

|
||||
1. Acesse com o GitHub clicando em `Continue with GitHub`
|
||||

|
||||
1. Entre no GitHub e permita acesso a todos os repositórios, se solicitado
|
||||
1. Faça Fork neste repositório
|
||||
1. Volte ao seu [painel principal do Vercel](https://vercel.com/dashboard)
|
||||
1. Selecione `Import Project`
|
||||

|
||||
1. Selecione `Import Git Repository`
|
||||

|
||||
1. Selecione a raiz e mantenha tudo como está, basta adicionar sua variável de ambiente chamada PAT_1 (que será exibida), que conterá um token de acesso pessoal (PAT), que você pode criar facilmente [aqui](https://github.com/settings/tokens/new) (deixe tudo como está, apenas dê um nome, que pode ser o que você quiser)
|
||||

|
||||
1. Clique em `deploy` e já estará tudo pronto. Veja seus domínios para usar a API!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: Apoie o projeto
|
||||
|
||||
Disponibilizo como código aberto quase tudo o que posso e tento responder a todos que precisam de ajuda para utilizar esses projetos. Claro,
|
||||
isso demanda tempo. Utilize este serviço gratuitamente.
|
||||
|
||||
No entanto, se você utilizar este projeto e estiver satisfeito com ele, ou apenas quiser me encorajar a continuar criando coisas, existem algumas formas fazê-lo:
|
||||
|
||||
- Dando os devidos créditos ao usar github-readme-stats no seu README.me, adicionando uma referência ao projeto :D
|
||||
- Dando uma estrela (Starring) e compartilhando o projeto 🚀
|
||||
- [](https://www.paypal.me/anuraghazra) - Você pode fazer doações únicas via PayPal. Provavelmente vou comprar um ~~café~~ chá. :tea:
|
||||
|
||||
Obrigado! :heart:
|
||||
|
||||
---
|
||||
|
||||
Contribuições são bem-vindas! <3
|
||||
|
||||
Feito com :heart: e JavaScript.
|
||||
+18
-4
@@ -4,20 +4,34 @@
|
||||
"description": "Dynamically generate stats for your github readmes",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch"
|
||||
"test": "jest --coverage",
|
||||
"test:watch": "jest --watch",
|
||||
"theme-readme-gen": "node scripts/generate-theme-doc",
|
||||
"preview-theme": "node scripts/preview-theme"
|
||||
},
|
||||
"author": "Anurag Hazra",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.2.4",
|
||||
"@actions/github": "^4.0.0",
|
||||
"@testing-library/dom": "^7.20.0",
|
||||
"@testing-library/jest-dom": "^5.11.0",
|
||||
"axios": "^0.19.2",
|
||||
"axios-mock-adapter": "^1.18.1",
|
||||
"css-to-object": "^1.1.0",
|
||||
"jest": "^26.1.0"
|
||||
"husky": "^4.2.5",
|
||||
"jest": "^26.1.0",
|
||||
"parse-diff": "^0.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^8.2.0"
|
||||
"dotenv": "^8.2.0",
|
||||
"emoji-name-map": "^1.2.8",
|
||||
"github-username-regex": "^1.0.0",
|
||||
"word-wrap": "^1.2.3"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "npm test"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,50 @@
|
||||
<p align="center">
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="Github Readme Stats" />
|
||||
<img width="100px" src="https://res.cloudinary.com/anuraghazra/image/upload/v1594908242/logo_ccswme.svg" align="center" alt="GitHub Readme Stats" />
|
||||
<h2 align="center">GitHub Readme Stats</h2>
|
||||
<p align="center">Get dynamically generated GitHub stats on your readmes!</p>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/actions">
|
||||
<img alt="Tests Passing" src="https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/anuraghazra/github-readme-stats">
|
||||
<img src="https://codecov.io/gh/anuraghazra/github-readme-stats/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">
|
||||
<img alt="Issues" src="https://img.shields.io/github/issues/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/pulls">
|
||||
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/anuraghazra/github-readme-stats?color=0088ff" />
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=1227">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-VSCode%20Power%20User%20%E2%86%92-gray.svg?colorA=655BE1&colorB=4F44D6&style=for-the-badge"/>
|
||||
</a>
|
||||
<a href="https://a.paddle.com/v2/click/16413/119403?link=2345">
|
||||
<img src="https://img.shields.io/badge/Supported%20by-Node%20Cli.com%20%E2%86%92-gray.svg?colorA=61c265&colorB=4CAF50&style=for-the-badge"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#demo">View Demo</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">Report Bug</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Report Bug</a>
|
||||
·
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues">Request Feature</a>
|
||||
<a href="https://github.com/anuraghazra/github-readme-stats/issues/new/choose">Request Feature</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="readme_cn.md">简体中文</a>
|
||||
<a href="/docs/readme_cn.md">简体中文</a>
|
||||
·
|
||||
<a href="readme_es.md">Español</a>
|
||||
<a href="/docs/readme_es.md">Español</a>
|
||||
·
|
||||
<a href="/docs/readme_de.md">Deutsch</a>
|
||||
·
|
||||
<a href="/docs/readme_ja.md">日本語</a>
|
||||
·
|
||||
<a href="/docs/readme_pt-BR.md">Português Brasileiro</a>
|
||||
·
|
||||
<a href="/docs/readme_kr.md">한국어</a>
|
||||
</p>
|
||||
</p>
|
||||
<p align="center">Loved the project? Please consider <a href="https://www.paypal.me/anuraghazra">donating</a> to help it improve!
|
||||
@@ -35,6 +53,7 @@
|
||||
|
||||
- [GitHub Stats Card](#github-stats-card)
|
||||
- [GitHub Extra Pins](#github-extra-pins)
|
||||
- [Top Languages Card](#top-languages-card)
|
||||
- [Themes](#themes)
|
||||
- [Customization](#customization)
|
||||
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
||||
@@ -53,12 +72,24 @@ _Note: Ranks are calculated based on user's stats, see [src/calculateRank.js](./
|
||||
|
||||
### Hiding individual stats
|
||||
|
||||
To hide any specific stats, you can pass a query parameter `?hide=` with an array of items you wanna hide.
|
||||
To hide any specific stats, you can pass a query parameter `?hide=` with comma separated values.
|
||||
|
||||
> Options: `&hide=["stars","commits","prs","issues","contribs"]`
|
||||
> Options: `&hide=stars,commits,prs,issues,contribs`
|
||||
|
||||
```md
|
||||

|
||||

|
||||
```
|
||||
|
||||
### Adding private contributions count to total commits count
|
||||
|
||||
You can add the count of all your private contributions to the total commits count by using the query parameter `?count_private=true`.
|
||||
|
||||
_Note: If you are deploying this project yourself, the private contributions will be counted by default otherwise you need to chose to share your private contribution counts._
|
||||
|
||||
> Options: `&count_private=true`
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Showing icons
|
||||
@@ -83,7 +114,7 @@ Use `?theme=THEME_NAME` parameter like so :-
|
||||
|
||||
dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="Github Readme Stat Themes" width="600px"/>
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stat 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) & **you can also contribute new themes** if you like :D
|
||||
|
||||
@@ -91,54 +122,49 @@ You can look at a preview for [all available themes](./themes/README.md) or chec
|
||||
|
||||
You can customize the appearance of your `Stats Card` or `Repo Card` however you want with URL params.
|
||||
|
||||
Customization Options:
|
||||
#### Common Options:
|
||||
|
||||
| Option | type | description | Stats Card (default) | Repo Card (default) |
|
||||
| ------------- | --------- | ------------------------------------ | -------------------- | ------------------- |
|
||||
| title_color | hex color | title color | 2f80ed | 2f80ed |
|
||||
| text_color | hex color | body color | 333 | 333 |
|
||||
| icon_color | hex color | icon color | 4c71f2 | 586069 |
|
||||
| bg_color | hex color | card bg color | FFFEFE | FFFEFE |
|
||||
| line_height | number | control the line-height between text | 30 | N/A |
|
||||
| hide_rank | boolean | hides the ranking | false | N/A |
|
||||
| hide_title | boolean | hides the stats title | false | N/A |
|
||||
| hide_border | boolean | hides the stats card border | false | N/A |
|
||||
| show_owner | boolean | shows owner name in repo card | N/A | false |
|
||||
| show_icons | boolean | shows icons | false | N/A |
|
||||
| theme | string | sets inbuilt theme | 'default' | 'default_repocard' |
|
||||
| cache_seconds | number | manually set custom cache control | 1800 | 1800 |
|
||||
- `title_color` - Card's title color _(hex color)_
|
||||
- `text_color` - Body text color _(hex color)_
|
||||
- `icon_color` - Icons color if available _(hex color)_
|
||||
- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_
|
||||
- `theme` - name of the theme, choose from [all available themes](./themes/README.md)
|
||||
- `cache_seconds` - set the cache header manually _(min: 1800, max: 86400)_
|
||||
|
||||
##### Gradient in bg_color
|
||||
|
||||
You can provide multiple comma saperated values in bg_color option to render a gradient, the format of the gradient is :-
|
||||
|
||||
```
|
||||
&bg_color=DEG,COLOR1,COLRO2,COLOR3...COLOR10
|
||||
```
|
||||
|
||||
> Note on cache: Repo cards have default cache of 30mins (1800 seconds) if the fork count & star count is less than 1k otherwise it's 2hours (7200). Also note that cache is clamped to minimum of 30min and maximum of 24hours
|
||||
|
||||
---
|
||||
#### Stats Card Exclusive Options:
|
||||
|
||||
### Demo
|
||||
- `hide` - Hide's the specified items from stats _(Comma seperated values)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `hide_rank` - _(boolean)_
|
||||
- `show_icons` - _(boolean)_
|
||||
- `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_
|
||||
- `count_private` - Count private commits _(boolean)_
|
||||
- `line_height` - Sets the line-height between text _(number)_
|
||||
|
||||
- Default
|
||||
#### Repo Card Exclusive Options:
|
||||
|
||||

|
||||
- `show_owner` - Show the owner name of the repo _(boolean)_
|
||||
|
||||
- Hiding specific stats
|
||||
#### Language Card Exclusive Options:
|
||||
|
||||

|
||||
- `hide` - Hide the languages specified from the card _(Comma seperated values)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `layout` - Switch between two available layouts `default` & `compact`
|
||||
- `card_width` - Set the card's width manually _(number)_
|
||||
|
||||
- Showing icons
|
||||
|
||||

|
||||
|
||||
- Themes
|
||||
|
||||
Choose from any of the [default themes](#themes)
|
||||
|
||||

|
||||
|
||||
- Customizing stats card
|
||||
|
||||

|
||||
|
||||
- Customizing repo card
|
||||
|
||||

|
||||
> :warning: **Important:**
|
||||
> Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
|
||||
> (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.)
|
||||
|
||||
---
|
||||
|
||||
@@ -166,6 +192,90 @@ Use [show_owner](#customization) variable to include the repo's owner username
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
# Top Languages Card
|
||||
|
||||
Top languages card shows github user's top langauges which has been mostly used.
|
||||
|
||||
_NOTE: Top languages does not indicate my skill level or something like that, it's a github metric of which languages i have the most code on github, it's a new feature of github-readme-stats_
|
||||
|
||||
### Usage
|
||||
|
||||
Copy-paste this code into your readme and change the links.
|
||||
|
||||
Endpoint: `api/top-langs?username=anuraghazra`
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Hide individual languages
|
||||
|
||||
You can use `?hide=language1,language2` parameter to hide individual languages.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Compact Language Card Layout
|
||||
|
||||
You can use the `&layout=compact` option to change the card design.
|
||||
|
||||
```md
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
- Compact layout
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### All Demos
|
||||
|
||||
- Default
|
||||
|
||||

|
||||
|
||||
- Hiding specific stats
|
||||
|
||||

|
||||
|
||||
- Showing icons
|
||||
|
||||

|
||||
|
||||
- Include All Commits
|
||||
|
||||

|
||||
|
||||
- Themes
|
||||
|
||||
Choose from any of the [default themes](#themes)
|
||||
|
||||

|
||||
|
||||
- Gradient
|
||||
|
||||

|
||||
|
||||
- Customizing stats card
|
||||
|
||||

|
||||
|
||||
- Customizing repo card
|
||||
|
||||

|
||||
|
||||
- Top languages
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
---
|
||||
|
||||
### Quick Tip (Align The Repo Cards)
|
||||
|
||||
You usually won't be able to layout the images side by side. To do that you can use this approach:
|
||||
@@ -188,7 +298,7 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
|
||||
[](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<details>
|
||||
<summary>Guide on setting up Vercel</summary>
|
||||
<summary><b> Guide on setting up Vercel 🔨 </b></summary>
|
||||
|
||||
1. Go to [vercel.com](https://vercel.com/)
|
||||
1. Click on `Log in`
|
||||
@@ -203,8 +313,9 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
|
||||
1. Select `Import Git Repository`
|
||||

|
||||
1. Select root and keep everything as is, just add your environment variable named PAT_1 (as shown), which will contain a personal access token (PAT), which you can easily create [here](https://github.com/settings/tokens/new) (leave everything as is, just name it something, it can be anything you want)
|
||||

|
||||

|
||||
1. Click deploy, and you're good to go. See your domains to use the API!
|
||||
|
||||
</details>
|
||||
|
||||
## :sparkling_heart: Support the project
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
const theme = require("../themes/index");
|
||||
const fs = require("fs");
|
||||
|
||||
const TARGET_FILE = "./themes/README.md";
|
||||
const REPO_CARD_LINKS_FLAG = "<!-- REPO_CARD_LINKS -->";
|
||||
const STAT_CARD_LINKS_FLAG = "<!-- STATS_CARD_LINKS -->";
|
||||
|
||||
const STAT_CARD_TABLE_FLAG = "<!-- STATS_CARD_TABLE -->";
|
||||
const REPO_CARD_TABLE_FLAG = "<!-- REPO_CARD_TABLE -->";
|
||||
|
||||
const THEME_TEMPLATE = `## Available Themes
|
||||
|
||||
<!-- DO NOT EDIT THIS FILE DIRECTLY -->
|
||||
|
||||
With inbuilt themes you can customize the look of the card without doing any manual customization.
|
||||
|
||||
Use \`?theme=THEME_NAME\` parameter like so :-
|
||||
|
||||
\`\`\`md
|
||||

|
||||
\`\`\`
|
||||
|
||||
## Stats
|
||||
|
||||
> These themes work both for the Stats Card and Repo Card.
|
||||
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
${STAT_CARD_TABLE_FLAG}
|
||||
|
||||
## Repo Card
|
||||
|
||||
> These themes work both for the Stats Card and Repo Card.
|
||||
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
${REPO_CARD_TABLE_FLAG}
|
||||
|
||||
${STAT_CARD_LINKS_FLAG}
|
||||
|
||||
${REPO_CARD_LINKS_FLAG}
|
||||
|
||||
|
||||
[add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js
|
||||
|
||||
Wanted to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D
|
||||
`;
|
||||
|
||||
const createRepoMdLink = (theme) => {
|
||||
return `\n[${theme}_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=${theme}`;
|
||||
};
|
||||
const createStatMdLink = (theme) => {
|
||||
return `\n[${theme}]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=${theme}`;
|
||||
};
|
||||
|
||||
const generateLinks = (fn) => {
|
||||
return Object.keys(theme)
|
||||
.map((name) => fn(name))
|
||||
.join("");
|
||||
};
|
||||
|
||||
const createTableItem = ({ link, label, isRepoCard }) => {
|
||||
if (!link || !label) return "";
|
||||
return `\`${label}\` ![${link}][${link}${isRepoCard ? "_repo" : ""}]`;
|
||||
};
|
||||
const generateTable = ({ isRepoCard }) => {
|
||||
const rows = [];
|
||||
const themes = Object.keys(theme).filter(
|
||||
(name) => name !== (!isRepoCard ? "default_repocard" : "default")
|
||||
);
|
||||
|
||||
for (let i = 0; i < themes.length; i += 3) {
|
||||
const one = themes[i];
|
||||
const two = themes[i + 1];
|
||||
const three = themes[i + 2];
|
||||
|
||||
let tableItem1 = createTableItem({ link: one, label: one, isRepoCard });
|
||||
let tableItem2 = createTableItem({ link: two, label: two, isRepoCard });
|
||||
let tableItem3 = createTableItem({ link: three, label: three, isRepoCard });
|
||||
|
||||
if (three === undefined) {
|
||||
tableItem3 = `[Add your theme][add-theme]`;
|
||||
}
|
||||
rows.push(`| ${tableItem1} | ${tableItem2} | ${tableItem3} |`);
|
||||
|
||||
// if it's the last row & the row has no empty space push a new row
|
||||
if (three && i + 3 === themes.length) {
|
||||
rows.push(`| [Add your theme][add-theme] | | |`);
|
||||
}
|
||||
}
|
||||
|
||||
return rows.join("\n");
|
||||
};
|
||||
|
||||
const buildReadme = () => {
|
||||
return THEME_TEMPLATE.split("\n")
|
||||
.map((line) => {
|
||||
if (line.includes(REPO_CARD_LINKS_FLAG)) {
|
||||
return generateLinks(createRepoMdLink);
|
||||
}
|
||||
if (line.includes(STAT_CARD_LINKS_FLAG)) {
|
||||
return generateLinks(createStatMdLink);
|
||||
}
|
||||
if (line.includes(REPO_CARD_TABLE_FLAG)) {
|
||||
return generateTable({ isRepoCard: true });
|
||||
}
|
||||
if (line.includes(STAT_CARD_TABLE_FLAG)) {
|
||||
return generateTable({ isRepoCard: false });
|
||||
}
|
||||
return line;
|
||||
})
|
||||
.join("\n");
|
||||
};
|
||||
|
||||
fs.writeFileSync(TARGET_FILE, buildReadme());
|
||||
@@ -0,0 +1,77 @@
|
||||
const core = require("@actions/core");
|
||||
const github = require("@actions/github");
|
||||
const parse = require("parse-diff");
|
||||
require("dotenv").config();
|
||||
|
||||
const parsePullRequestId = (githubRef) => {
|
||||
const result = /refs\/pull\/(\d+)\/merge/g.exec(githubRef);
|
||||
if (!result) {
|
||||
console.log("Reference not found.");
|
||||
return 297;
|
||||
}
|
||||
const [, pullRequestId] = result;
|
||||
return pullRequestId;
|
||||
};
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const token = core.getInput("token");
|
||||
const octokit = github.getOctokit(token || process.env.PERSONAL_TOKEN);
|
||||
const pullRequestId = parsePullRequestId(process.env.GITHUB_REF);
|
||||
|
||||
let res = await octokit.pulls.get({
|
||||
owner: "anuraghazra",
|
||||
repo: "github-readme-stats",
|
||||
pull_number: pullRequestId,
|
||||
mediaType: {
|
||||
format: "diff",
|
||||
},
|
||||
});
|
||||
|
||||
let diff = parse(res.data);
|
||||
let colorStrings = diff
|
||||
.find((file) => file.to === "themes/index.js")
|
||||
.chunks[0].changes.filter((c) => c.type === "add")
|
||||
.map((c) => c.content.replace("+", ""))
|
||||
.join("");
|
||||
|
||||
let matches = colorStrings.match(/(title_color:.*bg_color.*\")/);
|
||||
let colors = matches && matches[0].split(",");
|
||||
|
||||
if (!colors) {
|
||||
await octokit.issues.createComment({
|
||||
owner: "anuraghazra",
|
||||
repo: "github-readme-stats",
|
||||
body: `
|
||||
\rTheme preview (bot)
|
||||
Cannot create theme preview
|
||||
`,
|
||||
issue_number: pullRequestId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
colors = colors.map((color) =>
|
||||
color.replace(/.*\:\s/, "").replace(/\"/g, "")
|
||||
);
|
||||
|
||||
let titleColor = colors[0];
|
||||
let iconColor = colors[1];
|
||||
let textColor = colors[2];
|
||||
let bgColor = colors[3];
|
||||
const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra&title_color=${titleColor}&icon_color=${iconColor}&text_color=${textColor}&bg_color=${bgColor}&show_icons=true`;
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: "anuraghazra",
|
||||
repo: "github-readme-stats",
|
||||
body: `
|
||||
\rTheme preview (bot)
|
||||
\r
|
||||
`,
|
||||
issue_number: pullRequestId,
|
||||
});
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
export BRANCH_NAME=updated-theme-readme
|
||||
git --version
|
||||
git config --global user.email "no-reply@githubreadmestats.com"
|
||||
git config --global user.name "Github Readme Stats Bot"
|
||||
git branch -d $BRANCH_NAME || true
|
||||
git checkout -b $BRANCH_NAME
|
||||
git add --all
|
||||
git commit --message "docs(theme): Auto update theme readme" || exit 0
|
||||
git remote add origin-$BRANCH_NAME https://${PERSONAL_TOKEN}@github.com/${GH_REPO}.git
|
||||
git push --force --quiet --set-upstream origin-$BRANCH_NAME $BRANCH_NAME
|
||||
@@ -0,0 +1,159 @@
|
||||
const {
|
||||
kFormatter,
|
||||
encodeHTML,
|
||||
getCardColors,
|
||||
FlexLayout,
|
||||
wrapTextMultiline,
|
||||
} = require("../common/utils");
|
||||
const icons = require("../common/icons");
|
||||
const Card = require("../common/Card");
|
||||
const toEmoji = require("emoji-name-map");
|
||||
|
||||
const renderRepoCard = (repo, options = {}) => {
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
stargazers,
|
||||
isArchived,
|
||||
isTemplate,
|
||||
forkCount,
|
||||
} = repo;
|
||||
const {
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
show_owner,
|
||||
theme = "default_repocard",
|
||||
} = options;
|
||||
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified";
|
||||
const langColor = (primaryLanguage && primaryLanguage.color) || "#333";
|
||||
|
||||
const shiftText = langName.length > 15 ? 0 : 30;
|
||||
|
||||
let desc = description || "No description provided";
|
||||
|
||||
// parse emojis to unicode
|
||||
desc = desc.replace(/:\w+:/gm, (emoji) => {
|
||||
return toEmoji.get(emoji) || "";
|
||||
});
|
||||
|
||||
const multiLineDescription = wrapTextMultiline(desc);
|
||||
const descriptionLines = multiLineDescription.length;
|
||||
const lineHeight = 10;
|
||||
|
||||
const height =
|
||||
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const totalStars = kFormatter(stargazers.totalCount);
|
||||
const totalForks = kFormatter(forkCount);
|
||||
|
||||
const getBadgeSVG = (label) => `
|
||||
<g data-testid="badge" class="badge" transform="translate(320, 38)">
|
||||
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
||||
<text
|
||||
x="23" y="-5"
|
||||
alignment-baseline="central"
|
||||
dominant-baseline="central"
|
||||
text-anchor="middle"
|
||||
fill="${textColor}"
|
||||
>
|
||||
${label}
|
||||
</text>
|
||||
</g>
|
||||
`;
|
||||
|
||||
const svgLanguage = primaryLanguage
|
||||
? `
|
||||
<g data-testid="primary-lang" transform="translate(30, 0)">
|
||||
<circle data-testid="lang-color" cx="0" cy="-5" r="6" fill="${langColor}" />
|
||||
<text data-testid="lang-name" class="gray" x="15">${langName}</text>
|
||||
</g>
|
||||
`
|
||||
: "";
|
||||
|
||||
const iconWithLabel = (icon, label, testid) => {
|
||||
return `
|
||||
<svg class="icon" y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||
${icon}
|
||||
</svg>
|
||||
<text data-testid="${testid}" class="gray" x="25">${label}</text>
|
||||
`;
|
||||
};
|
||||
const svgStars =
|
||||
stargazers.totalCount > 0 &&
|
||||
iconWithLabel(icons.star, totalStars, "stargazers");
|
||||
const svgForks =
|
||||
forkCount > 0 && iconWithLabel(icons.fork, totalForks, "forkcount");
|
||||
|
||||
const starAndForkCount = FlexLayout({
|
||||
items: [svgStars, svgForks],
|
||||
gap: 65,
|
||||
}).join("");
|
||||
|
||||
const card = new Card({
|
||||
title: header,
|
||||
titlePrefixIcon: icons.contribs,
|
||||
width: 400,
|
||||
height,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
|
||||
card.disableAnimations();
|
||||
card.setHideBorder(false);
|
||||
card.setHideTitle(false);
|
||||
card.setCSS(`
|
||||
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
.icon { fill: ${iconColor} }
|
||||
.badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
|
||||
.badge rect { opacity: 0.2 }
|
||||
`);
|
||||
|
||||
return card.render(`
|
||||
${
|
||||
isTemplate
|
||||
? getBadgeSVG("Template")
|
||||
: isArchived
|
||||
? getBadgeSVG("Archived")
|
||||
: ""
|
||||
}
|
||||
|
||||
<text class="description" x="25" y="-5">
|
||||
${multiLineDescription
|
||||
.map((line) => `<tspan dy="1.2em" x="25">${encodeHTML(line)}</tspan>`)
|
||||
.join("")}
|
||||
</text>
|
||||
|
||||
<g transform="translate(0, ${height - 75})">
|
||||
${svgLanguage}
|
||||
|
||||
<g
|
||||
data-testid="star-fork-group"
|
||||
transform="translate(${primaryLanguage ? 155 - shiftText : 25}, 0)"
|
||||
>
|
||||
${starAndForkCount}
|
||||
</g>
|
||||
</g>
|
||||
`);
|
||||
};
|
||||
|
||||
module.exports = renderRepoCard;
|
||||
@@ -1,8 +1,22 @@
|
||||
const { kFormatter, getCardColors, FlexLayout } = require("../src/utils");
|
||||
const getStyles = require("./getStyles");
|
||||
const icons = require("./icons");
|
||||
const {
|
||||
kFormatter,
|
||||
getCardColors,
|
||||
FlexLayout,
|
||||
encodeHTML,
|
||||
} = require("../common/utils");
|
||||
const { getStyles } = require("../getStyles");
|
||||
const icons = require("../common/icons");
|
||||
const Card = require("../common/Card");
|
||||
|
||||
const createTextNode = ({ icon, label, value, id, index, showIcons }) => {
|
||||
const createTextNode = ({
|
||||
icon,
|
||||
label,
|
||||
value,
|
||||
id,
|
||||
index,
|
||||
showIcons,
|
||||
shiftValuePos,
|
||||
}) => {
|
||||
const kValue = kFormatter(value);
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
|
||||
@@ -18,7 +32,12 @@ const createTextNode = ({ icon, label, value, id, index, showIcons }) => {
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms" transform="translate(25, 0)">
|
||||
${iconSvg}
|
||||
<text class="stat bold" ${labelOffset} y="12.5">${label}:</text>
|
||||
<text class="stat" x="135" y="12.5" data-testid="${id}">${kValue}</text>
|
||||
<text
|
||||
class="stat"
|
||||
x="${shiftValuePos ? (showIcons ? 200 : 170) : 150}"
|
||||
y="12.5"
|
||||
data-testid="${id}"
|
||||
>${kValue}</text>
|
||||
</g>
|
||||
`;
|
||||
};
|
||||
@@ -39,6 +58,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
hide_title = false,
|
||||
hide_border = false,
|
||||
hide_rank = false,
|
||||
include_all_commits = false,
|
||||
line_height = 25,
|
||||
title_color,
|
||||
icon_color,
|
||||
@@ -47,7 +67,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
theme = "default",
|
||||
} = options;
|
||||
|
||||
const lheight = parseInt(line_height);
|
||||
const lheight = parseInt(line_height, 10);
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
@@ -68,7 +88,9 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
},
|
||||
commits: {
|
||||
icon: icons.commits,
|
||||
label: "Total Commits",
|
||||
label: `Total Commits${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
value: totalCommits,
|
||||
id: "commits",
|
||||
},
|
||||
@@ -101,6 +123,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
...STATS[key],
|
||||
index,
|
||||
showIcons: show_icons,
|
||||
shiftValuePos: !include_all_commits,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -111,45 +134,11 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
hide_rank ? 0 : 150
|
||||
);
|
||||
|
||||
// the better user's score the the rank will be closer to zero so
|
||||
// subtracting 100 to get the progress in 100%
|
||||
const progress = 100 - rank.score;
|
||||
|
||||
const styles = getStyles({
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
show_icons,
|
||||
progress,
|
||||
});
|
||||
|
||||
// Conditionally rendered elements
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1)) ? "" : "s";
|
||||
const title = hide_title
|
||||
? ""
|
||||
: `<text x="25" y="35" class="header">${name}'${apostrophe} GitHub Stats</text>`;
|
||||
|
||||
const border = hide_border
|
||||
? ""
|
||||
: `
|
||||
<rect
|
||||
data-testid="card-bg"
|
||||
x="0.5"
|
||||
y="0.5"
|
||||
width="494"
|
||||
height="99%"
|
||||
rx="4.5"
|
||||
fill="${bgColor}"
|
||||
stroke="#E4E2E2"
|
||||
/>
|
||||
`;
|
||||
|
||||
const rankCircle = hide_rank
|
||||
? ""
|
||||
: `<g data-testid="rank-circle" transform="translate(400, ${
|
||||
height / 1.85
|
||||
})">
|
||||
: `<g data-testid="rank-circle"
|
||||
transform="translate(400, ${height / 2 - 50})">
|
||||
<circle class="rank-circle-rim" cx="-10" cy="8" r="40" />
|
||||
<circle class="rank-circle" cx="-10" cy="8" r="40" />
|
||||
<g class="rank-text">
|
||||
@@ -165,34 +154,45 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
</g>
|
||||
</g>`;
|
||||
|
||||
if (hide_title) {
|
||||
height -= 30;
|
||||
}
|
||||
// the better user's score the the rank will be closer to zero so
|
||||
// subtracting 100 to get the progress in 100%
|
||||
const progress = 100 - rank.score;
|
||||
const cssStyles = getStyles({
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
show_icons,
|
||||
progress,
|
||||
});
|
||||
|
||||
return `
|
||||
<svg width="495" height="${height}" viewBox="0 0 495 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
${styles}
|
||||
</style>
|
||||
|
||||
${border}
|
||||
${title}
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1)) ? "" : "s";
|
||||
const card = new Card({
|
||||
title: `${encodeHTML(name)}'${apostrophe} GitHub Stats`,
|
||||
width: 495,
|
||||
height,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
|
||||
<g data-testid="card-body-content" transform="translate(0, ${
|
||||
hide_title ? -30 : 0
|
||||
})">
|
||||
${rankCircle}
|
||||
card.setHideBorder(hide_border);
|
||||
card.setHideTitle(hide_title);
|
||||
card.setCSS(cssStyles);
|
||||
|
||||
<svg x="0" y="55">
|
||||
${FlexLayout({
|
||||
items: statItems,
|
||||
gap: lheight,
|
||||
direction: "column",
|
||||
}).join("")}
|
||||
</svg>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
return card.render(`
|
||||
${rankCircle}
|
||||
|
||||
<svg x="0" y="0">
|
||||
${FlexLayout({
|
||||
items: statItems,
|
||||
gap: lheight,
|
||||
direction: "column",
|
||||
}).join("")}
|
||||
</svg>
|
||||
`);
|
||||
};
|
||||
|
||||
module.exports = renderStatsCard;
|
||||
@@ -0,0 +1,200 @@
|
||||
const { getCardColors, FlexLayout, clampValue } = require("../common/utils");
|
||||
const Card = require("../common/Card");
|
||||
|
||||
const createProgressNode = ({ width, color, name, progress }) => {
|
||||
const paddingRight = 95;
|
||||
const progressTextX = width - paddingRight + 10;
|
||||
const progressWidth = width - paddingRight;
|
||||
const progressPercentage = clampValue(progress, 2, 100);
|
||||
|
||||
return `
|
||||
<text data-testid="lang-name" x="2" y="15" class="lang-name">${name}</text>
|
||||
<text x="${progressTextX}" y="34" class="lang-name">${progress}%</text>
|
||||
<svg width="${progressWidth}">
|
||||
<rect rx="5" ry="5" x="0" y="25" width="${progressWidth}" height="8" fill="#ddd"></rect>
|
||||
<rect
|
||||
height="8"
|
||||
fill="${color}"
|
||||
rx="5" ry="5" x="0" y="25"
|
||||
data-testid="lang-progress"
|
||||
width="${progressPercentage}%"
|
||||
>
|
||||
</rect>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
const createCompactLangNode = ({ lang, totalSize, x, y }) => {
|
||||
const percentage = ((lang.size / totalSize) * 100).toFixed(2);
|
||||
const color = lang.color || "#858585";
|
||||
|
||||
return `
|
||||
<g transform="translate(${x}, ${y})">
|
||||
<circle cx="5" cy="6" r="5" fill="${color}" />
|
||||
<text data-testid="lang-name" x="15" y="10" class='lang-name'>
|
||||
${lang.name} ${percentage}%
|
||||
</text>
|
||||
</g>
|
||||
`;
|
||||
};
|
||||
|
||||
const createLanguageTextNode = ({ langs, totalSize, x, y }) => {
|
||||
return langs.map((lang, index) => {
|
||||
if (index % 2 === 0) {
|
||||
return createCompactLangNode({
|
||||
lang,
|
||||
x,
|
||||
y: 12.5 * index + y,
|
||||
totalSize,
|
||||
index,
|
||||
});
|
||||
}
|
||||
return createCompactLangNode({
|
||||
lang,
|
||||
x: 150,
|
||||
y: 12.5 + 12.5 * index,
|
||||
totalSize,
|
||||
index,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const lowercaseTrim = (name) => name.toLowerCase().trim();
|
||||
|
||||
const renderTopLanguages = (topLangs, options = {}) => {
|
||||
const {
|
||||
hide_title,
|
||||
hide_border,
|
||||
card_width,
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
hide,
|
||||
theme,
|
||||
layout,
|
||||
} = options;
|
||||
|
||||
let langs = Object.values(topLangs);
|
||||
let langsToHide = {};
|
||||
|
||||
// populate langsToHide map for quick lookup
|
||||
// while filtering out
|
||||
if (hide) {
|
||||
hide.forEach((langName) => {
|
||||
langsToHide[lowercaseTrim(langName)] = true;
|
||||
});
|
||||
}
|
||||
|
||||
// filter out langauges to be hidden
|
||||
langs = langs
|
||||
.sort((a, b) => b.size - a.size)
|
||||
.filter((lang) => {
|
||||
return !langsToHide[lowercaseTrim(lang.name)];
|
||||
});
|
||||
|
||||
const totalLanguageSize = langs.reduce((acc, curr) => {
|
||||
return acc + curr.size;
|
||||
}, 0);
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, bgColor } = getCardColors({
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
let width = isNaN(card_width) ? 300 : card_width;
|
||||
let height = 45 + (langs.length + 1) * 40;
|
||||
|
||||
let finalLayout = "";
|
||||
|
||||
// RENDER COMPACT LAYOUT
|
||||
if (layout === "compact") {
|
||||
width = width + 50;
|
||||
height = 30 + (langs.length / 2 + 1) * 40;
|
||||
|
||||
// progressOffset holds the previous language's width and used to offset the next language
|
||||
// so that we can stack them one after another, like this: [--][----][---]
|
||||
let progressOffset = 0;
|
||||
const compactProgressBar = langs
|
||||
.map((lang) => {
|
||||
const percentage = (
|
||||
(lang.size / totalLanguageSize) *
|
||||
(width - 50)
|
||||
).toFixed(2);
|
||||
|
||||
const progress =
|
||||
percentage < 10 ? parseFloat(percentage) + 10 : percentage;
|
||||
|
||||
const output = `
|
||||
<rect
|
||||
mask="url(#rect-mask)"
|
||||
data-testid="lang-progress"
|
||||
x="${progressOffset}"
|
||||
y="0"
|
||||
width="${progress}"
|
||||
height="8"
|
||||
fill="${lang.color || "#858585"}"
|
||||
/>
|
||||
`;
|
||||
progressOffset += parseFloat(percentage);
|
||||
return output;
|
||||
})
|
||||
.join("");
|
||||
|
||||
finalLayout = `
|
||||
<mask id="rect-mask">
|
||||
<rect x="0" y="0" width="${
|
||||
width - 50
|
||||
}" height="8" fill="white" rx="5" />
|
||||
</mask>
|
||||
${compactProgressBar}
|
||||
${createLanguageTextNode({
|
||||
x: 0,
|
||||
y: 25,
|
||||
langs,
|
||||
totalSize: totalLanguageSize,
|
||||
}).join("")}
|
||||
`;
|
||||
} else {
|
||||
finalLayout = FlexLayout({
|
||||
items: langs.map((lang) => {
|
||||
return createProgressNode({
|
||||
width: width,
|
||||
name: lang.name,
|
||||
color: lang.color || "#858585",
|
||||
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
|
||||
});
|
||||
}),
|
||||
gap: 40,
|
||||
direction: "column",
|
||||
}).join("");
|
||||
}
|
||||
|
||||
const card = new Card({
|
||||
title: "Most Used Languages",
|
||||
width,
|
||||
height,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
|
||||
card.disableAnimations();
|
||||
card.setHideBorder(hide_border);
|
||||
card.setHideTitle(hide_title);
|
||||
card.setCSS(`
|
||||
.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
`);
|
||||
|
||||
return card.render(`
|
||||
<svg data-testid="lang-items" x="25">
|
||||
${finalLayout}
|
||||
</svg>
|
||||
`);
|
||||
};
|
||||
|
||||
module.exports = renderTopLanguages;
|
||||
@@ -0,0 +1,166 @@
|
||||
const { FlexLayout } = require("../common/utils");
|
||||
const { getAnimations } = require("../getStyles");
|
||||
|
||||
class Card {
|
||||
constructor({
|
||||
width = 100,
|
||||
height = 100,
|
||||
colors = {},
|
||||
title = "",
|
||||
titlePrefixIcon,
|
||||
}) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.hideBorder = false;
|
||||
this.hideTitle = false;
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
this.colors = colors;
|
||||
this.title = title;
|
||||
this.css = "";
|
||||
|
||||
this.paddingX = 25;
|
||||
this.paddingY = 35;
|
||||
this.titlePrefixIcon = titlePrefixIcon;
|
||||
this.animations = true;
|
||||
}
|
||||
|
||||
disableAnimations() {
|
||||
this.animations = false;
|
||||
}
|
||||
|
||||
setCSS(value) {
|
||||
this.css = value;
|
||||
}
|
||||
|
||||
setHideBorder(value) {
|
||||
this.hideBorder = value;
|
||||
}
|
||||
|
||||
setHideTitle(value) {
|
||||
this.hideTitle = value;
|
||||
if (value) {
|
||||
this.height -= 30;
|
||||
}
|
||||
}
|
||||
|
||||
setTitle(text) {
|
||||
this.title = text;
|
||||
}
|
||||
|
||||
renderTitle() {
|
||||
const titleText = `
|
||||
<text
|
||||
x="0"
|
||||
y="0"
|
||||
class="header"
|
||||
data-testid="header"
|
||||
>${this.title}</text>
|
||||
`;
|
||||
|
||||
const prefixIcon = `
|
||||
<svg
|
||||
class="icon"
|
||||
x="0"
|
||||
y="-13"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
${this.titlePrefixIcon}
|
||||
</svg>
|
||||
`;
|
||||
return `
|
||||
<g
|
||||
data-testid="card-title"
|
||||
transform="translate(${this.paddingX}, ${this.paddingY})"
|
||||
>
|
||||
${FlexLayout({
|
||||
items: [this.titlePrefixIcon && prefixIcon, titleText],
|
||||
gap: 25,
|
||||
}).join("")}
|
||||
</g>
|
||||
`;
|
||||
}
|
||||
|
||||
renderGradient() {
|
||||
if (typeof this.colors.bgColor !== "object") return;
|
||||
|
||||
const gradients = this.colors.bgColor.slice(1);
|
||||
return typeof this.colors.bgColor === "object"
|
||||
? `
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="gradient"
|
||||
gradientTransform="rotate(${this.colors.bgColor[0]})"
|
||||
>
|
||||
${gradients.map((grad, index) => {
|
||||
let offset = (index * 100) / (gradients.length - 1);
|
||||
return `<stop offset="${offset}%" stop-color="#${grad}" />`;
|
||||
})}
|
||||
</linearGradient>
|
||||
</defs>
|
||||
`
|
||||
: "";
|
||||
}
|
||||
|
||||
render(body) {
|
||||
return `
|
||||
<svg
|
||||
width="${this.width}"
|
||||
height="${this.height}"
|
||||
viewBox="0 0 ${this.width} ${this.height}"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style>
|
||||
.header {
|
||||
font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif;
|
||||
fill: ${this.colors.titleColor};
|
||||
animation: fadeInAnimation 0.8s ease-in-out forwards;
|
||||
}
|
||||
${this.css}
|
||||
|
||||
${
|
||||
process.env.NODE_ENV === "test" || !this.animations
|
||||
? ""
|
||||
: getAnimations()
|
||||
}
|
||||
</style>
|
||||
|
||||
${this.renderGradient()}
|
||||
|
||||
<rect
|
||||
data-testid="card-bg"
|
||||
x="0.5"
|
||||
y="0.5"
|
||||
rx="4.5"
|
||||
height="99%"
|
||||
stroke="#E4E2E2"
|
||||
width="${this.width - 1}"
|
||||
fill="${
|
||||
typeof this.colors.bgColor === "object"
|
||||
? "url(#gradient)"
|
||||
: this.colors.bgColor
|
||||
}"
|
||||
stroke-opacity="${this.hideBorder ? 0 : 1}"
|
||||
/>
|
||||
|
||||
${this.hideTitle ? "" : this.renderTitle()}
|
||||
|
||||
<g
|
||||
data-testid="main-card-body"
|
||||
transform="translate(0, ${
|
||||
this.hideTitle ? this.paddingX : this.paddingY + 20
|
||||
})"
|
||||
>
|
||||
${body}
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Card;
|
||||
@@ -1,9 +1,11 @@
|
||||
const { logger } = require("../common/utils");
|
||||
|
||||
const retryer = async (fetcher, variables, retries = 0) => {
|
||||
if (retries > 7) {
|
||||
throw new Error("Maximum retries exceeded");
|
||||
}
|
||||
try {
|
||||
console.log(`Trying PAT_${retries + 1}`);
|
||||
logger.log(`Trying PAT_${retries + 1}`);
|
||||
|
||||
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
|
||||
let response = await fetcher(
|
||||
@@ -18,7 +20,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
||||
// if rate limit is hit increase the RETRIES and recursively call the retryer
|
||||
// with username, and current RETRIES
|
||||
if (isRateExceeded) {
|
||||
console.log(`PAT_${retries + 1} Failed`);
|
||||
logger.log(`PAT_${retries + 1} Failed`);
|
||||
retries++;
|
||||
// directly return from the function
|
||||
return retryer(fetcher, variables, retries);
|
||||
@@ -32,7 +34,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
||||
const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";
|
||||
|
||||
if (isBadCredential) {
|
||||
console.log(`PAT_${retries + 1} Failed`);
|
||||
logger.log(`PAT_${retries + 1} Failed`);
|
||||
retries++;
|
||||
// directly return from the function
|
||||
return retryer(fetcher, variables, retries);
|
||||
@@ -1,25 +1,32 @@
|
||||
const axios = require("axios");
|
||||
const themes = require("../themes");
|
||||
const wrap = require("word-wrap");
|
||||
const themes = require("../../themes");
|
||||
|
||||
const renderError = (message) => {
|
||||
const renderError = (message, secondaryMessage = "") => {
|
||||
return `
|
||||
<svg width="495" height="100" viewBox="0 0 495 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="495" height="120" viewBox="0 0 495 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
|
||||
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #252525 }
|
||||
.gray { fill: #858585 }
|
||||
</style>
|
||||
<rect x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
|
||||
<text x="25" y="45" class="text">Something went wrong! file an issue at https://git.io/JJmN9</text>
|
||||
<text id="message" x="25" y="65" class="text small">${message}</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>
|
||||
`;
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/48073476/10629172
|
||||
function encodeHTML(str) {
|
||||
return str.replace(/[\u00A0-\u9999<>&](?!#)/gim, function (i) {
|
||||
return "&#" + i.charCodeAt(0) + ";";
|
||||
});
|
||||
return str
|
||||
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
|
||||
return "&#" + i.charCodeAt(0) + ";";
|
||||
})
|
||||
.replace(/\u0008/gim, "");
|
||||
}
|
||||
|
||||
function kFormatter(num) {
|
||||
@@ -44,12 +51,31 @@ function parseBoolean(value) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseArray(str) {
|
||||
if (!str) return [];
|
||||
return str.split(",");
|
||||
}
|
||||
|
||||
function clampValue(number, min, max) {
|
||||
return Math.max(min, Math.min(number, max));
|
||||
}
|
||||
|
||||
function isValidGradient(colors) {
|
||||
return isValidHexColor(colors[1]) && isValidHexColor(colors[2]);
|
||||
}
|
||||
|
||||
function fallbackColor(color, fallbackColor) {
|
||||
return (isValidHexColor(color) && `#${color}`) || fallbackColor;
|
||||
let colors = color.split(",");
|
||||
let gradient = null;
|
||||
|
||||
if (colors.length > 1 && isValidGradient(colors)) {
|
||||
gradient = colors;
|
||||
}
|
||||
|
||||
return (
|
||||
(gradient ? gradient : isValidHexColor(color) && `#${color}`) ||
|
||||
fallbackColor
|
||||
);
|
||||
}
|
||||
|
||||
function request(data, headers) {
|
||||
@@ -116,6 +142,28 @@ function getCardColors({
|
||||
return { titleColor, iconColor, textColor, bgColor };
|
||||
}
|
||||
|
||||
function wrapTextMultiline(text, width = 60, maxLines = 3) {
|
||||
const wrapped = wrap(encodeHTML(text), { width })
|
||||
.split("\n") // Split wrapped lines to get an array of lines
|
||||
.map((line) => line.trim()); // Remove leading and trailing whitespace of each line
|
||||
|
||||
const lines = wrapped.slice(0, maxLines); // Only consider maxLines lines
|
||||
|
||||
// Add "..." to the last line if the text exceeds maxLines
|
||||
if (wrapped.length > maxLines) {
|
||||
lines[maxLines - 1] += "...";
|
||||
}
|
||||
|
||||
// Remove empty lines if text fits in less than maxLines lines
|
||||
const multiLineText = lines.filter(Boolean);
|
||||
return multiLineText;
|
||||
}
|
||||
|
||||
const noop = () => {};
|
||||
// return console instance based on the environment
|
||||
const logger =
|
||||
process.env.NODE_ENV !== "test" ? console : { log: noop, error: noop };
|
||||
|
||||
const CONSTANTS = {
|
||||
THIRTY_MINUTES: 1800,
|
||||
TWO_HOURS: 7200,
|
||||
@@ -128,10 +176,13 @@ module.exports = {
|
||||
encodeHTML,
|
||||
isValidHexColor,
|
||||
request,
|
||||
parseArray,
|
||||
parseBoolean,
|
||||
fallbackColor,
|
||||
FlexLayout,
|
||||
getCardColors,
|
||||
clampValue,
|
||||
wrapTextMultiline,
|
||||
logger,
|
||||
CONSTANTS,
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
const { request } = require("./utils");
|
||||
const retryer = require("./retryer");
|
||||
const { request } = require("../common/utils");
|
||||
const retryer = require("../common/retryer");
|
||||
|
||||
const fetcher = (variables, token) => {
|
||||
return request(
|
||||
@@ -10,6 +10,7 @@ const fetcher = (variables, token) => {
|
||||
nameWithOwner
|
||||
isPrivate
|
||||
isArchived
|
||||
isTemplate
|
||||
stargazers {
|
||||
totalCount
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
const { request } = require("./utils");
|
||||
const retryer = require("./retryer");
|
||||
const calculateRank = require("./calculateRank");
|
||||
const { request, logger } = require("../common/utils");
|
||||
const axios = require("axios");
|
||||
const retryer = require("../common/retryer");
|
||||
const calculateRank = require("../calculateRank");
|
||||
const githubUsernameRegex = require("github-username-regex");
|
||||
|
||||
require("dotenv").config();
|
||||
|
||||
const fetcher = (variables, token) => {
|
||||
@@ -13,6 +16,7 @@ const fetcher = (variables, token) => {
|
||||
login
|
||||
contributionsCollection {
|
||||
totalCommitContributions
|
||||
restrictedContributionsCount
|
||||
}
|
||||
repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
|
||||
totalCount
|
||||
@@ -45,7 +49,45 @@ const fetcher = (variables, token) => {
|
||||
);
|
||||
};
|
||||
|
||||
async function fetchStats(username) {
|
||||
// https://github.com/anuraghazra/github-readme-stats/issues/92#issuecomment-661026467
|
||||
// https://github.com/anuraghazra/github-readme-stats/pull/211/
|
||||
const totalCommitsFetcher = async (username) => {
|
||||
if (!githubUsernameRegex.test(username)) {
|
||||
logger.log("Invalid username");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// https://developer.github.com/v3/search/#search-commits
|
||||
const fetchTotalCommits = (variables, token) => {
|
||||
return axios({
|
||||
method: "get",
|
||||
url: `https://api.github.com/search/commits?q=author:${variables.login}`,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/vnd.github.cloak-preview",
|
||||
Authorization: `bearer ${token}`,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
let res = await retryer(fetchTotalCommits, { login: username });
|
||||
if (res.data.total_count) {
|
||||
return res.data.total_count;
|
||||
}
|
||||
} catch (err) {
|
||||
logger.log(err);
|
||||
// just return 0 if there is something wrong so that
|
||||
// we don't break the whole app
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
async function fetchStats(
|
||||
username,
|
||||
count_private = false,
|
||||
include_all_commits = false
|
||||
) {
|
||||
if (!username) throw Error("Invalid username");
|
||||
|
||||
const stats = {
|
||||
@@ -60,16 +102,29 @@ async function fetchStats(username) {
|
||||
|
||||
let res = await retryer(fetcher, { login: username });
|
||||
|
||||
let experimental_totalCommits = 0;
|
||||
if (include_all_commits) {
|
||||
experimental_totalCommits = await totalCommitsFetcher(username);
|
||||
}
|
||||
|
||||
if (res.data.errors) {
|
||||
console.log(res.data.errors);
|
||||
logger.error(res.data.errors);
|
||||
throw Error(res.data.errors[0].message || "Could not fetch user");
|
||||
}
|
||||
|
||||
const user = res.data.data.user;
|
||||
const contributionCount = user.contributionsCollection;
|
||||
|
||||
stats.name = user.name || user.login;
|
||||
stats.totalIssues = user.issues.totalCount;
|
||||
stats.totalCommits = user.contributionsCollection.totalCommitContributions;
|
||||
|
||||
stats.totalCommits =
|
||||
contributionCount.totalCommitContributions + experimental_totalCommits;
|
||||
|
||||
if (count_private) {
|
||||
stats.totalCommits += contributionCount.restrictedContributionsCount;
|
||||
}
|
||||
|
||||
stats.totalPRs = user.pullRequests.totalCount;
|
||||
stats.contributedTo = user.repositoriesContributedTo.totalCount;
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
const { request, logger } = require("../common/utils");
|
||||
const retryer = require("../common/retryer");
|
||||
require("dotenv").config();
|
||||
|
||||
const fetcher = (variables, token) => {
|
||||
return request(
|
||||
{
|
||||
query: `
|
||||
query userInfo($login: String!) {
|
||||
user(login: $login) {
|
||||
# fetch only owner repos & not forks
|
||||
repositories(ownerAffiliations: OWNER, isFork: false, first: 100) {
|
||||
nodes {
|
||||
languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
|
||||
edges {
|
||||
size
|
||||
node {
|
||||
color
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables,
|
||||
},
|
||||
{
|
||||
Authorization: `bearer ${token}`,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
async function fetchTopLanguages(username) {
|
||||
if (!username) throw Error("Invalid username");
|
||||
|
||||
let res = await retryer(fetcher, { login: username });
|
||||
|
||||
if (res.data.errors) {
|
||||
logger.error(res.data.errors);
|
||||
throw Error(res.data.errors[0].message || "Could not fetch user");
|
||||
}
|
||||
|
||||
let repoNodes = res.data.data.user.repositories.nodes;
|
||||
|
||||
repoNodes = repoNodes
|
||||
.filter((node) => {
|
||||
return node.languages.edges.length > 0;
|
||||
})
|
||||
// flatten the list of language nodes
|
||||
.reduce((acc, curr) => curr.languages.edges.concat(acc), [])
|
||||
.sort((a, b) => b.size - a.size)
|
||||
.reduce((acc, prev) => {
|
||||
// get the size of the language (bytes)
|
||||
let langSize = prev.size;
|
||||
|
||||
// if we already have the language in the accumulator
|
||||
// & the current language name is same as previous name
|
||||
// add the size to the language size.
|
||||
if (acc[prev.node.name] && prev.node.name === acc[prev.node.name].name) {
|
||||
langSize = prev.size + acc[prev.node.name].size;
|
||||
}
|
||||
return {
|
||||
...acc,
|
||||
[prev.node.name]: {
|
||||
name: prev.node.name,
|
||||
color: prev.node.color,
|
||||
size: langSize,
|
||||
},
|
||||
};
|
||||
}, {});
|
||||
|
||||
const topLangs = Object.keys(repoNodes)
|
||||
.slice(0, 5)
|
||||
.reduce((result, key) => {
|
||||
result[key] = repoNodes[key];
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
return topLangs;
|
||||
}
|
||||
|
||||
module.exports = fetchTopLanguages;
|
||||
+23
-23
@@ -9,10 +9,23 @@ const calculateCircleProgress = (value) => {
|
||||
return percentage;
|
||||
};
|
||||
|
||||
const getAnimations = ({ progress }) => {
|
||||
const getProgressAnimation = ({ progress }) => {
|
||||
return `
|
||||
@keyframes rankAnimation {
|
||||
from {
|
||||
stroke-dashoffset: ${calculateCircleProgress(0)};
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: ${calculateCircleProgress(progress)};
|
||||
}
|
||||
}
|
||||
`;
|
||||
};
|
||||
|
||||
const getAnimations = () => {
|
||||
return `
|
||||
/* Animations */
|
||||
@keyframes scaleIn {
|
||||
@keyframes scaleInAnimation {
|
||||
from {
|
||||
transform: translate(-5px, 5px) scale(0);
|
||||
}
|
||||
@@ -20,7 +33,7 @@ const getAnimations = ({ progress }) => {
|
||||
transform: translate(-5px, 5px) scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
@keyframes fadeInAnimation {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -28,14 +41,6 @@ const getAnimations = ({ progress }) => {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes rankAnimation {
|
||||
from {
|
||||
stroke-dashoffset: ${calculateCircleProgress(0)};
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: ${calculateCircleProgress(progress)};
|
||||
}
|
||||
}
|
||||
`;
|
||||
};
|
||||
|
||||
@@ -47,20 +52,16 @@ const getStyles = ({
|
||||
progress,
|
||||
}) => {
|
||||
return `
|
||||
.header {
|
||||
font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor};
|
||||
animation: fadeIn 0.8s ease-in-out forwards;
|
||||
}
|
||||
.stat {
|
||||
.stat {
|
||||
font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${textColor};
|
||||
}
|
||||
.stagger {
|
||||
.stagger {
|
||||
opacity: 0;
|
||||
animation: fadeIn 0.3s ease-in-out forwards;
|
||||
animation: fadeInAnimation 0.3s ease-in-out forwards;
|
||||
}
|
||||
.rank-text {
|
||||
.rank-text {
|
||||
font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor};
|
||||
animation: scaleIn 0.3s ease-in-out forwards;
|
||||
animation: scaleInAnimation 0.3s ease-in-out forwards;
|
||||
}
|
||||
|
||||
.bold { font-weight: 700 }
|
||||
@@ -86,9 +87,8 @@ const getStyles = ({
|
||||
transform: rotate(-90deg);
|
||||
animation: rankAnimation 1s forwards ease-in-out;
|
||||
}
|
||||
|
||||
${process.env.NODE_ENV === "test" ? "" : getAnimations({ progress })}
|
||||
${process.env.NODE_ENV === "test" ? "" : getProgressAnimation({ progress })}
|
||||
`;
|
||||
};
|
||||
|
||||
module.exports = getStyles;
|
||||
module.exports = { getStyles, getAnimations };
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
const {
|
||||
kFormatter,
|
||||
encodeHTML,
|
||||
getCardColors,
|
||||
FlexLayout,
|
||||
} = require("../src/utils");
|
||||
const icons = require("./icons");
|
||||
|
||||
const renderRepoCard = (repo, options = {}) => {
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
stargazers,
|
||||
isArchived,
|
||||
forkCount,
|
||||
} = repo;
|
||||
const {
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
show_owner,
|
||||
theme = "default_repocard",
|
||||
} = options;
|
||||
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
const langName = primaryLanguage ? primaryLanguage.name : "Unspecified";
|
||||
const langColor = primaryLanguage ? primaryLanguage.color : "#333";
|
||||
|
||||
const height = 120;
|
||||
const shiftText = langName.length > 15 ? 0 : 30;
|
||||
|
||||
let desc = description || "No description provided";
|
||||
if (desc.length > 55) {
|
||||
desc = `${description.slice(0, 55)}..`;
|
||||
}
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const totalStars = kFormatter(stargazers.totalCount);
|
||||
const totalForks = kFormatter(forkCount);
|
||||
|
||||
const archiveBadge = isArchived
|
||||
? `
|
||||
<g data-testid="archive-badge" class="archive-badge" transform="translate(320, 38)">
|
||||
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
||||
<text fill="${textColor}">Archived</text>
|
||||
</g>
|
||||
`
|
||||
: "";
|
||||
|
||||
const svgLanguage = `
|
||||
<g transform="translate(30, 100)">
|
||||
<circle data-testid="lang-color" cx="0" cy="-5" r="6" fill="${langColor}" />
|
||||
<text data-testid="lang" class="gray" x="15">${langName}</text>
|
||||
</g>
|
||||
`;
|
||||
|
||||
const svgStars =
|
||||
stargazers.totalCount > 0 &&
|
||||
`
|
||||
<svg class="icon" y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||
${icons.star}
|
||||
</svg>
|
||||
<text data-testid="stargazers" class="gray" x="25">${totalStars}</text>
|
||||
`;
|
||||
|
||||
const svgForks =
|
||||
forkCount > 0 &&
|
||||
`
|
||||
<svg class="icon" y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||
${icons.fork}
|
||||
</svg>
|
||||
<text data-testid="forkcount" class="gray" x="25">${totalForks}</text>
|
||||
`;
|
||||
|
||||
return `
|
||||
<svg version="1.1" width="400" height="${height}" viewBox="0 0 400 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.header { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor} }
|
||||
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
.icon { fill: ${iconColor} }
|
||||
.archive-badge { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; }
|
||||
.archive-badge rect { opacity: 0.2 }
|
||||
</style>
|
||||
<rect data-testid="card-bg" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
|
||||
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||
${icons.contribs}
|
||||
</svg>
|
||||
|
||||
${archiveBadge}
|
||||
|
||||
<text x="50" y="38" class="header">${header}</text>
|
||||
<text class="description" x="25" y="70">${encodeHTML(desc)}</text>
|
||||
|
||||
${svgLanguage}
|
||||
|
||||
<g transform="translate(${155 - shiftText}, 100)">
|
||||
${FlexLayout({ items: [svgStars, svgForks], gap: 65 }).join("")}
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
module.exports = renderRepoCard;
|
||||
+45
-5
@@ -2,8 +2,8 @@ require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const api = require("../api/index");
|
||||
const renderStatsCard = require("../src/renderStatsCard");
|
||||
const { renderError, CONSTANTS } = require("../src/utils");
|
||||
const renderStatsCard = require("../src/cards/stats-card");
|
||||
const { renderError, CONSTANTS } = require("../src/common/utils");
|
||||
const calculateRank = require("../src/calculateRank");
|
||||
|
||||
const stats = {
|
||||
@@ -30,7 +30,10 @@ const data = {
|
||||
user: {
|
||||
name: stats.name,
|
||||
repositoriesContributedTo: { totalCount: stats.contributedTo },
|
||||
contributionsCollection: { totalCommitContributions: stats.totalCommits },
|
||||
contributionsCollection: {
|
||||
totalCommitContributions: stats.totalCommits,
|
||||
restrictedContributionsCount: 100,
|
||||
},
|
||||
pullRequests: { totalCount: stats.totalPRs },
|
||||
issues: { totalCount: stats.totalIssues },
|
||||
followers: { totalCount: 0 },
|
||||
@@ -91,14 +94,19 @@ describe("Test /api/", () => {
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderError(error.errors[0].message));
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderError(
|
||||
error.errors[0].message,
|
||||
"Make sure the provided username is not an organization"
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it("should get the query options", async () => {
|
||||
const { req, res } = faker(
|
||||
{
|
||||
username: "anuraghazra",
|
||||
hide: `["issues","prs","contribs"]`,
|
||||
hide: "issues,prs,contribs",
|
||||
show_icons: true,
|
||||
hide_border: true,
|
||||
line_height: 100,
|
||||
@@ -181,4 +189,36 @@ describe("Test /api/", () => {
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it("should add private contributions", async () => {
|
||||
const { req, res } = faker(
|
||||
{
|
||||
username: "anuraghazra",
|
||||
count_private: true,
|
||||
},
|
||||
data
|
||||
);
|
||||
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderStatsCard(
|
||||
{
|
||||
...stats,
|
||||
totalCommits: stats.totalCommits + 100,
|
||||
rank: calculateRank({
|
||||
totalCommits: stats.totalCommits + 100,
|
||||
totalRepos: 1,
|
||||
followers: 0,
|
||||
contributions: stats.contributedTo,
|
||||
stargazers: stats.totalStars,
|
||||
prs: stats.totalPRs,
|
||||
issues: stats.totalIssues,
|
||||
}),
|
||||
},
|
||||
{}
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const cssToObject = require("css-to-object");
|
||||
const Card = require("../src/common/Card");
|
||||
const icons = require("../src/common/icons");
|
||||
const { getCardColors } = require("../src/common/utils");
|
||||
const { queryByTestId } = require("@testing-library/dom");
|
||||
|
||||
describe("Card", () => {
|
||||
it("should hide border", () => {
|
||||
const card = new Card({});
|
||||
card.setHideBorder(true);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"stroke-opacity",
|
||||
"0"
|
||||
);
|
||||
});
|
||||
|
||||
it("should not hide border", () => {
|
||||
const card = new Card({});
|
||||
card.setHideBorder(false);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"stroke-opacity",
|
||||
"1"
|
||||
);
|
||||
});
|
||||
|
||||
it("should hide title", () => {
|
||||
const card = new Card({});
|
||||
card.setHideTitle(true);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "card-title")).toBeNull();
|
||||
});
|
||||
|
||||
it("should not hide title", () => {
|
||||
const card = new Card({});
|
||||
card.setHideTitle(false);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "card-title")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("title should have prefix icon", () => {
|
||||
const card = new Card({ title: "ok", titlePrefixIcon: icons.contribs });
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(document.getElementsByClassName("icon")[0]).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("title should not have prefix icon", () => {
|
||||
const card = new Card({ title: "ok" });
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(document.getElementsByClassName("icon")[0]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should have proper height, width", () => {
|
||||
const card = new Card({ height: 200, width: 200, title: "ok" });
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"200"
|
||||
);
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"200"
|
||||
);
|
||||
});
|
||||
|
||||
it("should have less height after title is hidden", () => {
|
||||
const card = new Card({ height: 200, title: "ok" });
|
||||
card.setHideTitle(true);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"170"
|
||||
);
|
||||
});
|
||||
|
||||
it("main-card-body should have proper when title is visible", () => {
|
||||
const card = new Card({ height: 200 });
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "main-card-body")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(0, 55)"
|
||||
);
|
||||
});
|
||||
|
||||
it("main-card-body should have proper position after title is hidden", () => {
|
||||
const card = new Card({ height: 200 });
|
||||
card.setHideTitle(true);
|
||||
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "main-card-body")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(0, 25)"
|
||||
);
|
||||
});
|
||||
|
||||
it("should render with correct colors", () => {
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color: "f00",
|
||||
icon_color: "0f0",
|
||||
text_color: "00f",
|
||||
bg_color: "fff",
|
||||
theme: "default",
|
||||
});
|
||||
|
||||
const card = new Card({
|
||||
height: 200,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
document.body.innerHTML = card.render(``);
|
||||
|
||||
const styleTag = document.querySelector("style");
|
||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||
const headerClassStyles = stylesObject[".header"];
|
||||
|
||||
expect(headerClassStyles.fill).toBe("#f00");
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"#fff"
|
||||
);
|
||||
});
|
||||
it("should render gradient backgrounds", () => {
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color: "f00",
|
||||
icon_color: "0f0",
|
||||
text_color: "00f",
|
||||
bg_color: "90,fff,000,f00",
|
||||
theme: "default",
|
||||
});
|
||||
|
||||
const card = new Card({
|
||||
height: 200,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
document.body.innerHTML = card.render(``);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"url(#gradient)"
|
||||
);
|
||||
expect(document.querySelector("defs linearGradient")).toHaveAttribute(
|
||||
"gradientTransform",
|
||||
"rotate(90)"
|
||||
);
|
||||
expect(
|
||||
document.querySelector("defs linearGradient stop:nth-child(1)")
|
||||
).toHaveAttribute("stop-color", "#fff");
|
||||
expect(
|
||||
document.querySelector("defs linearGradient stop:nth-child(2)")
|
||||
).toHaveAttribute("stop-color", "#000");
|
||||
expect(
|
||||
document.querySelector("defs linearGradient stop:nth-child(3)")
|
||||
).toHaveAttribute("stop-color", "#f00");
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const fetchRepo = require("../src/fetchRepo");
|
||||
const fetchRepo = require("../src/fetchers/repo-fetcher");
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const fetchStats = require("../src/fetchStats");
|
||||
const fetchStats = require("../src/fetchers/stats-fetcher");
|
||||
const calculateRank = require("../src/calculateRank");
|
||||
|
||||
const data = {
|
||||
@@ -9,7 +9,10 @@ const data = {
|
||||
user: {
|
||||
name: "Anurag Hazra",
|
||||
repositoriesContributedTo: { totalCount: 61 },
|
||||
contributionsCollection: { totalCommitContributions: 100 },
|
||||
contributionsCollection: {
|
||||
totalCommitContributions: 100,
|
||||
restrictedContributionsCount: 50,
|
||||
},
|
||||
pullRequests: { totalCount: 300 },
|
||||
issues: { totalCount: 200 },
|
||||
followers: { totalCount: 100 },
|
||||
@@ -77,4 +80,57 @@ describe("Test fetchStats", () => {
|
||||
"Could not resolve to a User with the login of 'noname'."
|
||||
);
|
||||
});
|
||||
|
||||
it("should fetch and add private contributions", async () => {
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data);
|
||||
|
||||
let stats = await fetchStats("anuraghazra", true);
|
||||
const rank = calculateRank({
|
||||
totalCommits: 150,
|
||||
totalRepos: 5,
|
||||
followers: 100,
|
||||
contributions: 61,
|
||||
stargazers: 400,
|
||||
prs: 300,
|
||||
issues: 200,
|
||||
});
|
||||
|
||||
expect(stats).toStrictEqual({
|
||||
contributedTo: 61,
|
||||
name: "Anurag Hazra",
|
||||
totalCommits: 150,
|
||||
totalIssues: 200,
|
||||
totalPRs: 300,
|
||||
totalStars: 400,
|
||||
rank,
|
||||
});
|
||||
});
|
||||
|
||||
it("should fetch total commits", async () => {
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data);
|
||||
mock
|
||||
.onGet("https://api.github.com/search/commits?q=author:anuraghazra")
|
||||
.reply(200, { total_count: 1000 });
|
||||
|
||||
let stats = await fetchStats("anuraghazra", true, true);
|
||||
const rank = calculateRank({
|
||||
totalCommits: 1000 + 150,
|
||||
totalRepos: 5,
|
||||
followers: 100,
|
||||
contributions: 61,
|
||||
stargazers: 400,
|
||||
prs: 300,
|
||||
issues: 200,
|
||||
});
|
||||
|
||||
expect(stats).toStrictEqual({
|
||||
contributedTo: 61,
|
||||
name: "Anurag Hazra",
|
||||
totalCommits: 1000 + 150,
|
||||
totalIssues: 200,
|
||||
totalPRs: 300,
|
||||
totalStars: 400,
|
||||
rank,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher");
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
afterEach(() => {
|
||||
mock.reset();
|
||||
});
|
||||
|
||||
const data_langs = {
|
||||
data: {
|
||||
user: {
|
||||
repositories: {
|
||||
nodes: [
|
||||
{
|
||||
languages: {
|
||||
edges: [{ size: 100, node: { color: "#0f0", name: "HTML" } }],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [{ size: 100, node: { color: "#0f0", name: "HTML" } }],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [
|
||||
{ size: 100, node: { color: "#0ff", name: "javascript" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [
|
||||
{ size: 100, node: { color: "#0ff", name: "javascript" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const error = {
|
||||
errors: [
|
||||
{
|
||||
type: "NOT_FOUND",
|
||||
path: ["user"],
|
||||
locations: [],
|
||||
message: "Could not resolve to a User with the login of 'noname'.",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe("FetchTopLanguages", () => {
|
||||
it("should fetch correct language data", async () => {
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
let repo = await fetchTopLanguages("anuraghazra");
|
||||
expect(repo).toStrictEqual({
|
||||
HTML: {
|
||||
color: "#0f0",
|
||||
name: "HTML",
|
||||
size: 200,
|
||||
},
|
||||
javascript: {
|
||||
color: "#0ff",
|
||||
name: "javascript",
|
||||
size: 200,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should throw error", async () => {
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, error);
|
||||
|
||||
await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow(
|
||||
"Could not resolve to a User with the login of 'noname'."
|
||||
);
|
||||
});
|
||||
});
|
||||
+3
-2
@@ -2,8 +2,8 @@ require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const pin = require("../api/pin");
|
||||
const renderRepoCard = require("../src/renderRepoCard");
|
||||
const { renderError } = require("../src/utils");
|
||||
const renderRepoCard = require("../src/cards/repo-card");
|
||||
const { renderError } = require("../src/common/utils");
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
@@ -17,6 +17,7 @@ const data_repo = {
|
||||
name: "TypeScript",
|
||||
},
|
||||
forkCount: 100,
|
||||
isTemplate: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const cssToObject = require("css-to-object");
|
||||
const renderRepoCard = require("../src/renderRepoCard");
|
||||
const renderRepoCard = require("../src/cards/repo-card");
|
||||
|
||||
const { queryByTestId } = require("@testing-library/dom");
|
||||
const themes = require("../themes");
|
||||
@@ -29,11 +29,11 @@ describe("Test renderRepoCard", () => {
|
||||
expect(header).toHaveTextContent("convoychat");
|
||||
expect(header).not.toHaveTextContent("anuraghazra");
|
||||
expect(document.getElementsByClassName("description")[0]).toHaveTextContent(
|
||||
"Help us take over the world! React + TS + GraphQL Chat .."
|
||||
"Help us take over the world! React + TS + GraphQL Chat App"
|
||||
);
|
||||
expect(queryByTestId(document.body, "stargazers")).toHaveTextContent("38k");
|
||||
expect(queryByTestId(document.body, "forkcount")).toHaveTextContent("100");
|
||||
expect(queryByTestId(document.body, "lang")).toHaveTextContent(
|
||||
expect(queryByTestId(document.body, "lang-name")).toHaveTextContent(
|
||||
"TypeScript"
|
||||
);
|
||||
expect(queryByTestId(document.body, "lang-color")).toHaveAttribute(
|
||||
@@ -55,12 +55,16 @@ describe("Test renderRepoCard", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
description:
|
||||
"Very long long long long long long long long text it should trim it",
|
||||
"The quick brown fox jumps over the lazy dog is an English-language pangram—a sentence that contains all of the letters of the English alphabet",
|
||||
});
|
||||
|
||||
expect(document.getElementsByClassName("description")[0]).toHaveTextContent(
|
||||
"Very long long long long long long long long text it sh.."
|
||||
);
|
||||
expect(
|
||||
document.getElementsByClassName("description")[0].children[0].textContent
|
||||
).toBe("The quick brown fox jumps over the lazy dog is an");
|
||||
|
||||
expect(
|
||||
document.getElementsByClassName("description")[0].children[1].textContent
|
||||
).toBe("English-language pangram—a sentence that contains all");
|
||||
|
||||
// Should not trim
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
@@ -73,6 +77,18 @@ describe("Test renderRepoCard", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should render emojis", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
description: "This is a text with a :poop: poo emoji",
|
||||
});
|
||||
|
||||
// poop emoji may not show in all editors but it's there between "a" and "poo"
|
||||
expect(document.getElementsByClassName("description")[0]).toHaveTextContent(
|
||||
"This is a text with a 💩 poo emoji"
|
||||
);
|
||||
});
|
||||
|
||||
it("should shift the text position depending on language length", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
@@ -82,9 +98,10 @@ describe("Test renderRepoCard", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(document.getElementsByTagName("g")[1]).toHaveAttribute(
|
||||
expect(queryByTestId(document.body, "primary-lang")).toBeInTheDocument();
|
||||
expect(queryByTestId(document.body, "star-fork-group")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(155, 100)"
|
||||
"translate(155, 0)"
|
||||
);
|
||||
|
||||
// Small lang
|
||||
@@ -96,9 +113,33 @@ describe("Test renderRepoCard", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(document.getElementsByTagName("g")[1]).toHaveAttribute(
|
||||
expect(queryByTestId(document.body, "star-fork-group")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(125, 100)"
|
||||
"translate(125, 0)"
|
||||
);
|
||||
});
|
||||
|
||||
it("should hide language if primaryLanguage is null & fallback to correct values", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
primaryLanguage: null,
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "primary-lang")).toBeNull();
|
||||
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
primaryLanguage: { color: null, name: null },
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "primary-lang")).toBeInTheDocument();
|
||||
expect(queryByTestId(document.body, "lang-color")).toHaveAttribute(
|
||||
"fill",
|
||||
"#333"
|
||||
);
|
||||
|
||||
expect(queryByTestId(document.body, "lang-name")).toHaveTextContent(
|
||||
"Unspecified"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -117,7 +158,7 @@ describe("Test renderRepoCard", () => {
|
||||
expect(iconClassStyles.fill).toBe("#586069");
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"#FFFEFE"
|
||||
"#fffefe"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -217,17 +258,6 @@ describe("Test renderRepoCard", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should render archive badge if repo is archived", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
isArchived: true,
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "archive-badge")).toHaveTextContent(
|
||||
"Archived"
|
||||
);
|
||||
});
|
||||
|
||||
it("should not render star count or fork count if either of the are zero", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
@@ -235,7 +265,7 @@ describe("Test renderRepoCard", () => {
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
||||
expect(queryByTestId(document.body, "forkcount")).toBeDefined();
|
||||
expect(queryByTestId(document.body, "forkcount")).toBeInTheDocument();
|
||||
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
@@ -243,7 +273,7 @@ describe("Test renderRepoCard", () => {
|
||||
forkCount: 0,
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "stargazers")).toBeDefined();
|
||||
expect(queryByTestId(document.body, "stargazers")).toBeInTheDocument();
|
||||
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
||||
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
@@ -255,4 +285,26 @@ describe("Test renderRepoCard", () => {
|
||||
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
||||
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
||||
});
|
||||
|
||||
it("should render badges", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
isArchived: true,
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Archived");
|
||||
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
isTemplate: true,
|
||||
});
|
||||
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Template");
|
||||
});
|
||||
|
||||
it("should not render template", () => {
|
||||
document.body.innerHTML = renderRepoCard({
|
||||
...data_repo.repository,
|
||||
});
|
||||
expect(queryByTestId(document.body, "badge")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const cssToObject = require("css-to-object");
|
||||
const renderStatsCard = require("../src/renderStatsCard");
|
||||
const renderStatsCard = require("../src/cards/stats-card");
|
||||
|
||||
const {
|
||||
getByTestId,
|
||||
@@ -55,7 +55,7 @@ describe("Test renderStatsCard", () => {
|
||||
|
||||
it("should hide individual stats", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, {
|
||||
hide: "['issues', 'prs', 'contribs']",
|
||||
hide: ["issues", "prs", "contribs"],
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -69,12 +69,6 @@ describe("Test renderStatsCard", () => {
|
||||
expect(queryByTestId(document.body, "contribs")).toBeNull();
|
||||
});
|
||||
|
||||
it("should hide_border", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, { hide_border: true });
|
||||
|
||||
expect(queryByTestId(document.body, "card-bg")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should hide_rank", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, { hide_rank: true });
|
||||
|
||||
@@ -96,7 +90,7 @@ describe("Test renderStatsCard", () => {
|
||||
expect(iconClassStyles.fill).toBe("#4c71f2");
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"#FFFEFE"
|
||||
"#fffefe"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -194,36 +188,6 @@ describe("Test renderStatsCard", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should hide the title", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, {
|
||||
hide_title: true,
|
||||
});
|
||||
|
||||
expect(document.getElementsByClassName("header")[0]).toBeUndefined();
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"165"
|
||||
);
|
||||
expect(queryByTestId(document.body, "card-body-content")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(0, -30)"
|
||||
);
|
||||
});
|
||||
|
||||
it("should not hide the title", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, {});
|
||||
|
||||
expect(document.getElementsByClassName("header")[0]).toBeDefined();
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"195"
|
||||
);
|
||||
expect(queryByTestId(document.body, "card-body-content")).toHaveAttribute(
|
||||
"transform",
|
||||
"translate(0, 0)"
|
||||
);
|
||||
});
|
||||
|
||||
it("should render icons correctly", () => {
|
||||
document.body.innerHTML = renderStatsCard(stats, {
|
||||
show_icons: true,
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const cssToObject = require("css-to-object");
|
||||
const renderTopLanguages = require("../src/cards/top-languages-card");
|
||||
|
||||
const { queryByTestId, queryAllByTestId } = require("@testing-library/dom");
|
||||
const themes = require("../themes");
|
||||
|
||||
describe("Test renderTopLanguages", () => {
|
||||
const langs = {
|
||||
HTML: {
|
||||
color: "#0f0",
|
||||
name: "HTML",
|
||||
size: 200,
|
||||
},
|
||||
javascript: {
|
||||
color: "#0ff",
|
||||
name: "javascript",
|
||||
size: 200,
|
||||
},
|
||||
css: {
|
||||
color: "#ff0",
|
||||
name: "css",
|
||||
size: 100,
|
||||
},
|
||||
};
|
||||
|
||||
it("should render correctly", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs);
|
||||
|
||||
expect(queryByTestId(document.body, "header")).toHaveTextContent(
|
||||
"Most Used Languages"
|
||||
);
|
||||
|
||||
expect(queryAllByTestId(document.body, "lang-name")[0]).toHaveTextContent(
|
||||
"HTML"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-name")[1]).toHaveTextContent(
|
||||
"javascript"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-name")[2]).toHaveTextContent(
|
||||
"css"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[0]).toHaveAttribute(
|
||||
"width",
|
||||
"40%"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[1]).toHaveAttribute(
|
||||
"width",
|
||||
"40%"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[2]).toHaveAttribute(
|
||||
"width",
|
||||
"20%"
|
||||
);
|
||||
});
|
||||
|
||||
it("should hide languages when hide is passed", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, {
|
||||
hide: ["HTML"],
|
||||
});
|
||||
expect(queryAllByTestId(document.body, "lang-name")[0]).toBeInTheDocument(
|
||||
"javascript"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-name")[1]).toBeInTheDocument(
|
||||
"css"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-name")[2]).not.toBeDefined();
|
||||
|
||||
// multiple languages passed
|
||||
document.body.innerHTML = renderTopLanguages(langs, {
|
||||
hide: ["HTML", "css"],
|
||||
});
|
||||
expect(queryAllByTestId(document.body, "lang-name")[0]).toBeInTheDocument(
|
||||
"javascript"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-name")[1]).not.toBeDefined();
|
||||
});
|
||||
|
||||
it("should resize the height correctly depending on langs", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, {});
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "205");
|
||||
|
||||
document.body.innerHTML = renderTopLanguages(
|
||||
{
|
||||
...langs,
|
||||
python: {
|
||||
color: "#ff0",
|
||||
name: "python",
|
||||
size: 100,
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "245");
|
||||
});
|
||||
|
||||
it("should render with custom width set", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, {});
|
||||
|
||||
expect(document.querySelector("svg")).toHaveAttribute("width", "300");
|
||||
|
||||
document.body.innerHTML = renderTopLanguages(langs, { card_width: 400 });
|
||||
expect(document.querySelector("svg")).toHaveAttribute("width", "400");
|
||||
});
|
||||
|
||||
it("should render default colors properly", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs);
|
||||
|
||||
const styleTag = document.querySelector("style");
|
||||
const stylesObject = cssToObject(styleTag.textContent);
|
||||
|
||||
const headerStyles = stylesObject[".header"];
|
||||
const langNameStyles = stylesObject[".lang-name"];
|
||||
|
||||
expect(headerStyles.fill).toBe("#2f80ed");
|
||||
expect(langNameStyles.fill).toBe("#333");
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"#fffefe"
|
||||
);
|
||||
});
|
||||
|
||||
it("should render custom colors properly", () => {
|
||||
const customColors = {
|
||||
title_color: "5a0",
|
||||
icon_color: "1b998b",
|
||||
text_color: "9991",
|
||||
bg_color: "252525",
|
||||
};
|
||||
|
||||
document.body.innerHTML = renderTopLanguages(langs, { ...customColors });
|
||||
|
||||
const styleTag = document.querySelector("style");
|
||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||
|
||||
const headerStyles = stylesObject[".header"];
|
||||
const langNameStyles = stylesObject[".lang-name"];
|
||||
|
||||
expect(headerStyles.fill).toBe(`#${customColors.title_color}`);
|
||||
expect(langNameStyles.fill).toBe(`#${customColors.text_color}`);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
"#252525"
|
||||
);
|
||||
});
|
||||
|
||||
it("should render custom colors with themes", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, {
|
||||
title_color: "5a0",
|
||||
theme: "radical",
|
||||
});
|
||||
|
||||
const styleTag = document.querySelector("style");
|
||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||
|
||||
const headerStyles = stylesObject[".header"];
|
||||
const langNameStyles = stylesObject[".lang-name"];
|
||||
|
||||
expect(headerStyles.fill).toBe("#5a0");
|
||||
expect(langNameStyles.fill).toBe(`#${themes.radical.text_color}`);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
`#${themes.radical.bg_color}`
|
||||
);
|
||||
});
|
||||
|
||||
it("should render with all the themes", () => {
|
||||
Object.keys(themes).forEach((name) => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, {
|
||||
theme: name,
|
||||
});
|
||||
|
||||
const styleTag = document.querySelector("style");
|
||||
const stylesObject = cssToObject(styleTag.innerHTML);
|
||||
|
||||
const headerStyles = stylesObject[".header"];
|
||||
const langNameStyles = stylesObject[".lang-name"];
|
||||
|
||||
expect(headerStyles.fill).toBe(`#${themes[name].title_color}`);
|
||||
expect(langNameStyles.fill).toBe(`#${themes[name].text_color}`);
|
||||
expect(queryByTestId(document.body, "card-bg")).toHaveAttribute(
|
||||
"fill",
|
||||
`#${themes[name].bg_color}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should render with layout compact", () => {
|
||||
document.body.innerHTML = renderTopLanguages(langs, { layout: "compact" });
|
||||
|
||||
expect(queryByTestId(document.body, "header")).toHaveTextContent(
|
||||
"Most Used Languages"
|
||||
);
|
||||
|
||||
expect(queryAllByTestId(document.body, "lang-name")[0]).toHaveTextContent(
|
||||
"HTML 40.00%"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[0]).toHaveAttribute(
|
||||
"width",
|
||||
"120.00"
|
||||
);
|
||||
|
||||
expect(queryAllByTestId(document.body, "lang-name")[1]).toHaveTextContent(
|
||||
"javascript 40.00%"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[1]).toHaveAttribute(
|
||||
"width",
|
||||
"120.00"
|
||||
);
|
||||
|
||||
expect(queryAllByTestId(document.body, "lang-name")[2]).toHaveTextContent(
|
||||
"css 20.00%"
|
||||
);
|
||||
expect(queryAllByTestId(document.body, "lang-progress")[2]).toHaveAttribute(
|
||||
"width",
|
||||
"60.00"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,9 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const retryer = require("../src/retryer");
|
||||
const retryer = require("../src/common/retryer");
|
||||
const { logger } = require("../src/common/utils");
|
||||
|
||||
const fetcher = jest.fn((variables, token) => {
|
||||
console.log(variables, token);
|
||||
logger.log(variables, token);
|
||||
return new Promise((res, rej) => res({ data: "ok" }));
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const axios = require("axios");
|
||||
const MockAdapter = require("axios-mock-adapter");
|
||||
const topLangs = require("../api/top-langs");
|
||||
const renderTopLanguages = require("../src/cards/top-languages-card");
|
||||
const { renderError } = require("../src/common/utils");
|
||||
|
||||
const data_langs = {
|
||||
data: {
|
||||
user: {
|
||||
repositories: {
|
||||
nodes: [
|
||||
{
|
||||
languages: {
|
||||
edges: [{ size: 150, node: { color: "#0f0", name: "HTML" } }],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [{ size: 100, node: { color: "#0f0", name: "HTML" } }],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [
|
||||
{ size: 100, node: { color: "#0ff", name: "javascript" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
languages: {
|
||||
edges: [
|
||||
{ size: 100, node: { color: "#0ff", name: "javascript" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const error = {
|
||||
errors: [
|
||||
{
|
||||
type: "NOT_FOUND",
|
||||
path: ["user"],
|
||||
locations: [],
|
||||
message: "Could not fetch user",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const langs = {
|
||||
HTML: {
|
||||
color: "#0f0",
|
||||
name: "HTML",
|
||||
size: 250,
|
||||
},
|
||||
javascript: {
|
||||
color: "#0ff",
|
||||
name: "javascript",
|
||||
size: 200,
|
||||
},
|
||||
};
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
afterEach(() => {
|
||||
mock.reset();
|
||||
});
|
||||
|
||||
describe("Test /api/top-langs", () => {
|
||||
it("should test the request", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
await topLangs(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderTopLanguages(langs));
|
||||
});
|
||||
|
||||
it("should work with the query options", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
hide_title: true,
|
||||
card_width: 100,
|
||||
title_color: "fff",
|
||||
icon_color: "fff",
|
||||
text_color: "fff",
|
||||
bg_color: "fff",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_langs);
|
||||
|
||||
await topLangs(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderTopLanguages(langs, {
|
||||
hide_title: true,
|
||||
card_width: 100,
|
||||
title_color: "fff",
|
||||
icon_color: "fff",
|
||||
text_color: "fff",
|
||||
bg_color: "fff",
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("should render error card on error", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, error);
|
||||
|
||||
await topLangs(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderError(error.errors[0].message));
|
||||
});
|
||||
});
|
||||
+43
-4
@@ -1,10 +1,14 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const {
|
||||
kFormatter,
|
||||
encodeHTML,
|
||||
renderError,
|
||||
FlexLayout,
|
||||
getCardColors,
|
||||
} = require("../src/utils");
|
||||
wrapTextMultiline,
|
||||
} = require("../src/common/utils");
|
||||
|
||||
const { queryByTestId } = require("@testing-library/dom");
|
||||
|
||||
describe("Test utils.js", () => {
|
||||
it("should test kFormatter", () => {
|
||||
@@ -25,9 +29,19 @@ describe("Test utils.js", () => {
|
||||
|
||||
it("should test renderError", () => {
|
||||
document.body.innerHTML = renderError("Something went wrong");
|
||||
expect(document.getElementById("message").textContent).toBe(
|
||||
"Something went wrong"
|
||||
expect(
|
||||
queryByTestId(document.body, "message").children[0]
|
||||
).toHaveTextContent(/Something went wrong/gim);
|
||||
expect(queryByTestId(document.body, "message").children[1]).toBeEmpty(2);
|
||||
|
||||
// Secondary message
|
||||
document.body.innerHTML = renderError(
|
||||
"Something went wrong",
|
||||
"Secondary Message"
|
||||
);
|
||||
expect(
|
||||
queryByTestId(document.body, "message").children[1]
|
||||
).toHaveTextContent(/Secondary Message/gim);
|
||||
});
|
||||
|
||||
it("should test FlexLayout", () => {
|
||||
@@ -82,7 +96,7 @@ describe("Test utils.js", () => {
|
||||
bgColor: "#fff",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("getCardColors: should fallback to specified theme colors if is not defined", () => {
|
||||
let colors = getCardColors({
|
||||
theme: "dark",
|
||||
@@ -95,3 +109,28 @@ describe("Test utils.js", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("wrapTextMultiline", () => {
|
||||
it("should not wrap small texts", () => {
|
||||
{
|
||||
let multiLineText = wrapTextMultiline("Small text should not wrap");
|
||||
expect(multiLineText).toEqual(["Small text should not wrap"]);
|
||||
}
|
||||
});
|
||||
it("should wrap large texts", () => {
|
||||
let multiLineText = wrapTextMultiline(
|
||||
"Hello world long long long text",
|
||||
20,
|
||||
3
|
||||
);
|
||||
expect(multiLineText).toEqual(["Hello world long", "long long text"]);
|
||||
});
|
||||
it("should wrap large texts and limit max lines", () => {
|
||||
let multiLineText = wrapTextMultiline(
|
||||
"Hello world long long long text",
|
||||
10,
|
||||
2
|
||||
);
|
||||
expect(multiLineText).toEqual(["Hello", "world long..."]);
|
||||
});
|
||||
});
|
||||
|
||||
+88
-38
@@ -1,62 +1,112 @@
|
||||
## Available Themes
|
||||
|
||||
<!-- DO NOT EDIT THIS FILE DIRECTLY -->
|
||||
|
||||
With inbuilt themes you can customize the look of the card without doing any manual customization.
|
||||
|
||||
Use `?theme=THEME_NAME` parameter like so :-
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
## Stats
|
||||
|
||||
> These themes work both for the Stats Card and Repo Card.
|
||||
|
||||
| | | |
|
||||
| :---------------------------: | :------------------------------------: | :------------------------------------------: |
|
||||
| `default` ![default][default] | `radical` ![radical][radical] | `merko` ![merko][merko] |
|
||||
| `gruvbox` ![gruvbox][gruvbox] | `tokyonight` ![tokyonight][tokyonight] | `onedark` ![onedark][onedark] |
|
||||
| `cobalt` ![cobalt][cobalt] | `synthwave` ![synthwave][synthwave] | `highcontrast` ![highcontrast][highcontrast] |
|
||||
| `dracula` ![dracula][dracula] | `dark` ![dark][dark] | [Add your theme][add-theme] |
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
| `default` ![default][default] | `dark` ![dark][dark] | `radical` ![radical][radical] |
|
||||
| `merko` ![merko][merko] | `gruvbox` ![gruvbox][gruvbox] | `tokyonight` ![tokyonight][tokyonight] |
|
||||
| `onedark` ![onedark][onedark] | `cobalt` ![cobalt][cobalt] | `synthwave` ![synthwave][synthwave] |
|
||||
| `highcontrast` ![highcontrast][highcontrast] | `dracula` ![dracula][dracula] | `prussian` ![prussian][prussian] |
|
||||
| `monokai` ![monokai][monokai] | `vue` ![vue][vue] | `shades-of-purple` ![shades-of-purple][shades-of-purple] |
|
||||
| `nightowl` ![nightowl][nightowl] | `buefy` ![buefy][buefy] | `blue-green` ![blue-green][blue-green] |
|
||||
| `algolia` ![algolia][algolia] | `great-gatsby` ![great-gatsby][great-gatsby] | `bear` ![bear][bear] |
|
||||
| `solarized-dark` ![solarized-dark][solarized-dark] | `solarized-light` ![solarized-light][solarized-light] | `nord` ![nord][nord] |
|
||||
| `gotham` ![gotham][gotham] | `material-palenight` ![material-palenight][material-palenight] | `graywhite` ![graywhite][graywhite] |
|
||||
| `vue-dark` ![vue-dark][vue-dark] | | [Add your theme][add-theme] |
|
||||
|
||||
## Repo Card
|
||||
|
||||
> These themes work both for the Stats Card and Repo Card.
|
||||
|
||||
| | | |
|
||||
| :------------------------------------------------------: | :---------------------------------------------: | :---------------------------------------------------: |
|
||||
| `default_repocard` ![default_repocard][default_repocard] | `radical` ![radical][radical_repocard] | `merko` ![merko][merko_repocard] |
|
||||
| `gruvbox` ![gruvbox][gruvbox_repocard] | `tokyonight` ![tokyonight][tokyonight_repocard] | `onedark` ![onedark][onedark_repocard] |
|
||||
| `cobalt` ![cobalt][cobalt_repocard] | `synthwave` ![synthwave][synthwave_repocard] | `highcontrast` ![highcontrast][highcontrast_repocard] |
|
||||
| `dracula` ![dracula][dracula_repocard] | `dark` ![dark_repocard][dark_repocard] | [Add your theme][add-theme] |
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
| `default_repocard` ![default_repocard][default_repocard_repo] | `dark` ![dark][dark_repo] | `radical` ![radical][radical_repo] |
|
||||
| `merko` ![merko][merko_repo] | `gruvbox` ![gruvbox][gruvbox_repo] | `tokyonight` ![tokyonight][tokyonight_repo] |
|
||||
| `onedark` ![onedark][onedark_repo] | `cobalt` ![cobalt][cobalt_repo] | `synthwave` ![synthwave][synthwave_repo] |
|
||||
| `highcontrast` ![highcontrast][highcontrast_repo] | `dracula` ![dracula][dracula_repo] | `prussian` ![prussian][prussian_repo] |
|
||||
| `monokai` ![monokai][monokai_repo] | `vue` ![vue][vue_repo] | `shades-of-purple` ![shades-of-purple][shades-of-purple_repo] |
|
||||
| `nightowl` ![nightowl][nightowl_repo] | `buefy` ![buefy][buefy_repo] | `blue-green` ![blue-green][blue-green_repo] |
|
||||
| `algolia` ![algolia][algolia_repo] | `great-gatsby` ![great-gatsby][great-gatsby_repo] | `bear` ![bear][bear_repo] |
|
||||
| `solarized-dark` ![solarized-dark][solarized-dark_repo] | `solarized-light` ![solarized-light][solarized-light_repo] | `nord` ![nord][nord_repo] |
|
||||
| `gotham` ![gotham][gotham_repo] | `material-palenight` ![material-palenight][material-palenight_repo] | `graywhite` ![graywhite][graywhite_repo] |
|
||||
| `vue-dark` ![vue-dark][vue-dark_repo] | | [Add your theme][add-theme] |
|
||||
|
||||
<!-- Repo Card Theme previews -->
|
||||
|
||||
[default_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default_repocard
|
||||
[dark_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dark
|
||||
[radical_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=radical
|
||||
[merko_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=merko
|
||||
[gruvbox_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=gruvbox
|
||||
[cobalt_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=cobalt
|
||||
[dark_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dark
|
||||
[dracula_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dracula
|
||||
[tokyonight_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=tokyonight
|
||||
[synthwave_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=synthwave
|
||||
[onedark_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=onedark
|
||||
[highcontrast_repocard]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=highcontrast
|
||||
[default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default
|
||||
[default_repocard]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default_repocard
|
||||
[dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=dark
|
||||
[radical]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=radical
|
||||
[merko]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=merko
|
||||
[gruvbox]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=gruvbox
|
||||
[tokyonight]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=tokyonight
|
||||
[onedark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=onedark
|
||||
[cobalt]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=cobalt
|
||||
[synthwave]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=synthwave
|
||||
[highcontrast]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=highcontrast
|
||||
[dracula]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=dracula
|
||||
[prussian]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=prussian
|
||||
[monokai]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=monokai
|
||||
[vue]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=vue
|
||||
[shades-of-purple]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=shades-of-purple
|
||||
[nightowl]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=nightowl
|
||||
[buefy]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=buefy
|
||||
[blue-green]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=blue-green
|
||||
[algolia]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=algolia
|
||||
[great-gatsby]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=great-gatsby
|
||||
[bear]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=bear
|
||||
[solarized-dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=solarized-dark
|
||||
[solarized-light]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=solarized-light
|
||||
[nord]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=nord
|
||||
[gotham]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=gotham
|
||||
[material-palenight]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=material-palenight
|
||||
[graywhite]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=graywhite
|
||||
[vue-dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=vue-dark
|
||||
|
||||
<!-- Stats Theme previews -->
|
||||
|
||||
[default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=default&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=dark&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[radical]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=radical&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[merko]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=merko&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[gruvbox]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=gruvbox&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[tokyonight]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=tokyonight&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[onedark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=onedark&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[cobalt]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=cobalt&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[synthwave]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=synthwave&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[highcontrast]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=highcontrast&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[dracula]: https://github-readme-stats.vercel.app/api?username=anuraghazra&theme=dracula&hide=["contribs","prs"]&cache_seconds=86400
|
||||
[default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default
|
||||
[default_repocard_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default_repocard
|
||||
[dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dark
|
||||
[radical_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=radical
|
||||
[merko_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=merko
|
||||
[gruvbox_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=gruvbox
|
||||
[tokyonight_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=tokyonight
|
||||
[onedark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=onedark
|
||||
[cobalt_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=cobalt
|
||||
[synthwave_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=synthwave
|
||||
[highcontrast_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=highcontrast
|
||||
[dracula_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dracula
|
||||
[prussian_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=prussian
|
||||
[monokai_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=monokai
|
||||
[vue_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=vue
|
||||
[shades-of-purple_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=shades-of-purple
|
||||
[nightowl_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=nightowl
|
||||
[buefy_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=buefy
|
||||
[blue-green_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=blue-green
|
||||
[algolia_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=algolia
|
||||
[great-gatsby_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=great-gatsby
|
||||
[bear_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=bear
|
||||
[solarized-dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=solarized-dark
|
||||
[solarized-light_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=solarized-light
|
||||
[nord_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=nord
|
||||
[gotham_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=gotham
|
||||
[material-palenight_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=material-palenight
|
||||
[graywhite_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=graywhite
|
||||
[vue-dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=vue-dark
|
||||
|
||||
|
||||
[add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js
|
||||
|
||||
Wanted to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D
|
||||
|
||||
+104
-2
@@ -3,13 +3,13 @@ const themes = {
|
||||
title_color: "2f80ed",
|
||||
icon_color: "4c71f2",
|
||||
text_color: "333",
|
||||
bg_color: "FFFEFE",
|
||||
bg_color: "fffefe",
|
||||
},
|
||||
default_repocard: {
|
||||
title_color: "2f80ed",
|
||||
icon_color: "586069", // icon color is different
|
||||
text_color: "333",
|
||||
bg_color: "FFFEFE",
|
||||
bg_color: "fffefe",
|
||||
},
|
||||
dark: {
|
||||
title_color: "fff",
|
||||
@@ -77,6 +77,108 @@ const themes = {
|
||||
text_color: "6e93b5",
|
||||
bg_color: "172f45",
|
||||
},
|
||||
monokai: {
|
||||
title_color: "eb1f6a",
|
||||
icon_color: "e28905",
|
||||
text_color: "f1f1eb",
|
||||
bg_color: "272822",
|
||||
},
|
||||
vue: {
|
||||
title_color: "41b883",
|
||||
icon_color: "41b883",
|
||||
text_color: "273849",
|
||||
bg_color: "fffefe",
|
||||
},
|
||||
"shades-of-purple": {
|
||||
title_color: "fad000",
|
||||
icon_color: "b362ff",
|
||||
text_color: "a599e9",
|
||||
bg_color: "2d2b55",
|
||||
},
|
||||
nightowl: {
|
||||
title_color: "c792ea",
|
||||
icon_color: "ffeb95",
|
||||
text_color: "7fdbca",
|
||||
bg_color: "011627",
|
||||
},
|
||||
buefy: {
|
||||
title_color: "7957d5",
|
||||
icon_color: "ff3860",
|
||||
text_color: "363636",
|
||||
bg_color: "ffffff",
|
||||
},
|
||||
"blue-green": {
|
||||
title_color: "2f97c1",
|
||||
icon_color: "f5b700",
|
||||
text_color: "0cf574",
|
||||
bg_color: "040f0f",
|
||||
},
|
||||
algolia: {
|
||||
title_color: "00AEFF",
|
||||
icon_color: "2DDE98",
|
||||
text_color: "FFFFFF",
|
||||
bg_color: "050F2C",
|
||||
},
|
||||
"great-gatsby": {
|
||||
title_color: "ffa726",
|
||||
icon_color: "ffb74d",
|
||||
text_color: "ffd95b",
|
||||
bg_color: "000000",
|
||||
},
|
||||
darcula: {
|
||||
title_color: "BA5F17",
|
||||
icon_color: "84628F",
|
||||
text_color: "BEBEBE",
|
||||
bg_color: "242424",
|
||||
},
|
||||
bear: {
|
||||
title_color: "e03c8a",
|
||||
icon_color: "00AEFF",
|
||||
text_color: "bcb28d",
|
||||
bg_color: "1f2023",
|
||||
},
|
||||
"solarized-dark": {
|
||||
title_color: "268bd2",
|
||||
icon_color: "b58900",
|
||||
text_color: "859900",
|
||||
bg_color: "002b36",
|
||||
},
|
||||
"solarized-light": {
|
||||
title_color: "268bd2",
|
||||
icon_color: "b58900",
|
||||
text_color: "859900",
|
||||
bg_color: "fdf6e3",
|
||||
},
|
||||
nord: {
|
||||
title_color: "81a1c1",
|
||||
text_color: "d8dee9",
|
||||
icon_color: "88c0d0",
|
||||
bg_color: "2e3440",
|
||||
},
|
||||
"gotham": {
|
||||
title_color: "2aa889",
|
||||
icon_color: "599cab",
|
||||
text_color: "99d1ce",
|
||||
bg_color: "0c1014",
|
||||
},
|
||||
"material-palenight": {
|
||||
title_color: "c792ea",
|
||||
icon_color: "89ddff",
|
||||
text_color: "a6accd",
|
||||
bg_color: "292d3e",
|
||||
},
|
||||
"graywhite": {
|
||||
title_color: "24292e",
|
||||
icon_color: "24292e",
|
||||
text_color: "24292e",
|
||||
bg_color: "ffffff",
|
||||
},
|
||||
"vue-dark":{
|
||||
title_color: "19f9d8",
|
||||
icon_color: "19f9d8",
|
||||
text_color: "ffffff",
|
||||
bg_color: "002b36",
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = themes;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/",
|
||||
"destination": "https://github.com/anuraghazra/github-readme-stats"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user