@stats-organization/github-readme-stats-core 2.1.5 → 2.2.0
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 +2 -7
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +9 -41
- package/build/api/index.d.ts +3 -8
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +23 -45
- package/build/api/pin.d.ts +2 -7
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +9 -41
- package/build/api/top-langs.d.ts +2 -7
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +11 -55
- package/build/api/wakatime.d.ts +2 -7
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +9 -41
- package/build/cards/common-options.d.ts +13 -0
- package/build/cards/common-options.d.ts.map +1 -0
- package/build/cards/common-options.js +1 -0
- package/build/cards/gist.d.ts +11 -16
- package/build/cards/gist.d.ts.map +1 -1
- package/build/cards/gist.js +26 -31
- package/build/cards/repo.d.ts +19 -16
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +58 -60
- package/build/cards/stats.d.ts +29 -46
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +113 -181
- package/build/cards/top-languages.d.ts +81 -77
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +174 -200
- package/build/cards/wakatime.d.ts +21 -11
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +73 -111
- package/build/common/Card.d.ts +34 -13
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +73 -40
- package/build/common/I18n.d.ts +4 -2
- package/build/common/I18n.d.ts.map +1 -1
- package/build/common/color.d.ts +60 -18
- package/build/common/color.d.ts.map +1 -1
- package/build/common/color.js +102 -5
- package/build/common/config.d.ts +2 -1
- package/build/common/config.d.ts.map +1 -1
- package/build/common/config.js +16 -26
- package/build/common/constants.d.ts +2 -1
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/date.d.ts +37 -0
- package/build/common/date.d.ts.map +1 -0
- package/build/common/date.js +31 -0
- package/build/common/http.d.ts +25 -2
- package/build/common/http.d.ts.map +1 -1
- package/build/common/http.js +26 -3
- package/build/common/icons.d.ts +1 -0
- package/build/common/icons.d.ts.map +1 -1
- package/build/common/icons.js +1 -0
- package/build/common/languageColors.d.ts +11 -0
- package/build/common/languageColors.d.ts.map +1 -0
- package/build/common/languageColors.js +15 -0
- package/build/common/languageColors.json +1 -0
- package/build/common/ops.d.ts +3 -10
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +3 -15
- package/build/common/render.d.ts +43 -6
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +77 -11
- package/build/common/retryer.d.ts +3 -2
- package/build/common/retryer.d.ts.map +1 -1
- package/build/common/retryer.js +1 -0
- package/build/fetchers/gist.d.ts.map +1 -1
- package/build/fetchers/gist.js +8 -39
- package/build/fetchers/repo.d.ts +12 -11
- package/build/fetchers/repo.d.ts.map +1 -1
- package/build/fetchers/repo.js +26 -67
- package/build/fetchers/stats.d.ts +24 -17
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +302 -183
- package/build/fetchers/top-languages.d.ts +10 -15
- package/build/fetchers/top-languages.d.ts.map +1 -1
- package/build/fetchers/top-languages.js +52 -103
- package/build/fetchers/types.d.ts +24 -20
- package/build/fetchers/types.d.ts.map +1 -1
- package/build/fetchers/wakatime.d.ts +9 -5
- package/build/fetchers/wakatime.d.ts.map +1 -1
- package/build/fetchers/wakatime.js +8 -4
- package/build/graphql/contributionsDocument.d.ts +18 -0
- package/build/graphql/contributionsDocument.d.ts.map +1 -0
- package/build/graphql/contributionsDocument.js +30 -0
- package/build/graphql/generated/common.d.ts +42 -0
- package/build/graphql/generated/common.d.ts.map +1 -0
- package/build/graphql/generated/common.js +2 -0
- package/build/graphql/generated/gist.d.ts +44 -0
- package/build/graphql/generated/gist.d.ts.map +1 -0
- package/build/graphql/generated/gist.js +27 -0
- package/build/graphql/generated/repo.d.ts +67 -0
- package/build/graphql/generated/repo.d.ts.map +1 -0
- package/build/graphql/generated/repo.js +30 -0
- package/build/graphql/generated/stats.d.ts +150 -0
- package/build/graphql/generated/stats.d.ts.map +1 -0
- package/build/graphql/generated/stats.js +95 -0
- package/build/graphql/generated/top-languages.d.ts +54 -0
- package/build/graphql/generated/top-languages.d.ts.map +1 -0
- package/build/graphql/generated/top-languages.js +27 -0
- package/build/graphql/graphqlDocument.d.ts +22 -0
- package/build/graphql/graphqlDocument.d.ts.map +1 -0
- package/build/graphql/graphqlDocument.js +8 -0
- package/build/graphql/reposContributedToDocument.d.ts +27 -0
- package/build/graphql/reposContributedToDocument.d.ts.map +1 -0
- package/build/graphql/reposContributedToDocument.js +59 -0
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -1
- package/build/themes/index.d.ts +32 -0
- package/build/themes/index.d.ts.map +1 -1
- package/build/themes/index.js +28 -0
- package/build/translations.d.ts +17 -0
- package/build/translations.d.ts.map +1 -1
- package/build/translations.js +17 -0
- package/package.json +13 -7
- package/src/_github-username-regex.d.ts +4 -0
- package/src/api/gist.js +10 -46
- package/src/api/index.js +30 -51
- package/src/api/pin.js +10 -46
- package/src/api/top-langs.js +13 -60
- package/src/api/wakatime.js +10 -46
- package/src/cards/common-options.ts +13 -0
- package/src/cards/{gist.js → gist.ts} +37 -37
- package/src/cards/{repo.js → repo.ts} +86 -68
- package/src/cards/{stats.js → stats.ts} +168 -219
- package/src/cards/{top-languages.js → top-languages.ts} +309 -265
- package/src/cards/{wakatime.js → wakatime.ts} +136 -130
- package/src/common/Card.ts +94 -49
- package/src/common/I18n.ts +6 -2
- package/src/common/color.ts +163 -14
- package/src/common/config.ts +22 -29
- package/src/common/constants.ts +3 -1
- package/src/common/date.ts +45 -0
- package/src/common/http.ts +43 -3
- package/src/common/icons.ts +1 -0
- package/src/common/languageColors.json +1 -0
- package/src/common/languageColors.ts +19 -0
- package/src/common/ops.ts +8 -18
- package/src/common/render.ts +114 -14
- package/src/common/retryer.ts +6 -5
- package/src/fetchers/gist.ts +15 -72
- package/src/fetchers/repo.ts +114 -0
- package/src/fetchers/stats.ts +743 -0
- package/src/fetchers/top-languages.ts +135 -0
- package/src/fetchers/types.ts +28 -20
- package/src/fetchers/{wakatime.js → wakatime.ts} +19 -5
- package/src/graphql/contributionsDocument.ts +44 -0
- package/src/graphql/generated/common.ts +26 -0
- package/src/graphql/generated/gist.ts +59 -0
- package/src/graphql/generated/repo.ts +90 -0
- package/src/graphql/generated/stats.ts +194 -0
- package/src/graphql/generated/top-languages.ts +75 -0
- package/src/graphql/graphqlDocument.ts +25 -0
- package/src/graphql/queries/gist.graphql +25 -0
- package/src/graphql/queries/repo.graphql +28 -0
- package/src/graphql/queries/stats.graphql +120 -0
- package/src/graphql/queries/top-languages.graphql +34 -0
- package/src/graphql/reposContributedToDocument.ts +86 -0
- package/src/index.ts +3 -1
- package/src/themes/index.ts +33 -0
- package/src/translations.ts +17 -0
- package/src/cards/types.d.ts +0 -78
- package/src/fetchers/repo.js +0 -161
- package/src/fetchers/stats.js +0 -473
- package/src/fetchers/top-languages.js +0 -175
- package/src/themes/README.md +0 -229
package/src/api/wakatime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderWakatimeCard } from "../cards/wakatime.js";
|
|
2
|
-
import {
|
|
2
|
+
import { findInvalidColorParam, pickColorParams } from "../common/color.js";
|
|
3
3
|
import {
|
|
4
4
|
MissingParamError,
|
|
5
5
|
retrieveSecondaryMessage,
|
|
@@ -12,14 +12,9 @@ import { isLocaleAvailable } from "../translations.js";
|
|
|
12
12
|
// @ts-ignore
|
|
13
13
|
export default async ({
|
|
14
14
|
username,
|
|
15
|
-
title_color,
|
|
16
|
-
icon_color,
|
|
17
15
|
hide_border,
|
|
18
16
|
card_width,
|
|
19
17
|
line_height,
|
|
20
|
-
text_color,
|
|
21
|
-
bg_color,
|
|
22
|
-
theme,
|
|
23
18
|
hide_title,
|
|
24
19
|
hide_progress,
|
|
25
20
|
custom_title,
|
|
@@ -29,17 +24,13 @@ export default async ({
|
|
|
29
24
|
hide,
|
|
30
25
|
api_domain,
|
|
31
26
|
border_radius,
|
|
32
|
-
border_color,
|
|
33
27
|
display_format,
|
|
34
28
|
disable_animations,
|
|
29
|
+
...remainingParams
|
|
35
30
|
}) => {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
text_color,
|
|
40
|
-
bg_color,
|
|
41
|
-
border_color,
|
|
42
|
-
});
|
|
31
|
+
const colorParams = pickColorParams(remainingParams);
|
|
32
|
+
|
|
33
|
+
const invalidColorInput = findInvalidColorParam(colorParams);
|
|
43
34
|
if (invalidColorInput) {
|
|
44
35
|
return {
|
|
45
36
|
status: "error - permanent",
|
|
@@ -56,13 +47,7 @@ export default async ({
|
|
|
56
47
|
content: renderError({
|
|
57
48
|
message: "Something went wrong",
|
|
58
49
|
secondaryMessage: "Language not found",
|
|
59
|
-
renderOptions:
|
|
60
|
-
title_color,
|
|
61
|
-
text_color,
|
|
62
|
-
bg_color,
|
|
63
|
-
border_color,
|
|
64
|
-
theme,
|
|
65
|
-
},
|
|
50
|
+
renderOptions: colorParams,
|
|
66
51
|
}),
|
|
67
52
|
};
|
|
68
53
|
}
|
|
@@ -74,13 +59,7 @@ export default async ({
|
|
|
74
59
|
content: renderError({
|
|
75
60
|
message: "Something went wrong",
|
|
76
61
|
secondaryMessage: "Username contains unsafe characters",
|
|
77
|
-
renderOptions:
|
|
78
|
-
title_color,
|
|
79
|
-
text_color,
|
|
80
|
-
bg_color,
|
|
81
|
-
border_color,
|
|
82
|
-
theme,
|
|
83
|
-
},
|
|
62
|
+
renderOptions: colorParams,
|
|
84
63
|
}),
|
|
85
64
|
};
|
|
86
65
|
}
|
|
@@ -91,20 +70,15 @@ export default async ({
|
|
|
91
70
|
return {
|
|
92
71
|
status: "success",
|
|
93
72
|
content: renderWakatimeCard(stats, {
|
|
73
|
+
...colorParams,
|
|
94
74
|
custom_title,
|
|
95
75
|
hide_title: parseBoolean(hide_title),
|
|
96
76
|
hide_border: parseBoolean(hide_border),
|
|
97
77
|
card_width: parseInt(card_width, 10),
|
|
98
78
|
hide: parseArray(hide),
|
|
99
79
|
line_height,
|
|
100
|
-
title_color,
|
|
101
|
-
icon_color,
|
|
102
|
-
text_color,
|
|
103
|
-
bg_color,
|
|
104
|
-
theme,
|
|
105
80
|
hide_progress,
|
|
106
81
|
border_radius,
|
|
107
|
-
border_color,
|
|
108
82
|
locale: locale ? locale.toLowerCase() : null,
|
|
109
83
|
layout,
|
|
110
84
|
langs_count,
|
|
@@ -120,11 +94,7 @@ export default async ({
|
|
|
120
94
|
message: err.message,
|
|
121
95
|
secondaryMessage: retrieveSecondaryMessage(err),
|
|
122
96
|
renderOptions: {
|
|
123
|
-
|
|
124
|
-
text_color,
|
|
125
|
-
bg_color,
|
|
126
|
-
border_color,
|
|
127
|
-
theme,
|
|
97
|
+
...colorParams,
|
|
128
98
|
show_repo_link: !(err instanceof MissingParamError),
|
|
129
99
|
},
|
|
130
100
|
}),
|
|
@@ -134,13 +104,7 @@ export default async ({
|
|
|
134
104
|
status: "error - temporary",
|
|
135
105
|
content: renderError({
|
|
136
106
|
message: "An unknown error occurred",
|
|
137
|
-
renderOptions:
|
|
138
|
-
title_color,
|
|
139
|
-
text_color,
|
|
140
|
-
bg_color,
|
|
141
|
-
border_color,
|
|
142
|
-
theme,
|
|
143
|
-
},
|
|
107
|
+
renderOptions: colorParams,
|
|
144
108
|
}),
|
|
145
109
|
};
|
|
146
110
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ThemeName } from "../themes/index.js";
|
|
2
|
+
|
|
3
|
+
export interface CommonOptions {
|
|
4
|
+
title_color: string;
|
|
5
|
+
icon_color: string;
|
|
6
|
+
text_color: string;
|
|
7
|
+
bg_color: string;
|
|
8
|
+
theme: ThemeName;
|
|
9
|
+
border_radius: number;
|
|
10
|
+
border_color: string;
|
|
11
|
+
locale: string;
|
|
12
|
+
hide_border: boolean;
|
|
13
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { default as Card } from "../common/Card.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getLightDarkColors } from "../common/color.js";
|
|
3
3
|
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
|
|
4
4
|
import { encodeHTML } from "../common/html.js";
|
|
5
5
|
import { icons } from "../common/icons.js";
|
|
6
|
-
import
|
|
6
|
+
import { getLanguageColor } from "../common/languageColors.js";
|
|
7
7
|
import { parseEmojis } from "../common/ops.js";
|
|
8
8
|
import {
|
|
9
9
|
countWrappedLines,
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
wrappedTextNode,
|
|
15
15
|
wrappedTextStyles,
|
|
16
16
|
} from "../common/render.js";
|
|
17
|
+
import type { GistData } from "../fetchers/types.js";
|
|
18
|
+
|
|
19
|
+
import type { CommonOptions } from "./common-options.js";
|
|
17
20
|
|
|
18
21
|
const ICON_SIZE = 16;
|
|
19
22
|
const CARD_DEFAULT_WIDTH = 400;
|
|
@@ -24,48 +27,39 @@ const DESCRIPTION_FONT_SIZE = 13;
|
|
|
24
27
|
const DESCRIPTION_LINE_HEIGHT_PX = 16;
|
|
25
28
|
const DESCRIPTION_MAX_LINES = 10;
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
interface GistCardOptions extends CommonOptions {
|
|
31
|
+
show_owner: boolean;
|
|
32
|
+
browser_rendering: boolean;
|
|
33
|
+
}
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* Render gist card.
|
|
34
37
|
*
|
|
35
|
-
* @param
|
|
36
|
-
* @param
|
|
37
|
-
* @returns
|
|
38
|
+
* @param gistData Gist data.
|
|
39
|
+
* @param options Gist card options.
|
|
40
|
+
* @returns Gist card.
|
|
38
41
|
*/
|
|
39
|
-
const renderGistCard = (
|
|
42
|
+
const renderGistCard = (
|
|
43
|
+
gistData: GistData,
|
|
44
|
+
options: Partial<GistCardOptions> = {},
|
|
45
|
+
): string => {
|
|
40
46
|
const { name, nameWithOwner, description, language, starsCount, forksCount } =
|
|
41
47
|
gistData;
|
|
42
48
|
const {
|
|
43
|
-
title_color,
|
|
44
|
-
icon_color,
|
|
45
|
-
text_color,
|
|
46
|
-
bg_color,
|
|
47
49
|
theme = "default_repocard",
|
|
48
50
|
border_radius,
|
|
49
|
-
border_color,
|
|
50
51
|
show_owner = false,
|
|
51
52
|
browser_rendering = false,
|
|
52
53
|
hide_border = false,
|
|
53
54
|
} = options;
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
const {
|
|
57
|
-
getCardColors({
|
|
58
|
-
title_color,
|
|
59
|
-
icon_color,
|
|
60
|
-
text_color,
|
|
61
|
-
bg_color,
|
|
62
|
-
border_color,
|
|
63
|
-
theme,
|
|
64
|
-
});
|
|
56
|
+
const { lightColors, darkColors } = getLightDarkColors({ ...options, theme });
|
|
57
|
+
const { textColor, iconColor } = lightColors;
|
|
65
58
|
|
|
66
59
|
const desc = parseEmojis(description || "No description provided");
|
|
67
60
|
|
|
68
|
-
let descriptionLines
|
|
61
|
+
let descriptionLines: number;
|
|
62
|
+
let descriptionSvg: string;
|
|
69
63
|
if (browser_rendering) {
|
|
70
64
|
// The browser performs the actual text wrapping inside the foreignObject;
|
|
71
65
|
// we only estimate the line count server-side so the SVG can reserve enough
|
|
@@ -128,8 +122,7 @@ const renderGistCard = (gistData, options = {}) => {
|
|
|
128
122
|
);
|
|
129
123
|
|
|
130
124
|
const languageName = language || "Unspecified";
|
|
131
|
-
|
|
132
|
-
const languageColor = languageColors[languageName] || "#858585";
|
|
125
|
+
const languageColor = getLanguageColor(languageName);
|
|
133
126
|
|
|
134
127
|
const svgLanguage = createLanguageNode(languageName, languageColor);
|
|
135
128
|
|
|
@@ -154,23 +147,30 @@ const renderGistCard = (gistData, options = {}) => {
|
|
|
154
147
|
width: CARD_DEFAULT_WIDTH,
|
|
155
148
|
height,
|
|
156
149
|
border_radius,
|
|
157
|
-
colors: {
|
|
158
|
-
titleColor,
|
|
159
|
-
textColor,
|
|
160
|
-
iconColor,
|
|
161
|
-
bgColor,
|
|
162
|
-
borderColor,
|
|
163
|
-
},
|
|
150
|
+
colors: { light: lightColors, dark: darkColors },
|
|
164
151
|
});
|
|
165
152
|
|
|
166
|
-
card.setCSS(
|
|
153
|
+
card.setCSS({
|
|
154
|
+
light: `
|
|
167
155
|
.description {
|
|
168
156
|
font: 400 ${DESCRIPTION_FONT_SIZE}px 'Segoe UI', Ubuntu, Sans-Serif;fill: ${textColor};
|
|
169
157
|
${browser_rendering ? wrappedTextStyles(textColor) : ""}
|
|
170
158
|
}
|
|
171
159
|
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
|
172
160
|
.icon { fill: ${iconColor} }
|
|
173
|
-
|
|
161
|
+
`,
|
|
162
|
+
dark: darkColors
|
|
163
|
+
? `
|
|
164
|
+
.description {
|
|
165
|
+
fill: ${darkColors.textColor};
|
|
166
|
+
${browser_rendering ? wrappedTextStyles(darkColors.textColor) : ""}
|
|
167
|
+
}
|
|
168
|
+
.gray { fill: ${darkColors.textColor} }
|
|
169
|
+
.icon { fill: ${darkColors.iconColor} }
|
|
170
|
+
`
|
|
171
|
+
: null,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
174
|
card.setHideBorder(hide_border);
|
|
175
175
|
|
|
176
176
|
return card.render(`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Card } from "../common/Card.js";
|
|
2
2
|
import { I18n } from "../common/I18n.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getLightDarkColors } 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";
|
|
@@ -8,15 +8,17 @@ import { buildSearchFilter, clampValue, parseEmojis } from "../common/ops.js";
|
|
|
8
8
|
import {
|
|
9
9
|
countWrappedLines,
|
|
10
10
|
createLanguageNode,
|
|
11
|
+
createTextNode,
|
|
11
12
|
flexLayout,
|
|
12
13
|
iconWithLabel,
|
|
13
14
|
measureText,
|
|
14
15
|
wrappedTextNode,
|
|
15
16
|
wrappedTextStyles,
|
|
16
17
|
} from "../common/render.js";
|
|
18
|
+
import type { RepositoryData } from "../fetchers/types.js";
|
|
17
19
|
import { repoCardLocales } from "../translations.js";
|
|
18
20
|
|
|
19
|
-
import {
|
|
21
|
+
import type { CommonOptions } from "./common-options.js";
|
|
20
22
|
|
|
21
23
|
const ICON_SIZE = 16;
|
|
22
24
|
const CARD_DEFAULT_WIDTH = 400;
|
|
@@ -25,30 +27,48 @@ const DESCRIPTION_FONT_SIZE = 13;
|
|
|
25
27
|
const DESCRIPTION_LINE_HEIGHT_PX = 16;
|
|
26
28
|
const DESCRIPTION_MAX_LINES = 3;
|
|
27
29
|
|
|
30
|
+
interface RepoCardOptions extends CommonOptions {
|
|
31
|
+
show_owner: boolean;
|
|
32
|
+
browser_rendering: boolean;
|
|
33
|
+
description_lines_count: number;
|
|
34
|
+
card_width_input: number;
|
|
35
|
+
show: Array<string>;
|
|
36
|
+
show_icons: boolean;
|
|
37
|
+
number_format: string;
|
|
38
|
+
text_bold: boolean;
|
|
39
|
+
line_height: number | string;
|
|
40
|
+
username: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface RepoStatItem {
|
|
44
|
+
icon: string;
|
|
45
|
+
label: string;
|
|
46
|
+
value: number | undefined;
|
|
47
|
+
id: string;
|
|
48
|
+
link: string;
|
|
49
|
+
unitSymbol?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
28
52
|
/**
|
|
29
53
|
* Retrieves the repository description and wraps it to fit the card width.
|
|
30
54
|
*
|
|
31
|
-
* @param
|
|
32
|
-
* @param
|
|
33
|
-
* @returns
|
|
55
|
+
* @param label The repository description.
|
|
56
|
+
* @param xOffset Horizontal offset of the badge.
|
|
57
|
+
* @returns Wrapped repo description SVG object.
|
|
34
58
|
*/
|
|
35
|
-
const getBadgeSVG = (label
|
|
36
|
-
if (!isPrefixedHexColor(textColor)) {
|
|
37
|
-
throw new Error(`Invalid text color: "${textColor}"`);
|
|
38
|
-
}
|
|
59
|
+
const getBadgeSVG = (label: string, xOffset = 0): string => {
|
|
39
60
|
if (!Number.isFinite(xOffset)) {
|
|
40
61
|
throw new Error(`Invalid xOffset: "${xOffset}"`);
|
|
41
62
|
}
|
|
42
63
|
|
|
43
64
|
return `
|
|
44
65
|
<g data-testid="badge" class="badge" transform="translate(${320 + xOffset}, -18)">
|
|
45
|
-
<rect stroke
|
|
66
|
+
<rect stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
|
46
67
|
<text
|
|
47
68
|
x="23" y="-5"
|
|
48
69
|
alignment-baseline="central"
|
|
49
70
|
dominant-baseline="central"
|
|
50
71
|
text-anchor="middle"
|
|
51
|
-
fill="${textColor}"
|
|
52
72
|
>
|
|
53
73
|
${encodeHTML(label)}
|
|
54
74
|
</text>
|
|
@@ -56,19 +76,17 @@ const getBadgeSVG = (label, textColor, xOffset = 0) => {
|
|
|
56
76
|
`;
|
|
57
77
|
};
|
|
58
78
|
|
|
59
|
-
/**
|
|
60
|
-
* @typedef {import("../fetchers/types").RepositoryData} RepositoryData Repository data.
|
|
61
|
-
* @typedef {import("./types").RepoCardOptions} RepoCardOptions Repo card options.
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
79
|
/**
|
|
65
80
|
* Renders repository card details.
|
|
66
81
|
*
|
|
67
|
-
* @param
|
|
68
|
-
* @param
|
|
69
|
-
* @returns
|
|
82
|
+
* @param repo Repository data.
|
|
83
|
+
* @param options Card options.
|
|
84
|
+
* @returns Repository card SVG object.
|
|
70
85
|
*/
|
|
71
|
-
const renderRepoCard = (
|
|
86
|
+
const renderRepoCard = (
|
|
87
|
+
repo: RepositoryData,
|
|
88
|
+
options: Partial<RepoCardOptions> = {},
|
|
89
|
+
): string => {
|
|
72
90
|
const {
|
|
73
91
|
name,
|
|
74
92
|
nameWithOwner,
|
|
@@ -76,7 +94,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
76
94
|
primaryLanguage,
|
|
77
95
|
isArchived,
|
|
78
96
|
isTemplate,
|
|
79
|
-
|
|
97
|
+
stargazerCount,
|
|
80
98
|
forkCount,
|
|
81
99
|
totalPRsAuthored,
|
|
82
100
|
totalPRsCommented,
|
|
@@ -86,10 +104,6 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
86
104
|
} = repo;
|
|
87
105
|
const {
|
|
88
106
|
hide_border = false,
|
|
89
|
-
title_color,
|
|
90
|
-
icon_color,
|
|
91
|
-
text_color,
|
|
92
|
-
bg_color,
|
|
93
107
|
card_width_input,
|
|
94
108
|
show_owner = false,
|
|
95
109
|
browser_rendering = false,
|
|
@@ -101,7 +115,6 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
101
115
|
username,
|
|
102
116
|
theme = "default_repocard",
|
|
103
117
|
border_radius,
|
|
104
|
-
border_color,
|
|
105
118
|
locale,
|
|
106
119
|
description_lines_count,
|
|
107
120
|
} = options;
|
|
@@ -118,11 +131,11 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
118
131
|
translations: repoCardLocales,
|
|
119
132
|
});
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
const encodedUsername = encodeURIComponent(username);
|
|
123
|
-
const STATS = {};
|
|
134
|
+
const repoFilter = encodeURIComponent(buildSearchFilter([nameWithOwner], []));
|
|
135
|
+
const encodedUsername = encodeURIComponent(username ?? "");
|
|
136
|
+
const STATS: Record<string, RepoStatItem> = {};
|
|
124
137
|
if (show.includes("prs_authored")) {
|
|
125
|
-
STATS
|
|
138
|
+
STATS["prs_authored"] = {
|
|
126
139
|
icon: icons.prs,
|
|
127
140
|
label: i18n.t("repocard.prs-authored"),
|
|
128
141
|
value: totalPRsAuthored,
|
|
@@ -131,7 +144,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
131
144
|
};
|
|
132
145
|
}
|
|
133
146
|
if (show.includes("prs_commented")) {
|
|
134
|
-
STATS
|
|
147
|
+
STATS["prs_commented"] = {
|
|
135
148
|
icon: icons.comments,
|
|
136
149
|
label: i18n.t("repocard.prs-commented"),
|
|
137
150
|
value: totalPRsCommented,
|
|
@@ -140,7 +153,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
140
153
|
};
|
|
141
154
|
}
|
|
142
155
|
if (show.includes("prs_reviewed")) {
|
|
143
|
-
STATS
|
|
156
|
+
STATS["prs_reviewed"] = {
|
|
144
157
|
icon: icons.reviews,
|
|
145
158
|
label: i18n.t("repocard.prs-reviewed"),
|
|
146
159
|
value: totalPRsReviewed,
|
|
@@ -149,7 +162,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
149
162
|
};
|
|
150
163
|
}
|
|
151
164
|
if (show.includes("issues_authored")) {
|
|
152
|
-
STATS
|
|
165
|
+
STATS["issues_authored"] = {
|
|
153
166
|
icon: icons.issues,
|
|
154
167
|
label: i18n.t("repocard.issues-authored"),
|
|
155
168
|
value: totalIssuesAuthored,
|
|
@@ -158,7 +171,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
158
171
|
};
|
|
159
172
|
}
|
|
160
173
|
if (show.includes("issues_commented")) {
|
|
161
|
-
STATS
|
|
174
|
+
STATS["issues_commented"] = {
|
|
162
175
|
icon: icons.discussions_started,
|
|
163
176
|
label: i18n.t("repocard.issues-commented"),
|
|
164
177
|
value: totalIssuesCommented,
|
|
@@ -167,20 +180,20 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
167
180
|
};
|
|
168
181
|
}
|
|
169
182
|
|
|
170
|
-
const statItems = Object.
|
|
183
|
+
const statItems = Object.values(STATS).map((stat, index) =>
|
|
171
184
|
// create the text nodes, and pass index so that we can calculate the line spacing
|
|
172
185
|
createTextNode({
|
|
173
|
-
icon:
|
|
174
|
-
label:
|
|
175
|
-
value:
|
|
176
|
-
id:
|
|
177
|
-
unitSymbol:
|
|
186
|
+
icon: stat.icon,
|
|
187
|
+
label: stat.label,
|
|
188
|
+
value: stat.value ?? 0,
|
|
189
|
+
id: stat.id,
|
|
190
|
+
unitSymbol: stat.unitSymbol,
|
|
178
191
|
index,
|
|
179
192
|
showIcons: show_icons,
|
|
180
193
|
shiftValuePos: 14.01,
|
|
181
194
|
bold: text_bold,
|
|
182
195
|
numberFormat: number_format,
|
|
183
|
-
link:
|
|
196
|
+
link: stat.link,
|
|
184
197
|
labelXOffset: 23,
|
|
185
198
|
}),
|
|
186
199
|
);
|
|
@@ -193,7 +206,8 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
193
206
|
const desc = parseEmojis(description || "No description provided");
|
|
194
207
|
const descriptionBoxWidth = card_width - 2 * X_OFFSET;
|
|
195
208
|
|
|
196
|
-
let descriptionLinesCount
|
|
209
|
+
let descriptionLinesCount: number;
|
|
210
|
+
let descriptionSvg: string;
|
|
197
211
|
if (browser_rendering) {
|
|
198
212
|
// The browser performs the actual text wrapping inside the foreignObject;
|
|
199
213
|
// we only estimate the line count server-side so the SVG can reserve enough
|
|
@@ -249,21 +263,13 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
249
263
|
descriptionLinesCount * lineHeight +
|
|
250
264
|
extraHeight;
|
|
251
265
|
|
|
252
|
-
|
|
253
|
-
const colors = getCardColors({
|
|
254
|
-
title_color,
|
|
255
|
-
icon_color,
|
|
256
|
-
text_color,
|
|
257
|
-
bg_color,
|
|
258
|
-
border_color,
|
|
259
|
-
theme,
|
|
260
|
-
});
|
|
266
|
+
const { lightColors, darkColors } = getLightDarkColors({ ...options, theme });
|
|
261
267
|
|
|
262
268
|
const svgLanguage = primaryLanguage
|
|
263
269
|
? createLanguageNode(langName, langColor)
|
|
264
270
|
: "";
|
|
265
271
|
|
|
266
|
-
const totalStars = kFormatter(
|
|
272
|
+
const totalStars = kFormatter(stargazerCount);
|
|
267
273
|
const totalForks = kFormatter(forkCount);
|
|
268
274
|
const svgStars = iconWithLabel(
|
|
269
275
|
icons.star,
|
|
@@ -288,7 +294,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
288
294
|
gap: 25,
|
|
289
295
|
}).join("");
|
|
290
296
|
|
|
291
|
-
|
|
297
|
+
const extraRows: Array<string> = [];
|
|
292
298
|
for (let i = 0; i < statItems.length; i += 2) {
|
|
293
299
|
extraRows.push(
|
|
294
300
|
flexLayout({
|
|
@@ -314,22 +320,24 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
314
320
|
width: card_width,
|
|
315
321
|
height,
|
|
316
322
|
border_radius,
|
|
317
|
-
colors,
|
|
323
|
+
colors: { light: lightColors, dark: darkColors },
|
|
318
324
|
});
|
|
319
325
|
|
|
320
326
|
card.disableAnimations();
|
|
321
327
|
card.setHideBorder(hide_border);
|
|
322
328
|
card.setHideTitle(false);
|
|
323
|
-
card.setCSS(
|
|
329
|
+
card.setCSS({
|
|
330
|
+
light: `
|
|
324
331
|
.description {
|
|
325
|
-
font: 400 ${DESCRIPTION_FONT_SIZE}px 'Segoe UI', Ubuntu, Sans-Serif;fill: ${
|
|
326
|
-
${browser_rendering ? wrappedTextStyles(
|
|
332
|
+
font: 400 ${DESCRIPTION_FONT_SIZE}px 'Segoe UI', Ubuntu, Sans-Serif;fill: ${lightColors.textColor};
|
|
333
|
+
${browser_rendering ? wrappedTextStyles(lightColors.textColor) : ""}
|
|
327
334
|
}
|
|
328
|
-
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${
|
|
335
|
+
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${lightColors.textColor} }
|
|
329
336
|
.badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
|
|
330
|
-
.badge rect { opacity: 0.2 }
|
|
337
|
+
.badge rect { opacity: 0.2; stroke: ${lightColors.textColor} }
|
|
338
|
+
.badge text { fill: ${lightColors.textColor} }
|
|
331
339
|
|
|
332
|
-
.stat { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${
|
|
340
|
+
.stat { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${lightColors.textColor} }
|
|
333
341
|
.stagger {
|
|
334
342
|
opacity: 0;
|
|
335
343
|
animation: fadeInAnimation 0.3s ease-in-out forwards;
|
|
@@ -337,25 +345,35 @@ const renderRepoCard = (repo, options = {}) => {
|
|
|
337
345
|
.not_bold { font-weight: 400 }
|
|
338
346
|
.bold { font-weight: 700 }
|
|
339
347
|
.icon {
|
|
340
|
-
fill: ${
|
|
348
|
+
fill: ${lightColors.iconColor};
|
|
341
349
|
display: block;
|
|
342
350
|
}
|
|
343
|
-
|
|
351
|
+
`,
|
|
352
|
+
dark: darkColors
|
|
353
|
+
? `
|
|
354
|
+
.description {
|
|
355
|
+
fill: ${darkColors.textColor};
|
|
356
|
+
${browser_rendering ? wrappedTextStyles(darkColors.textColor) : ""}
|
|
357
|
+
}
|
|
358
|
+
.gray { fill: ${darkColors.textColor} }
|
|
359
|
+
.badge rect { stroke: ${darkColors.textColor} }
|
|
360
|
+
.badge text { fill: ${darkColors.textColor} }
|
|
361
|
+
.stat { fill: ${darkColors.textColor} }
|
|
362
|
+
.icon { fill: ${darkColors.iconColor}; }
|
|
363
|
+
`
|
|
364
|
+
: null,
|
|
365
|
+
});
|
|
344
366
|
|
|
345
367
|
return card.render(`
|
|
346
368
|
${
|
|
347
369
|
isTemplate
|
|
348
|
-
?
|
|
349
|
-
getBadgeSVG(
|
|
370
|
+
? getBadgeSVG(
|
|
350
371
|
i18n.t("repocard.template"),
|
|
351
|
-
colors.textColor,
|
|
352
372
|
card_width - CARD_DEFAULT_WIDTH,
|
|
353
373
|
)
|
|
354
374
|
: isArchived
|
|
355
|
-
?
|
|
356
|
-
getBadgeSVG(
|
|
375
|
+
? getBadgeSVG(
|
|
357
376
|
i18n.t("repocard.archived"),
|
|
358
|
-
colors.textColor,
|
|
359
377
|
card_width - CARD_DEFAULT_WIDTH,
|
|
360
378
|
)
|
|
361
379
|
: ""
|