forked from mirrored/github-readme-stats
Compare commits
283
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b65f498e55 | ||
|
|
2817001891 | ||
|
|
c8af8c52db | ||
|
|
232270d74d | ||
|
|
63abbdc2e2 | ||
|
|
935e5b3eda | ||
|
|
ad8ba37d51 | ||
|
|
81b651d58e | ||
|
|
13754b3d1f | ||
|
|
d07b088a85 | ||
|
|
4d2e77bfec | ||
|
|
e54b15ea69 | ||
|
|
eeefd7e6a4 | ||
|
|
ef3139f015 | ||
|
|
cea9e64a70 | ||
|
|
bc601863f6 | ||
|
|
490b022618 | ||
|
|
7d311d5c65 | ||
|
|
a3cfe1b602 | ||
|
|
3344bfd150 | ||
|
|
e4f8c521a4 | ||
|
|
e86b74d7df | ||
|
|
290d0946c6 | ||
|
|
7905f8e5c2 | ||
|
|
01d4705e1c | ||
|
|
b88bf687af | ||
|
|
590dab64ba | ||
|
|
5b6b399d6e | ||
|
|
74142f012f | ||
|
|
2861fb4781 | ||
|
|
b2fbca83b3 | ||
|
|
318a3c83b4 | ||
|
|
194db99da7 | ||
|
|
d234202c83 | ||
|
|
024db90fa8 | ||
|
|
7c9bfeab17 | ||
|
|
244ac4df31 | ||
|
|
0810a1d844 | ||
|
|
03c1974a73 | ||
|
|
90e415b698 | ||
|
|
5fdf20e7f6 | ||
|
|
3b2c8885fc | ||
|
|
2bdb5359cd | ||
|
|
396105ee60 | ||
|
|
5ba83c5663 | ||
|
|
6da4265302 | ||
|
|
9bfae5883f | ||
|
|
bb68a8621d | ||
|
|
4bc92a5929 | ||
|
|
cdbf21249d | ||
|
|
a091154ab2 | ||
|
|
d3886588bd | ||
|
|
5c9d4fdf5b | ||
|
|
764b4c9493 | ||
|
|
221831bfed | ||
|
|
abea3ee49f | ||
|
|
5c4faa2274 | ||
|
|
0cbe58a867 | ||
|
|
f86a12b34d | ||
|
|
745433a153 | ||
|
|
c85d5920e7 | ||
|
|
7e60f6c950 | ||
|
|
9a0d9ae2c1 | ||
|
|
78cef88da6 | ||
|
|
4e8345a5a9 | ||
|
|
3bd266c1e0 | ||
|
|
706d311bd6 | ||
|
|
bebcb26431 | ||
|
|
53e40413e7 | ||
|
|
cdc6ad1eaf | ||
|
|
37bf205914 | ||
|
|
4a795c66e6 | ||
|
|
212eb2c842 | ||
|
|
b59745c09c | ||
|
|
a148495a2e | ||
|
|
3b0699a14e | ||
|
|
af2a595f27 | ||
|
|
c2c825424b | ||
|
|
92237caa2f | ||
|
|
57ccffc795 | ||
|
|
2dd1ea1c03 | ||
|
|
c0a9cc6615 | ||
|
|
27ba0bd8a3 | ||
|
|
f86a548799 | ||
|
|
ea935528ce | ||
|
|
43009e2bf8 | ||
|
|
d87baf51c5 | ||
|
|
e331475796 | ||
|
|
e7d086046b | ||
|
|
4720be4c98 | ||
|
|
7a1edb21b1 | ||
|
|
87dd0fa735 | ||
|
|
3645362350 | ||
|
|
856ea613e6 | ||
|
|
a8e44580fe | ||
|
|
8ecc085cc5 | ||
|
|
9a5b007e1d | ||
|
|
ce831da0a9 | ||
|
|
11219b1275 | ||
|
|
30db7790d6 | ||
|
|
08c94ac28c | ||
|
|
5e9445112b | ||
|
|
9ce55231a8 | ||
|
|
d0c290408f | ||
|
|
e559268be4 | ||
|
|
d0cc449e64 | ||
|
|
911958f5a0 | ||
|
|
d52deb0758 | ||
|
|
16b4382269 | ||
|
|
5325e6afe5 | ||
|
|
8aa4c0776b | ||
|
|
120f176f21 | ||
|
|
bf7a3b0f45 | ||
|
|
975d38b9f0 | ||
|
|
d91f6295f6 | ||
|
|
13b3660b6c | ||
|
|
af839e9609 | ||
|
|
dc4717af57 | ||
|
|
20fb82fa0a | ||
|
|
6c6888e516 | ||
|
|
0496044a76 | ||
|
|
b6f5077d58 | ||
|
|
62cdee3c6e | ||
|
|
26571cab88 | ||
|
|
bf4fbc2fa8 | ||
|
|
66579b1466 | ||
|
|
6999c86048 | ||
|
|
127a5076dc | ||
|
|
e48d073ac4 | ||
|
|
e26c013593 | ||
|
|
1a269d6fa4 | ||
|
|
2ec2716ec0 | ||
|
|
7a78036e3f | ||
|
|
e06b0d2960 | ||
|
|
0bdc2bf742 | ||
|
|
e1356e3d50 | ||
|
|
124225d321 | ||
|
|
daa04325a4 | ||
|
|
9d9ad871ac | ||
|
|
d739c0a973 | ||
|
|
cb4b630398 | ||
|
|
0b3e07adae | ||
|
|
ee0b0e9ff8 | ||
|
|
0706c26c44 | ||
|
|
e93b5d5e99 | ||
|
|
af9b2c8b94 | ||
|
|
c9f850ce22 | ||
|
|
bd5f26844b | ||
|
|
a71bb1bbbd | ||
|
|
fd12c01494 | ||
|
|
0a372d2ca1 | ||
|
|
4761871c92 | ||
|
|
df84138c9c | ||
|
|
018e7fd86a | ||
|
|
abf9c666a1 | ||
|
|
8282afb486 | ||
|
|
9ea7535e5b | ||
|
|
4de672c1d8 | ||
|
|
e69427e73f | ||
|
|
1d27c6b1da | ||
|
|
c2647d848d | ||
|
|
537862f75f | ||
|
|
364bba7018 | ||
|
|
1e30934f6b | ||
|
|
918d274022 | ||
|
|
663e4f0536 | ||
|
|
57960248b7 | ||
|
|
200b7035bb | ||
|
|
8c268eefb7 | ||
|
|
bf937abfca | ||
|
|
c48c4f513e | ||
|
|
916c51a03c | ||
|
|
c213f9ea1a | ||
|
|
2f67ff11cb | ||
|
|
e71c63d5ac | ||
|
|
a7159aae49 | ||
|
|
8ad4eee3a7 | ||
|
|
3ba76665c0 | ||
|
|
5f411be854 | ||
|
|
1be7d06fd3 | ||
|
|
3e14bafe6b | ||
|
|
62c7101183 | ||
|
|
91d0ed68c8 | ||
|
|
95333194c5 | ||
|
|
5a05bd2180 | ||
|
|
13c25c7a62 | ||
|
|
547660b0f1 | ||
|
|
319e3d401f | ||
|
|
0704b5a58d | ||
|
|
26f6d7f759 | ||
|
|
b9fa27bf22 | ||
|
|
8b610da0c0 | ||
|
|
734c69a70b | ||
|
|
4f567cc334 | ||
|
|
91db5356fc | ||
|
|
533469d677 | ||
|
|
fa50161a65 | ||
|
|
9a11163c49 | ||
|
|
eb3b4d1f6a | ||
|
|
3d996b940b | ||
|
|
14fe8cd650 | ||
|
|
9cce439520 | ||
|
|
d1540efc1b | ||
|
|
39e8c20768 | ||
|
|
62662be9cf | ||
|
|
940646697f | ||
|
|
258d54d134 | ||
|
|
69f58261d8 | ||
|
|
5dd50ee847 | ||
|
|
1852db0635 | ||
|
|
53a1e349e3 | ||
|
|
d2dbffeb2d | ||
|
|
4710f24670 | ||
|
|
7d4c49b7f7 | ||
|
|
59367dc6b0 | ||
|
|
c1e8037973 | ||
|
|
f44dddef0b | ||
|
|
e30da927c7 | ||
|
|
3ea55bb73e | ||
|
|
82699d6ba6 | ||
|
|
beb0172465 | ||
|
|
9c1bb80fdb | ||
|
|
f831dadf79 | ||
|
|
c402a23360 | ||
|
|
2259870e8e | ||
|
|
c31f3e81bd | ||
|
|
23472f40e8 | ||
|
|
6633d68f79 | ||
|
|
34c67ffa6d | ||
|
|
4412af8b53 | ||
|
|
91889a3319 | ||
|
|
105e136c5e | ||
|
|
1cba9c13f3 | ||
|
|
80b2d23242 | ||
|
|
1656ec6d3c | ||
|
|
0616df3746 | ||
|
|
7595456677 | ||
|
|
4793de4a6e | ||
|
|
c6c4a88d6d | ||
|
|
1262002624 | ||
|
|
b8983dd697 | ||
|
|
a8663a8025 | ||
|
|
afcb773b11 | ||
|
|
ffe28620ba | ||
|
|
723cdd74d4 | ||
|
|
68c49dd824 | ||
|
|
ddcc30d641 | ||
|
|
d4f1a5d061 | ||
|
|
f26b83d6cd | ||
|
|
3a15963a3d | ||
|
|
49973083b1 | ||
|
|
e50a9b435c | ||
|
|
e04e1397c5 | ||
|
|
36bbea2aab | ||
|
|
034ee0666e | ||
|
|
d654fe5715 | ||
|
|
51eefa2dca | ||
|
|
5ea659579e | ||
|
|
edf9f7413b | ||
|
|
aa90efcae5 | ||
|
|
dda9647c49 | ||
|
|
8d7e9df697 | ||
|
|
843b15ed36 | ||
|
|
a99abe8c24 | ||
|
|
bc7ea33782 | ||
|
|
79cee30ac3 | ||
|
|
e5b5da86e5 | ||
|
|
6d8169fd2c | ||
|
|
90c30f2bd2 | ||
|
|
5b3b920ed2 | ||
|
|
236577f70a | ||
|
|
ff16984988 | ||
|
|
2ddcd9c2bd | ||
|
|
1886fe0379 | ||
|
|
2b90336430 | ||
|
|
6cf9bb8448 | ||
|
|
10236d8cd3 | ||
|
|
91a3ac2705 | ||
|
|
2feebd011d | ||
|
|
5b72dfbc32 | ||
|
|
89fc14609e | ||
|
|
9c6eb22862 | ||
|
|
db921818be |
+208
-209
@@ -1,235 +1,234 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
// "eslint:recommended",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2022
|
||||
},
|
||||
"rules": {
|
||||
// Possible Errors (overrides from recommended set)
|
||||
// {
|
||||
// "env": {
|
||||
// "node": true,
|
||||
// "browser": true,
|
||||
// "es2021": true
|
||||
// },
|
||||
// "extends": [
|
||||
// // "eslint:recommended",
|
||||
// "prettier"
|
||||
// ],
|
||||
// "parserOptions": {
|
||||
// "sourceType": "module",
|
||||
// "ecmaVersion": 2022
|
||||
// },
|
||||
// "rules": {
|
||||
// // Possible Errors (overrides from recommended set)
|
||||
|
||||
// "no-extra-parens": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
// // "no-extra-parens": "error",
|
||||
// "no-unexpected-multiline": "error",
|
||||
|
||||
// All JSDoc comments must be valid
|
||||
// // All JSDoc comments must be valid
|
||||
|
||||
"valid-jsdoc": [ "error", {
|
||||
"requireReturn": true,
|
||||
"requireReturnDescription": true,
|
||||
"requireParamDescription": true,
|
||||
"prefer": {
|
||||
"return": "returns"
|
||||
}
|
||||
}],
|
||||
// "valid-jsdoc": [ "error", {
|
||||
// "requireReturn": true,
|
||||
// "requireReturnDescription": true,
|
||||
// "requireParamDescription": true,
|
||||
// "prefer": {
|
||||
// "return": "returns"
|
||||
// }
|
||||
// }],
|
||||
|
||||
// Best Practices
|
||||
// // Best Practices
|
||||
|
||||
// Allowed a getter without setter, but all setters require getters
|
||||
// // Allowed a getter without setter, but all setters require getters
|
||||
|
||||
"accessor-pairs": [ "error", {
|
||||
"getWithoutSet": false,
|
||||
"setWithoutGet": true
|
||||
}],
|
||||
"block-scoped-var": "warn",
|
||||
"consistent-return": "error",
|
||||
"curly": "error",
|
||||
// "default-case": "warn",
|
||||
// "accessor-pairs": [ "error", {
|
||||
// "getWithoutSet": false,
|
||||
// "setWithoutGet": true
|
||||
// }],
|
||||
// "block-scoped-var": "warn",
|
||||
// "consistent-return": "error",
|
||||
// "curly": "error",
|
||||
// // "default-case": "warn",
|
||||
|
||||
// the dot goes with the property when doing multiline
|
||||
// // the dot goes with the property when doing multiline
|
||||
|
||||
// "dot-location": [ "warn", "property" ],
|
||||
// "dot-notation": "warn",
|
||||
// "eqeqeq": [ "error", "smart" ],
|
||||
// "guard-for-in": "warn",
|
||||
// "no-alert": "error",
|
||||
// "no-caller": "error",
|
||||
// "no-case-declarations": "warn",
|
||||
// "no-div-regex": "warn",
|
||||
// "no-else-return": "warn",
|
||||
// "no-empty-label": "warn",
|
||||
// "no-empty-pattern": "warn",
|
||||
// "no-eq-null": "warn",
|
||||
// "no-eval": "error",
|
||||
// "no-extend-native": "error",
|
||||
// "no-extra-bind": "warn",
|
||||
// "no-floating-decimal": "warn",
|
||||
// "no-implicit-coercion": [ "warn", {
|
||||
// "boolean": true,
|
||||
// "number": true,
|
||||
// "string": true
|
||||
// }],
|
||||
// "no-implied-eval": "error",
|
||||
// "no-invalid-this": "error",
|
||||
// "no-iterator": "error",
|
||||
// "no-labels": "warn",
|
||||
// "no-lone-blocks": "warn",
|
||||
// "no-loop-func": "error",
|
||||
// "no-magic-numbers": "warn",
|
||||
// "no-multi-spaces": "error",
|
||||
// "no-multi-str": "warn",
|
||||
// "no-native-reassign": "error",
|
||||
// "no-new-func": "error",
|
||||
// "no-new-wrappers": "error",
|
||||
// "no-new": "error",
|
||||
// "no-octal-escape": "error",
|
||||
// "no-param-reassign": "error",
|
||||
// "no-process-env": "warn",
|
||||
// "no-proto": "error",
|
||||
// "no-redeclare": "error",
|
||||
// "no-return-assign": "error",
|
||||
// "no-script-url": "error",
|
||||
// "no-self-compare": "error",
|
||||
// "no-throw-literal": "error",
|
||||
// "no-unused-expressions": "error",
|
||||
// "no-useless-call": "error",
|
||||
// "no-useless-concat": "error",
|
||||
// "no-void": "warn",
|
||||
// // "dot-location": [ "warn", "property" ],
|
||||
// // "dot-notation": "warn",
|
||||
// // "eqeqeq": [ "error", "smart" ],
|
||||
// // "guard-for-in": "warn",
|
||||
// "no-alert": "error",
|
||||
// "no-caller": "error",
|
||||
// // "no-case-declarations": "warn",
|
||||
// // "no-div-regex": "warn",
|
||||
// // "no-else-return": "warn",
|
||||
// // "no-empty-label": "warn",
|
||||
// // "no-empty-pattern": "warn",
|
||||
// // "no-eq-null": "warn",
|
||||
// // "no-eval": "error",
|
||||
// // "no-extend-native": "error",
|
||||
// // "no-extra-bind": "warn",
|
||||
// // "no-floating-decimal": "warn",
|
||||
// // "no-implicit-coercion": [ "warn", {
|
||||
// // "boolean": true,
|
||||
// // "number": true,
|
||||
// // "string": true
|
||||
// // }],
|
||||
// // "no-implied-eval": "error",
|
||||
// // "no-invalid-this": "error",
|
||||
// // "no-iterator": "error",
|
||||
// // "no-labels": "warn",
|
||||
// // "no-lone-blocks": "warn",
|
||||
// // "no-loop-func": "error",
|
||||
// // "no-magic-numbers": "warn",
|
||||
// // "no-multi-spaces": "error",
|
||||
// // "no-multi-str": "warn",
|
||||
// // "no-native-reassign": "error",
|
||||
// // "no-new-func": "error",
|
||||
// // "no-new-wrappers": "error",
|
||||
// // "no-new": "error",
|
||||
// // "no-octal-escape": "error",
|
||||
// // "no-param-reassign": "error",
|
||||
// // "no-process-env": "warn",
|
||||
// // "no-proto": "error",
|
||||
// // "no-redeclare": "error",
|
||||
// // "no-return-assign": "error",
|
||||
// // "no-script-url": "error",
|
||||
// // "no-self-compare": "error",
|
||||
// // "no-throw-literal": "error",
|
||||
// // "no-unused-expressions": "error",
|
||||
// // "no-useless-call": "error",
|
||||
// // "no-useless-concat": "error",
|
||||
// // "no-void": "warn",
|
||||
|
||||
// Produce warnings when something is commented as TODO or FIXME
|
||||
// // Produce warnings when something is commented as TODO or FIXME
|
||||
|
||||
"no-warning-comments": [ "warn", {
|
||||
"terms": [ "TODO", "FIXME" ],
|
||||
"location": "start"
|
||||
}],
|
||||
"no-with": "warn",
|
||||
"radix": "warn",
|
||||
// "vars-on-top": "error",
|
||||
// "no-warning-comments": [ "warn", {
|
||||
// "terms": [ "TODO", "FIXME" ],
|
||||
// "location": "start"
|
||||
// }],
|
||||
// "no-with": "warn",
|
||||
// "radix": "warn",
|
||||
// // "vars-on-top": "error",
|
||||
|
||||
// Enforces the style of wrapped functions
|
||||
// "wrap-iife": [ "error", "outside" ],
|
||||
// "yoda": "error",
|
||||
// // Enforces the style of wrapped functions
|
||||
// // "wrap-iife": [ "error", "outside" ],
|
||||
// // "yoda": "error",
|
||||
|
||||
// Strict Mode - for ES6, never use strict.
|
||||
// "strict": [ "error", "never" ],
|
||||
// // Strict Mode - for ES6, never use strict.
|
||||
// // "strict": [ "error", "never" ],
|
||||
|
||||
// Variables
|
||||
// // Variables
|
||||
|
||||
// "init-declarations": [ "error", "always" ],
|
||||
// "no-catch-shadow": "warn",
|
||||
// "no-delete-var": "error",
|
||||
// "no-label-var": "error",
|
||||
// "no-shadow-restricted-names": "error",
|
||||
// "no-shadow": "warn",
|
||||
// // "init-declarations": [ "error", "always" ],
|
||||
// // "no-catch-shadow": "warn",
|
||||
// "no-delete-var": "error",
|
||||
// // "no-label-var": "error",
|
||||
// // "no-shadow-restricted-names": "error",
|
||||
// // "no-shadow": "warn",
|
||||
|
||||
// We require all vars to be initialized (see init-declarations)
|
||||
// If we NEED a var to be initialized to undefined, it needs to be explicit
|
||||
// // We require all vars to be initialized (see init-declarations)
|
||||
// // If we NEED a var to be initialized to undefined, it needs to be explicit
|
||||
|
||||
"no-undef-init": "off",
|
||||
"no-undef": "error",
|
||||
"no-undefined": "off",
|
||||
"no-unused-vars": "warn",
|
||||
// "no-undef-init": "off",
|
||||
// "no-undef": "error",
|
||||
// "no-undefined": "off",
|
||||
// "no-unused-vars": "warn",
|
||||
|
||||
// Disallow hoisting - let & const don't allow hoisting anyhow
|
||||
// // Disallow hoisting - let & const don't allow hoisting anyhow
|
||||
|
||||
"no-use-before-define": "error",
|
||||
// "no-use-before-define": "error",
|
||||
|
||||
// Node.js and CommonJS
|
||||
// // Node.js and CommonJS
|
||||
|
||||
// "callback-return": [ "warn", [ "callback", "next" ]],
|
||||
// "global-require": "error",
|
||||
// "handle-callback-err": "warn",
|
||||
// "no-mixed-requires": "warn",
|
||||
// "no-new-require": "error",
|
||||
// // "callback-return": [ "warn", [ "callback", "next" ]],
|
||||
// // "global-require": "error",
|
||||
// // "handle-callback-err": "warn",
|
||||
// // "no-mixed-requires": "warn",
|
||||
// // "no-new-require": "error",
|
||||
|
||||
// Use path.concat instead
|
||||
// // Use path.concat instead
|
||||
|
||||
// "no-path-concat": "error",
|
||||
// "no-process-exit": "error",
|
||||
// "no-restricted-modules": "off",
|
||||
// "no-sync": "warn",
|
||||
// // "no-path-concat": "error",
|
||||
// // "no-process-exit": "error",
|
||||
// // "no-restricted-modules": "off",
|
||||
// // "no-sync": "warn",
|
||||
|
||||
// ECMAScript 6 support
|
||||
// // ECMAScript 6 support
|
||||
|
||||
// "arrow-body-style": [ "error", "always" ],
|
||||
// "arrow-parens": [ "error", "always" ],
|
||||
// "arrow-spacing": [ "error", { "before": true, "after": true }],
|
||||
// "constructor-super": "error",
|
||||
// "generator-star-spacing": [ "error", "before" ],
|
||||
// "no-arrow-condition": "error",
|
||||
// "no-class-assign": "error",
|
||||
// "no-const-assign": "error",
|
||||
// "no-dupe-class-members": "error",
|
||||
"no-this-before-super": "error",
|
||||
// "no-var": "warn",
|
||||
"object-shorthand": [ "warn" ],
|
||||
// "prefer-arrow-callback": "warn",
|
||||
// "prefer-spread": "warn",
|
||||
// "prefer-template": "warn",
|
||||
// "require-yield": "error",
|
||||
// // "arrow-body-style": [ "error", "always" ],
|
||||
// // "arrow-parens": [ "error", "always" ],
|
||||
// // "arrow-spacing": [ "error", { "before": true, "after": true }],
|
||||
// "constructor-super": "error",
|
||||
// // "generator-star-spacing": [ "error", "before" ],
|
||||
// // "no-arrow-condition": "error",
|
||||
// "no-class-assign": "error",
|
||||
// "no-const-assign": "error",
|
||||
// "no-dupe-class-members": "error",
|
||||
// "no-this-before-super": "error",
|
||||
// // "no-var": "warn",
|
||||
// "object-shorthand": [ "warn" ],
|
||||
// // "prefer-arrow-callback": "warn",
|
||||
// // "prefer-spread": "warn",
|
||||
// // "prefer-template": "warn",
|
||||
// // "require-yield": "error",
|
||||
|
||||
// Stylistic - everything here is a warning because of style.
|
||||
// // Stylistic - everything here is a warning because of style.
|
||||
|
||||
// "array-bracket-spacing": [ "warn", "always" ],
|
||||
// "block-spacing": [ "warn", "always" ],
|
||||
// "brace-style": [ "warn", "1tbs", { "allowSingleLine": false } ],
|
||||
// "camelcase": "warn",
|
||||
// "comma-spacing": [ "warn", { "before": false, "after": true } ],
|
||||
// "comma-style": [ "warn", "last" ],
|
||||
// "computed-property-spacing": [ "warn", "never" ],
|
||||
// "consistent-this": [ "warn", "self" ],
|
||||
// "eol-last": "warn",
|
||||
// "func-names": "warn",
|
||||
// "func-style": [ "warn", "declaration" ],
|
||||
// "id-length": [ "warn", { "min": 2, "max": 32 } ],
|
||||
// "indent": [ "warn", 4 ],
|
||||
// "jsx-quotes": [ "warn", "prefer-double" ],
|
||||
// "linebreak-style": [ "warn", "unix" ],
|
||||
// "lines-around-comment": [ "warn", { "beforeBlockComment": true } ],
|
||||
// "max-depth": [ "warn", 8 ],
|
||||
// "max-len": [ "warn", 132 ],
|
||||
// "max-nested-callbacks": [ "warn", 8 ],
|
||||
// "max-params": [ "warn", 8 ],
|
||||
// "new-cap": "warn",
|
||||
// "new-parens": "warn",
|
||||
// "no-array-constructor": "warn",
|
||||
// "no-bitwise": "off",
|
||||
// "no-continue": "off",
|
||||
// "no-inline-comments": "off",
|
||||
// "no-lonely-if": "warn",
|
||||
"no-mixed-spaces-and-tabs": "warn",
|
||||
"no-multiple-empty-lines": "warn",
|
||||
"no-negated-condition": "warn",
|
||||
// "no-nested-ternary": "warn",
|
||||
// "no-new-object": "warn",
|
||||
// "no-plusplus": "off",
|
||||
// "no-spaced-func": "warn",
|
||||
// "no-ternary": "off",
|
||||
// "no-trailing-spaces": "warn",
|
||||
// "no-underscore-dangle": "warn",
|
||||
"no-unneeded-ternary": "warn",
|
||||
// "object-curly-spacing": [ "warn", "always" ],
|
||||
// "one-var": "off",
|
||||
// "operator-assignment": [ "warn", "never" ],
|
||||
// "operator-linebreak": [ "warn", "after" ],
|
||||
// "padded-blocks": [ "warn", "never" ],
|
||||
// "quote-props": [ "warn", "consistent-as-needed" ],
|
||||
// "quotes": [ "warn", "single" ],
|
||||
"require-jsdoc": [ "warn", {
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": true,
|
||||
"ClassDeclaration": false
|
||||
}
|
||||
}]
|
||||
// "semi-spacing": [ "warn", { "before": false, "after": true }],
|
||||
// "semi": [ "error", "always" ],
|
||||
// "sort-vars": "off",
|
||||
// "space-after-keywords": [ "warn", "always" ],
|
||||
// "space-before-blocks": [ "warn", "always" ],
|
||||
// "space-before-function-paren": [ "warn", "never" ],
|
||||
// "space-before-keywords": [ "warn", "always" ],
|
||||
// "space-in-parens": [ "warn", "never" ],
|
||||
// "space-infix-ops": [ "warn", { "int32Hint": true } ],
|
||||
// "space-return-throw-case": "error",
|
||||
// "space-unary-ops": "error",
|
||||
// "spaced-comment": [ "warn", "always" ],
|
||||
// "wrap-regex": "warn"
|
||||
}
|
||||
}
|
||||
// // "array-bracket-spacing": [ "warn", "always" ],
|
||||
// // "block-spacing": [ "warn", "always" ],
|
||||
// // "brace-style": [ "warn", "1tbs", { "allowSingleLine": false } ],
|
||||
// // "camelcase": "warn",
|
||||
// // "comma-spacing": [ "warn", { "before": false, "after": true } ],
|
||||
// // "comma-style": [ "warn", "last" ],
|
||||
// // "computed-property-spacing": [ "warn", "never" ],
|
||||
// // "consistent-this": [ "warn", "self" ],
|
||||
// // "eol-last": "warn",
|
||||
// // "func-names": "warn",
|
||||
// // "func-style": [ "warn", "declaration" ],
|
||||
// // "id-length": [ "warn", { "min": 2, "max": 32 } ],
|
||||
// // "indent": [ "warn", 4 ],
|
||||
// // "jsx-quotes": [ "warn", "prefer-double" ],
|
||||
// // "linebreak-style": [ "warn", "unix" ],
|
||||
// // "lines-around-comment": [ "warn", { "beforeBlockComment": true } ],
|
||||
// // "max-depth": [ "warn", 8 ],
|
||||
// // "max-len": [ "warn", 132 ],
|
||||
// // "max-nested-callbacks": [ "warn", 8 ],
|
||||
// // "max-params": [ "warn", 8 ],
|
||||
// // "new-cap": "warn",
|
||||
// // "new-parens": "warn",
|
||||
// // "no-array-constructor": "warn",
|
||||
// // "no-bitwise": "off",
|
||||
// // "no-continue": "off",
|
||||
// // "no-inline-comments": "off",
|
||||
// // "no-lonely-if": "warn",
|
||||
// "no-mixed-spaces-and-tabs": "warn",
|
||||
// "no-multiple-empty-lines": "warn",
|
||||
// "no-negated-condition": "warn",
|
||||
// // "no-nested-ternary": "warn",
|
||||
// // "no-new-object": "warn",
|
||||
// // "no-plusplus": "off",
|
||||
// // "no-spaced-func": "warn",
|
||||
// // "no-ternary": "off",
|
||||
// // "no-trailing-spaces": "warn",
|
||||
// // "no-underscore-dangle": "warn",
|
||||
// "no-unneeded-ternary": "warn",
|
||||
// // "object-curly-spacing": [ "warn", "always" ],
|
||||
// // "one-var": "off",
|
||||
// // "operator-assignment": [ "warn", "never" ],
|
||||
// // "operator-linebreak": [ "warn", "after" ],
|
||||
// // "padded-blocks": [ "warn", "never" ],
|
||||
// // "quote-props": [ "warn", "consistent-as-needed" ],
|
||||
// // "quotes": [ "warn", "single" ],
|
||||
// "require-jsdoc": [ "warn", {
|
||||
// "require": {
|
||||
// "FunctionDeclaration": true,
|
||||
// "MethodDefinition": true,
|
||||
// "ClassDeclaration": false
|
||||
// }
|
||||
// }],
|
||||
// // "semi-spacing": [ "warn", { "before": false, "after": true }],
|
||||
// // "semi": [ "error", "always" ],
|
||||
// // "sort-vars": "off",
|
||||
// "keyword-spacing": ["error", { "before": true, "after": true }]
|
||||
// // "space-before-blocks": [ "warn", "always" ],
|
||||
// // "space-before-function-paren": [ "warn", "never" ],
|
||||
// // "space-in-parens": [ "warn", "never" ],
|
||||
// // "space-infix-ops": [ "warn", { "int32Hint": true } ],
|
||||
// // "space-return-throw-case": "error",
|
||||
// // "space-unary-ops": "error",
|
||||
// // "spaced-comment": [ "warn", "always" ],
|
||||
// // "wrap-regex": "warn"
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -6,6 +6,11 @@ updates:
|
||||
schedule:
|
||||
interval: weekly
|
||||
open-pull-requests-limit: 10
|
||||
commit-message:
|
||||
prefix: "build(deps)"
|
||||
prefix-development: "build(deps-dev)"
|
||||
reviewers:
|
||||
- "qwerty541"
|
||||
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: github-actions
|
||||
@@ -13,3 +18,8 @@ updates:
|
||||
schedule:
|
||||
interval: weekly
|
||||
open-pull-requests-limit: 10
|
||||
commit-message:
|
||||
prefix: "ci(deps)"
|
||||
prefix-development: "ci(deps-dev)"
|
||||
reviewers:
|
||||
- "qwerty541"
|
||||
|
||||
+86
-43
@@ -1,52 +1,95 @@
|
||||
themes: themes/index.js
|
||||
doc-translation: docs/*
|
||||
themes:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- themes/index.js
|
||||
|
||||
doc-translation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- docs/*
|
||||
|
||||
card-i18n:
|
||||
- src/translations.js
|
||||
- src/common/I18n.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- src/translations.js
|
||||
- src/common/I18n.js
|
||||
|
||||
documentation:
|
||||
- readme.md
|
||||
- CONTRIBUTING.md
|
||||
- CODE_OF_CONDUCT.md
|
||||
- SECURITY.md
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- readme.md
|
||||
- CONTRIBUTING.md
|
||||
- CODE_OF_CONDUCT.md
|
||||
- SECURITY.md
|
||||
|
||||
dependencies:
|
||||
- package.json
|
||||
- package-lock.json
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- package.json
|
||||
- package-lock.json
|
||||
|
||||
lang-card:
|
||||
- api/top-langs.js
|
||||
- src/cards/top-languages-card.js
|
||||
- src/fetchers/top-languages-fetcher.js
|
||||
- tests/fetchTopLanguages.test.js
|
||||
- tests/renderTopLanguagesCard.test.js
|
||||
- tests/top-langs.test.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- api/top-langs.js
|
||||
- src/cards/top-languages-card.js
|
||||
- src/fetchers/top-languages-fetcher.js
|
||||
- tests/fetchTopLanguages.test.js
|
||||
- tests/renderTopLanguagesCard.test.js
|
||||
- tests/top-langs.test.js
|
||||
|
||||
repo-card:
|
||||
- api/pin.js
|
||||
- src/cards/repo-card.js
|
||||
- src/fetchers/repo-fetcher.js
|
||||
- tests/fetchRepo.test.js
|
||||
- tests/renderRepoCard.test.js
|
||||
- tests/pin.test.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- api/pin.js
|
||||
- src/cards/repo-card.js
|
||||
- src/fetchers/repo-fetcher.js
|
||||
- tests/fetchRepo.test.js
|
||||
- tests/renderRepoCard.test.js
|
||||
- tests/pin.test.js
|
||||
|
||||
stats-card:
|
||||
- api/index.js
|
||||
- src/cards/stats-card.js
|
||||
- src/fetchers/stats-fetcher.js
|
||||
- tests/fetchStats.test.js
|
||||
- tests/renderStatsCard.test.js
|
||||
- tests/api.test.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- api/index.js
|
||||
- src/cards/stats-card.js
|
||||
- src/fetchers/stats-fetcher.js
|
||||
- tests/fetchStats.test.js
|
||||
- tests/renderStatsCard.test.js
|
||||
- tests/api.test.js
|
||||
|
||||
wakatime-card:
|
||||
- api/wakatime.js
|
||||
- src/cards/wakatime-card.js
|
||||
- src/fetchers/wakatime-fetcher.js
|
||||
- tests/fetchWakatime.test.js
|
||||
- tests/renderWakatimeCard.test.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- api/wakatime.js
|
||||
- src/cards/wakatime-card.js
|
||||
- src/fetchers/wakatime-fetcher.js
|
||||
- tests/fetchWakatime.test.js
|
||||
- tests/renderWakatimeCard.test.js
|
||||
- tests/wakatime.test.js
|
||||
|
||||
gist-card:
|
||||
- api/gist.js
|
||||
- src/cards/gist-card.js
|
||||
- src/fetchers/gist-fetcher.js
|
||||
- tests/fetchGist.test.js
|
||||
- tests/renderGistCard.test.js
|
||||
- tests/gist.test.js
|
||||
ranks: src/calculateRank.js
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- api/gist.js
|
||||
- src/cards/gist-card.js
|
||||
- src/fetchers/gist-fetcher.js
|
||||
- tests/fetchGist.test.js
|
||||
- tests/renderGistCard.test.js
|
||||
- tests/gist.test.js
|
||||
|
||||
ranks:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- src/calculateRank.js
|
||||
|
||||
ci:
|
||||
- .github/workflows/*
|
||||
- scripts/*
|
||||
infrastructure: .eslintrc.json
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- .github/workflows/*
|
||||
- scripts/*
|
||||
|
||||
infrastructure:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- .eslintrc.json
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
||||
@@ -4,7 +4,7 @@ file = open('./vercel.json', 'r')
|
||||
str = file.read()
|
||||
file = open('./vercel.json', 'w')
|
||||
|
||||
str = str.replace('"maxDuration": 10', '"maxDuration": 30')
|
||||
str = str.replace('"maxDuration": 10', '"maxDuration": 15')
|
||||
|
||||
file.write(str)
|
||||
file.close()
|
||||
|
||||
@@ -10,10 +10,10 @@ jobs:
|
||||
if: github.repository == 'anuraghazra/github-readme-stats'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Deployment Prep
|
||||
run: python ./.github/workflows/deploy-prep.py
|
||||
- uses: stefanzweifel/git-auto-commit-action@8756aa072ef5b4a080af5dc8fef36c5d586e521d # v5.0.0
|
||||
- uses: stefanzweifel/git-auto-commit-action@e348103e9026cc0eee72ae06630dbe30c8bf7a79 # v5.1.0
|
||||
with:
|
||||
branch: vercel
|
||||
create_branch: true
|
||||
|
||||
@@ -17,10 +17,10 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
|
||||
+2
-2
@@ -27,10 +27,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# NOTE: Retrieve issue templates.
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Run empty issues closer action
|
||||
uses: rickstaa/empty-issues-closer-action@af151e679df0e3b59cda0e10c43010556d6c5bff # v1.1.35
|
||||
uses: rickstaa/empty-issues-closer-action@e96914613221511279ca25f50fd4acc85e331d99 # v1.1.74
|
||||
env:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -29,10 +29,10 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
|
||||
@@ -21,6 +21,7 @@ jobs:
|
||||
if: github.repository == 'anuraghazra/github-readme-stats'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0
|
||||
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
sync-labels: true
|
||||
|
||||
@@ -11,6 +11,7 @@ permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
if: github.repository == 'anuraghazra/github-readme-stats'
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -21,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -35,7 +36,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
|
||||
@@ -30,15 +30,15 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
|
||||
- uses: bahmutov/npm-install@2509f13e8485d88340a789a3f7ca11aaac47c9fc # v1.8.36
|
||||
- uses: bahmutov/npm-install@7481d8fd7815dc5abfda5f1ec48aa2770e64c318 # v1.10.6
|
||||
with:
|
||||
useLockFile: false
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Cleanup
|
||||
run: |
|
||||
|
||||
+3
-3
@@ -36,15 +36,15 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
|
||||
- uses: bahmutov/npm-install@2509f13e8485d88340a789a3f7ca11aaac47c9fc # v1.8.36
|
||||
- uses: bahmutov/npm-install@7481d8fd7815dc5abfda5f1ec48aa2770e64c318 # v1.10.6
|
||||
with:
|
||||
useLockFile: false
|
||||
|
||||
@@ -18,10 +18,10 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
@@ -44,4 +44,4 @@ jobs:
|
||||
npm run format:check
|
||||
|
||||
- name: Code Coverage
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
|
||||
uses: codecov/codecov-action@4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0 # v3.1.5
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run top issues action
|
||||
uses: rickstaa/top-issues-action@36df2af30c15ddf48558931420138890ed1b1708 # v1.3.61
|
||||
uses: rickstaa/top-issues-action@7e8dda5d5ae3087670f9094b9724a9a091fc3ba1 # v1.3.101
|
||||
env:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
@@ -36,10 +36,10 @@ jobs:
|
||||
node-version: [18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
run: npm run generate-langs-json
|
||||
|
||||
- name: Create Pull Request if upstream language file is changed
|
||||
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
|
||||
uses: peter-evans/create-pull-request@dd2324fc52d5d43c699a5636bcf19fceaa70c284 # v7.0.7
|
||||
with:
|
||||
commit-message: "refactor: update languages JSON"
|
||||
branch: "update_langs/patch"
|
||||
@@ -1,6 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm test
|
||||
npm run lint
|
||||
npx lint-staged
|
||||
|
||||
+22
-21
@@ -27,39 +27,32 @@ export default async (req, res) => {
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "Language not found", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const gistData = await fetchGist(id);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.SIX_HOURS, 10),
|
||||
CONSTANTS.SIX_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
parseInt(cache_seconds || CONSTANTS.TWO_DAY, 10),
|
||||
CONSTANTS.TWO_DAY,
|
||||
CONSTANTS.SIX_DAY,
|
||||
);
|
||||
cacheSeconds = process.env.CACHE_SECONDS
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
: cacheSeconds;
|
||||
|
||||
/*
|
||||
if star count & fork count is over 1k then we are kFormating the text
|
||||
and if both are zero we are not showing the stats
|
||||
so we can just make the cache longer, since there is no need to frequent updates
|
||||
*/
|
||||
const stars = gistData.starsCount;
|
||||
const forks = gistData.forksCount;
|
||||
const isBothOver1K = stars > 1000 && forks > 1000;
|
||||
const isBothUnder1 = stars < 1 && forks < 1;
|
||||
if (!cache_seconds && (isBothOver1K || isBothUnder1)) {
|
||||
cacheSeconds = CONSTANTS.SIX_HOURS;
|
||||
}
|
||||
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
cacheSeconds / 2
|
||||
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
`max-age=${cacheSeconds}, s-maxage=${cacheSeconds}`,
|
||||
);
|
||||
|
||||
return res.send(
|
||||
@@ -83,6 +76,14 @@ export default async (req, res) => {
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
return res.send(
|
||||
renderError(err.message, err.secondaryMessage, {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+30
-8
@@ -42,11 +42,27 @@ export default async (req, res) => {
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (blacklist.includes(username)) {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "This username is blacklisted", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "Language not found", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -63,8 +79,8 @@ export default async (req, res) => {
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.SIX_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
CONSTANTS.TWELVE_HOURS,
|
||||
CONSTANTS.TWO_DAY,
|
||||
);
|
||||
cacheSeconds = process.env.CACHE_SECONDS
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
@@ -72,9 +88,7 @@ export default async (req, res) => {
|
||||
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
cacheSeconds / 2
|
||||
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
`max-age=${cacheSeconds}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
);
|
||||
|
||||
return res.send(
|
||||
@@ -111,6 +125,14 @@ export default async (req, res) => {
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
return res.send(
|
||||
renderError(err.message, err.secondaryMessage, {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+32
-28
@@ -3,7 +3,6 @@ import { blacklist } from "../src/common/blacklist.js";
|
||||
import {
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
getBase64URIFromImage,
|
||||
parseBoolean,
|
||||
renderError,
|
||||
} from "../src/common/utils.js";
|
||||
@@ -25,53 +24,50 @@ export default async (req, res) => {
|
||||
locale,
|
||||
border_radius,
|
||||
border_color,
|
||||
show_image,
|
||||
description_lines_count,
|
||||
} = req.query;
|
||||
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (blacklist.includes(username)) {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "This username is blacklisted", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "Language not found", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const repoData = await fetchRepo(username, repo);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.SIX_HOURS,
|
||||
parseInt(cache_seconds || CONSTANTS.PIN_CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.ONE_DAY,
|
||||
CONSTANTS.TEN_DAY,
|
||||
);
|
||||
cacheSeconds = process.env.CACHE_SECONDS
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
: cacheSeconds;
|
||||
|
||||
/*
|
||||
if star count & fork count is over 1k then we are kFormating the text
|
||||
and if both are zero we are not showing the stats
|
||||
so we can just make the cache longer, since there is no need to frequent updates
|
||||
*/
|
||||
const stars = repoData.starCount;
|
||||
const forks = repoData.forkCount;
|
||||
const isBothOver1K = stars > 1000 && forks > 1000;
|
||||
const isBothUnder1 = stars < 1 && forks < 1;
|
||||
if (!cache_seconds && (isBothOver1K || isBothUnder1)) {
|
||||
cacheSeconds = CONSTANTS.SIX_HOURS;
|
||||
}
|
||||
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
cacheSeconds / 2
|
||||
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
);
|
||||
|
||||
repoData.stringifiedRepoImage = await getBase64URIFromImage(
|
||||
repoData.openGraphImageUrl,
|
||||
`max-age=${cacheSeconds}, s-maxage=${cacheSeconds}`,
|
||||
);
|
||||
|
||||
return res.send(
|
||||
@@ -86,7 +82,7 @@ export default async (req, res) => {
|
||||
border_color,
|
||||
show_owner: parseBoolean(show_owner),
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
show_image: parseBoolean(show_image),
|
||||
description_lines_count,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -96,6 +92,14 @@ export default async (req, res) => {
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
return res.send(
|
||||
renderError(err.message, err.secondaryMessage, {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -91,6 +91,9 @@ export default async (req, res) => {
|
||||
try {
|
||||
await retryer(uptimeFetcher, {});
|
||||
} catch (err) {
|
||||
// Resolve eslint no-unused-vars
|
||||
err;
|
||||
|
||||
PATsValid = false;
|
||||
}
|
||||
|
||||
|
||||
+22
-10
@@ -1,7 +1,6 @@
|
||||
import { renderTopLanguages } from "../src/cards/top-languages-card.js";
|
||||
import { blacklist } from "../src/common/blacklist.js";
|
||||
import {
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
parseArray,
|
||||
parseBoolean,
|
||||
@@ -37,7 +36,15 @@ export default async (req, res) => {
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (blacklist.includes(username)) {
|
||||
return res.send(renderError("Something went wrong"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "This username is blacklisted", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
@@ -62,10 +69,9 @@ export default async (req, res) => {
|
||||
count_weight,
|
||||
);
|
||||
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.SIX_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
let cacheSeconds = parseInt(
|
||||
cache_seconds || CONSTANTS.TOP_LANGS_CACHE_SECONDS,
|
||||
10,
|
||||
);
|
||||
cacheSeconds = process.env.CACHE_SECONDS
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
@@ -73,9 +79,7 @@ export default async (req, res) => {
|
||||
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
cacheSeconds / 2
|
||||
}, s-maxage=${cacheSeconds}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
`max-age=${cacheSeconds / 2}, s-maxage=${cacheSeconds}`,
|
||||
);
|
||||
|
||||
return res.send(
|
||||
@@ -105,6 +109,14 @@ export default async (req, res) => {
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
return res.send(
|
||||
renderError(err.message, err.secondaryMessage, {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+23
-3
@@ -30,12 +30,22 @@ export default async (req, res) => {
|
||||
api_domain,
|
||||
border_radius,
|
||||
border_color,
|
||||
display_format,
|
||||
disable_animations,
|
||||
} = req.query;
|
||||
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
if (locale && !isLocaleAvailable(locale)) {
|
||||
return res.send(renderError("Something went wrong", "Language not found"));
|
||||
return res.send(
|
||||
renderError("Something went wrong", "Language not found", {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -44,7 +54,7 @@ export default async (req, res) => {
|
||||
let cacheSeconds = clampValue(
|
||||
parseInt(cache_seconds || CONSTANTS.CARD_CACHE_SECONDS, 10),
|
||||
CONSTANTS.SIX_HOURS,
|
||||
CONSTANTS.ONE_DAY,
|
||||
CONSTANTS.TWO_DAY,
|
||||
);
|
||||
cacheSeconds = process.env.CACHE_SECONDS
|
||||
? parseInt(process.env.CACHE_SECONDS, 10) || cacheSeconds
|
||||
@@ -75,6 +85,8 @@ export default async (req, res) => {
|
||||
locale: locale ? locale.toLowerCase() : null,
|
||||
layout,
|
||||
langs_count,
|
||||
display_format,
|
||||
disable_animations: parseBoolean(disable_animations),
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -84,6 +96,14 @@ export default async (req, res) => {
|
||||
CONSTANTS.ERROR_CACHE_SECONDS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
); // Use lower cache period for errors.
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
return res.send(
|
||||
renderError(err.message, err.secondaryMessage, {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import globals from "globals";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import js from "@eslint/js";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import jsdoc from "eslint-plugin-jsdoc";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
...compat.extends("prettier"),
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.browser,
|
||||
},
|
||||
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "module",
|
||||
},
|
||||
plugins: {
|
||||
jsdoc,
|
||||
},
|
||||
rules: {
|
||||
"no-unexpected-multiline": "error",
|
||||
"accessor-pairs": [
|
||||
"error",
|
||||
{
|
||||
getWithoutSet: false,
|
||||
setWithoutGet: true,
|
||||
},
|
||||
],
|
||||
"block-scoped-var": "warn",
|
||||
"consistent-return": "error",
|
||||
curly: "error",
|
||||
"no-alert": "error",
|
||||
"no-caller": "error",
|
||||
"no-warning-comments": [
|
||||
"warn",
|
||||
{
|
||||
terms: ["TODO", "FIXME"],
|
||||
location: "start",
|
||||
},
|
||||
],
|
||||
"no-with": "warn",
|
||||
radix: "warn",
|
||||
"no-delete-var": "error",
|
||||
"no-undef-init": "off",
|
||||
"no-undef": "error",
|
||||
"no-undefined": "off",
|
||||
"no-unused-vars": "warn",
|
||||
"no-use-before-define": "error",
|
||||
"constructor-super": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-this-before-super": "error",
|
||||
"object-shorthand": ["warn"],
|
||||
"no-mixed-spaces-and-tabs": "warn",
|
||||
"no-multiple-empty-lines": "warn",
|
||||
"no-negated-condition": "warn",
|
||||
"no-unneeded-ternary": "warn",
|
||||
"keyword-spacing": [
|
||||
"error",
|
||||
{
|
||||
before: true,
|
||||
after: true,
|
||||
},
|
||||
],
|
||||
"jsdoc/require-returns": "warn",
|
||||
"jsdoc/require-returns-description": "warn",
|
||||
"jsdoc/require-param-description": "warn",
|
||||
"jsdoc/require-jsdoc": "warn",
|
||||
},
|
||||
},
|
||||
];
|
||||
+1
-2
@@ -1,12 +1,11 @@
|
||||
import "dotenv/config";
|
||||
import statsCard from "./api/index.js";
|
||||
import repoCard from "./api/pin.js";
|
||||
import langCard from "./api/top-langs.js";
|
||||
import wakatimeCard from "./api/wakatime.js";
|
||||
import gistCard from "./api/gist.js";
|
||||
import express from "express";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
dotenv.config();
|
||||
const app = express();
|
||||
app.listen(process.env.port || 9000);
|
||||
|
||||
|
||||
Generated
+1392
-1938
File diff suppressed because it is too large
Load Diff
+17
-13
@@ -29,36 +29,40 @@
|
||||
"generate-langs-json": "node scripts/generate-langs-json",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
"prepare": "husky install",
|
||||
"prepare": "husky",
|
||||
"lint": "npx eslint --max-warnings 0 \"./src/**/*.js\" \"./scripts/**/*.js\" \"./tests/**/*.js\" \"./api/**/*.js\" \"./themes/**/*.js\"",
|
||||
"bench": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.bench.config.js"
|
||||
},
|
||||
"author": "Anurag Hazra",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@testing-library/dom": "^9.3.3",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@eslint/eslintrc": "^3.3.0",
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@uppercod/css-to-object": "^1.1.1",
|
||||
"axios-mock-adapter": "^1.22.0",
|
||||
"axios-mock-adapter": "^2.1.0",
|
||||
"color-contrast-checker": "^2.1.0",
|
||||
"eslint": "^8.52.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-jsdoc": "^50.6.3",
|
||||
"globals": "^16.0.0",
|
||||
"hjson": "^3.2.2",
|
||||
"husky": "^8.0.3",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.7.0",
|
||||
"jest-bench": "^29.4.1",
|
||||
"jest-bench": "^29.7.1",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lint-staged": "^15.0.2",
|
||||
"lint-staged": "^15.4.3",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"parse-diff": "^0.11.1",
|
||||
"prettier": "^3.0.3"
|
||||
"prettier": "^3.5.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.5.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"axios": "^1.7.9",
|
||||
"dotenv": "^16.4.7",
|
||||
"emoji-name-map": "^1.2.8",
|
||||
"github-username-regex": "^1.0.0",
|
||||
"upgrade": "^1.1.0",
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p align="center">Please note that documentation translations may be outdated, try to use english documentation if possible.</p>
|
||||
<p align="center">Please note that documentation translations may be outdated; try to use English documentation if possible.</p>
|
||||
|
||||
<p align="center">Love the project? Please consider <a href="https://www.paypal.me/anuraghazra">donating</a> to help it improve!</p>
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
<img src="https://cfstatic.give.do/logo.png" alt="Give india logo" width="200" />
|
||||
</a>
|
||||
|
||||
Are you considering supporting the project by donating to me? Please DO NOT!!
|
||||
Are you considering supporting the project by donating to me? Please DO NOT!!!
|
||||
|
||||
<img src="https://cfstatic.give.do/910ede2a-7892-43fe-8c8a-dea45e96d950.webp" alt="Picture of Coromandel Express train tragedy" width="35%">
|
||||
|
||||
India just suffered one of the most devastating train accident and your help will be immensely valuable for the people who were affected by this tragedy.
|
||||
India has recently suffered one of the most devastating train accidents, and your help will be immensely valuable for the people who were affected by this tragedy.
|
||||
|
||||
Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of-the-coromandel-express-train-tragedy-in-odisha-donate-now) and make a small donation to help the people in need. A small donation goes a long way. :heart:
|
||||
|
||||
@@ -129,11 +129,11 @@ Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of
|
||||
<img alt="Uptime Badge" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fgithub-readme-stats-git-monitoring-github-readme-stats-team.vercel.app%2Fapi%2Fstatus%2Fup%3Ftype%3Dshields">
|
||||
|
||||
> [!IMPORTANT]\
|
||||
> We're a small team, and to prioritize, we rely on upvotes :+1:. We use Top issues dashboard for tracking community demand (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935)). Do not hesitate to upvote the issues and pull requests you are interested in. We will work on the most upvoted first.
|
||||
> We're a small team, and to prioritize, we rely on upvotes :+1:. We use the Top Issues dashboard for tracking community demand (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935)). Do not hesitate to upvote the issues and pull requests you are interested in. We will work on the most upvoted first.
|
||||
|
||||
# GitHub Stats Card
|
||||
|
||||
Copy-paste this into your markdown content, and that is it. Simple!
|
||||
Copy and paste this into your markdown, and that's it. Simple!
|
||||
|
||||
Change the `?username=` value to your GitHub username.
|
||||
|
||||
@@ -142,10 +142,10 @@ Change the `?username=` value to your GitHub username.
|
||||
```
|
||||
|
||||
> [!WARNING]\
|
||||
> By default, the stats card only shows statistics like stars, commits and pull requests from public repositories. To show private statistics on the stats card, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token.
|
||||
> By default, the stats card only shows statistics like stars, commits, and pull requests from public repositories. To show private statistics on the stats card, you should [deploy your own instance](#deploy-on-your-own) using your own GitHub API token.
|
||||
|
||||
> [!NOTE]\
|
||||
> Available ranks are S (top 1%), A+ (12.5%), A (25%), A- (37.5%), B+ (50%), B (62.5%), B- (75%), C+ (87.5%) and C (everyone). This ranking scheme is based on the [Japanese academic grading](https://wikipedia.org/wiki/Academic_grading_in_Japan) system. The global percentile is calculated as a weighted sum of percentiles for each statistic (number of commits, pull requests, reviews, issues, stars and followers), based on the cumulative distribution function of the [exponential](https://wikipedia.org/wiki/exponential_distribution) and the [log-normal](https://wikipedia.org/wiki/Log-normal_distribution) distributions. The implementation can be investigated at [src/calculateRank.js](https://github.com/anuraghazra/github-readme-stats/blob/master/src/calculateRank.js). The circle around the rank shows 100 minus the global percentile.
|
||||
> Available ranks are S (top 1%), A+ (12.5%), A (25%), A- (37.5%), B+ (50%), B (62.5%), B- (75%), C+ (87.5%) and C (everyone). This ranking scheme is based on the [Japanese academic grading](https://wikipedia.org/wiki/Academic_grading_in_Japan) system. The global percentile is calculated as a weighted sum of percentiles for each statistic (number of commits, pull requests, reviews, issues, stars, and followers), based on the cumulative distribution function of the [exponential](https://wikipedia.org/wiki/exponential_distribution) and the [log-normal](https://wikipedia.org/wiki/Log-normal_distribution) distributions. The implementation can be investigated at [src/calculateRank.js](https://github.com/anuraghazra/github-readme-stats/blob/master/src/calculateRank.js). The circle around the rank shows 100 minus the global percentile.
|
||||
|
||||
### Hiding individual stats
|
||||
|
||||
@@ -191,7 +191,7 @@ GitHub Readme Stats comes with several built-in themes (e.g. `dark`, `radical`,
|
||||
|
||||
<img src="https://res.cloudinary.com/anuraghazra/image/upload/v1595174536/grs-themes_l4ynja.png" alt="GitHub Readme Stats Themes" width="600px"/>
|
||||
|
||||
You can look at a preview for [all available themes](themes/README.md) or checkout the [theme config file](themes/index.js). Please note that we paused addition of new themes to decrease maintenance efforts, all pull requests related to new themes will be closed.
|
||||
You can look at a preview for [all available themes](themes/README.md) or checkout the [theme config file](themes/index.js). Please note that we paused the addition of new themes to decrease maintenance efforts; all pull requests related to new themes will be closed.
|
||||
|
||||
#### Responsive Card Theme
|
||||
|
||||
@@ -288,16 +288,18 @@ You can customize the appearance of all your cards however you wish with URL par
|
||||
|
||||
#### Common Options
|
||||
|
||||
* `title_color` - Card's title color *(hex color)*. Default: `2f80ed`.
|
||||
* `text_color` - Body text color *(hex color)*. Default: `434d58`.
|
||||
* `icon_color` - Icons color if available *(hex color)*. Default: `4c71f2`.
|
||||
* `border_color` - Card's border color *(hex color)*. Default: `e4e2e2` (Does not apply when `hide_border` is enabled).
|
||||
* `bg_color` - Card's background color *(hex color)* **or** a gradient in the form of *angle,start,end*. Default: `fffefe`
|
||||
* `hide_border` - Hides the card's border *(boolean)*. Default: `false`
|
||||
* `theme` - Name of the theme, choose from [all available themes](themes/README.md). Default: `default` theme.
|
||||
* `cache_seconds` - Sets the cache header manually *(min: 21600, max: 86400)*. Default: `21600 seconds (6 hours)`.
|
||||
* `locale` - Sets the language in the card, you can check full list of available locales [here](#available-locales). Default: `en`.
|
||||
* `border_radius` - Corner rounding on the card. Default: `4.5`.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `title_color` | Card's title color. | string (hex color) | `2f80ed` |
|
||||
| `text_color` | Body text color. | string (hex color) | `434d58` |
|
||||
| `icon_color` | Icons color if available. | string (hex color) | `4c71f2` |
|
||||
| `border_color` | Card's border color. Does not apply when `hide_border` is enabled. | string (hex color) | `e4e2e2` |
|
||||
| `bg_color` | Card's background color. | string (hex color or a gradient in the form of *angle,start,end*) | `fffefe` |
|
||||
| `hide_border` | Hides the card's border. | boolean | `false` |
|
||||
| `theme` | Name of the theme, choose from [all available themes](themes/README.md). | enum | `default` |
|
||||
| `cache_seconds` | Sets the cache header manually (min: 21600, max: 86400). | integer | `21600` |
|
||||
| `locale` | Sets the language in the card, you can check full list of available locales [here](#available-locales). | enum | `en` |
|
||||
| `border_radius` | Corner rounding on the card. | number | `4.5` |
|
||||
|
||||
> [!WARNING]\
|
||||
> We use caching to decrease the load on our servers (see <https://github.com/anuraghazra/github-readme-stats/issues/1471#issuecomment-1271551425>). Our cards have a default cache of 6 hours (21600 seconds). Also, note that the cache is clamped to a minimum of 6 hours and a maximum of 24 hours. If you want the data on your statistics card to be updated more often you can [deploy your own instance](#deploy-on-your-own) and set [environment variable](#disable-rate-limit-protections) `CACHE_SECONDS` to a value of your choosing.
|
||||
@@ -364,47 +366,55 @@ If we don't support your language, please consider contributing! You can find mo
|
||||
|
||||
#### Stats Card Exclusive Options
|
||||
|
||||
* `hide` - Hides the [specified items](#hiding-individual-stats) from stats *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
* `hide_title` - *(boolean)*. Default: `false`.
|
||||
* `card_width` - Sets the card's width manually *(number)*. Default: `500px (approx.)`.
|
||||
* `hide_rank` - *(boolean)* hides the rank and automatically resizes the card width. Default: `false`.
|
||||
* `rank_icon` - Shows alternative rank icon (i.e. `github`, `percentile` or `default`). Default: `default`.
|
||||
* `show_icons` - *(boolean)*. Default: `false`.
|
||||
* `include_all_commits` - Counts total commits instead of just the current year commits *(boolean)*. Default: `false`.
|
||||
* `line_height` - Sets the line height between text *(number)*. Default: `25`.
|
||||
* `exclude_repo` - Excludes stars from specified repositories *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
* `custom_title` - Sets a custom title for the card. Default: `<username> GitHub Stats`.
|
||||
* `text_bold` - Uses bold text *(boolean)*. Default: `true`.
|
||||
* `disable_animations` - Disables all animations in the card *(boolean)*. Default: `false`.
|
||||
* `ring_color` - Color of the rank circle *(hex color)*. Defaults to the theme ring color if it exists and otherwise the title color.
|
||||
* `number_format` - Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). Default: `short`.
|
||||
* `show` - Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`) *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `hide` | Hides the [specified items](#hiding-individual-stats) from stats. | string (comma-separated values) | `null` |
|
||||
| `hide_title` | Hides the title of your stats card. | boolean | `false` |
|
||||
| `card_width` | Sets the card's width manually. | number | `500px (approx.)` |
|
||||
| `hide_rank` | Hides the rank and automatically resizes the card width. | boolean | `false` |
|
||||
| `rank_icon` | Shows alternative rank icon (i.e. `github`, `percentile` or `default`). | enum | `default` |
|
||||
| `show_icons` | Shows icons near all stats. | boolean | `false` |
|
||||
| `include_all_commits` | Count total commits instead of just the current year commits. | boolean | `false` |
|
||||
| `line_height` | Sets the line height between text. | integer | `25` |
|
||||
| `exclude_repo` | Excludes specified repositories. | string (comma-separated values) | `null` |
|
||||
| `custom_title` | Sets a custom title for the card. | string | `<username> GitHub Stats` |
|
||||
| `text_bold` | Uses bold text. | boolean | `true` |
|
||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
||||
| `ring_color` | Color of the rank circle. | string (hex color) | `2f80ed` |
|
||||
| `number_format` | Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). | enum | `short` |
|
||||
| `show` | Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`). | string (comma-separated values) | `null` |
|
||||
|
||||
> [!NOTE]\
|
||||
> When hide\_rank=`true`, the minimum card width is 270 px + the title length and padding.
|
||||
|
||||
#### Repo Card Exclusive Options
|
||||
|
||||
* `show_owner` - Shows the repo's owner name *(boolean)*. Default: `false`.
|
||||
* `show_image` - Shows the repo's social preview image *(boolean)*. Default: `false`.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `show_owner` | Shows the repo's owner name. | boolean | `false` |
|
||||
| `description_lines_count` | Manually set the number of lines for the description. Specified value will be clamped between 1 and 3. If this parameter is not specified, the number of lines will be automatically adjusted according to the actual length of the description. | number | `null` |
|
||||
|
||||
#### Gist Card Exclusive Options
|
||||
|
||||
* `show_owner` - Shows the gist's owner name *(boolean)*. Default: `false`.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `show_owner` | Shows the gist's owner name. | boolean | `false` |
|
||||
|
||||
#### Language Card Exclusive Options
|
||||
|
||||
* `hide` - Hides the languages specified from the card *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
* `hide_title` - *(boolean)*. Default: `false`.
|
||||
* `layout` - Switches between five available layouts `normal` & `compact` & `donut` & `donut-vertical` & `pie`. Default: `normal`.
|
||||
* `card_width` - Sets the card's width manually *(number)*. Default `300`.
|
||||
* `langs_count` - Shows more languages on the card, between 1-20 *(number)*. Default: `5` for `normal` and `donut`, `6` for other layouts.
|
||||
* `exclude_repo` - Excludes specified repositories *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
* `custom_title` - Sets a custom title for the card *(string)*. Default `Most Used Languages`.
|
||||
* `disable_animations` - Disables all animations in the card *(boolean)*. Default: `false`.
|
||||
* `hide_progress` - Uses the compact layout option, hides percentages, and removes the bars. Default: `false`.
|
||||
* `size_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 1.
|
||||
* `count_weight` - Configures language stats algorithm *(number)* (see [Language stats algorithm](#Language-stats-algorithm)), defaults to 0.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `hide` | Hides the [specified languages](#hide-individual-languages) from card. | string (comma-separated values) | `null` |
|
||||
| `hide_title` | Hides the title of your card. | boolean | `false` |
|
||||
| `layout` | Switches between five available layouts `normal` & `compact` & `donut` & `donut-vertical` & `pie`. | enum | `normal` |
|
||||
| `card_width` | Sets the card's width manually. | number | `300` |
|
||||
| `langs_count` | Shows more languages on the card, between 1-20. | integer | `5` for `normal` and `donut`, `6` for other layouts |
|
||||
| `exclude_repo` | Excludes specified repositories. | string (comma-separated values) | `null` |
|
||||
| `custom_title` | Sets a custom title for the card. | string | `Most Used Languages` |
|
||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
||||
| `hide_progress` | Uses the compact layout option, hides percentages, and removes the bars. | boolean | `false` |
|
||||
| `size_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `1` |
|
||||
| `count_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `0` |
|
||||
|
||||
> [!WARNING]\
|
||||
> Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
|
||||
@@ -413,14 +423,18 @@ If we don't support your language, please consider contributing! You can find mo
|
||||
|
||||
#### WakaTime Card Exclusive Options
|
||||
|
||||
* `hide` - Hides the languages specified from the card *(Comma-separated values)*. Default: `[] (blank array)`.
|
||||
* `hide_title` - *(boolean)*. Default `false`.
|
||||
* `line_height` - Sets the line height between text *(number)*. Default `25`.
|
||||
* `hide_progress` - Hides the progress bar and percentage *(boolean)*. Default `false`.
|
||||
* `custom_title` - Sets a custom title for the card *(string)*. Default `WakaTime Stats`.
|
||||
* `layout` - Switches between two available layouts `default` & `compact`. Default `default`.
|
||||
* `langs_count` - Limits the number of languages on the card, defaults to all reported languages *(number)*.
|
||||
* `api_domain` - Sets a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) *(string)*. Default `Waka API`.
|
||||
| Name | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| `hide` | Hides the languages specified from the card. | string (comma-separated values) | `null` |
|
||||
| `hide_title` | Hides the title of your card. | boolean | `false` |
|
||||
| `line_height` | Sets the line height between text. | integer | `25` |
|
||||
| `hide_progress` | Hides the progress bar and percentage. | boolean | `false` |
|
||||
| `custom_title` | Sets a custom title for the card. | string | `WakaTime Stats` |
|
||||
| `layout` | Switches between two available layouts `default` & `compact`. | enum | `default` |
|
||||
| `langs_count` | Limits the number of languages on the card, defaults to all reported languages. | integer | `null` |
|
||||
| `api_domain` | Sets a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) | string | `wakatime.com` |
|
||||
| `display_format` | Sets the WakaTime stats display format. Choose `time` to display time-based stats or `percent` to show percentages. | enum | `time` |
|
||||
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
|
||||
|
||||
***
|
||||
|
||||
@@ -448,11 +462,6 @@ Use [show\_owner](#repo-card-exclusive-options) query option to include the repo
|
||||
|
||||

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

|
||||
|
||||
# GitHub Gist Pins
|
||||
|
||||
GitHub gist pins allow you to pin gists in your GitHub profile using a GitHub readme profile.
|
||||
@@ -486,10 +495,10 @@ The top languages card shows a GitHub user's most frequently used languages.
|
||||
> Top Languages does not indicate the user's skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It is a new feature of github-readme-stats.
|
||||
|
||||
> [!WARNING]\
|
||||
> This card shows languages usage only inside your own non-forked repositories, not depending from who is the author of the commits. It does not include your contributions into another users/organizations repositories. Currently there are no way to get this data from GitHub API. If you want this behavior to be improved you can support [this feature request](https://github.com/orgs/community/discussions/18230) created by [@rickstaa](https://github.com/rickstaa) inside GitHub Community.
|
||||
> This card shows language usage only inside your own non-forked repositories, not depending on who the author of the commits is. It does not include your contributions into another users/organizations repositories. Currently there are no way to get this data from GitHub API. If you want this behavior to be improved you can support [this feature request](https://github.com/orgs/community/discussions/18230) created by [@rickstaa](https://github.com/rickstaa) inside GitHub Community.
|
||||
|
||||
> [!WARNING]\
|
||||
> Currently this card shows data only about first 100 repositories. This is because GitHub API limitations which cause downtimes of public instance (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). In future this behavior will be improved by releasing GitHub action or providing environment variable for user's own instances.
|
||||
> Currently this card shows data only about first 100 repositories. This is because GitHub API limitations which cause downtimes of public instances (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). In future this behavior will be improved by releasing GitHub action or providing environment variables for user's own instances.
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -806,7 +815,7 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
|
||||
|
||||
Github Readme Stats contains several Vercel environment variables that can be used to remove the rate limit protections:
|
||||
|
||||
* `CACHE_SECONDS`: This environment variable takes precedence over our cache minimum and maximum values and can circumvent these values for self Hosted Vercel instances.
|
||||
* `CACHE_SECONDS`: This environment variable takes precedence over our cache minimum and maximum values and can circumvent these values for self-hosted Vercel instances.
|
||||
|
||||
See [the Vercel documentation](https://vercel.com/docs/concepts/projects/environment-variables) on adding these environment variables to your Vercel instance.
|
||||
|
||||
@@ -821,9 +830,9 @@ this takes time. You can use this service for free.
|
||||
|
||||
However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it:
|
||||
|
||||
* Giving proper credit when you use github-readme-stats on your readme, linking back to it :D
|
||||
* Starring and sharing the project :rocket:
|
||||
* [](https://www.paypal.me/anuraghazra) - You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea:
|
||||
* Giving proper credit when you use github-readme-stats on your readme, linking back to it. :D
|
||||
* Starring and sharing the project. :rocket:
|
||||
* [](https://www.paypal.me/anuraghazra) - You can make a one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea:
|
||||
|
||||
Thanks! :heart:
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ export const getRepoInfo = (ctx) => {
|
||||
repo: ctx.repo.repo,
|
||||
};
|
||||
} catch (error) {
|
||||
// Resolve eslint no-unused-vars
|
||||
error;
|
||||
|
||||
return {
|
||||
owner: OWNER,
|
||||
repo: REPO,
|
||||
|
||||
@@ -332,6 +332,9 @@ const parseJSON = (json) => {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
// Resolve eslint no-unused-vars
|
||||
error;
|
||||
|
||||
// Remove trailing commas (if any).
|
||||
let parsedJson = json.replace(/(,\s*})/g, "}");
|
||||
|
||||
|
||||
+21
-9
@@ -12,10 +12,13 @@ import {
|
||||
wrapTextMultiline,
|
||||
iconWithLabel,
|
||||
createLanguageNode,
|
||||
clampValue,
|
||||
} from "../common/utils.js";
|
||||
import { repoCardLocales } from "../translations.js";
|
||||
|
||||
const ICON_SIZE = 16;
|
||||
const DESCRIPTION_LINE_WIDTH = 59;
|
||||
const DESCRIPTION_MAX_LINES = 3;
|
||||
|
||||
/**
|
||||
* Retrieves the repository description and wraps it to fit the card width.
|
||||
@@ -61,7 +64,6 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
isTemplate,
|
||||
starCount,
|
||||
forkCount,
|
||||
stringifiedRepoImage,
|
||||
} = repo;
|
||||
const {
|
||||
hide_border = false,
|
||||
@@ -74,23 +76,34 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
border_radius,
|
||||
border_color,
|
||||
locale,
|
||||
show_image = false,
|
||||
description_lines_count,
|
||||
} = options;
|
||||
|
||||
const lineHeight = 10;
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified";
|
||||
const langColor = (primaryLanguage && primaryLanguage.color) || "#333";
|
||||
const descriptionMaxLines = description_lines_count
|
||||
? clampValue(description_lines_count, 1, DESCRIPTION_MAX_LINES)
|
||||
: DESCRIPTION_MAX_LINES;
|
||||
|
||||
const desc = parseEmojis(description || "No description provided");
|
||||
const multiLineDescription = wrapTextMultiline(desc);
|
||||
const descriptionLines = multiLineDescription.length;
|
||||
const multiLineDescription = wrapTextMultiline(
|
||||
desc,
|
||||
DESCRIPTION_LINE_WIDTH,
|
||||
descriptionMaxLines,
|
||||
);
|
||||
const descriptionLinesCount = description_lines_count
|
||||
? clampValue(description_lines_count, 1, DESCRIPTION_MAX_LINES)
|
||||
: multiLineDescription.length;
|
||||
|
||||
const descriptionSvg = multiLineDescription
|
||||
.map((line) => `<tspan dy="1.2em" x="25">${encodeHTML(line)}</tspan>`)
|
||||
.join("");
|
||||
|
||||
const height =
|
||||
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||
(descriptionLinesCount > 1 ? 120 : 110) +
|
||||
descriptionLinesCount * lineHeight;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
@@ -143,7 +156,6 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
height,
|
||||
border_radius,
|
||||
colors,
|
||||
stringifiedRepoImage: show_image ? stringifiedRepoImage : "",
|
||||
});
|
||||
|
||||
card.disableAnimations();
|
||||
@@ -163,9 +175,9 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||
: isArchived
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
}
|
||||
|
||||
<text class="description" x="25" y="-5">
|
||||
|
||||
@@ -76,7 +76,7 @@ const createTextNode = ({
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates progress along the boundary of the circle i.e it's circumference.
|
||||
* Calculates progress along the boundary of the circle, i.e. its circumference.
|
||||
*
|
||||
* @param {number} value The rank value to calculate progress for.
|
||||
* @returns {number} Progress value.
|
||||
@@ -412,8 +412,8 @@ const renderStatsCard = (stats, options = {}) => {
|
||||
custom_title
|
||||
? custom_title
|
||||
: statItems.length
|
||||
? i18n.t("statcard.title")
|
||||
: i18n.t("statcard.ranktitle"),
|
||||
? i18n.t("statcard.title")
|
||||
: i18n.t("statcard.ranktitle"),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -431,14 +431,14 @@ const renderStatsCard = (stats, options = {}) => {
|
||||
Infinity,
|
||||
)
|
||||
: statItems.length
|
||||
? RANK_CARD_MIN_WIDTH
|
||||
: RANK_ONLY_CARD_MIN_WIDTH) + iconWidth;
|
||||
? RANK_CARD_MIN_WIDTH
|
||||
: RANK_ONLY_CARD_MIN_WIDTH) + iconWidth;
|
||||
const defaultCardWidth =
|
||||
(hide_rank
|
||||
? CARD_DEFAULT_WIDTH
|
||||
: statItems.length
|
||||
? RANK_CARD_DEFAULT_WIDTH
|
||||
: RANK_ONLY_CARD_DEFAULT_WIDTH) + iconWidth;
|
||||
? RANK_CARD_DEFAULT_WIDTH
|
||||
: RANK_ONLY_CARD_DEFAULT_WIDTH) + iconWidth;
|
||||
let width = card_width
|
||||
? isNaN(card_width)
|
||||
? defaultCardWidth
|
||||
@@ -518,7 +518,7 @@ const renderStatsCard = (stats, options = {}) => {
|
||||
if (key === "commits") {
|
||||
return `${i18n.t("statcard.commits")} ${
|
||||
include_all_commits ? "" : `in ${new Date().getFullYear()}`
|
||||
} : ${totalStars}`;
|
||||
} : ${STATS[key].value}`;
|
||||
}
|
||||
return `${STATS[key].label}: ${STATS[key].value}`;
|
||||
})
|
||||
|
||||
@@ -755,8 +755,8 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
? isNaN(card_width)
|
||||
? DEFAULT_CARD_WIDTH
|
||||
: card_width < MIN_CARD_WIDTH
|
||||
? MIN_CARD_WIDTH
|
||||
: card_width
|
||||
? MIN_CARD_WIDTH
|
||||
: card_width
|
||||
: DEFAULT_CARD_WIDTH;
|
||||
let height = calculateNormalLayoutHeight(langs.length);
|
||||
|
||||
|
||||
Vendored
+4
-2
@@ -32,7 +32,7 @@ export type StatCardOptions = CommonOptions & {
|
||||
|
||||
export type RepoCardOptions = CommonOptions & {
|
||||
show_owner: boolean;
|
||||
show_image: boolean;
|
||||
description_lines_count: number;
|
||||
};
|
||||
|
||||
export type TopLangOptions = CommonOptions & {
|
||||
@@ -46,7 +46,7 @@ export type TopLangOptions = CommonOptions & {
|
||||
hide_progress: boolean;
|
||||
};
|
||||
|
||||
type WakaTimeOptions = CommonOptions & {
|
||||
export type WakaTimeOptions = CommonOptions & {
|
||||
hide_title: boolean;
|
||||
hide: string[];
|
||||
line_height: string;
|
||||
@@ -54,6 +54,8 @@ type WakaTimeOptions = CommonOptions & {
|
||||
custom_title: string;
|
||||
layout: "compact" | "normal";
|
||||
langs_count: number;
|
||||
display_format: "time" | "percent";
|
||||
disable_animations: boolean;
|
||||
};
|
||||
|
||||
export type GistCardOptions = CommonOptions & {
|
||||
|
||||
@@ -39,6 +39,20 @@ const noCodingActivityNode = ({ color, text }) => {
|
||||
* @typedef {import('../fetchers/types').WakaTimeLang} WakaTimeLang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format language value.
|
||||
*
|
||||
* @param {Object} args The function arguments.
|
||||
* @param {WakaTimeLang} args.lang The language object.
|
||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
||||
* @returns {string} The formatted language value.
|
||||
*/
|
||||
const formatLanguageValue = ({ display_format, lang }) => {
|
||||
return display_format === "percent"
|
||||
? `${lang.percent.toFixed(2).toString()} %`
|
||||
: lang.text;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create compact WakaTime layout.
|
||||
*
|
||||
@@ -46,16 +60,18 @@ const noCodingActivityNode = ({ color, text }) => {
|
||||
* @param {WakaTimeLang} args.lang The languages array.
|
||||
* @param {number} args.x The x position of the language node.
|
||||
* @param {number} args.y The y position of the language node.
|
||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
||||
* @returns {string} The compact layout language SVG node.
|
||||
*/
|
||||
const createCompactLangNode = ({ lang, x, y }) => {
|
||||
const createCompactLangNode = ({ lang, x, y, display_format }) => {
|
||||
const color = languageColors[lang.name] || "#858585";
|
||||
const value = formatLanguageValue({ display_format, lang });
|
||||
|
||||
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} - ${lang.text}
|
||||
${lang.name} - ${value}
|
||||
</text>
|
||||
</g>
|
||||
`;
|
||||
@@ -67,21 +83,24 @@ const createCompactLangNode = ({ lang, x, y }) => {
|
||||
* @param {Object} args The function arguments.
|
||||
* @param {WakaTimeLang[]} args.langs The language objects.
|
||||
* @param {number} args.y The y position of the language node.
|
||||
* @param {"time" | "percent"} args.display_format The display format of the language node.
|
||||
* @returns {string[]} The language text node items.
|
||||
*/
|
||||
const createLanguageTextNode = ({ langs, y }) => {
|
||||
const createLanguageTextNode = ({ langs, y, display_format }) => {
|
||||
return langs.map((lang, index) => {
|
||||
if (index % 2 === 0) {
|
||||
return createCompactLangNode({
|
||||
lang,
|
||||
x: 25,
|
||||
y: 12.5 * index + y,
|
||||
display_format,
|
||||
});
|
||||
}
|
||||
return createCompactLangNode({
|
||||
lang,
|
||||
x: 230,
|
||||
y: 12.5 + 12.5 * index,
|
||||
display_format,
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -218,6 +237,8 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
langs_count = languages.length,
|
||||
border_radius,
|
||||
border_color,
|
||||
display_format = "time",
|
||||
disable_animations,
|
||||
} = options;
|
||||
|
||||
const shouldHideLangs = Array.isArray(hide) && hide.length > 0;
|
||||
@@ -311,6 +332,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
? createLanguageTextNode({
|
||||
y: 25,
|
||||
langs: filteredLanguages,
|
||||
display_format,
|
||||
}).join("")
|
||||
: noCodingActivityNode({
|
||||
// @ts-ignore
|
||||
@@ -330,7 +352,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
return createTextNode({
|
||||
id: language.name,
|
||||
label: language.name,
|
||||
value: language.text,
|
||||
value: formatLanguageValue({ display_format, lang: language }),
|
||||
index,
|
||||
percent: language.percent,
|
||||
// @ts-ignore
|
||||
@@ -382,6 +404,10 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
},
|
||||
});
|
||||
|
||||
if (disable_animations) {
|
||||
card.disableAnimations();
|
||||
}
|
||||
|
||||
card.setHideBorder(hide_border);
|
||||
card.setHideTitle(hide_title);
|
||||
card.setCSS(
|
||||
|
||||
@@ -11,8 +11,6 @@ class Card {
|
||||
* @param {string?=} args.customTitle Card custom title.
|
||||
* @param {string?=} args.defaultTitle Card default title.
|
||||
* @param {string?=} args.titlePrefixIcon Card title prefix icon.
|
||||
* @param {string?=} args.stringifiedRepoImage Card preview image.
|
||||
* @param {number?=} args.imageHeight Card preview image.
|
||||
* @param {object?=} args.colors Card colors arguments.
|
||||
* @param {string} args.colors.titleColor Card title color.
|
||||
* @param {string} args.colors.textColor Card text color.
|
||||
@@ -29,8 +27,6 @@ class Card {
|
||||
customTitle,
|
||||
defaultTitle = "",
|
||||
titlePrefixIcon,
|
||||
stringifiedRepoImage = "",
|
||||
imageHeight = 200,
|
||||
}) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@@ -40,9 +36,6 @@ class Card {
|
||||
|
||||
this.border_radius = border_radius;
|
||||
|
||||
this.imageHeight = imageHeight;
|
||||
this.stringifiedRepoImage = stringifiedRepoImage;
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
this.colors = colors;
|
||||
this.title =
|
||||
@@ -58,10 +51,6 @@ class Card {
|
||||
this.animations = true;
|
||||
this.a11yTitle = "";
|
||||
this.a11yDesc = "";
|
||||
if (this.stringifiedRepoImage) {
|
||||
this.height += this.imageHeight;
|
||||
this.paddingY += this.imageHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,21 +199,6 @@ class Card {
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {string} Renders social preview image
|
||||
*/
|
||||
renderImage = () => {
|
||||
if (!this.stringifiedRepoImage) {
|
||||
return "";
|
||||
}
|
||||
return `
|
||||
<g data-testid="card-image" transform="translate(0, 0)">
|
||||
<image x="0" y="0" width="${this.width}" height="${this.imageHeight}"
|
||||
href="${this.stringifiedRepoImage}">
|
||||
</image>
|
||||
</g>`;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} body The inner body of the card.
|
||||
* @returns {string} The rendered card.
|
||||
@@ -290,7 +264,6 @@ class Card {
|
||||
>
|
||||
${body}
|
||||
</g>
|
||||
${this.renderImage()}
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
const blacklist = ["renovate-bot", "technote-space", "sw-yx"];
|
||||
const blacklist = [
|
||||
"renovate-bot",
|
||||
"technote-space",
|
||||
"sw-yx",
|
||||
"YourUsername",
|
||||
"[YourUsername]",
|
||||
];
|
||||
|
||||
export { blacklist };
|
||||
export default blacklist;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"Alpine Abuild": "#0D597F",
|
||||
"Altium Designer": "#A89663",
|
||||
"AngelScript": "#C7D7DC",
|
||||
"Answer Set Programming": "#A9CC29",
|
||||
"Ant Build System": "#A9157E",
|
||||
"Antlers": "#ff269e",
|
||||
"ApacheConf": "#d12127",
|
||||
@@ -39,7 +40,9 @@
|
||||
"AutoIt": "#1C3552",
|
||||
"Avro IDL": "#0040FF",
|
||||
"Awk": "#c30e9b",
|
||||
"B4X": "#00e4ff",
|
||||
"BASIC": "#ff0000",
|
||||
"BQN": "#2b7067",
|
||||
"Ballerina": "#FF5000",
|
||||
"Batchfile": "#C1F12E",
|
||||
"Beef": "#a52f4e",
|
||||
@@ -53,6 +56,7 @@
|
||||
"BlitzBasic": "#00FFAE",
|
||||
"BlitzMax": "#cd6400",
|
||||
"Bluespec": "#12223c",
|
||||
"Bluespec BH": "#12223c",
|
||||
"Boo": "#d4bec1",
|
||||
"Boogie": "#c80fa0",
|
||||
"Brainfuck": "#2F2530",
|
||||
@@ -67,15 +71,18 @@
|
||||
"CMake": "#DA3434",
|
||||
"COLLADA": "#F1A42B",
|
||||
"CSON": "#244776",
|
||||
"CSS": "#563d7c",
|
||||
"CSS": "#663399",
|
||||
"CSV": "#237346",
|
||||
"CUE": "#5886E1",
|
||||
"CWeb": "#00007a",
|
||||
"Cabal Config": "#483465",
|
||||
"Caddyfile": "#22b638",
|
||||
"Cadence": "#00ef8b",
|
||||
"Cairo": "#ff4a48",
|
||||
"Cairo Zero": "#ff4a48",
|
||||
"CameLIGO": "#3be133",
|
||||
"Cap'n Proto": "#c42727",
|
||||
"Carbon": "#222222",
|
||||
"Ceylon": "#dfa535",
|
||||
"Chapel": "#8dc63f",
|
||||
"ChucK": "#3f8000",
|
||||
@@ -103,6 +110,7 @@
|
||||
"Csound Score": "#1a1a1a",
|
||||
"Cuda": "#3A4E3A",
|
||||
"Curry": "#531242",
|
||||
"Cylc": "#00b3fd",
|
||||
"Cypher": "#34c0eb",
|
||||
"Cython": "#fedf5b",
|
||||
"D": "#ba595e",
|
||||
@@ -119,6 +127,7 @@
|
||||
"Dockerfile": "#384d54",
|
||||
"Dogescript": "#cca760",
|
||||
"Dotenv": "#e5d559",
|
||||
"Dune": "#89421e",
|
||||
"Dylan": "#6c616e",
|
||||
"E": "#ccce35",
|
||||
"ECL": "#8a1267",
|
||||
@@ -129,6 +138,8 @@
|
||||
"Easybuild": "#069406",
|
||||
"Ecere Projects": "#913960",
|
||||
"Ecmarkup": "#eb8131",
|
||||
"Edge": "#0dffe0",
|
||||
"EdgeQL": "#31A7FF",
|
||||
"EditorConfig": "#fff1f2",
|
||||
"Eiffel": "#4d6977",
|
||||
"Elixir": "#6e4a7e",
|
||||
@@ -142,6 +153,7 @@
|
||||
"F#": "#b845fc",
|
||||
"F*": "#572e30",
|
||||
"FIGlet Font": "#FFDDBB",
|
||||
"FIRRTL": "#2f632f",
|
||||
"FLUX": "#88ccff",
|
||||
"Factor": "#636746",
|
||||
"Fancy": "#7b9db4",
|
||||
@@ -153,7 +165,7 @@
|
||||
"Forth": "#341708",
|
||||
"Fortran": "#4d41b1",
|
||||
"Fortran Free Form": "#4d41b1",
|
||||
"FreeBasic": "#141AC9",
|
||||
"FreeBASIC": "#141AC9",
|
||||
"FreeMarker": "#0050b2",
|
||||
"Frege": "#00cafe",
|
||||
"Futhark": "#5f021f",
|
||||
@@ -169,8 +181,8 @@
|
||||
"Game Maker Language": "#71b417",
|
||||
"Gemfile.lock": "#701516",
|
||||
"Gemini": "#ff6900",
|
||||
"Genero": "#63408e",
|
||||
"Genero Forms": "#d8df39",
|
||||
"Genero 4gl": "#63408e",
|
||||
"Genero per": "#d8df39",
|
||||
"Genie": "#fb855d",
|
||||
"Genshi": "#951531",
|
||||
"Gentoo Ebuild": "#9400ff",
|
||||
@@ -181,6 +193,8 @@
|
||||
"Git Config": "#F44D27",
|
||||
"Git Revision List": "#F44D27",
|
||||
"Gleam": "#ffaff3",
|
||||
"Glimmer JS": "#F5835F",
|
||||
"Glimmer TS": "#3178c6",
|
||||
"Glyph": "#c1ac7f",
|
||||
"Gnuplot": "#f0a9f0",
|
||||
"Go": "#00ADD8",
|
||||
@@ -192,6 +206,7 @@
|
||||
"Gosu": "#82937f",
|
||||
"Grace": "#615f8b",
|
||||
"Gradle": "#02303a",
|
||||
"Gradle Kotlin DSL": "#02303a",
|
||||
"Grammatical Framework": "#ff0000",
|
||||
"GraphQL": "#e10098",
|
||||
"Graphviz (DOT)": "#2596be",
|
||||
@@ -213,6 +228,7 @@
|
||||
"Haml": "#ece2a9",
|
||||
"Handlebars": "#f7931e",
|
||||
"Harbour": "#0e60e3",
|
||||
"Hare": "#9d7424",
|
||||
"Haskell": "#5e5086",
|
||||
"Haxe": "#df7900",
|
||||
"HiveQL": "#dce200",
|
||||
@@ -240,11 +256,13 @@
|
||||
"JSON5": "#267CB9",
|
||||
"JSONLD": "#0c479c",
|
||||
"JSONiq": "#40d47e",
|
||||
"Jai": "#ab8b4b",
|
||||
"Janet": "#0886a5",
|
||||
"Jasmin": "#d03600",
|
||||
"Java": "#b07219",
|
||||
"Java Properties": "#2A6277",
|
||||
"Java Server Pages": "#2A6277",
|
||||
"Java Template Engine": "#2A6277",
|
||||
"JavaScript": "#f1e05a",
|
||||
"JavaScript+ERB": "#f1e05a",
|
||||
"Jest Snapshot": "#15c213",
|
||||
@@ -255,8 +273,10 @@
|
||||
"Jolie": "#843179",
|
||||
"Jsonnet": "#0064bd",
|
||||
"Julia": "#a270ba",
|
||||
"Julia REPL": "#a270ba",
|
||||
"Jupyter Notebook": "#DA5B0B",
|
||||
"Just": "#384d54",
|
||||
"KDL": "#ffb3b3",
|
||||
"KRL": "#28430A",
|
||||
"Kaitai Struct": "#773b37",
|
||||
"KakouneScript": "#6f8042",
|
||||
@@ -281,10 +301,12 @@
|
||||
"Literate Agda": "#315665",
|
||||
"Literate CoffeeScript": "#244776",
|
||||
"Literate Haskell": "#5e5086",
|
||||
"LiveCode Script": "#0c5ba5",
|
||||
"LiveScript": "#499886",
|
||||
"Logtalk": "#295b9a",
|
||||
"LookML": "#652B81",
|
||||
"Lua": "#000080",
|
||||
"Luau": "#00A2FF",
|
||||
"MATLAB": "#e16737",
|
||||
"MAXScript": "#00a6a6",
|
||||
"MDX": "#fcb32c",
|
||||
@@ -305,18 +327,22 @@
|
||||
"Meson": "#007800",
|
||||
"Metal": "#8f14e9",
|
||||
"MiniYAML": "#ff1111",
|
||||
"MiniZinc": "#06a9e6",
|
||||
"Mint": "#02b046",
|
||||
"Mirah": "#c7a938",
|
||||
"Modelica": "#de1d31",
|
||||
"Modula-2": "#10253f",
|
||||
"Modula-3": "#223388",
|
||||
"Mojo": "#ff4c1f",
|
||||
"Monkey C": "#8D6747",
|
||||
"MoonBit": "#b92381",
|
||||
"MoonScript": "#ff4585",
|
||||
"Motoko": "#fbb03b",
|
||||
"Motorola 68K Assembly": "#005daa",
|
||||
"Move": "#4a137a",
|
||||
"Mustache": "#724b3b",
|
||||
"NCL": "#28431f",
|
||||
"NMODL": "#00356B",
|
||||
"NPM Config": "#cb3837",
|
||||
"NWScript": "#111522",
|
||||
"Nasal": "#1d2c4e",
|
||||
@@ -331,6 +357,7 @@
|
||||
"Nim": "#ffc200",
|
||||
"Nit": "#009917",
|
||||
"Nix": "#7e7eff",
|
||||
"Noir": "#2f1f49",
|
||||
"Nu": "#c9df40",
|
||||
"NumPy": "#9C8AF9",
|
||||
"Nunjucks": "#3d8137",
|
||||
@@ -340,6 +367,8 @@
|
||||
"OASv3-json": "#85ea2d",
|
||||
"OASv3-yaml": "#85ea2d",
|
||||
"OCaml": "#ef7a08",
|
||||
"OMNeT++ MSG": "#a0e0a0",
|
||||
"OMNeT++ NED": "#08607c",
|
||||
"ObjectScript": "#424893",
|
||||
"Objective-C": "#438eff",
|
||||
"Objective-C++": "#6866fb",
|
||||
@@ -356,6 +385,7 @@
|
||||
"OpenSCAD": "#e5cd45",
|
||||
"Option List": "#476732",
|
||||
"Org": "#77aa99",
|
||||
"OverpassQL": "#cce2aa",
|
||||
"Oxygene": "#cdd0e3",
|
||||
"Oz": "#fab738",
|
||||
"P4": "#7055b5",
|
||||
@@ -376,6 +406,8 @@
|
||||
"PicoLisp": "#6067af",
|
||||
"PigLatin": "#fcd7de",
|
||||
"Pike": "#005390",
|
||||
"Pip Requirements": "#FFD343",
|
||||
"Pkl": "#6b9543",
|
||||
"PlantUML": "#fbbd16",
|
||||
"PogoScript": "#d80074",
|
||||
"Polar": "#ae81ff",
|
||||
@@ -384,6 +416,7 @@
|
||||
"PostScript": "#da291c",
|
||||
"PowerBuilder": "#8f0f8d",
|
||||
"PowerShell": "#012456",
|
||||
"Praat": "#c8506d",
|
||||
"Prisma": "#0c344b",
|
||||
"Processing": "#0096D8",
|
||||
"Procfile": "#3B2F63",
|
||||
@@ -402,12 +435,14 @@
|
||||
"QML": "#44a51c",
|
||||
"Qt Script": "#00b841",
|
||||
"Quake": "#882233",
|
||||
"QuickBASIC": "#008080",
|
||||
"R": "#198CE7",
|
||||
"RAML": "#77d9fb",
|
||||
"RBS": "#701516",
|
||||
"RDoc": "#701516",
|
||||
"REXX": "#d90e09",
|
||||
"RMarkdown": "#198ce7",
|
||||
"RON": "#a62c00",
|
||||
"RPGLE": "#2BDE21",
|
||||
"RUNOFF": "#665a4e",
|
||||
"Racket": "#3c5caa",
|
||||
@@ -422,9 +457,11 @@
|
||||
"Red": "#f50000",
|
||||
"Regular Expression": "#009a00",
|
||||
"Ren'Py": "#ff7f7f",
|
||||
"Rez": "#FFDAB3",
|
||||
"Ring": "#2D54CB",
|
||||
"Riot": "#A71E49",
|
||||
"RobotFramework": "#00c0b5",
|
||||
"Roc": "#7c38f5",
|
||||
"Roff": "#ecdebe",
|
||||
"Roff Manpage": "#ecdebe",
|
||||
"Rouge": "#cc0088",
|
||||
@@ -457,6 +494,7 @@
|
||||
"Slash": "#007eff",
|
||||
"Slice": "#003fa2",
|
||||
"Slim": "#2b2b2b",
|
||||
"Slint": "#2379F4",
|
||||
"SmPL": "#c94949",
|
||||
"Smalltalk": "#596706",
|
||||
"Smarty": "#f0c040",
|
||||
@@ -474,8 +512,10 @@
|
||||
"SubRip Text": "#9e0101",
|
||||
"SugarSS": "#2fcc9f",
|
||||
"SuperCollider": "#46390b",
|
||||
"Survex data": "#ffcc99",
|
||||
"Svelte": "#ff3e00",
|
||||
"Sway": "#dea584",
|
||||
"Sway": "#00F58C",
|
||||
"Sweave": "#198ce7",
|
||||
"Swift": "#F05138",
|
||||
"SystemVerilog": "#DAE1C2",
|
||||
"TI Program": "#A0AA87",
|
||||
@@ -486,16 +526,22 @@
|
||||
"TSV": "#237346",
|
||||
"TSX": "#3178c6",
|
||||
"TXL": "#0178b8",
|
||||
"Tact": "#48b5ff",
|
||||
"Talon": "#333333",
|
||||
"Tcl": "#e4cc98",
|
||||
"TeX": "#3D6117",
|
||||
"Terra": "#00004c",
|
||||
"Terraform Template": "#7b42bb",
|
||||
"TextGrid": "#c8506d",
|
||||
"TextMate Properties": "#df66e4",
|
||||
"Textile": "#ffe7ac",
|
||||
"Thrift": "#D12127",
|
||||
"Toit": "#c2c9fb",
|
||||
"Turing": "#cf142b",
|
||||
"Twig": "#c1d026",
|
||||
"TypeScript": "#3178c6",
|
||||
"TypeSpec": "#4A3665",
|
||||
"Typst": "#239dad",
|
||||
"Unified Parallel C": "#4e3617",
|
||||
"Unity3D Asset": "#222c37",
|
||||
"Uno": "#9933cc",
|
||||
@@ -536,6 +582,7 @@
|
||||
"XML Property List": "#0060ac",
|
||||
"XQuery": "#5232e7",
|
||||
"XSLT": "#EB8CEB",
|
||||
"Xmake": "#22a079",
|
||||
"Xojo": "#81bd41",
|
||||
"Xonsh": "#285EEF",
|
||||
"Xtend": "#24255d",
|
||||
@@ -550,13 +597,16 @@
|
||||
"Zephir": "#118f9e",
|
||||
"Zig": "#ec915c",
|
||||
"Zimpl": "#d67711",
|
||||
"crontab": "#ead7ac",
|
||||
"eC": "#913960",
|
||||
"fish": "#4aae47",
|
||||
"hoon": "#00b171",
|
||||
"iCalendar": "#ec564c",
|
||||
"jq": "#c7254e",
|
||||
"kvlang": "#1da6e0",
|
||||
"mIRC Script": "#3d57c3",
|
||||
"mcfunction": "#E22837",
|
||||
"mdsvex": "#5f9ea0",
|
||||
"mupad": "#244963",
|
||||
"nanorc": "#2d004d",
|
||||
"nesC": "#94B0C7",
|
||||
@@ -564,6 +614,8 @@
|
||||
"q": "#0040cd",
|
||||
"reStructuredText": "#141414",
|
||||
"sed": "#64b970",
|
||||
"templ": "#66D0DD",
|
||||
"vCard": "#ee2647",
|
||||
"wisp": "#7582D1",
|
||||
"xBase": "#403a40"
|
||||
}
|
||||
+86
-78
@@ -39,61 +39,6 @@ class CustomError extends Error {
|
||||
static WAKATIME_ERROR = "WAKATIME_ERROR";
|
||||
}
|
||||
|
||||
// Script parameters.
|
||||
const ERROR_CARD_LENGTH = 576.5;
|
||||
|
||||
/**
|
||||
* Encode string as HTML.
|
||||
*
|
||||
* @see https://stackoverflow.com/a/48073476/10629172
|
||||
*
|
||||
* @param {string} str String to encode.
|
||||
* @returns {string} Encoded string.
|
||||
*/
|
||||
const encodeHTML = (str) => {
|
||||
return str
|
||||
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
|
||||
return "&#" + i.charCodeAt(0) + ";";
|
||||
})
|
||||
.replace(/\u0008/gim, "");
|
||||
};
|
||||
|
||||
const UPSTREAM_API_ERRORS = [
|
||||
TRY_AGAIN_LATER,
|
||||
SECONDARY_ERROR_MESSAGES.MAX_RETRY,
|
||||
];
|
||||
|
||||
/**
|
||||
* Renders error message on the card.
|
||||
*
|
||||
* @param {string} message Main error message.
|
||||
* @param {string} secondaryMessage The secondary error message.
|
||||
* @returns {string} The SVG markup.
|
||||
*/
|
||||
const renderError = (message, secondaryMessage = "") => {
|
||||
return `
|
||||
<svg width="${ERROR_CARD_LENGTH}" height="120" viewBox="0 0 ${ERROR_CARD_LENGTH} 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
|
||||
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #252525 }
|
||||
.gray { fill: #858585 }
|
||||
</style>
|
||||
<rect x="0.5" y="0.5" width="${
|
||||
ERROR_CARD_LENGTH - 1
|
||||
}" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
|
||||
<text x="25" y="45" class="text">Something went wrong!${
|
||||
UPSTREAM_API_ERRORS.includes(secondaryMessage)
|
||||
? ""
|
||||
: " file an issue at https://tiny.one/readme-stats"
|
||||
}</text>
|
||||
<text data-testid="message" x="25" y="55" class="text small">
|
||||
<tspan x="25" dy="18">${encodeHTML(message)}</tspan>
|
||||
<tspan x="25" dy="18" class="gray">${secondaryMessage}</tspan>
|
||||
</text>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Auto layout utility, allows us to layout things vertically or horizontally with
|
||||
* proper gaping.
|
||||
@@ -380,6 +325,81 @@ const getCardColors = ({
|
||||
return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor };
|
||||
};
|
||||
|
||||
// Script parameters.
|
||||
const ERROR_CARD_LENGTH = 576.5;
|
||||
|
||||
/**
|
||||
* Encode string as HTML.
|
||||
*
|
||||
* @see https://stackoverflow.com/a/48073476/10629172
|
||||
*
|
||||
* @param {string} str String to encode.
|
||||
* @returns {string} Encoded string.
|
||||
*/
|
||||
const encodeHTML = (str) => {
|
||||
return str
|
||||
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
|
||||
return "&#" + i.charCodeAt(0) + ";";
|
||||
})
|
||||
.replace(/\u0008/gim, "");
|
||||
};
|
||||
|
||||
const UPSTREAM_API_ERRORS = [
|
||||
TRY_AGAIN_LATER,
|
||||
SECONDARY_ERROR_MESSAGES.MAX_RETRY,
|
||||
];
|
||||
|
||||
/**
|
||||
* Renders error message on the card.
|
||||
*
|
||||
* @param {string} message Main error message.
|
||||
* @param {string} secondaryMessage The secondary error message.
|
||||
* @param {object} options Function options.
|
||||
* @returns {string} The SVG markup.
|
||||
*/
|
||||
const renderError = (message, secondaryMessage = "", options = {}) => {
|
||||
const {
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme = "default",
|
||||
} = options;
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, bgColor, borderColor } = getCardColors({
|
||||
title_color,
|
||||
text_color,
|
||||
icon_color: "",
|
||||
bg_color,
|
||||
border_color,
|
||||
ring_color: "",
|
||||
theme,
|
||||
});
|
||||
|
||||
return `
|
||||
<svg width="${ERROR_CARD_LENGTH}" height="120" viewBox="0 0 ${ERROR_CARD_LENGTH} 120" fill="${bgColor}" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor} }
|
||||
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
.gray { fill: #858585 }
|
||||
</style>
|
||||
<rect x="0.5" y="0.5" width="${
|
||||
ERROR_CARD_LENGTH - 1
|
||||
}" height="99%" rx="4.5" fill="${bgColor}" stroke="${borderColor}"/>
|
||||
<text x="25" y="45" class="text">Something went wrong!${
|
||||
UPSTREAM_API_ERRORS.includes(secondaryMessage)
|
||||
? ""
|
||||
: " file an issue at https://tiny.one/readme-stats"
|
||||
}</text>
|
||||
<text data-testid="message" x="25" y="55" class="text small">
|
||||
<tspan x="25" dy="18">${encodeHTML(message)}</tspan>
|
||||
<tspan x="25" dy="18" class="gray">${secondaryMessage}</tspan>
|
||||
</text>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Split text over multiple lines based on the card width.
|
||||
*
|
||||
@@ -429,7 +449,11 @@ const TWO_HOURS = 7200;
|
||||
const FOUR_HOURS = 14400;
|
||||
const SIX_HOURS = 21600;
|
||||
const EIGHT_HOURS = 28800;
|
||||
const TWELVE_HOURS = 43200;
|
||||
const ONE_DAY = 86400;
|
||||
const TWO_DAY = ONE_DAY * 2;
|
||||
const SIX_DAY = ONE_DAY * 6;
|
||||
const TEN_DAY = ONE_DAY * 10;
|
||||
|
||||
const CONSTANTS = {
|
||||
ONE_MINUTE,
|
||||
@@ -441,8 +465,14 @@ const CONSTANTS = {
|
||||
FOUR_HOURS,
|
||||
SIX_HOURS,
|
||||
EIGHT_HOURS,
|
||||
TWELVE_HOURS,
|
||||
ONE_DAY,
|
||||
CARD_CACHE_SECONDS: SIX_HOURS,
|
||||
TWO_DAY,
|
||||
SIX_DAY,
|
||||
TEN_DAY,
|
||||
CARD_CACHE_SECONDS: ONE_DAY,
|
||||
TOP_LANGS_CACHE_SECONDS: SIX_DAY,
|
||||
PIN_CARD_CACHE_SECONDS: TEN_DAY,
|
||||
ERROR_CACHE_SECONDS: TEN_MINUTES,
|
||||
};
|
||||
|
||||
@@ -569,27 +599,6 @@ const dateDiff = (d1, d2) => {
|
||||
return Math.round(diff / (1000 * 60));
|
||||
};
|
||||
|
||||
const getBase64URIFromImage = async (imageURL) => {
|
||||
try {
|
||||
const response = await axios.get(imageURL, {
|
||||
responseType: "arraybuffer",
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
const base64Image = Buffer.from(response.data, "binary").toString(
|
||||
"base64",
|
||||
);
|
||||
const mimeType = response.headers["content-type"];
|
||||
return `data:${mimeType};base64,${base64Image}`;
|
||||
} else {
|
||||
throw new Error("Failed to fetch the image.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
ERROR_CARD_LENGTH,
|
||||
renderError,
|
||||
@@ -616,5 +625,4 @@ export {
|
||||
chunkArray,
|
||||
parseEmojis,
|
||||
dateDiff,
|
||||
getBase64URIFromImage,
|
||||
};
|
||||
|
||||
@@ -34,7 +34,6 @@ const fetcher = (variables, token) => {
|
||||
name
|
||||
}
|
||||
forkCount
|
||||
openGraphImageUrl
|
||||
}
|
||||
query getRepo($login: String!, $repo: String!) {
|
||||
user(login: $login) {
|
||||
|
||||
@@ -92,7 +92,7 @@ const fetchTopLanguages = async (
|
||||
);
|
||||
}
|
||||
throw new CustomError(
|
||||
"Something went while trying to retrieve the language data using the GraphQL API.",
|
||||
"Something went wrong while trying to retrieve the language data using the GraphQL API.",
|
||||
CustomError.GRAPHQL_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -22,7 +22,6 @@ export type RepositoryData = {
|
||||
};
|
||||
forkCount: number;
|
||||
starCount: number;
|
||||
stringifiedRepoImage: string;
|
||||
};
|
||||
|
||||
export type StatsData = {
|
||||
|
||||
@@ -150,7 +150,6 @@ exports[`Test Render WakaTime Card should render correctly with compact layout 1
|
||||
</svg>
|
||||
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
"
|
||||
`;
|
||||
@@ -303,7 +302,6 @@ exports[`Test Render WakaTime Card should render correctly with compact layout w
|
||||
</svg>
|
||||
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
"
|
||||
`;
|
||||
|
||||
+18
-83
@@ -120,6 +120,21 @@ describe("Test /api/", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should render error card in same theme as requested card", async () => {
|
||||
const { req, res } = faker({ theme: "merko" }, error);
|
||||
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderError(
|
||||
error.errors[0].message,
|
||||
"Make sure the provided username is not an organization",
|
||||
{ theme: "merko" },
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("should get the query options", async () => {
|
||||
const { req, res } = faker(
|
||||
{
|
||||
@@ -153,40 +168,6 @@ describe("Test /api/", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should have proper cache", async () => {
|
||||
const { req, res } = faker({}, data_stats);
|
||||
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
it("should set proper cache", async () => {
|
||||
const cache_seconds = 35000;
|
||||
const { req, res } = faker({ cache_seconds }, data_stats);
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${
|
||||
cache_seconds / 2
|
||||
}, s-maxage=${cache_seconds}, stale-while-revalidate=${
|
||||
CONSTANTS.ONE_DAY
|
||||
}`,
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
it("should set shorter cache when error", async () => {
|
||||
const { req, res } = faker({}, error);
|
||||
await api(req, res);
|
||||
@@ -202,54 +183,6 @@ describe("Test /api/", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("should set proper cache with clamped values", async () => {
|
||||
{
|
||||
let { req, res } = faker({ cache_seconds: 200000 }, data_stats);
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.ONE_DAY / 2}, s-maxage=${
|
||||
CONSTANTS.ONE_DAY
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
// note i'm using block scoped vars
|
||||
{
|
||||
let { req, res } = faker({ cache_seconds: 0 }, data_stats);
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
{
|
||||
let { req, res } = faker({ cache_seconds: -10000 }, data_stats);
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader.mock.calls).toEqual([
|
||||
["Content-Type", "image/svg+xml"],
|
||||
[
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
],
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it("should allow changing ring_color", async () => {
|
||||
const { req, res } = faker(
|
||||
{
|
||||
@@ -291,7 +224,9 @@ describe("Test /api/", () => {
|
||||
await api(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderError("Something went wrong", "This username is blacklisted"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should render error card when wrong locale is provided", async () => {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { benchmarkSuite } from "jest-bench";
|
||||
import gist from "../../api/gist.js";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { jest } from "@jest/globals";
|
||||
|
||||
const gist_data = {
|
||||
data: {
|
||||
viewer: {
|
||||
gist: {
|
||||
description:
|
||||
"List of countries and territories in English and Spanish: name, continent, capital, dial code, country codes, TLD, and area in sq km. Lista de países y territorios en Inglés y Español: nombre, continente, capital, código de teléfono, códigos de país, dominio y área en km cuadrados. Updated 2023",
|
||||
owner: {
|
||||
login: "Yizack",
|
||||
},
|
||||
stargazerCount: 33,
|
||||
forks: {
|
||||
totalCount: 11,
|
||||
},
|
||||
files: [
|
||||
{
|
||||
name: "countries.json",
|
||||
language: {
|
||||
name: "JSON",
|
||||
},
|
||||
size: 85858,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
benchmarkSuite("test /api/gist", {
|
||||
["simple request"]: async () => {
|
||||
const req = {
|
||||
query: {
|
||||
id: "bbfce31e0217a3689c8d961a356cb10d",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
|
||||
await gist(req, res);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
import { benchmarkSuite } from "jest-bench";
|
||||
import pin from "../../api/pin.js";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { jest } from "@jest/globals";
|
||||
|
||||
const data_repo = {
|
||||
repository: {
|
||||
username: "anuraghazra",
|
||||
name: "convoychat",
|
||||
stargazers: {
|
||||
totalCount: 38000,
|
||||
},
|
||||
description: "Help us take over the world! React + TS + GraphQL Chat App",
|
||||
primaryLanguage: {
|
||||
color: "#2b7489",
|
||||
id: "MDg6TGFuZ3VhZ2UyODc=",
|
||||
name: "TypeScript",
|
||||
},
|
||||
forkCount: 100,
|
||||
isTemplate: false,
|
||||
},
|
||||
};
|
||||
|
||||
const data_user = {
|
||||
data: {
|
||||
user: { repository: data_repo.repository },
|
||||
organization: null,
|
||||
},
|
||||
};
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
benchmarkSuite("test /api/pin", {
|
||||
["simple request"]: async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
repo: "convoychat",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
|
||||
await pin(req, res);
|
||||
},
|
||||
});
|
||||
+1
-1
@@ -89,7 +89,7 @@ describe("Card", () => {
|
||||
"200",
|
||||
);
|
||||
expect(document.getElementsByTagName("svg")[0]).toHaveAttribute(
|
||||
"height",
|
||||
"width",
|
||||
"200",
|
||||
);
|
||||
});
|
||||
|
||||
+11
-8
@@ -14,19 +14,20 @@ import { expect, describe, beforeAll, test } from "@jest/globals";
|
||||
|
||||
const REPO = "curly-fiesta";
|
||||
const USER = "catelinemnemosyne";
|
||||
const STATS_CARD_USER = "e2eninja";
|
||||
const GIST_ID = "372cef55fd897b31909fdeb3a7262758";
|
||||
|
||||
const STATS_DATA = {
|
||||
name: "Cateline Mnemosyne",
|
||||
totalPRs: 2,
|
||||
name: "CodeNinja",
|
||||
totalPRs: 1,
|
||||
totalReviews: 0,
|
||||
totalCommits: 8,
|
||||
totalCommits: 3,
|
||||
totalIssues: 1,
|
||||
totalStars: 1,
|
||||
contributedTo: 1,
|
||||
contributedTo: 0,
|
||||
rank: {
|
||||
level: "C",
|
||||
percentile: 98.06929469995667,
|
||||
percentile: 98.73972605284538,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -116,15 +117,17 @@ describe("Fetch Cards", () => {
|
||||
|
||||
// Check if the Vercel preview instance stats card function is up and running.
|
||||
await expect(
|
||||
axios.get(`${VERCEL_PREVIEW_URL}/api?username=${USER}`),
|
||||
axios.get(`${VERCEL_PREVIEW_URL}/api?username=${STATS_CARD_USER}`),
|
||||
).resolves.not.toThrow();
|
||||
|
||||
// Get local stats card.
|
||||
const localStatsCardSVG = renderStatsCard(STATS_DATA);
|
||||
const localStatsCardSVG = renderStatsCard(STATS_DATA, {
|
||||
include_all_commits: true,
|
||||
});
|
||||
|
||||
// Get the Vercel preview stats card response.
|
||||
const serverStatsSvg = await axios.get(
|
||||
`${VERCEL_PREVIEW_URL}/api?username=${USER}&${CACHE_BURST_STRING}`,
|
||||
`${VERCEL_PREVIEW_URL}/api?username=${STATS_CARD_USER}&include_all_commits=true&${CACHE_BURST_STRING}`,
|
||||
);
|
||||
|
||||
// Check if stats card from deployment matches the stats card from local.
|
||||
|
||||
@@ -165,7 +165,7 @@ describe("FetchTopLanguages", () => {
|
||||
});
|
||||
|
||||
await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow(
|
||||
"Something went while trying to retrieve the language data using the GraphQL API.",
|
||||
"Something went wrong while trying to retrieve the language data using the GraphQL API.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -103,7 +103,7 @@ const wakaTimeData = {
|
||||
};
|
||||
|
||||
describe("WakaTime fetcher", () => {
|
||||
it("should fetch correct wakatime data", async () => {
|
||||
it("should fetch correct WakaTime data", async () => {
|
||||
const username = "anuraghazra";
|
||||
mock
|
||||
.onGet(
|
||||
|
||||
+1
-24
@@ -4,7 +4,7 @@ import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import { expect, it, describe, afterEach } from "@jest/globals";
|
||||
import { renderGistCard } from "../src/cards/gist-card.js";
|
||||
import { renderError, CONSTANTS } from "../src/common/utils.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import gist from "../api/gist.js";
|
||||
|
||||
const gist_data = {
|
||||
@@ -170,27 +170,4 @@ describe("Test /api/gist", () => {
|
||||
renderError("Something went wrong", "Language not found"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should have proper cache", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
id: "bbfce31e0217a3689c8d961a356cb10d",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, gist_data);
|
||||
|
||||
await gist(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.setHeader).toBeCalledWith(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
+4
-26
@@ -4,7 +4,7 @@ import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import pin from "../api/pin.js";
|
||||
import { renderRepoCard } from "../src/cards/repo-card.js";
|
||||
import { renderError, CONSTANTS } from "../src/common/utils.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { expect, it, describe, afterEach } from "@jest/globals";
|
||||
|
||||
const data_repo = {
|
||||
@@ -155,7 +155,9 @@ describe("Test /api/pin", () => {
|
||||
await pin(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderError("Something went wrong", "This username is blacklisted"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should render error card if wrong locale provided", async () => {
|
||||
@@ -199,28 +201,4 @@ describe("Test /api/pin", () => {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("should have proper cache", async () => {
|
||||
const req = {
|
||||
query: {
|
||||
username: "anuraghazra",
|
||||
repo: "convoychat",
|
||||
},
|
||||
};
|
||||
const res = {
|
||||
setHeader: jest.fn(),
|
||||
send: jest.fn(),
|
||||
};
|
||||
mock.onPost("https://api.github.com/graphql").reply(200, data_user);
|
||||
|
||||
await pin(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.setHeader).toBeCalledWith(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,7 +18,6 @@ const data_repo = {
|
||||
},
|
||||
starCount: 38000,
|
||||
forkCount: 100,
|
||||
stringifiedRepoImage: "data:image/png;base64,base64/image/string",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -341,20 +340,33 @@ describe("Test renderRepoCard", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should render repo's social preview image, when show_image is true", () => {
|
||||
it("should have correct height with specified `description_lines_count` parameter", () => {
|
||||
// Testing short description
|
||||
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
||||
show_image: true,
|
||||
description_lines_count: 1,
|
||||
});
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "120");
|
||||
document.body.innerHTML = renderRepoCard(data_repo.repository, {
|
||||
description_lines_count: 3,
|
||||
});
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "150");
|
||||
|
||||
expect(queryByTestId(document.body, "card-image")).toBeInTheDocument();
|
||||
expect(
|
||||
queryByTestId(document.body, "card-image").children[0],
|
||||
).toHaveAttribute("href", data_repo.repository.stringifiedRepoImage);
|
||||
});
|
||||
|
||||
it("should not render repo's social preview image by default", () => {
|
||||
document.body.innerHTML = renderRepoCard(data_repo.repository);
|
||||
|
||||
expect(queryByTestId(document.body, "card-image")).not.toBeInTheDocument();
|
||||
// Testing long description
|
||||
const longDescription =
|
||||
"A tool that will make a lot of iPhone/iPad developers' life easier. It shares your app over-the-air in a WiFi network. Bonjour is used and no configuration is needed.";
|
||||
document.body.innerHTML = renderRepoCard(
|
||||
{ ...data_repo.repository, description: longDescription },
|
||||
{
|
||||
description_lines_count: 3,
|
||||
},
|
||||
);
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "150");
|
||||
document.body.innerHTML = renderRepoCard(
|
||||
{ ...data_repo.repository, description: longDescription },
|
||||
{
|
||||
description_lines_count: 1,
|
||||
},
|
||||
);
|
||||
expect(document.querySelector("svg")).toHaveAttribute("height", "120");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -387,7 +387,9 @@ describe("Test renderStatsCard", () => {
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
|
||||
).textContent,
|
||||
).toMatchInlineSnapshot(`"累计提交数(commit) (2023):"`);
|
||||
).toMatchInlineSnapshot(
|
||||
`"累计提交数(commit) (${new Date().getFullYear()}):"`,
|
||||
);
|
||||
expect(
|
||||
document.querySelector(
|
||||
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
|
||||
|
||||
+4
-25
@@ -4,7 +4,7 @@ import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import topLangs from "../api/top-langs.js";
|
||||
import { renderTopLanguages } from "../src/cards/top-languages-card.js";
|
||||
import { renderError, CONSTANTS } from "../src/common/utils.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { expect, it, describe, afterEach } from "@jest/globals";
|
||||
|
||||
const data_langs = {
|
||||
@@ -183,7 +183,9 @@ describe("Test /api/top-langs", () => {
|
||||
await topLangs(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderError("Something went wrong"));
|
||||
expect(res.send).toBeCalledWith(
|
||||
renderError("Something went wrong", "This username is blacklisted"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should render error card if wrong locale provided", async () => {
|
||||
@@ -206,27 +208,4 @@ describe("Test /api/top-langs", () => {
|
||||
renderError("Something went wrong", "Locale not found"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should have proper cache", 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.setHeader).toBeCalledWith(
|
||||
"Cache-Control",
|
||||
`max-age=${CONSTANTS.SIX_HOURS / 2}, s-maxage=${
|
||||
CONSTANTS.SIX_HOURS
|
||||
}, stale-while-revalidate=${CONSTANTS.ONE_DAY}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import { jest } from "@jest/globals";
|
||||
import "@testing-library/jest-dom";
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import wakatime from "../api/wakatime.js";
|
||||
import { renderWakatimeCard } from "../src/cards/wakatime-card.js";
|
||||
import { expect, it, describe, afterEach } from "@jest/globals";
|
||||
|
||||
const wakaTimeData = {
|
||||
data: {
|
||||
categories: [
|
||||
{
|
||||
digital: "22:40",
|
||||
hours: 22,
|
||||
minutes: 40,
|
||||
name: "Coding",
|
||||
percent: 100,
|
||||
text: "22 hrs 40 mins",
|
||||
total_seconds: 81643.570077,
|
||||
},
|
||||
],
|
||||
daily_average: 16095,
|
||||
daily_average_including_other_language: 16329,
|
||||
days_including_holidays: 7,
|
||||
days_minus_holidays: 5,
|
||||
editors: [
|
||||
{
|
||||
digital: "22:40",
|
||||
hours: 22,
|
||||
minutes: 40,
|
||||
name: "VS Code",
|
||||
percent: 100,
|
||||
text: "22 hrs 40 mins",
|
||||
total_seconds: 81643.570077,
|
||||
},
|
||||
],
|
||||
holidays: 2,
|
||||
human_readable_daily_average: "4 hrs 28 mins",
|
||||
human_readable_daily_average_including_other_language: "4 hrs 32 mins",
|
||||
human_readable_total: "22 hrs 21 mins",
|
||||
human_readable_total_including_other_language: "22 hrs 40 mins",
|
||||
id: "random hash",
|
||||
is_already_updating: false,
|
||||
is_coding_activity_visible: true,
|
||||
is_including_today: false,
|
||||
is_other_usage_visible: true,
|
||||
is_stuck: false,
|
||||
is_up_to_date: true,
|
||||
languages: [
|
||||
{
|
||||
digital: "0:19",
|
||||
hours: 0,
|
||||
minutes: 19,
|
||||
name: "Other",
|
||||
percent: 1.43,
|
||||
text: "19 mins",
|
||||
total_seconds: 1170.434361,
|
||||
},
|
||||
{
|
||||
digital: "0:01",
|
||||
hours: 0,
|
||||
minutes: 1,
|
||||
name: "TypeScript",
|
||||
percent: 0.1,
|
||||
text: "1 min",
|
||||
total_seconds: 83.293809,
|
||||
},
|
||||
{
|
||||
digital: "0:00",
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
name: "YAML",
|
||||
percent: 0.07,
|
||||
text: "0 secs",
|
||||
total_seconds: 54.975151,
|
||||
},
|
||||
],
|
||||
operating_systems: [
|
||||
{
|
||||
digital: "22:40",
|
||||
hours: 22,
|
||||
minutes: 40,
|
||||
name: "Mac",
|
||||
percent: 100,
|
||||
text: "22 hrs 40 mins",
|
||||
total_seconds: 81643.570077,
|
||||
},
|
||||
],
|
||||
percent_calculated: 100,
|
||||
range: "last_7_days",
|
||||
status: "ok",
|
||||
timeout: 15,
|
||||
total_seconds: 80473.135716,
|
||||
total_seconds_including_other_language: 81643.570077,
|
||||
user_id: "random hash",
|
||||
username: "anuraghazra",
|
||||
writes_only: false,
|
||||
},
|
||||
};
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
afterEach(() => {
|
||||
mock.reset();
|
||||
});
|
||||
|
||||
describe("Test /api/wakatime", () => {
|
||||
it("should test the request", async () => {
|
||||
const username = "anuraghazra";
|
||||
const req = { query: { username } };
|
||||
const res = { setHeader: jest.fn(), send: jest.fn() };
|
||||
mock
|
||||
.onGet(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
|
||||
)
|
||||
.reply(200, wakaTimeData);
|
||||
|
||||
await wakatime(req, res);
|
||||
|
||||
expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml");
|
||||
expect(res.send).toBeCalledWith(renderWakatimeCard(wakaTimeData.data, {}));
|
||||
});
|
||||
});
|
||||
+6
-4
@@ -12,7 +12,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
||||
|
||||
## Stats
|
||||
|
||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
|
||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and WakaTime Card.
|
||||
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
@@ -40,11 +40,11 @@ Use `?theme=THEME_NAME` parameter like so:
|
||||
| `rose_pine` ![rose_pine][rose_pine] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha] |
|
||||
| `date_night` ![date_night][date_night] | `one_dark_pro` ![one_dark_pro][one_dark_pro] | `rose` ![rose][rose] |
|
||||
| `holi` ![holi][holi] | `neon` ![neon][neon] | `blue_navy` ![blue_navy][blue_navy] |
|
||||
| `calm_pink` ![calm_pink][calm_pink] | | [Add your theme][add-theme] |
|
||||
| `calm_pink` ![calm_pink][calm_pink] | `ambient_gradient` ![ambient_gradient][ambient_gradient] | [Add your theme][add-theme] |
|
||||
|
||||
## Repo Card
|
||||
|
||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
|
||||
> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and WakaTime Card.
|
||||
|
||||
| | | |
|
||||
| :--: | :--: | :--: |
|
||||
@@ -72,7 +72,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
||||
| `rose_pine` ![rose_pine][rose_pine_repo] | `catppuccin_latte` ![catppuccin_latte][catppuccin_latte_repo] | `catppuccin_mocha` ![catppuccin_mocha][catppuccin_mocha_repo] |
|
||||
| `date_night` ![date_night][date_night_repo] | `one_dark_pro` ![one_dark_pro][one_dark_pro_repo] | `rose` ![rose][rose_repo] |
|
||||
| `holi` ![holi][holi_repo] | `neon` ![neon][neon_repo] | `blue_navy` ![blue_navy][blue_navy_repo] |
|
||||
| `calm_pink` ![calm_pink][calm_pink_repo] | | [Add your theme][add-theme] |
|
||||
| `calm_pink` ![calm_pink][calm_pink_repo] | `ambient_gradient` ![ambient_gradient][ambient_gradient_repo] | [Add your theme][add-theme] |
|
||||
|
||||
|
||||
[default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default
|
||||
@@ -149,6 +149,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
||||
[neon]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=neon
|
||||
[blue_navy]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=blue_navy
|
||||
[calm_pink]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=calm_pink
|
||||
[ambient_gradient]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=ambient_gradient
|
||||
|
||||
|
||||
[default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default
|
||||
@@ -225,6 +226,7 @@ Use `?theme=THEME_NAME` parameter like so:
|
||||
[neon_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=neon
|
||||
[blue_navy_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=blue_navy
|
||||
[calm_pink_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=calm_pink
|
||||
[ambient_gradient_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=ambient_gradient
|
||||
|
||||
|
||||
[add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js
|
||||
|
||||
@@ -456,6 +456,12 @@ export const themes = {
|
||||
border_color: "e1bc29",
|
||||
bg_color: "2b2d40",
|
||||
},
|
||||
ambient_gradient: {
|
||||
title_color: "ffffff",
|
||||
text_color: "ffffff",
|
||||
icon_color: "ffffff",
|
||||
bg_color: "35,4158d0,c850c0,ffcc70",
|
||||
},
|
||||
};
|
||||
|
||||
export default themes;
|
||||
|
||||
+1
-1
@@ -11,4 +11,4 @@
|
||||
"destination": "https://github.com/anuraghazra/github-readme-stats"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user