@stats-forge/github-stats-forge-core 0.1.0 → 0.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/contributed-to.d.ts +23 -0
- package/build/api/contributed-to.d.ts.map +1 -0
- package/build/api/contributed-to.js +43 -0
- package/build/api/gist.d.ts +8 -15
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +14 -29
- package/build/api/handler.d.ts +16 -0
- package/build/api/handler.d.ts.map +1 -0
- package/build/api/handler.js +29 -0
- package/build/api/index.d.ts +1 -0
- package/build/api/index.d.ts.map +1 -1
- package/build/api/index.js +1 -0
- package/build/api/params.d.ts +11 -5
- package/build/api/params.d.ts.map +1 -1
- package/build/api/params.js +26 -6
- package/build/api/pin.d.ts +11 -15
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +34 -46
- package/build/api/stats.d.ts +15 -22
- package/build/api/stats.d.ts.map +1 -1
- package/build/api/stats.js +59 -72
- package/build/api/top-langs.d.ts +11 -22
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +34 -51
- package/build/api/wakatime.d.ts +10 -24
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +27 -47
- package/build/cards/contributed-to.d.ts +19 -0
- package/build/cards/contributed-to.d.ts.map +1 -0
- package/build/cards/contributed-to.js +242 -0
- package/build/cards/gist.d.ts +1 -0
- package/build/cards/gist.d.ts.map +1 -1
- package/build/cards/gist.js +13 -9
- package/build/cards/repo.d.ts +12 -1
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +40 -18
- package/build/cards/stats.d.ts +15 -3
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +91 -76
- package/build/cards/top-languages.d.ts +13 -2
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +26 -9
- package/build/cards/wakatime.d.ts +13 -2
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +22 -9
- package/build/common/Card.d.ts +9 -0
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +44 -9
- package/build/common/I18n.d.ts +1 -1
- package/build/common/I18n.d.ts.map +1 -1
- package/build/common/I18n.js +4 -2
- package/build/common/brand.d.ts +76 -0
- package/build/common/brand.d.ts.map +1 -0
- package/build/common/brand.js +73 -0
- package/build/common/constants.d.ts +3 -1
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/constants.js +3 -1
- package/build/common/date.d.ts +50 -3
- package/build/common/date.d.ts.map +1 -1
- package/build/common/date.js +104 -2
- package/build/common/icons.d.ts +4 -2
- package/build/common/icons.d.ts.map +1 -1
- package/build/common/icons.js +10 -5
- package/build/common/ops.d.ts +8 -3
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +8 -14
- package/build/common/render.d.ts +7 -1
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +60 -58
- package/build/fetchers/contributed-to.d.ts +62 -0
- package/build/fetchers/contributed-to.d.ts.map +1 -0
- package/build/fetchers/contributed-to.js +184 -0
- package/build/fetchers/graphql-error.d.ts +13 -0
- package/build/fetchers/graphql-error.d.ts.map +1 -0
- package/build/fetchers/graphql-error.js +29 -0
- package/build/fetchers/index.d.ts +2 -1
- package/build/fetchers/index.d.ts.map +1 -1
- package/build/fetchers/index.js +1 -0
- package/build/fetchers/stats.d.ts +14 -8
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +72 -195
- package/build/fetchers/top-languages.d.ts.map +1 -1
- package/build/fetchers/top-languages.js +3 -18
- package/build/fetchers/types.d.ts +24 -0
- package/build/fetchers/types.d.ts.map +1 -1
- package/build/graphql/contributionsCollection.d.ts +9 -0
- package/build/graphql/contributionsCollection.d.ts.map +1 -0
- package/build/graphql/contributionsCollection.js +12 -0
- package/build/graphql/contributionsDocument.d.ts +5 -5
- package/build/graphql/contributionsDocument.d.ts.map +1 -1
- package/build/graphql/contributionsDocument.js +8 -15
- package/build/graphql/generated/contributed-to.d.ts +22 -0
- package/build/graphql/generated/contributed-to.d.ts.map +1 -0
- package/build/graphql/generated/contributed-to.js +11 -0
- package/build/graphql/generated/stats.d.ts +13 -1
- package/build/graphql/generated/stats.d.ts.map +1 -1
- package/build/graphql/generated/stats.js +2 -2
- package/build/graphql/graphqlDocument.d.ts +1 -1
- package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
- package/build/graphql/reposContributedToDocument.js +11 -5
- package/build/translations.d.ts +64 -1
- package/build/translations.d.ts.map +1 -1
- package/build/translations.js +65 -1
- package/package.json +1 -1
- package/src/api/contributed-to.ts +84 -0
- package/src/api/gist.ts +20 -37
- package/src/api/handler.ts +42 -0
- package/src/api/index.ts +1 -0
- package/src/api/params.ts +48 -9
- package/src/api/pin.ts +33 -45
- package/src/api/stats.ts +78 -89
- package/src/api/top-langs.ts +34 -56
- package/src/api/wakatime.ts +33 -54
- package/src/cards/contributed-to.ts +373 -0
- package/src/cards/gist.ts +17 -8
- package/src/cards/repo.ts +44 -20
- package/src/cards/stats.ts +119 -90
- package/src/cards/top-languages.ts +27 -18
- package/src/cards/wakatime.ts +23 -13
- package/src/common/Card.ts +56 -11
- package/src/common/I18n.ts +4 -2
- package/src/common/brand.ts +109 -0
- package/src/common/constants.ts +4 -1
- package/src/common/date.ts +135 -3
- package/src/common/icons.ts +10 -5
- package/src/common/ops.ts +10 -19
- package/src/common/render.ts +65 -62
- package/src/fetchers/contributed-to.ts +271 -0
- package/src/fetchers/graphql-error.ts +36 -0
- package/src/fetchers/index.ts +3 -0
- package/src/fetchers/stats.ts +123 -274
- package/src/fetchers/top-languages.ts +5 -19
- package/src/fetchers/types.ts +26 -0
- package/src/graphql/contributionsCollection.ts +18 -0
- package/src/graphql/contributionsDocument.ts +11 -18
- package/src/graphql/generated/contributed-to.ts +25 -0
- package/src/graphql/generated/stats.ts +19 -6
- package/src/graphql/graphqlDocument.ts +1 -1
- package/src/graphql/queries/contributed-to.graphql +8 -0
- package/src/graphql/queries/stats.graphql +14 -2
- package/src/graphql/reposContributedToDocument.ts +11 -9
- package/src/translations.ts +77 -0
package/src/api/params.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as z from 'zod/mini';
|
|
|
3
3
|
import type { ColorParams } from '../common/color.ts';
|
|
4
4
|
import { COLOR_PARAM_KEYS, THEME_PARAM_KEYS, isValidColorInput } from '../common/color.ts';
|
|
5
5
|
import { GITHUB_USERNAME_PATTERN } from '../common/constants.ts';
|
|
6
|
+
import { getWidestRange, parseRangeDate } from '../common/date.ts';
|
|
6
7
|
import { CardError } from '../common/error.ts';
|
|
7
8
|
import { parseArray, parseBoolean } from '../common/ops.ts';
|
|
8
9
|
import { isLocaleAvailable } from '../translations.ts';
|
|
@@ -24,7 +25,16 @@ const rawParam = z.optional(z.string());
|
|
|
24
25
|
const SAFE_PATTERN = /^[-\w/.,]+$/;
|
|
25
26
|
|
|
26
27
|
/** What a check rejected a param for. */
|
|
27
|
-
type Rejection =
|
|
28
|
+
type Rejection =
|
|
29
|
+
| 'number'
|
|
30
|
+
| 'date'
|
|
31
|
+
| 'out_of_range'
|
|
32
|
+
| 'inverted_range'
|
|
33
|
+
| 'unsafe'
|
|
34
|
+
| 'username'
|
|
35
|
+
| 'locale'
|
|
36
|
+
| 'enum'
|
|
37
|
+
| 'color';
|
|
28
38
|
|
|
29
39
|
/**
|
|
30
40
|
* Every rejection the api can put on an error card, in one place.
|
|
@@ -32,7 +42,9 @@ type Rejection = 'number' | 'year' | 'unsafe' | 'username' | 'locale' | 'enum' |
|
|
|
32
42
|
*/
|
|
33
43
|
const REJECTION_MESSAGES: Record<Rejection, (param: string) => string> = {
|
|
34
44
|
number: (param) => `Invalid number input for parameter "${param}"`,
|
|
35
|
-
|
|
45
|
+
date: (param) => `Invalid date input for parameter "${param}"`,
|
|
46
|
+
out_of_range: (param) => `Out of range date for parameter "${param}"`,
|
|
47
|
+
inverted_range: () => 'Range "from" is after "to"',
|
|
36
48
|
unsafe: (param) => `Parameter "${param}" contains unsafe characters`,
|
|
37
49
|
username: (param) => `Invalid username input for parameter "${param}"`,
|
|
38
50
|
locale: () => 'Locale not found',
|
|
@@ -86,13 +98,38 @@ const looseIntParam = z.pipe(
|
|
|
86
98
|
);
|
|
87
99
|
|
|
88
100
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
101
|
+
* One end of the range a card counts within, written as `2024`, `2024-03` or `2024-03-15`.
|
|
102
|
+
*
|
|
103
|
+
* @returns Schema yielding the instant, or `undefined` when the param is absent.
|
|
104
|
+
*/
|
|
105
|
+
const rangeParam = (end: 'from' | 'to'): z.ZodMiniType<Date | undefined, string | undefined> => {
|
|
106
|
+
const parse = (value: string): Date | undefined => parseRangeDate(value, end);
|
|
107
|
+
return z.pipe(
|
|
108
|
+
rawParam.check(rejects('date', (value) => parse(value) !== undefined)).check(
|
|
109
|
+
rejects('out_of_range', (value) => {
|
|
110
|
+
const date = parse(value);
|
|
111
|
+
const widest = getWidestRange();
|
|
112
|
+
// a bad shape is already reported by the check above
|
|
113
|
+
return date === undefined || (date >= widest.from && date <= widest.to);
|
|
114
|
+
}),
|
|
115
|
+
),
|
|
116
|
+
z.transform((value) => (value === undefined ? undefined : parse(value))),
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/** The start of a card's range; see {@link rangeParam}. */
|
|
121
|
+
const fromParam = rangeParam('from');
|
|
122
|
+
|
|
123
|
+
/** The end of a card's range; see {@link rangeParam}. */
|
|
124
|
+
const toParam = rangeParam('to');
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The pair-level rule the two ends cannot see on their own.
|
|
128
|
+
* Every endpoint taking a range applies it, so an order no card could draw is rejected once.
|
|
92
129
|
*/
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
130
|
+
const ORDERED_RANGE = z.refine<{ from?: Date | undefined; to?: Date | undefined }>(
|
|
131
|
+
({ from, to }) => from === undefined || to === undefined || from <= to,
|
|
132
|
+
{ error: REJECTION_MESSAGES.inverted_range('from'), path: ['from'] },
|
|
96
133
|
);
|
|
97
134
|
|
|
98
135
|
/**
|
|
@@ -213,7 +250,9 @@ export type { ApiQuery };
|
|
|
213
250
|
export {
|
|
214
251
|
booleanParam,
|
|
215
252
|
enumParam,
|
|
253
|
+
fromParam,
|
|
216
254
|
listParam,
|
|
255
|
+
ORDERED_RANGE,
|
|
217
256
|
localeParam,
|
|
218
257
|
looseIntParam,
|
|
219
258
|
numberParam,
|
|
@@ -222,6 +261,6 @@ export {
|
|
|
222
261
|
rawParam,
|
|
223
262
|
safeListParam,
|
|
224
263
|
safeParam,
|
|
264
|
+
toParam,
|
|
225
265
|
usernameParam,
|
|
226
|
-
yearParam,
|
|
227
266
|
};
|
package/src/api/pin.ts
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import * as z from 'zod/mini';
|
|
2
2
|
|
|
3
3
|
import { renderRepoCard } from '../cards/repo.ts';
|
|
4
|
-
import type { CardConfig } from '../common/config.ts';
|
|
5
4
|
import { fetchRepo } from '../fetchers/repo.ts';
|
|
6
5
|
|
|
7
|
-
import
|
|
8
|
-
import { errorResult } from './api-result.ts';
|
|
9
|
-
import type { ApiQuery } from './params.ts';
|
|
6
|
+
import { cardHandler } from './handler.ts';
|
|
10
7
|
import {
|
|
11
8
|
booleanParam,
|
|
12
9
|
listParam,
|
|
13
10
|
localeParam,
|
|
14
11
|
looseIntParam,
|
|
15
12
|
numberParam,
|
|
16
|
-
parseColorParams,
|
|
17
|
-
parseParams,
|
|
18
13
|
rawParam,
|
|
19
14
|
safeParam,
|
|
20
15
|
usernameParam,
|
|
@@ -38,25 +33,15 @@ const pinQuery = z.object({
|
|
|
38
33
|
description_lines_count: looseIntParam,
|
|
39
34
|
});
|
|
40
35
|
|
|
41
|
-
/** The query this endpoint accepts, checked against the schema above. */
|
|
42
|
-
type PinApiQuery = ApiQuery<typeof pinQuery>;
|
|
43
|
-
|
|
44
36
|
/**
|
|
45
37
|
* Render the repository card for a set of query params.
|
|
46
38
|
*
|
|
47
39
|
* @returns The rendered card, or a rendered error.
|
|
48
40
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// A rejected color cannot be used to draw its own error card.
|
|
55
|
-
return errorResult(error);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
const {
|
|
41
|
+
const renderPin = cardHandler(
|
|
42
|
+
pinQuery,
|
|
43
|
+
async (
|
|
44
|
+
{
|
|
60
45
|
username,
|
|
61
46
|
repo,
|
|
62
47
|
hide_border,
|
|
@@ -71,8 +56,10 @@ export const pin = async (query: PinApiQuery, config: CardConfig): Promise<ApiRe
|
|
|
71
56
|
locale,
|
|
72
57
|
border_radius,
|
|
73
58
|
description_lines_count,
|
|
74
|
-
}
|
|
75
|
-
|
|
59
|
+
},
|
|
60
|
+
colors,
|
|
61
|
+
config,
|
|
62
|
+
) => {
|
|
76
63
|
const repoData = await fetchRepo(
|
|
77
64
|
{
|
|
78
65
|
username,
|
|
@@ -86,26 +73,27 @@ export const pin = async (query: PinApiQuery, config: CardConfig): Promise<ApiRe
|
|
|
86
73
|
config,
|
|
87
74
|
);
|
|
88
75
|
|
|
89
|
-
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
76
|
+
return renderRepoCard(repoData, {
|
|
77
|
+
...colors,
|
|
78
|
+
hide_border,
|
|
79
|
+
border_radius,
|
|
80
|
+
card_width_input: card_width,
|
|
81
|
+
show_owner,
|
|
82
|
+
browser_rendering,
|
|
83
|
+
show,
|
|
84
|
+
show_icons,
|
|
85
|
+
number_format,
|
|
86
|
+
text_bold,
|
|
87
|
+
line_height,
|
|
88
|
+
username,
|
|
89
|
+
locale,
|
|
90
|
+
description_lines_count,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The card, and the values each of its options accepts, keyed by the option's own name.
|
|
97
|
+
* A UI reads them off the function it calls: `pin.OPTIONS.show`.
|
|
98
|
+
*/
|
|
99
|
+
export const pin = Object.assign(renderPin, { OPTIONS: renderRepoCard.OPTIONS });
|
package/src/api/stats.ts
CHANGED
|
@@ -1,74 +1,65 @@
|
|
|
1
1
|
import * as z from 'zod/mini';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
3
|
+
import { renderStatsCard } from '../cards/stats.ts';
|
|
4
|
+
import { OWNER_AFFILIATIONS } from '../common/constants.ts';
|
|
5
5
|
import { fetchStats } from '../fetchers/stats.ts';
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
import { errorResult } from './api-result.ts';
|
|
9
|
-
import type { ApiQuery } from './params.ts';
|
|
7
|
+
import { cardHandler } from './handler.ts';
|
|
10
8
|
import {
|
|
11
9
|
booleanParam,
|
|
12
10
|
enumParam,
|
|
11
|
+
fromParam,
|
|
13
12
|
listParam,
|
|
14
13
|
localeParam,
|
|
15
14
|
looseIntParam,
|
|
16
15
|
numberParam,
|
|
17
|
-
|
|
18
|
-
parseParams,
|
|
16
|
+
ORDERED_RANGE,
|
|
19
17
|
rawParam,
|
|
20
18
|
safeListParam,
|
|
19
|
+
toParam,
|
|
21
20
|
usernameParam,
|
|
22
|
-
yearParam,
|
|
23
21
|
} from './params.ts';
|
|
24
22
|
|
|
25
23
|
/** What the stats endpoint accepts, on top of the shared color params. */
|
|
26
|
-
const statsQuery = z
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
24
|
+
const statsQuery = z
|
|
25
|
+
.object({
|
|
26
|
+
username: usernameParam,
|
|
27
|
+
repo: safeListParam,
|
|
28
|
+
owner: safeListParam,
|
|
29
|
+
hide: listParam,
|
|
30
|
+
hide_title: booleanParam,
|
|
31
|
+
hide_border: booleanParam,
|
|
32
|
+
card_width: looseIntParam,
|
|
33
|
+
hide_rank: booleanParam,
|
|
34
|
+
show_icons: booleanParam,
|
|
35
|
+
include_all_commits: booleanParam,
|
|
36
|
+
from: fromParam,
|
|
37
|
+
to: toParam,
|
|
38
|
+
line_height: rawParam,
|
|
39
|
+
text_bold: booleanParam,
|
|
40
|
+
exclude_repo: listParam,
|
|
41
|
+
custom_title: rawParam,
|
|
42
|
+
locale: localeParam,
|
|
43
|
+
disable_animations: booleanParam,
|
|
44
|
+
border_radius: numberParam,
|
|
45
|
+
number_format: rawParam,
|
|
46
|
+
role: listParam,
|
|
47
|
+
number_precision: looseIntParam,
|
|
48
|
+
rank_icon: enumParam(renderStatsCard.OPTIONS.rank_icon),
|
|
49
|
+
show: listParam,
|
|
50
|
+
contribs_include_own_repos: booleanParam,
|
|
51
|
+
})
|
|
52
|
+
.check(ORDERED_RANGE);
|
|
55
53
|
|
|
56
54
|
/**
|
|
57
55
|
* Render the stats card for a set of query params.
|
|
58
56
|
*
|
|
59
57
|
* @returns The rendered card, or a rendered error.
|
|
60
58
|
*/
|
|
61
|
-
const renderStats =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} catch (error) {
|
|
66
|
-
// A rejected color cannot be used to draw its own error card.
|
|
67
|
-
return errorResult(error);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
const {
|
|
59
|
+
const renderStats = cardHandler(
|
|
60
|
+
statsQuery,
|
|
61
|
+
async (
|
|
62
|
+
{
|
|
72
63
|
username,
|
|
73
64
|
repo,
|
|
74
65
|
owner,
|
|
@@ -79,7 +70,8 @@ const renderStats = async (query: StatsApiQuery, config: CardConfig): Promise<Ap
|
|
|
79
70
|
hide_rank,
|
|
80
71
|
show_icons,
|
|
81
72
|
include_all_commits,
|
|
82
|
-
|
|
73
|
+
from,
|
|
74
|
+
to,
|
|
83
75
|
line_height,
|
|
84
76
|
text_bold,
|
|
85
77
|
exclude_repo,
|
|
@@ -93,8 +85,10 @@ const renderStats = async (query: StatsApiQuery, config: CardConfig): Promise<Ap
|
|
|
93
85
|
rank_icon,
|
|
94
86
|
show,
|
|
95
87
|
contribs_include_own_repos,
|
|
96
|
-
}
|
|
97
|
-
|
|
88
|
+
},
|
|
89
|
+
colors,
|
|
90
|
+
config,
|
|
91
|
+
) => {
|
|
98
92
|
// A bare repo name is scoped to the user whose card this is.
|
|
99
93
|
const repository = repo.map((name) =>
|
|
100
94
|
name.includes('/') ? name : `${username ?? ''}/${name}`,
|
|
@@ -109,7 +103,8 @@ const renderStats = async (query: StatsApiQuery, config: CardConfig): Promise<Ap
|
|
|
109
103
|
show.includes('prs_merged') || show.includes('prs_merged_percentage'),
|
|
110
104
|
include_discussions: show.includes('discussions_started'),
|
|
111
105
|
include_discussions_answers: show.includes('discussions_answered'),
|
|
112
|
-
|
|
106
|
+
from,
|
|
107
|
+
to,
|
|
113
108
|
repo: repository,
|
|
114
109
|
owner,
|
|
115
110
|
include_prs_authored: show.includes('prs_authored'),
|
|
@@ -125,45 +120,39 @@ const renderStats = async (query: StatsApiQuery, config: CardConfig): Promise<Ap
|
|
|
125
120
|
config,
|
|
126
121
|
);
|
|
127
122
|
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
),
|
|
157
|
-
};
|
|
158
|
-
} catch (error) {
|
|
159
|
-
return errorResult(error, colors);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
123
|
+
return renderStatsCard(
|
|
124
|
+
stats,
|
|
125
|
+
{
|
|
126
|
+
...colors,
|
|
127
|
+
hide,
|
|
128
|
+
show_icons,
|
|
129
|
+
hide_title,
|
|
130
|
+
hide_border,
|
|
131
|
+
card_width,
|
|
132
|
+
hide_rank,
|
|
133
|
+
include_all_commits,
|
|
134
|
+
line_height,
|
|
135
|
+
text_bold,
|
|
136
|
+
custom_title,
|
|
137
|
+
border_radius,
|
|
138
|
+
number_format,
|
|
139
|
+
number_precision,
|
|
140
|
+
locale,
|
|
141
|
+
disable_animations,
|
|
142
|
+
rank_icon,
|
|
143
|
+
show,
|
|
144
|
+
},
|
|
145
|
+
username,
|
|
146
|
+
repository,
|
|
147
|
+
owner,
|
|
148
|
+
);
|
|
149
|
+
},
|
|
150
|
+
);
|
|
162
151
|
|
|
163
152
|
/**
|
|
164
|
-
* The card,
|
|
165
|
-
* A UI reads them off the function it calls
|
|
153
|
+
* The card, and the values each of its options accepts, keyed by the option's own name.
|
|
154
|
+
* A UI reads them off the function it calls: `stats.OPTIONS.rank_icon`.
|
|
166
155
|
*/
|
|
167
156
|
export const stats = Object.assign(renderStats, {
|
|
168
|
-
|
|
157
|
+
OPTIONS: { ...renderStatsCard.OPTIONS, role: OWNER_AFFILIATIONS },
|
|
169
158
|
});
|
package/src/api/top-langs.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import * as z from 'zod/mini';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
TOP_LANG_STATS_FORMATS,
|
|
6
|
-
renderTopLanguages,
|
|
7
|
-
} from '../cards/top-languages.ts';
|
|
8
|
-
import type { CardConfig } from '../common/config.ts';
|
|
3
|
+
import { renderTopLanguages } from '../cards/top-languages.ts';
|
|
4
|
+
import { OWNER_AFFILIATIONS } from '../common/constants.ts';
|
|
9
5
|
import { fetchTopLanguages } from '../fetchers/top-languages.ts';
|
|
10
6
|
|
|
11
|
-
import
|
|
12
|
-
import { errorResult } from './api-result.ts';
|
|
13
|
-
import type { ApiQuery } from './params.ts';
|
|
7
|
+
import { cardHandler } from './handler.ts';
|
|
14
8
|
import {
|
|
15
9
|
booleanParam,
|
|
16
10
|
enumParam,
|
|
@@ -18,8 +12,6 @@ import {
|
|
|
18
12
|
localeParam,
|
|
19
13
|
looseIntParam,
|
|
20
14
|
numberParam,
|
|
21
|
-
parseColorParams,
|
|
22
|
-
parseParams,
|
|
23
15
|
rawParam,
|
|
24
16
|
usernameParam,
|
|
25
17
|
} from './params.ts';
|
|
@@ -31,7 +23,7 @@ const topLangsQuery = z.object({
|
|
|
31
23
|
hide_title: booleanParam,
|
|
32
24
|
hide_border: booleanParam,
|
|
33
25
|
card_width: looseIntParam,
|
|
34
|
-
layout: enumParam(
|
|
26
|
+
layout: enumParam(renderTopLanguages.OPTIONS.layout),
|
|
35
27
|
langs_count: looseIntParam,
|
|
36
28
|
exclude_repo: listParam,
|
|
37
29
|
size_weight: numberParam,
|
|
@@ -43,28 +35,18 @@ const topLangsQuery = z.object({
|
|
|
43
35
|
disable_animations: booleanParam,
|
|
44
36
|
hide_progress: booleanParam,
|
|
45
37
|
hide_values: booleanParam,
|
|
46
|
-
stats_format: enumParam(
|
|
38
|
+
stats_format: enumParam(renderTopLanguages.OPTIONS.stats_format),
|
|
47
39
|
});
|
|
48
40
|
|
|
49
|
-
/** The query this endpoint accepts, checked against the schema above. */
|
|
50
|
-
type TopLangsApiQuery = ApiQuery<typeof topLangsQuery>;
|
|
51
|
-
|
|
52
41
|
/**
|
|
53
42
|
* Render the top languages card for a set of query params.
|
|
54
43
|
*
|
|
55
44
|
* @returns The rendered card, or a rendered error.
|
|
56
45
|
*/
|
|
57
|
-
const renderTopLangs =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} catch (error) {
|
|
62
|
-
// A rejected color cannot be used to draw its own error card.
|
|
63
|
-
return errorResult(error);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const {
|
|
46
|
+
const renderTopLangs = cardHandler(
|
|
47
|
+
topLangsQuery,
|
|
48
|
+
async (
|
|
49
|
+
{
|
|
68
50
|
username,
|
|
69
51
|
hide,
|
|
70
52
|
hide_title,
|
|
@@ -83,8 +65,10 @@ const renderTopLangs = async (query: TopLangsApiQuery, config: CardConfig): Prom
|
|
|
83
65
|
hide_progress,
|
|
84
66
|
hide_values,
|
|
85
67
|
stats_format,
|
|
86
|
-
}
|
|
87
|
-
|
|
68
|
+
},
|
|
69
|
+
colors,
|
|
70
|
+
config,
|
|
71
|
+
) => {
|
|
88
72
|
const topLangs = await fetchTopLanguages(
|
|
89
73
|
{
|
|
90
74
|
username,
|
|
@@ -96,35 +80,29 @@ const renderTopLangs = async (query: TopLangsApiQuery, config: CardConfig): Prom
|
|
|
96
80
|
config,
|
|
97
81
|
);
|
|
98
82
|
|
|
99
|
-
return {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
};
|
|
118
|
-
} catch (error) {
|
|
119
|
-
return errorResult(error, colors);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
83
|
+
return renderTopLanguages(topLangs, {
|
|
84
|
+
...colors,
|
|
85
|
+
custom_title,
|
|
86
|
+
hide_title,
|
|
87
|
+
hide_border,
|
|
88
|
+
card_width,
|
|
89
|
+
hide,
|
|
90
|
+
layout,
|
|
91
|
+
langs_count,
|
|
92
|
+
border_radius,
|
|
93
|
+
locale,
|
|
94
|
+
disable_animations,
|
|
95
|
+
hide_progress,
|
|
96
|
+
hide_values,
|
|
97
|
+
stats_format,
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
);
|
|
122
101
|
|
|
123
102
|
/**
|
|
124
|
-
* The card,
|
|
125
|
-
* A UI reads them off the function it calls
|
|
103
|
+
* The card, and the values each of its options accepts, keyed by the option's own name.
|
|
104
|
+
* A UI reads them off the function it calls: `topLangs.OPTIONS.layout`.
|
|
126
105
|
*/
|
|
127
106
|
export const topLangs = Object.assign(renderTopLangs, {
|
|
128
|
-
|
|
129
|
-
STATS_FORMATS: TOP_LANG_STATS_FORMATS,
|
|
107
|
+
OPTIONS: { ...renderTopLanguages.OPTIONS, role: OWNER_AFFILIATIONS },
|
|
130
108
|
});
|