@stats-organization/github-readme-stats-core 2.1.4 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +34 -0
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +18 -0
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +17 -0
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +36 -4
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +34 -0
- package/build/calculateRank.d.ts +12 -11
- package/build/calculateRank.d.ts.map +1 -1
- package/build/calculateRank.js +18 -18
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +29 -20
- package/build/cards/stats.d.ts +4 -2
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +21 -8
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +39 -11
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +29 -8
- package/build/common/Card.d.ts +9 -3
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +47 -19
- package/build/common/color.d.ts +42 -8
- package/build/common/color.d.ts.map +1 -1
- package/build/common/color.js +62 -13
- package/build/common/html.js +1 -1
- package/build/common/http.d.ts +13 -4
- package/build/common/http.d.ts.map +1 -1
- package/build/common/http.js +3 -3
- package/build/common/languageColors.json +9 -1
- package/build/common/ops.d.ts +30 -29
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +32 -37
- package/build/common/render.d.ts +115 -111
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +138 -87
- package/build/common/retryer.d.ts +14 -6
- package/build/common/retryer.d.ts.map +1 -1
- package/build/common/retryer.js +1 -0
- package/build/fetchers/gist.d.ts +6 -21
- package/build/fetchers/gist.d.ts.map +1 -1
- package/build/fetchers/gist.js +30 -35
- package/build/fetchers/repo.js +1 -1
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +0 -1
- package/build/fetchers/types.d.ts +126 -0
- package/build/fetchers/types.d.ts.map +1 -0
- package/build/fetchers/types.js +1 -0
- package/package.json +4 -4
- package/src/_emoji-name-map.d.ts +10 -0
- package/src/api/gist.js +36 -0
- package/src/api/index.js +19 -0
- package/src/api/pin.js +18 -0
- package/src/api/top-langs.js +38 -4
- package/src/api/wakatime.js +36 -0
- package/src/{calculateRank.js → calculateRank.ts} +29 -19
- package/src/cards/repo.js +30 -20
- package/src/cards/stats.js +22 -8
- package/src/cards/top-languages.js +49 -11
- package/src/cards/wakatime.js +33 -8
- package/src/common/Card.ts +51 -16
- package/src/common/color.ts +85 -22
- package/src/common/html.ts +1 -1
- package/src/common/http.ts +31 -0
- package/src/common/languageColors.json +9 -1
- package/src/common/{ops.js → ops.ts} +48 -50
- package/src/common/{render.js → render.ts} +208 -96
- package/src/common/retryer.ts +18 -10
- package/src/fetchers/gist.ts +136 -0
- package/src/fetchers/repo.js +1 -1
- package/src/fetchers/stats.js +0 -1
- package/src/common/http.js +0 -19
- package/src/fetchers/gist.js +0 -112
- /package/src/fetchers/{types.d.ts → types.ts} +0 -0
package/build/api/gist.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/api/gist.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/api/gist.js"],"names":[],"mappings":"AAYe;;;;;;;;;;;;;;;;GAwHd"}
|
package/build/api/gist.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { renderGistCard } from "../cards/gist.js";
|
|
2
|
+
import { findInvalidColor } from "../common/color.js";
|
|
2
3
|
import { MissingParamError, retrieveSecondaryMessage, } from "../common/error.js";
|
|
3
4
|
import { parseBoolean } from "../common/ops.js";
|
|
4
5
|
import { renderError } from "../common/render.js";
|
|
@@ -6,6 +7,22 @@ import { fetchGist } from "../fetchers/gist.js";
|
|
|
6
7
|
import { isLocaleAvailable } from "../translations.js";
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
export default async ({ id, title_color, icon_color, text_color, bg_color, theme, locale, border_radius, border_color, show_owner, browser_rendering, hide_border, }, pat = null) => {
|
|
10
|
+
const invalidColorInput = findInvalidColor({
|
|
11
|
+
title_color,
|
|
12
|
+
icon_color,
|
|
13
|
+
text_color,
|
|
14
|
+
bg_color,
|
|
15
|
+
border_color,
|
|
16
|
+
});
|
|
17
|
+
if (invalidColorInput) {
|
|
18
|
+
return {
|
|
19
|
+
status: "error - permanent",
|
|
20
|
+
content: renderError({
|
|
21
|
+
message: "Something went wrong",
|
|
22
|
+
secondaryMessage: `Invalid color input for parameter "${invalidColorInput}"`,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
9
26
|
if (locale && !isLocaleAvailable(locale)) {
|
|
10
27
|
return {
|
|
11
28
|
status: "error - permanent",
|
|
@@ -22,6 +39,23 @@ export default async ({ id, title_color, icon_color, text_color, bg_color, theme
|
|
|
22
39
|
}),
|
|
23
40
|
};
|
|
24
41
|
}
|
|
42
|
+
const safePattern = /^[-\w/.,]+$/;
|
|
43
|
+
if (id && !safePattern.test(id)) {
|
|
44
|
+
return {
|
|
45
|
+
status: "error - permanent",
|
|
46
|
+
content: renderError({
|
|
47
|
+
message: "Something went wrong",
|
|
48
|
+
secondaryMessage: "Gist ID contains unsafe characters",
|
|
49
|
+
renderOptions: {
|
|
50
|
+
title_color,
|
|
51
|
+
text_color,
|
|
52
|
+
bg_color,
|
|
53
|
+
border_color,
|
|
54
|
+
theme,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
25
59
|
try {
|
|
26
60
|
const gistData = await fetchGist(id, pat);
|
|
27
61
|
return {
|
package/build/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.js"],"names":[],"mappings":"AAYe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6Ld"}
|
package/build/api/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { renderStatsCard } from "../cards/stats.js";
|
|
2
|
+
import { findInvalidColor } from "../common/color.js";
|
|
2
3
|
import { MissingParamError, retrieveSecondaryMessage, } from "../common/error.js";
|
|
3
4
|
import { parseArray, parseBoolean } from "../common/ops.js";
|
|
4
5
|
import { renderError } from "../common/render.js";
|
|
@@ -6,6 +7,23 @@ import { fetchStats } from "../fetchers/stats.js";
|
|
|
6
7
|
import { isLocaleAvailable } from "../translations.js";
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
export default async ({ username, repo, owner, hide, hide_title, hide_border, card_width, hide_rank, show_icons, include_all_commits, commits_year, line_height, title_color, ring_color, icon_color, text_color, text_bold, bg_color, theme, exclude_repo, custom_title, locale, disable_animations, border_radius, number_format, role, number_precision, border_color, rank_icon, show, }, pat = null) => {
|
|
10
|
+
const invalidColorInput = findInvalidColor({
|
|
11
|
+
title_color,
|
|
12
|
+
ring_color,
|
|
13
|
+
icon_color,
|
|
14
|
+
text_color,
|
|
15
|
+
bg_color,
|
|
16
|
+
border_color,
|
|
17
|
+
});
|
|
18
|
+
if (invalidColorInput) {
|
|
19
|
+
return {
|
|
20
|
+
status: "error - permanent",
|
|
21
|
+
content: renderError({
|
|
22
|
+
message: "Something went wrong",
|
|
23
|
+
secondaryMessage: `Invalid color input for parameter "${invalidColorInput}"`,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
9
27
|
if (locale && !isLocaleAvailable(locale)) {
|
|
10
28
|
return {
|
|
11
29
|
status: "error - permanent",
|
package/build/api/pin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../src/api/pin.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../src/api/pin.js"],"names":[],"mappings":"AAYe;;;;;;;;;;;;;;;;;;;;;;;;GAqJd"}
|
package/build/api/pin.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { renderRepoCard } from "../cards/repo.js";
|
|
2
|
+
import { findInvalidColor } from "../common/color.js";
|
|
2
3
|
import { MissingParamError, retrieveSecondaryMessage, } from "../common/error.js";
|
|
3
4
|
import { parseArray, parseBoolean } from "../common/ops.js";
|
|
4
5
|
import { renderError } from "../common/render.js";
|
|
@@ -6,6 +7,22 @@ import { fetchRepo } from "../fetchers/repo.js";
|
|
|
6
7
|
import { isLocaleAvailable } from "../translations.js";
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
export default async ({ username, repo, hide_border, title_color, icon_color, text_color, bg_color, card_width, theme, show_owner, browser_rendering, show, show_icons, number_format, text_bold, line_height, locale, border_radius, border_color, description_lines_count, }, pat = null) => {
|
|
10
|
+
const invalidColorInput = findInvalidColor({
|
|
11
|
+
title_color,
|
|
12
|
+
icon_color,
|
|
13
|
+
text_color,
|
|
14
|
+
bg_color,
|
|
15
|
+
border_color,
|
|
16
|
+
});
|
|
17
|
+
if (invalidColorInput) {
|
|
18
|
+
return {
|
|
19
|
+
status: "error - permanent",
|
|
20
|
+
content: renderError({
|
|
21
|
+
message: "Something went wrong",
|
|
22
|
+
secondaryMessage: `Invalid color input for parameter "${invalidColorInput}"`,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
9
26
|
if (locale && !isLocaleAvailable(locale)) {
|
|
10
27
|
return {
|
|
11
28
|
status: "error - permanent",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-langs.d.ts","sourceRoot":"","sources":["../../src/api/top-langs.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"top-langs.d.ts","sourceRoot":"","sources":["../../src/api/top-langs.js"],"names":[],"mappings":"AAYe;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2Ld"}
|
package/build/api/top-langs.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { renderTopLanguages } from "../cards/top-languages.js";
|
|
2
|
+
import { findInvalidColor } from "../common/color.js";
|
|
2
3
|
import { MissingParamError, retrieveSecondaryMessage, } from "../common/error.js";
|
|
3
4
|
import { parseArray, parseBoolean } from "../common/ops.js";
|
|
4
5
|
import { renderError } from "../common/render.js";
|
|
@@ -6,6 +7,22 @@ import { fetchTopLanguages } from "../fetchers/top-languages.js";
|
|
|
6
7
|
import { isLocaleAvailable } from "../translations.js";
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
export default async ({ username, hide, hide_title, hide_border, card_width, title_color, text_color, bg_color, prog_bar_bg_color, theme, layout, langs_count, exclude_repo, size_weight, count_weight, custom_title, locale, border_radius, border_color, role, disable_animations, hide_progress, hide_values, stats_format, }, pat = null) => {
|
|
10
|
+
const invalidColorInput = findInvalidColor({
|
|
11
|
+
title_color,
|
|
12
|
+
text_color,
|
|
13
|
+
bg_color,
|
|
14
|
+
prog_bar_bg_color,
|
|
15
|
+
border_color,
|
|
16
|
+
});
|
|
17
|
+
if (invalidColorInput) {
|
|
18
|
+
return {
|
|
19
|
+
status: "error - permanent",
|
|
20
|
+
content: renderError({
|
|
21
|
+
message: "Something went wrong",
|
|
22
|
+
secondaryMessage: `Invalid color input for parameter "${invalidColorInput}"`,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
9
26
|
if (locale && !isLocaleAvailable(locale)) {
|
|
10
27
|
return {
|
|
11
28
|
status: "error - permanent",
|
|
@@ -22,9 +39,25 @@ export default async ({ username, hide, hide_title, hide_border, card_width, tit
|
|
|
22
39
|
}),
|
|
23
40
|
};
|
|
24
41
|
}
|
|
42
|
+
const safePattern = /^[-\w/.,]+$/;
|
|
43
|
+
if (username && !safePattern.test(username)) {
|
|
44
|
+
return {
|
|
45
|
+
status: "error - permanent",
|
|
46
|
+
content: renderError({
|
|
47
|
+
message: "Something went wrong",
|
|
48
|
+
secondaryMessage: "Username contains unsafe characters",
|
|
49
|
+
renderOptions: {
|
|
50
|
+
title_color,
|
|
51
|
+
text_color,
|
|
52
|
+
bg_color,
|
|
53
|
+
border_color,
|
|
54
|
+
theme,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
25
59
|
if (layout !== undefined &&
|
|
26
|
-
|
|
27
|
-
!["compact", "normal", "donut", "donut-vertical", "pie"].includes(layout))) {
|
|
60
|
+
!["compact", "normal", "donut", "donut-vertical", "pie"].includes(layout)) {
|
|
28
61
|
return {
|
|
29
62
|
status: "error - permanent",
|
|
30
63
|
content: renderError({
|
|
@@ -41,8 +74,7 @@ export default async ({ username, hide, hide_title, hide_border, card_width, tit
|
|
|
41
74
|
};
|
|
42
75
|
}
|
|
43
76
|
if (stats_format !== undefined &&
|
|
44
|
-
|
|
45
|
-
!["bytes", "percentages"].includes(stats_format))) {
|
|
77
|
+
!["bytes", "percentages"].includes(stats_format)) {
|
|
46
78
|
return {
|
|
47
79
|
status: "error - permanent",
|
|
48
80
|
content: renderError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/api/wakatime.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/api/wakatime.js"],"names":[],"mappings":"AAYe;;;;;;;;;;;;;;;;;;;;;;;;;GAsId"}
|
package/build/api/wakatime.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { renderWakatimeCard } from "../cards/wakatime.js";
|
|
2
|
+
import { findInvalidColor } from "../common/color.js";
|
|
2
3
|
import { MissingParamError, retrieveSecondaryMessage, } from "../common/error.js";
|
|
3
4
|
import { parseArray, parseBoolean } from "../common/ops.js";
|
|
4
5
|
import { renderError } from "../common/render.js";
|
|
@@ -6,6 +7,22 @@ import { fetchWakatimeStats } from "../fetchers/wakatime.js";
|
|
|
6
7
|
import { isLocaleAvailable } from "../translations.js";
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
export default async ({ username, title_color, icon_color, hide_border, card_width, line_height, text_color, bg_color, theme, hide_title, hide_progress, custom_title, locale, layout, langs_count, hide, api_domain, border_radius, border_color, display_format, disable_animations, }) => {
|
|
10
|
+
const invalidColorInput = findInvalidColor({
|
|
11
|
+
title_color,
|
|
12
|
+
icon_color,
|
|
13
|
+
text_color,
|
|
14
|
+
bg_color,
|
|
15
|
+
border_color,
|
|
16
|
+
});
|
|
17
|
+
if (invalidColorInput) {
|
|
18
|
+
return {
|
|
19
|
+
status: "error - permanent",
|
|
20
|
+
content: renderError({
|
|
21
|
+
message: "Something went wrong",
|
|
22
|
+
secondaryMessage: `Invalid color input for parameter "${invalidColorInput}"`,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
9
26
|
if (locale && !isLocaleAvailable(locale)) {
|
|
10
27
|
return {
|
|
11
28
|
status: "error - permanent",
|
|
@@ -22,6 +39,23 @@ export default async ({ username, title_color, icon_color, hide_border, card_wid
|
|
|
22
39
|
}),
|
|
23
40
|
};
|
|
24
41
|
}
|
|
42
|
+
const safePattern = /^[-\w/.,]+$/;
|
|
43
|
+
if (username && !safePattern.test(username)) {
|
|
44
|
+
return {
|
|
45
|
+
status: "error - permanent",
|
|
46
|
+
content: renderError({
|
|
47
|
+
message: "Something went wrong",
|
|
48
|
+
secondaryMessage: "Username contains unsafe characters",
|
|
49
|
+
renderOptions: {
|
|
50
|
+
title_color,
|
|
51
|
+
text_color,
|
|
52
|
+
bg_color,
|
|
53
|
+
border_color,
|
|
54
|
+
theme,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
25
59
|
try {
|
|
26
60
|
const stats = await fetchWakatimeStats({ username, api_domain });
|
|
27
61
|
return {
|
package/build/calculateRank.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Calculates the users rank.
|
|
3
3
|
*
|
|
4
|
-
* @param
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
11
|
-
* @param
|
|
12
|
-
* @param
|
|
13
|
-
* @returns
|
|
4
|
+
* @param params Parameters on which the user's rank depends.
|
|
5
|
+
* @param params.all_commits Whether `include_all_commits` was used.
|
|
6
|
+
* @param params.commits Number of commits.
|
|
7
|
+
* @param params.prs The number of pull requests.
|
|
8
|
+
* @param params.issues The number of issues.
|
|
9
|
+
* @param params.reviews The number of reviews.
|
|
10
|
+
* @param params.repos Total number of repos (accepted for compatibility, unused in the calculation).
|
|
11
|
+
* @param params.stars The number of stars.
|
|
12
|
+
* @param params.followers The number of followers.
|
|
13
|
+
* @returns The users rank.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
declare function calculateRank({ all_commits, commits, prs, issues, reviews, stars, followers, }: {
|
|
16
16
|
all_commits: boolean;
|
|
17
17
|
commits: number;
|
|
18
18
|
prs: number;
|
|
@@ -25,4 +25,5 @@ export function calculateRank({ all_commits, commits, prs, issues, reviews, repo
|
|
|
25
25
|
level: string;
|
|
26
26
|
percentile: number;
|
|
27
27
|
};
|
|
28
|
+
export { calculateRank };
|
|
28
29
|
//# sourceMappingURL=calculateRank.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculateRank.d.ts","sourceRoot":"","sources":["../src/calculateRank.
|
|
1
|
+
{"version":3,"file":"calculateRank.d.ts","sourceRoot":"","sources":["../src/calculateRank.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;GAaG;AACH,iBAAS,aAAa,CAAC,EACrB,WAAW,EACX,OAAO,EACP,GAAG,EACH,MAAM,EACN,OAAO,EACP,KAAK,EACL,SAAS,GACV,EAAE;IACD,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAyCxC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/build/calculateRank.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Calculates the exponential cdf.
|
|
3
3
|
*
|
|
4
|
-
* @param
|
|
5
|
-
* @returns
|
|
4
|
+
* @param x The value.
|
|
5
|
+
* @returns The exponential cdf.
|
|
6
6
|
*/
|
|
7
7
|
function exponential_cdf(x) {
|
|
8
8
|
return 1 - 2 ** -x;
|
|
@@ -10,8 +10,8 @@ function exponential_cdf(x) {
|
|
|
10
10
|
/**
|
|
11
11
|
* Calculates the log normal cdf.
|
|
12
12
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @returns
|
|
13
|
+
* @param x The value.
|
|
14
|
+
* @returns The log normal cdf.
|
|
15
15
|
*/
|
|
16
16
|
function log_normal_cdf(x) {
|
|
17
17
|
// approximation
|
|
@@ -20,21 +20,18 @@ function log_normal_cdf(x) {
|
|
|
20
20
|
/**
|
|
21
21
|
* Calculates the users rank.
|
|
22
22
|
*
|
|
23
|
-
* @param
|
|
24
|
-
* @param
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
-
* @param
|
|
32
|
-
* @returns
|
|
23
|
+
* @param params Parameters on which the user's rank depends.
|
|
24
|
+
* @param params.all_commits Whether `include_all_commits` was used.
|
|
25
|
+
* @param params.commits Number of commits.
|
|
26
|
+
* @param params.prs The number of pull requests.
|
|
27
|
+
* @param params.issues The number of issues.
|
|
28
|
+
* @param params.reviews The number of reviews.
|
|
29
|
+
* @param params.repos Total number of repos (accepted for compatibility, unused in the calculation).
|
|
30
|
+
* @param params.stars The number of stars.
|
|
31
|
+
* @param params.followers The number of followers.
|
|
32
|
+
* @returns The users rank.
|
|
33
33
|
*/
|
|
34
|
-
function calculateRank({ all_commits, commits, prs, issues, reviews,
|
|
35
|
-
// eslint-disable-next-line no-unused-vars
|
|
36
|
-
repos, // unused
|
|
37
|
-
stars, followers, }) {
|
|
34
|
+
function calculateRank({ all_commits, commits, prs, issues, reviews, stars, followers, }) {
|
|
38
35
|
const COMMITS_MEDIAN = all_commits ? 1000 : 250, COMMITS_WEIGHT = 2;
|
|
39
36
|
const PRS_MEDIAN = 50, PRS_WEIGHT = 3;
|
|
40
37
|
const ISSUES_MEDIAN = 25, ISSUES_WEIGHT = 1;
|
|
@@ -58,6 +55,9 @@ stars, followers, }) {
|
|
|
58
55
|
FOLLOWERS_WEIGHT * log_normal_cdf(followers / FOLLOWERS_MEDIAN)) /
|
|
59
56
|
TOTAL_WEIGHT;
|
|
60
57
|
const level = LEVELS[THRESHOLDS.findIndex((t) => rank * 100 <= t)];
|
|
58
|
+
if (level === undefined) {
|
|
59
|
+
throw new Error("Unable to determine rank level");
|
|
60
|
+
}
|
|
61
61
|
return { level, percentile: rank * 100 };
|
|
62
62
|
}
|
|
63
63
|
export { calculateRank };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/cards/repo.js"],"names":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/cards/repo.js"],"names":[],"mappings":";;;;;;;;AA0DA;;;GAGG;AAEH;;;;;;GAMG;AACH,qCAJW,cAAc,YACd,OAAO,CAAC,eAAe,CAAC,GACtB,MAAM,CA8SlB"}
|
package/build/cards/repo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Card } from "../common/Card.js";
|
|
2
2
|
import { I18n } from "../common/I18n.js";
|
|
3
|
-
import { getCardColors } from "../common/color.js";
|
|
3
|
+
import { getCardColors, isPrefixedHexColor } from "../common/color.js";
|
|
4
4
|
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
|
|
5
5
|
import { encodeHTML } from "../common/html.js";
|
|
6
6
|
import { icons } from "../common/icons.js";
|
|
@@ -21,20 +21,28 @@ const DESCRIPTION_MAX_LINES = 3;
|
|
|
21
21
|
* @param {string} textColor The color of the text.
|
|
22
22
|
* @returns {string} Wrapped repo description SVG object.
|
|
23
23
|
*/
|
|
24
|
-
const getBadgeSVG = (label, textColor, xOffset = 0) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
const getBadgeSVG = (label, textColor, xOffset = 0) => {
|
|
25
|
+
if (!isPrefixedHexColor(textColor)) {
|
|
26
|
+
throw new Error(`Invalid text color: "${textColor}"`);
|
|
27
|
+
}
|
|
28
|
+
if (!Number.isFinite(xOffset)) {
|
|
29
|
+
throw new Error(`Invalid xOffset: "${xOffset}"`);
|
|
30
|
+
}
|
|
31
|
+
return `
|
|
32
|
+
<g data-testid="badge" class="badge" transform="translate(${320 + xOffset}, -18)">
|
|
33
|
+
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
|
34
|
+
<text
|
|
35
|
+
x="23" y="-5"
|
|
36
|
+
alignment-baseline="central"
|
|
37
|
+
dominant-baseline="central"
|
|
38
|
+
text-anchor="middle"
|
|
39
|
+
fill="${textColor}"
|
|
40
|
+
>
|
|
41
|
+
${encodeHTML(label)}
|
|
42
|
+
</text>
|
|
43
|
+
</g>
|
|
44
|
+
`;
|
|
45
|
+
};
|
|
38
46
|
/**
|
|
39
47
|
* @typedef {import("../fetchers/types").RepositoryData} RepositoryData Repository data.
|
|
40
48
|
* @typedef {import("./types").RepoCardOptions} RepoCardOptions Repo card options.
|
|
@@ -59,6 +67,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
59
67
|
translations: repoCardLocales,
|
|
60
68
|
});
|
|
61
69
|
let repoFilter = encodeURIComponent(buildSearchFilter([nameWithOwner], []));
|
|
70
|
+
const encodedUsername = encodeURIComponent(username);
|
|
62
71
|
const STATS = {};
|
|
63
72
|
if (show.includes("prs_authored")) {
|
|
64
73
|
STATS.prs_authored = {
|
|
@@ -66,7 +75,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
66
75
|
label: i18n.t("repocard.prs-authored"),
|
|
67
76
|
value: totalPRsAuthored,
|
|
68
77
|
id: "prs_authored",
|
|
69
|
-
link: `https://github.com/search?q=${repoFilter}author%3A${
|
|
78
|
+
link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&type=pullrequests`,
|
|
70
79
|
};
|
|
71
80
|
}
|
|
72
81
|
if (show.includes("prs_commented")) {
|
|
@@ -75,7 +84,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
75
84
|
label: i18n.t("repocard.prs-commented"),
|
|
76
85
|
value: totalPRsCommented,
|
|
77
86
|
id: "prs_commented",
|
|
78
|
-
link: `https://github.com/search?q=${repoFilter}commenter%3A${
|
|
87
|
+
link: `https://github.com/search?q=${repoFilter}commenter%3A${encodedUsername}+-author%3A${encodedUsername}&type=pullrequests`,
|
|
79
88
|
};
|
|
80
89
|
}
|
|
81
90
|
if (show.includes("prs_reviewed")) {
|
|
@@ -84,7 +93,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
84
93
|
label: i18n.t("repocard.prs-reviewed"),
|
|
85
94
|
value: totalPRsReviewed,
|
|
86
95
|
id: "prs_reviewed",
|
|
87
|
-
link: `https://github.com/search?q=${repoFilter}reviewed-by%3A${
|
|
96
|
+
link: `https://github.com/search?q=${repoFilter}reviewed-by%3A${encodedUsername}+-author%3A${encodedUsername}&type=pullrequests`,
|
|
88
97
|
};
|
|
89
98
|
}
|
|
90
99
|
if (show.includes("issues_authored")) {
|
|
@@ -93,7 +102,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
93
102
|
label: i18n.t("repocard.issues-authored"),
|
|
94
103
|
value: totalIssuesAuthored,
|
|
95
104
|
id: "issues_authored",
|
|
96
|
-
link: `https://github.com/search?q=${repoFilter}author%3A${
|
|
105
|
+
link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&type=issues`,
|
|
97
106
|
};
|
|
98
107
|
}
|
|
99
108
|
if (show.includes("issues_commented")) {
|
|
@@ -102,7 +111,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
102
111
|
label: i18n.t("repocard.issues-commented"),
|
|
103
112
|
value: totalIssuesCommented,
|
|
104
113
|
id: "issues_commented",
|
|
105
|
-
link: `https://github.com/search?q=${repoFilter}commenter%3A${
|
|
114
|
+
link: `https://github.com/search?q=${repoFilter}commenter%3A${encodedUsername}+-author%3A${encodedUsername}&type=issues`,
|
|
106
115
|
};
|
|
107
116
|
}
|
|
108
117
|
const statItems = Object.keys(STATS).map((key, index) =>
|
package/build/cards/stats.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export function renderStatsCard(stats: StatsData, options: Partial<StatCardOptio
|
|
|
15
15
|
/**
|
|
16
16
|
* Create a stats card text item.
|
|
17
17
|
*
|
|
18
|
+
* The caller must ensure that the passed `icon` and `link` are properly sanitized!
|
|
19
|
+
*
|
|
18
20
|
* @param {object} params Object that contains the createTextNode parameters.
|
|
19
|
-
* @param {string} params.icon The icon to display.
|
|
21
|
+
* @param {string} params.icon The sanitized icon to display.
|
|
20
22
|
* @param {string} params.label The label to display.
|
|
21
23
|
* @param {number} params.value The value to display.
|
|
22
24
|
* @param {string} params.id The id of the stat.
|
|
@@ -27,7 +29,7 @@ export function renderStatsCard(stats: StatsData, options: Partial<StatCardOptio
|
|
|
27
29
|
* @param {boolean} params.bold Whether to bold the label.
|
|
28
30
|
* @param {string} params.numberFormat The format of numbers on card.
|
|
29
31
|
* @param {number=} params.numberPrecision The precision of numbers on card.
|
|
30
|
-
* @param {string} params.link
|
|
32
|
+
* @param {string} params.link Sanitized url to link to.
|
|
31
33
|
* @param {number} params.labelXOffset horizontal offset for label.
|
|
32
34
|
* @returns {string} The stats card text item SVG object.
|
|
33
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/cards/stats.js"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/cards/stats.js"],"names":[],"mappings":";;AAyQA;;;GAGG;AAEH;;;;;;GAMG;AACH,uCAJW,SAAS,WACT,OAAO,CAAC,eAAe,CAAC,+CACtB,MAAM,CAuZlB;AAtnBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,kKAfG;IAAuB,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,EAAE,EAAjB,MAAM;IACU,UAAU,GAA1B,MAAM,YAAC;IACQ,KAAK,EAApB,MAAM;IACU,SAAS,EAAzB,OAAO;IACQ,aAAa,EAA5B,MAAM;IACU,IAAI,EAApB,OAAO;IACQ,YAAY,EAA3B,MAAM;IACU,eAAe,GAA/B,MAAM,YAAC;IACQ,IAAI,EAAnB,MAAM;IACS,YAAY,EAA3B,MAAM;CACd,GAAU,MAAM,CAiElB"}
|
package/build/cards/stats.js
CHANGED
|
@@ -3,6 +3,7 @@ import { I18n } from "../common/I18n.js";
|
|
|
3
3
|
import { getCardColors } from "../common/color.js";
|
|
4
4
|
import { CustomError } from "../common/error.js";
|
|
5
5
|
import { kFormatter } from "../common/fmt.js";
|
|
6
|
+
import { encodeHTML } from "../common/html.js";
|
|
6
7
|
import { icons, rankIcon } from "../common/icons.js";
|
|
7
8
|
import { buildSearchFilter, clampValue } from "../common/ops.js";
|
|
8
9
|
import { flexLayout, measureText } from "../common/render.js";
|
|
@@ -49,8 +50,10 @@ const LONG_LOCALES = [
|
|
|
49
50
|
/**
|
|
50
51
|
* Create a stats card text item.
|
|
51
52
|
*
|
|
53
|
+
* The caller must ensure that the passed `icon` and `link` are properly sanitized!
|
|
54
|
+
*
|
|
52
55
|
* @param {object} params Object that contains the createTextNode parameters.
|
|
53
|
-
* @param {string} params.icon The icon to display.
|
|
56
|
+
* @param {string} params.icon The sanitized icon to display.
|
|
54
57
|
* @param {string} params.label The label to display.
|
|
55
58
|
* @param {number} params.value The value to display.
|
|
56
59
|
* @param {string} params.id The id of the stat.
|
|
@@ -61,11 +64,20 @@ const LONG_LOCALES = [
|
|
|
61
64
|
* @param {boolean} params.bold Whether to bold the label.
|
|
62
65
|
* @param {string} params.numberFormat The format of numbers on card.
|
|
63
66
|
* @param {number=} params.numberPrecision The precision of numbers on card.
|
|
64
|
-
* @param {string} params.link
|
|
67
|
+
* @param {string} params.link Sanitized url to link to.
|
|
65
68
|
* @param {number} params.labelXOffset horizontal offset for label.
|
|
66
69
|
* @returns {string} The stats card text item SVG object.
|
|
67
70
|
*/
|
|
68
71
|
const createTextNode = ({ icon, label, value, id, unitSymbol, index, showIcons, shiftValuePos, bold, numberFormat, numberPrecision, link, labelXOffset = 25, }) => {
|
|
72
|
+
if (!Number.isFinite(labelXOffset)) {
|
|
73
|
+
throw new Error(`Invalid labelXOffset: "${labelXOffset}"`);
|
|
74
|
+
}
|
|
75
|
+
if (!Number.isFinite(shiftValuePos)) {
|
|
76
|
+
throw new Error(`Invalid shiftValuePos: "${shiftValuePos}"`);
|
|
77
|
+
}
|
|
78
|
+
if (!Number.isFinite(index)) {
|
|
79
|
+
throw new Error(`Invalid index: "${index}"`);
|
|
80
|
+
}
|
|
69
81
|
const precision = typeof numberPrecision === "number" && !isNaN(numberPrecision)
|
|
70
82
|
? clampValue(numberPrecision, 0, 2)
|
|
71
83
|
: undefined;
|
|
@@ -86,7 +98,7 @@ const createTextNode = ({ icon, label, value, id, unitSymbol, index, showIcons,
|
|
|
86
98
|
(link ? `<a href="${link}">` : "") +
|
|
87
99
|
`
|
|
88
100
|
${iconSvg}
|
|
89
|
-
<text class="stat ${bold ? " bold" : "not_bold"}" ${labelOffset} y="12.5">${label}:</text>
|
|
101
|
+
<text class="stat ${bold ? " bold" : "not_bold"}" ${labelOffset} y="12.5">${encodeHTML(label)}:</text>
|
|
90
102
|
<text
|
|
91
103
|
class="stat ${bold ? " bold" : "not_bold"}"
|
|
92
104
|
x="${(showIcons ? 140 : 120) + (bold ? 5 : 0) + shiftValuePos}"
|
|
@@ -315,13 +327,14 @@ const renderStatsCard = (stats, options = {}, username, repo = [], owner = []) =
|
|
|
315
327
|
};
|
|
316
328
|
}
|
|
317
329
|
let repoFilter = encodeURIComponent(buildSearchFilter(repo, owner));
|
|
330
|
+
const encodedUsername = encodeURIComponent(username);
|
|
318
331
|
if (show.includes("prs_authored")) {
|
|
319
332
|
STATS.prs_authored = {
|
|
320
333
|
icon: icons.prs,
|
|
321
334
|
label: i18n.t("statcard.prs-authored"),
|
|
322
335
|
value: totalPRsAuthored,
|
|
323
336
|
id: "prs_authored",
|
|
324
|
-
link: `https://github.com/search?q=${repoFilter}author%3A${
|
|
337
|
+
link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&type=pullrequests`,
|
|
325
338
|
};
|
|
326
339
|
}
|
|
327
340
|
if (show.includes("prs_commented")) {
|
|
@@ -330,7 +343,7 @@ const renderStatsCard = (stats, options = {}, username, repo = [], owner = []) =
|
|
|
330
343
|
label: i18n.t("statcard.prs-commented"),
|
|
331
344
|
value: totalPRsCommented,
|
|
332
345
|
id: "prs_commented",
|
|
333
|
-
link: `https://github.com/search?q=${repoFilter}commenter%3A${
|
|
346
|
+
link: `https://github.com/search?q=${repoFilter}commenter%3A${encodedUsername}+-author%3A${encodedUsername}&type=pullrequests`,
|
|
334
347
|
};
|
|
335
348
|
}
|
|
336
349
|
if (show.includes("prs_reviewed")) {
|
|
@@ -339,7 +352,7 @@ const renderStatsCard = (stats, options = {}, username, repo = [], owner = []) =
|
|
|
339
352
|
label: i18n.t("statcard.prs-reviewed"),
|
|
340
353
|
value: totalPRsReviewed,
|
|
341
354
|
id: "prs_reviewed",
|
|
342
|
-
link: `https://github.com/search?q=${repoFilter}reviewed-by%3A${
|
|
355
|
+
link: `https://github.com/search?q=${repoFilter}reviewed-by%3A${encodedUsername}+-author%3A${encodedUsername}&type=pullrequests`,
|
|
343
356
|
};
|
|
344
357
|
}
|
|
345
358
|
if (show.includes("issues_authored")) {
|
|
@@ -348,7 +361,7 @@ const renderStatsCard = (stats, options = {}, username, repo = [], owner = []) =
|
|
|
348
361
|
label: i18n.t("statcard.issues-authored"),
|
|
349
362
|
value: totalIssuesAuthored,
|
|
350
363
|
id: "issues_authored",
|
|
351
|
-
link: `https://github.com/search?q=${repoFilter}author%3A${
|
|
364
|
+
link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&type=issues`,
|
|
352
365
|
};
|
|
353
366
|
}
|
|
354
367
|
if (show.includes("issues_commented")) {
|
|
@@ -357,7 +370,7 @@ const renderStatsCard = (stats, options = {}, username, repo = [], owner = []) =
|
|
|
357
370
|
label: i18n.t("statcard.issues-commented"),
|
|
358
371
|
value: totalIssuesCommented,
|
|
359
372
|
id: "issues_commented",
|
|
360
|
-
link: `https://github.com/search?q=${repoFilter}commenter%3A${
|
|
373
|
+
link: `https://github.com/search?q=${repoFilter}commenter%3A${encodedUsername}+-author%3A${encodedUsername}&type=issues`,
|
|
361
374
|
};
|
|
362
375
|
}
|
|
363
376
|
STATS.contribs = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-languages.d.ts","sourceRoot":"","sources":["../../src/cards/top-languages.js"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"top-languages.d.ts","sourceRoot":"","sources":["../../src/cards/top-languages.js"],"names":[],"mappings":";;qBAsyBa,cAAc,CAAC,QAAQ,CAAC;;AAxwBrC;;GAEG;AAEH;;;;;GAKG;AACH,oCAHW,IAAI,EAAE,GACJ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOvD;AAEH;;;;;GAKG;AACH,iDAHW,MAAM,GACJ,MAAM,CAE4D;AAE/E;;;;;GAKG;AACH,iDAHW,MAAM,GACJ,MAAM,CAE4D;AAE/E;;;;;;;;GAQG;AACH,0CANW,MAAM,WACN,MAAM,UACN,MAAM,kBACN,MAAM,GACJ;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,CAQlC;AAED;;;;;;;;GAQG;AACH,0CANW,MAAM,WACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAC,CASpD;AAED;;;;;GAKG;AACH,wCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,yDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,wDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,uDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,+DAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,qDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,mDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;GAOG;AACH,2CALW,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,eACpB,MAAM,SACN,MAAM,EAAE,YAAC,GACP;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CA4BxD;AA2oBD;;GAEG;AAEH;;;;;;GAMG;AACH,6CAJW,WAAW,YACX,OAAO,CAAC,cAAc,CAAC,GACrB,MAAM,CAkLlB;AA7/BD,6BAAuB,GAAG,CAAC;AA4yB3B;;;;;;;GAOG;AACH,4EAJG;IAAuB,MAAM,GAArB,MAAM,YAAC;IACS,aAAa,GAA7B,OAAO,YAAC;CAChB,GAAU,MAAM,CAclB"}
|