@stats-forge/github-stats-forge-core 0.0.2 → 0.1.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/README.md +0 -10
- package/build/api/api-result.d.ts +6 -7
- package/build/api/api-result.d.ts.map +1 -1
- package/build/api/api-result.js +4 -5
- package/build/api/gist.d.ts +3 -10
- package/build/api/gist.d.ts.map +1 -1
- package/build/api/gist.js +4 -11
- package/build/api/index.d.ts +12 -12
- package/build/api/params.d.ts +11 -8
- package/build/api/params.d.ts.map +1 -1
- package/build/api/params.js +16 -14
- package/build/api/pin.d.ts +3 -19
- package/build/api/pin.d.ts.map +1 -1
- package/build/api/pin.js +6 -22
- package/build/api/stats.d.ts +10 -4
- package/build/api/stats.d.ts.map +1 -1
- package/build/api/stats.js +6 -32
- package/build/api/top-langs.d.ts +12 -6
- package/build/api/top-langs.d.ts.map +1 -1
- package/build/api/top-langs.js +6 -26
- package/build/api/wakatime.d.ts +13 -5
- package/build/api/wakatime.d.ts.map +1 -1
- package/build/api/wakatime.js +4 -21
- package/build/calculateRank.d.ts +0 -9
- package/build/calculateRank.d.ts.map +1 -1
- package/build/calculateRank.js +12 -17
- package/build/cards/gist.d.ts +2 -4
- package/build/cards/gist.d.ts.map +1 -1
- package/build/cards/gist.js +27 -36
- package/build/cards/options.d.ts +1 -1
- package/build/cards/repo.d.ts +2 -4
- package/build/cards/repo.d.ts.map +1 -1
- package/build/cards/repo.js +61 -93
- package/build/cards/stats.d.ts +3 -8
- package/build/cards/stats.d.ts.map +1 -1
- package/build/cards/stats.js +119 -165
- package/build/cards/top-languages.d.ts +5 -31
- package/build/cards/top-languages.d.ts.map +1 -1
- package/build/cards/top-languages.js +176 -384
- package/build/cards/wakatime.d.ts +4 -6
- package/build/cards/wakatime.d.ts.map +1 -1
- package/build/cards/wakatime.js +118 -185
- package/build/common/Card.d.ts +14 -62
- package/build/common/Card.d.ts.map +1 -1
- package/build/common/Card.js +97 -199
- package/build/common/I18n.d.ts +0 -6
- package/build/common/I18n.d.ts.map +1 -1
- package/build/common/I18n.js +3 -6
- package/build/common/color.d.ts +4 -17
- package/build/common/color.d.ts.map +1 -1
- package/build/common/color.js +67 -49
- package/build/common/config.d.ts +4 -14
- package/build/common/config.d.ts.map +1 -1
- package/build/common/config.js +3 -16
- package/build/common/constants.d.ts +4 -2
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/constants.js +3 -1
- package/build/common/date.d.ts +0 -2
- package/build/common/date.d.ts.map +1 -1
- package/build/common/date.js +0 -2
- package/build/common/emojiMap.d.ts +8 -0
- package/build/common/emojiMap.d.ts.map +1 -0
- package/build/common/emojiMap.js +10 -0
- package/build/common/emojiMap.json +1915 -0
- package/build/common/error.d.ts +1 -10
- package/build/common/error.d.ts.map +1 -1
- package/build/common/error.js +1 -10
- package/build/common/fmt.d.ts +3 -15
- package/build/common/fmt.d.ts.map +1 -1
- package/build/common/fmt.js +7 -35
- package/build/common/http.d.ts +2 -7
- package/build/common/http.d.ts.map +1 -1
- package/build/common/http.js +8 -17
- package/build/common/icons.d.ts +18 -20
- package/build/common/icons.d.ts.map +1 -1
- package/build/common/icons.js +103 -67
- package/build/common/languageColors.d.ts +0 -1
- package/build/common/languageColors.d.ts.map +1 -1
- package/build/common/languageColors.js +1 -4
- package/build/common/languageColors.json +18 -2
- package/build/common/ops.d.ts +3 -14
- package/build/common/ops.d.ts.map +1 -1
- package/build/common/ops.js +19 -30
- package/build/common/render.d.ts +28 -82
- package/build/common/render.d.ts.map +1 -1
- package/build/common/render.js +175 -211
- package/build/common/retryer.d.ts +2 -7
- package/build/common/retryer.d.ts.map +1 -1
- package/build/common/retryer.js +4 -11
- package/build/fetchers/gist.d.ts +2 -5
- package/build/fetchers/gist.d.ts.map +1 -1
- package/build/fetchers/gist.js +1 -5
- package/build/fetchers/index.d.ts +12 -12
- package/build/fetchers/repo.d.ts +2 -11
- package/build/fetchers/repo.d.ts.map +1 -1
- package/build/fetchers/repo.js +20 -33
- package/build/fetchers/stats.d.ts +2 -32
- package/build/fetchers/stats.d.ts.map +1 -1
- package/build/fetchers/stats.js +27 -86
- package/build/fetchers/top-languages.d.ts +2 -9
- package/build/fetchers/top-languages.d.ts.map +1 -1
- package/build/fetchers/top-languages.js +15 -31
- package/build/fetchers/types.d.ts +1 -1
- package/build/fetchers/wakatime.d.ts +2 -6
- package/build/fetchers/wakatime.d.ts.map +1 -1
- package/build/fetchers/wakatime.js +1 -5
- package/build/graphql/contributionsDocument.d.ts +3 -3
- package/build/graphql/contributionsDocument.d.ts.map +1 -1
- package/build/graphql/contributionsDocument.js +0 -1
- package/build/graphql/generated/gist.d.ts +1 -1
- package/build/graphql/generated/repo.d.ts +1 -1
- package/build/graphql/generated/stats.d.ts +3 -3
- package/build/graphql/generated/top-languages.d.ts +2 -2
- package/build/graphql/graphqlDocument.d.ts +0 -1
- package/build/graphql/graphqlDocument.d.ts.map +1 -1
- package/build/graphql/graphqlDocument.js +0 -1
- package/build/graphql/reposContributedToDocument.d.ts +4 -5
- package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
- package/build/graphql/reposContributedToDocument.js +0 -2
- package/build/markup/css.d.ts +35 -0
- package/build/markup/css.d.ts.map +1 -0
- package/build/markup/css.js +64 -0
- package/build/markup/element.d.ts +41 -0
- package/build/markup/element.d.ts.map +1 -0
- package/build/markup/element.js +127 -0
- package/build/markup/html.d.ts +13 -0
- package/build/markup/html.d.ts.map +1 -0
- package/build/markup/html.js +27 -0
- package/build/markup/index.d.ts +9 -0
- package/build/markup/index.d.ts.map +1 -0
- package/build/markup/index.js +6 -0
- package/build/markup/serialize.d.ts +16 -0
- package/build/markup/serialize.d.ts.map +1 -0
- package/build/markup/serialize.js +17 -0
- package/build/themes/index.d.ts +332 -333
- package/build/themes/index.d.ts.map +1 -1
- package/build/themes/index.js +1 -1
- package/build/translations.d.ts +2 -6
- package/build/translations.d.ts.map +1 -1
- package/build/translations.js +621 -628
- package/package.json +17 -26
- package/src/api/api-result.ts +10 -9
- package/src/api/gist.ts +11 -18
- package/src/api/index.ts +12 -12
- package/src/api/params.ts +27 -21
- package/src/api/pin.ts +13 -28
- package/src/api/stats.ts +13 -39
- package/src/api/top-langs.ts +13 -33
- package/src/api/wakatime.ts +11 -28
- package/src/calculateRank.ts +12 -23
- package/src/cards/gist.ts +40 -43
- package/src/cards/options.ts +1 -1
- package/src/cards/repo.ts +97 -107
- package/src/cards/stats.ts +165 -184
- package/src/cards/top-languages.ts +297 -413
- package/src/cards/wakatime.ts +193 -221
- package/src/common/Card.ts +165 -217
- package/src/common/I18n.ts +3 -6
- package/src/common/color.ts +80 -57
- package/src/common/config.ts +5 -18
- package/src/common/constants.ts +5 -2
- package/src/common/date.ts +0 -2
- package/src/common/emojiMap.json +1915 -0
- package/src/common/emojiMap.ts +13 -0
- package/src/common/error.ts +2 -11
- package/src/common/fmt.ts +7 -44
- package/src/common/http.ts +9 -15
- package/src/common/icons.ts +117 -42
- package/src/common/languageColors.json +18 -2
- package/src/common/languageColors.ts +1 -4
- package/src/common/ops.ts +26 -34
- package/src/common/render.ts +279 -232
- package/src/common/retryer.ts +8 -15
- package/src/fetchers/gist.ts +8 -12
- package/src/fetchers/index.ts +12 -12
- package/src/fetchers/repo.ts +27 -40
- package/src/fetchers/stats.ts +44 -102
- package/src/fetchers/top-languages.ts +26 -40
- package/src/fetchers/types.ts +1 -1
- package/src/fetchers/wakatime.ts +5 -9
- package/src/graphql/contributionsDocument.ts +7 -5
- package/src/graphql/generated/gist.ts +1 -1
- package/src/graphql/generated/repo.ts +1 -1
- package/src/graphql/generated/stats.ts +2 -2
- package/src/graphql/generated/top-languages.ts +2 -2
- package/src/graphql/graphqlDocument.ts +0 -1
- package/src/graphql/reposContributedToDocument.ts +6 -7
- package/src/markup/css.ts +118 -0
- package/src/markup/element.ts +246 -0
- package/src/markup/html.ts +34 -0
- package/src/markup/index.ts +9 -0
- package/src/markup/serialize.ts +27 -0
- package/src/themes/index.ts +1 -1
- package/src/translations.ts +622 -629
- package/build/cards/index.d.ts +0 -11
- package/build/cards/index.d.ts.map +0 -1
- package/build/cards/index.js +0 -7
- package/build/common/html.d.ts +0 -8
- package/build/common/html.d.ts.map +0 -1
- package/build/common/html.js +0 -14
- package/build/index.d.ts +0 -15
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -10
- package/src/_emoji-name-map.d.ts +0 -10
- package/src/_github-username-regex.d.ts +0 -4
- package/src/cards/index.ts +0 -21
- package/src/common/html.ts +0 -17
- package/src/index.ts +0 -18
package/build/fetchers/gist.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import type { CardConfig } from '../common/config.
|
|
2
|
-
import type { GistData } from './types.
|
|
1
|
+
import type { CardConfig } from '../common/config.ts';
|
|
2
|
+
import type { GistData } from './types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch GitHub gist information by given username and ID.
|
|
5
5
|
*
|
|
6
|
-
* @param props Fetcher props.
|
|
7
|
-
* @param props.id GitHub gist ID.
|
|
8
|
-
* @param config Deployment config supplying the PAT pool.
|
|
9
6
|
* @returns Gist data.
|
|
10
7
|
*/
|
|
11
8
|
declare const fetchGist: ({ id }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/fetchers/gist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/fetchers/gist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA8B3C;;;;GAIG;AACH,QAAA,MAAM,SAAS,WACL;IAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,UAC1B,UAAU,KACjB,OAAO,CAAC,QAAQ,CA8BlB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/build/fetchers/gist.js
CHANGED
|
@@ -6,7 +6,6 @@ const fetcher = createGraphQLFetcher(GistInfoDocument, 'token');
|
|
|
6
6
|
/**
|
|
7
7
|
* This function calculates the primary language of a gist by files size.
|
|
8
8
|
*
|
|
9
|
-
* @param files Files.
|
|
10
9
|
* @returns Primary language, or `null` when no file has a language.
|
|
11
10
|
*/
|
|
12
11
|
const calculatePrimaryLanguage = (files) => {
|
|
@@ -29,9 +28,6 @@ const calculatePrimaryLanguage = (files) => {
|
|
|
29
28
|
/**
|
|
30
29
|
* Fetch GitHub gist information by given username and ID.
|
|
31
30
|
*
|
|
32
|
-
* @param props Fetcher props.
|
|
33
|
-
* @param props.id GitHub gist ID.
|
|
34
|
-
* @param config Deployment config supplying the PAT pool.
|
|
35
31
|
* @returns Gist data.
|
|
36
32
|
*/
|
|
37
33
|
const fetchGist = async ({ id }, config) => {
|
|
@@ -44,7 +40,7 @@ const fetchGist = async ({ id }, config) => {
|
|
|
44
40
|
code: 'upstream',
|
|
45
41
|
});
|
|
46
42
|
}
|
|
47
|
-
const gist = res.data.data.viewer
|
|
43
|
+
const { gist } = res.data.data.viewer;
|
|
48
44
|
if (!gist) {
|
|
49
45
|
throw new CardError('Gist not found', {
|
|
50
46
|
code: 'not_found',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { fetchGist } from './gist.
|
|
2
|
-
export { fetchRepo } from './repo.
|
|
3
|
-
export { fetchRepoUserStats, fetchStats } from './stats.
|
|
4
|
-
export { fetchTopLanguages } from './top-languages.
|
|
5
|
-
export { fetchWakatimeStats } from './wakatime.
|
|
6
|
-
export type { GistData, Lang, RepoUserStats, RepositoryData, StatsData, TopLangData, WakaTimeData, WakaTimeLang, } from './types.
|
|
7
|
-
export { CardConfig } from '../common/config.
|
|
8
|
-
export type { CardConfigInit, PersonalAccessToken } from '../common/config.
|
|
9
|
-
export type { FetchLike } from '../common/http.
|
|
10
|
-
export { retryer } from '../common/retryer.
|
|
11
|
-
export { CardError } from '../common/error.
|
|
12
|
-
export type { ErrorCode } from '../common/error.
|
|
1
|
+
export { fetchGist } from './gist.ts';
|
|
2
|
+
export { fetchRepo } from './repo.ts';
|
|
3
|
+
export { fetchRepoUserStats, fetchStats } from './stats.ts';
|
|
4
|
+
export { fetchTopLanguages } from './top-languages.ts';
|
|
5
|
+
export { fetchWakatimeStats } from './wakatime.ts';
|
|
6
|
+
export type { GistData, Lang, RepoUserStats, RepositoryData, StatsData, TopLangData, WakaTimeData, WakaTimeLang, } from './types.ts';
|
|
7
|
+
export { CardConfig } from '../common/config.ts';
|
|
8
|
+
export type { CardConfigInit, PersonalAccessToken } from '../common/config.ts';
|
|
9
|
+
export type { FetchLike } from '../common/http.ts';
|
|
10
|
+
export { retryer } from '../common/retryer.ts';
|
|
11
|
+
export { CardError } from '../common/error.ts';
|
|
12
|
+
export type { ErrorCode } from '../common/error.ts';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/build/fetchers/repo.d.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import type { CardConfig } from '../common/config.
|
|
2
|
-
import type { RepositoryData } from './types.
|
|
1
|
+
import type { CardConfig } from '../common/config.ts';
|
|
2
|
+
import type { RepositoryData } from './types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch repository data.
|
|
5
5
|
*
|
|
6
|
-
* @param props Fetcher props.
|
|
7
|
-
* @param props.username GitHub username.
|
|
8
|
-
* @param props.reponame GitHub repository name.
|
|
9
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
10
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
11
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
12
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
13
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
14
|
-
* @param config Deployment config supplying the PAT pool.
|
|
15
6
|
* @returns Repository data.
|
|
16
7
|
*/
|
|
17
8
|
declare const fetchRepo: ({ username, reponame, include_prs_authored, include_prs_commented, include_prs_reviewed, include_issues_authored, include_issues_commented, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/fetchers/repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/fetchers/repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD;;;;GAIG;AACH,QAAA,MAAM,SAAS,kJASV;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,qBAAqB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5C,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,uBAAuB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChD,UACO,UAAU,KACjB,OAAO,CAAC,cAAc,CAuFxB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/build/fetchers/repo.js
CHANGED
|
@@ -8,43 +8,30 @@ const urlExample = '/api/pin?username=USERNAME&repo=REPO_NAME';
|
|
|
8
8
|
/**
|
|
9
9
|
* Fetch repository data.
|
|
10
10
|
*
|
|
11
|
-
* @param props Fetcher props.
|
|
12
|
-
* @param props.username GitHub username.
|
|
13
|
-
* @param props.reponame GitHub repository name.
|
|
14
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
15
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
16
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
17
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
18
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
19
|
-
* @param config Deployment config supplying the PAT pool.
|
|
20
11
|
* @returns Repository data.
|
|
21
12
|
*/
|
|
22
13
|
const fetchRepo = async ({ username, reponame, include_prs_authored = false, include_prs_commented = false, include_prs_reviewed = false, include_issues_authored = false, include_issues_commented = false, }, config) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
// `?repo=owner/name` carries the owner itself, and then it wins over `?username=`.
|
|
15
|
+
let parsedOwner = username;
|
|
16
|
+
let repo = reponame;
|
|
17
|
+
if (repo?.includes('/')) {
|
|
18
|
+
const [ownerFromRepo, nameFromRepo] = repo.split('/');
|
|
19
|
+
parsedOwner = ownerFromRepo ?? '';
|
|
20
|
+
repo = nameFromRepo ?? '';
|
|
28
21
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (username && !owner) {
|
|
33
|
-
owner = username;
|
|
34
|
-
}
|
|
35
|
-
if (!username && !reponame) {
|
|
22
|
+
const login = username || parsedOwner;
|
|
23
|
+
if (!login && !repo) {
|
|
36
24
|
throw CardError.missingParam(['username', 'repo'], urlExample);
|
|
37
25
|
}
|
|
38
|
-
if (!
|
|
26
|
+
if (!login) {
|
|
39
27
|
throw CardError.missingParam(['username'], urlExample);
|
|
40
28
|
}
|
|
41
|
-
if (!
|
|
29
|
+
if (!repo) {
|
|
42
30
|
throw CardError.missingParam(['repo'], urlExample);
|
|
43
31
|
}
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const data = res.data.data;
|
|
32
|
+
const repoOwner = parsedOwner || login;
|
|
33
|
+
const res = await retryer(fetcher, { login: repoOwner, repo }, config);
|
|
34
|
+
const { data } = res.data;
|
|
48
35
|
if (!data.user && !data.organization) {
|
|
49
36
|
throw new CardError('Not found', {
|
|
50
37
|
code: 'not_found',
|
|
@@ -52,7 +39,7 @@ const fetchRepo = async ({ username, reponame, include_prs_authored = false, inc
|
|
|
52
39
|
});
|
|
53
40
|
}
|
|
54
41
|
if (data.organization === null && data.user) {
|
|
55
|
-
const repository = data.user
|
|
42
|
+
const { repository } = data.user;
|
|
56
43
|
if (!repository || repository.isPrivate) {
|
|
57
44
|
throw new CardError('User Repository Not found', {
|
|
58
45
|
code: 'not_found',
|
|
@@ -60,8 +47,8 @@ const fetchRepo = async ({ username, reponame, include_prs_authored = false, inc
|
|
|
60
47
|
});
|
|
61
48
|
}
|
|
62
49
|
const repoUserStats = await fetchRepoUserStats({
|
|
63
|
-
username,
|
|
64
|
-
repo: [`${repoOwner}/${
|
|
50
|
+
username: login,
|
|
51
|
+
repo: [`${repoOwner}/${repo}`],
|
|
65
52
|
include_prs_authored,
|
|
66
53
|
include_prs_commented,
|
|
67
54
|
include_prs_reviewed,
|
|
@@ -74,7 +61,7 @@ const fetchRepo = async ({ username, reponame, include_prs_authored = false, inc
|
|
|
74
61
|
};
|
|
75
62
|
}
|
|
76
63
|
if (data.user === null && data.organization) {
|
|
77
|
-
const repository = data.organization
|
|
64
|
+
const { repository } = data.organization;
|
|
78
65
|
if (!repository || repository.isPrivate) {
|
|
79
66
|
throw new CardError('Organization Repository Not found', {
|
|
80
67
|
code: 'not_found',
|
|
@@ -82,8 +69,8 @@ const fetchRepo = async ({ username, reponame, include_prs_authored = false, inc
|
|
|
82
69
|
});
|
|
83
70
|
}
|
|
84
71
|
const repoUserStats = await fetchRepoUserStats({
|
|
85
|
-
username,
|
|
86
|
-
repo: [`${repoOwner}/${
|
|
72
|
+
username: login,
|
|
73
|
+
repo: [`${repoOwner}/${repo}`],
|
|
87
74
|
include_prs_authored,
|
|
88
75
|
include_prs_commented,
|
|
89
76
|
include_prs_reviewed,
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import type { CardConfig } from '../common/config.
|
|
2
|
-
import type { RepoUserStats, StatsData } from './types.
|
|
1
|
+
import type { CardConfig } from '../common/config.ts';
|
|
2
|
+
import type { RepoUserStats, StatsData } from './types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch the per-repository counts the REST search API answers, one request each.
|
|
5
5
|
*
|
|
6
|
-
* @param props Fetcher props.
|
|
7
|
-
* @param props.username GitHub username.
|
|
8
|
-
* @param props.repo Repositories the search is scoped to.
|
|
9
|
-
* @param props.owner Owners the search is scoped to.
|
|
10
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
11
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
12
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
13
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
14
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
15
|
-
* @param config Deployment config supplying the PAT pool.
|
|
16
6
|
* @returns Only the counts that were asked for.
|
|
17
7
|
*/
|
|
18
8
|
declare const fetchRepoUserStats: ({ username, repo, owner, include_prs_authored, include_prs_commented, include_prs_reviewed, include_issues_authored, include_issues_commented, }: {
|
|
@@ -28,26 +18,6 @@ declare const fetchRepoUserStats: ({ username, repo, owner, include_prs_authored
|
|
|
28
18
|
/**
|
|
29
19
|
* Fetch stats for a given username.
|
|
30
20
|
*
|
|
31
|
-
* @param props Fetcher props.
|
|
32
|
-
* @param props.username GitHub username.
|
|
33
|
-
* @param props.include_all_commits Include all commits.
|
|
34
|
-
* @param props.exclude_repo Repositories to exclude.
|
|
35
|
-
* @param props.include_merged_pull_requests Include merged pull requests.
|
|
36
|
-
* @param props.include_discussions Include discussions.
|
|
37
|
-
* @param props.include_discussions_answers Include discussions answers.
|
|
38
|
-
* @param props.commits_year Year to count total commits.
|
|
39
|
-
* @param props.repo Repositories to scope the REST search to.
|
|
40
|
-
* @param props.owner Owners to scope the REST search to.
|
|
41
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
42
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
43
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
44
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
45
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
46
|
-
* @param props.ownerAffiliations Owner affiliations. Default: OWNER.
|
|
47
|
-
* @param props.include_contributions Include all-time contributions.
|
|
48
|
-
* @param props.include_all_time_contribs Include all-time count of repos contributed to.
|
|
49
|
-
* @param props.contribs_include_own_repos Include user-owned repos in contributed-to counts.
|
|
50
|
-
* @param config Deployment config supplying the PAT pool.
|
|
51
21
|
* @returns Stats data.
|
|
52
22
|
*/
|
|
53
23
|
declare const fetchStats: ({ username, include_all_commits, exclude_repo, include_merged_pull_requests, include_discussions, include_discussions_answers, commits_year, repo, owner, include_prs_authored, include_prs_commented, include_prs_reviewed, include_issues_authored, include_issues_commented, ownerAffiliations, include_contributions, include_all_time_contribs, contribs_include_own_repos, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/fetchers/stats.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/fetchers/stats.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAwBtD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA4L3D;;;;GAIG;AACH,QAAA,MAAM,kBAAkB,qJAUnB;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,qBAAqB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5C,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,uBAAuB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChD,UACO,UAAU,KACjB,OAAO,CAAC,aAAa,CA+DvB,CAAC;AA8KF;;;;GAIG;AACH,QAAA,MAAM,UAAU,uXAoBX;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClD,UACO,UAAU,KACjB,OAAO,CAAC,SAAS,CA+JnB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC"}
|
package/build/fetchers/stats.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import githubUsernameRegex from 'github-username-regex';
|
|
2
1
|
import { calculateRank } from '../calculateRank.js';
|
|
2
|
+
import { GITHUB_USERNAME_PATTERN } from '../common/constants.js';
|
|
3
3
|
import { getGitHubYearRange, toGitHubDateTime } from '../common/date.js';
|
|
4
4
|
import { CardError, USER_NOT_FOUND } from '../common/error.js';
|
|
5
|
-
import { wrapTextMultiline } from '../common/fmt.js';
|
|
6
5
|
import { createGraphQLFetcher, httpRequest } from '../common/http.js';
|
|
7
6
|
import { logger } from '../common/log.js';
|
|
8
7
|
import { buildSearchFilter, chunkArray, parseOwnerAffiliations } from '../common/ops.js';
|
|
8
|
+
import { wrapTextMultiline } from '../common/render.js';
|
|
9
9
|
import { retryer } from '../common/retryer.js';
|
|
10
10
|
import { buildContributionsDocument } from '../graphql/contributionsDocument.js';
|
|
11
11
|
import { UserInfoDocument, UserReposDocument } from '../graphql/generated/stats.js';
|
|
@@ -16,19 +16,10 @@ const reposFetcher = createGraphQLFetcher(UserReposDocument, 'bearer');
|
|
|
16
16
|
/**
|
|
17
17
|
* Fetch stats information for a given username.
|
|
18
18
|
*
|
|
19
|
-
* @param variables Fetcher variables.
|
|
20
|
-
* @param variables.username GitHub username.
|
|
21
|
-
* @param variables.includeMergedPullRequests Include merged pull requests.
|
|
22
|
-
* @param variables.includeDiscussions Include discussions.
|
|
23
|
-
* @param variables.includeDiscussionsAnswers Include discussions answers.
|
|
24
|
-
* @param variables.startTime Time to start the count of total commits.
|
|
25
|
-
* @param variables.ownerAffiliations The owner affiliations to filter by. Default: OWNER.
|
|
26
|
-
* @param variables.includeUserRepositories Whether to include the user's own repositories in the repos contributed to.
|
|
27
|
-
* @param config Deployment config supplying the PAT pool.
|
|
28
|
-
* @returns The stats response, with every fetched page's repos merged in.
|
|
29
|
-
*
|
|
30
19
|
* @description Supports multi-page fetching when the `FETCH_MULTI_PAGE_STARS`
|
|
31
20
|
* env variable is `true` or a fetch limit.
|
|
21
|
+
*
|
|
22
|
+
* @returns The stats response, with every fetched page's repos merged in.
|
|
32
23
|
*/
|
|
33
24
|
const statsFetcher = async ({ username, includeMergedPullRequests, includeDiscussions, includeDiscussionsAnswers, startTime, ownerAffiliations, includeUserRepositories, }, config) => {
|
|
34
25
|
// only the first request carries the stats themselves
|
|
@@ -69,10 +60,10 @@ const statsFetcher = async ({ username, includeMergedPullRequests, includeDiscus
|
|
|
69
60
|
}
|
|
70
61
|
pageRepositories = page.data.data.user?.repositories;
|
|
71
62
|
extraRepoNodes.push(...(pageRepositories?.nodes ?? []));
|
|
72
|
-
fetchedPages
|
|
63
|
+
fetchedPages += 1;
|
|
73
64
|
}
|
|
74
65
|
if (extraRepoNodes.length > 0) {
|
|
75
|
-
//
|
|
66
|
+
// defensive: the merge below is the only place a parsed response is mutated
|
|
76
67
|
stats = structuredClone({
|
|
77
68
|
data: stats.data,
|
|
78
69
|
statusText: stats.statusText,
|
|
@@ -84,22 +75,16 @@ const statsFetcher = async ({ username, includeMergedPullRequests, includeDiscus
|
|
|
84
75
|
/**
|
|
85
76
|
* Fetch total items count using the REST search API.
|
|
86
77
|
*
|
|
87
|
-
* @param variables Fetcher variables.
|
|
88
|
-
* @param token GitHub token.
|
|
89
|
-
* @param context What the retryer supplies each attempt.
|
|
90
|
-
* @param context.fetch Transport to send the request with.
|
|
91
|
-
* @returns The search response, carrying `total_count`.
|
|
92
|
-
*
|
|
93
78
|
* @see https://developer.github.com/v3/search/#search-commits
|
|
79
|
+
*
|
|
80
|
+
* @returns The search response, carrying `total_count`.
|
|
94
81
|
*/
|
|
95
82
|
const fetchTotalItems = (variables, token, { fetch }) => {
|
|
96
83
|
const type = String(variables['type']);
|
|
97
84
|
const filter = String(variables['filter']);
|
|
98
85
|
const repo = variables['repo'];
|
|
99
86
|
const owner = variables['owner'];
|
|
100
|
-
return httpRequest(fetch, `https://api.github.com/search/${type}?per_page=1&q
|
|
101
|
-
buildSearchFilter(repo, owner).replaceAll(' ', '+') +
|
|
102
|
-
filter, {
|
|
87
|
+
return httpRequest(fetch, `https://api.github.com/search/${type}?per_page=1&q=${buildSearchFilter(repo, owner).replaceAll(' ', '+')}${filter}`, {
|
|
103
88
|
method: 'GET',
|
|
104
89
|
headers: {
|
|
105
90
|
'Content-Type': 'application/json',
|
|
@@ -111,21 +96,14 @@ const fetchTotalItems = (variables, token, { fetch }) => {
|
|
|
111
96
|
/**
|
|
112
97
|
* Fetch a total count for a given username via the REST search API.
|
|
113
98
|
*
|
|
114
|
-
* @param props Fetcher props.
|
|
115
|
-
* @param props.username GitHub username.
|
|
116
|
-
* @param props.repo Repositories the search is scoped to.
|
|
117
|
-
* @param props.owner Owners the search is scoped to.
|
|
118
|
-
* @param props.type Search endpoint to hit, `issues` or `commits`.
|
|
119
|
-
* @param props.filter Query fragment appended to the scope filter.
|
|
120
|
-
* @param config Deployment config supplying the PAT pool.
|
|
121
|
-
* @returns Total count.
|
|
122
|
-
*
|
|
123
99
|
* The GraphQL API can't return this.
|
|
124
100
|
* @see https://github.com/anuraghazra/github-readme-stats/issues/92#issuecomment-661026467
|
|
125
101
|
* @see https://github.com/anuraghazra/github-readme-stats/pull/211
|
|
102
|
+
*
|
|
103
|
+
* @returns Total count.
|
|
126
104
|
*/
|
|
127
105
|
const totalItemsFetcher = async ({ username, repo, owner, type, filter, }, config) => {
|
|
128
|
-
if (!
|
|
106
|
+
if (!GITHUB_USERNAME_PATTERN.test(username)) {
|
|
129
107
|
logger.log('Invalid username provided.');
|
|
130
108
|
throw new CardError('Invalid username provided.', {
|
|
131
109
|
code: 'invalid_param',
|
|
@@ -136,13 +114,13 @@ const totalItemsFetcher = async ({ username, repo, owner, type, filter, }, confi
|
|
|
136
114
|
try {
|
|
137
115
|
res = await retryer(fetchTotalItems, { login: username, repo, owner, type, filter }, config);
|
|
138
116
|
}
|
|
139
|
-
catch (
|
|
140
|
-
logger.log(
|
|
141
|
-
throw
|
|
117
|
+
catch (error) {
|
|
118
|
+
logger.log(error);
|
|
119
|
+
throw error;
|
|
142
120
|
}
|
|
143
121
|
const totalCount = res.data.total_count;
|
|
144
|
-
if (totalCount
|
|
145
|
-
logger.error(
|
|
122
|
+
if (typeof totalCount !== 'number' || Number.isNaN(totalCount)) {
|
|
123
|
+
logger.error(`GitHub error: ${JSON.stringify(res.data)}`);
|
|
146
124
|
throw new CardError('Could not fetch data from GitHub REST API.', {
|
|
147
125
|
code: 'upstream',
|
|
148
126
|
});
|
|
@@ -152,16 +130,6 @@ const totalItemsFetcher = async ({ username, repo, owner, type, filter, }, confi
|
|
|
152
130
|
/**
|
|
153
131
|
* Fetch the per-repository counts the REST search API answers, one request each.
|
|
154
132
|
*
|
|
155
|
-
* @param props Fetcher props.
|
|
156
|
-
* @param props.username GitHub username.
|
|
157
|
-
* @param props.repo Repositories the search is scoped to.
|
|
158
|
-
* @param props.owner Owners the search is scoped to.
|
|
159
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
160
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
161
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
162
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
163
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
164
|
-
* @param config Deployment config supplying the PAT pool.
|
|
165
133
|
* @returns Only the counts that were asked for.
|
|
166
134
|
*/
|
|
167
135
|
const fetchRepoUserStats = async ({ username, repo = [], owner = [], include_prs_authored = false, include_prs_commented = false, include_prs_reviewed = false, include_issues_authored = false, include_issues_commented = false, }, config) => {
|
|
@@ -215,10 +183,6 @@ const fetchRepoUserStats = async ({ username, repo = [], owner = [], include_prs
|
|
|
215
183
|
};
|
|
216
184
|
/**
|
|
217
185
|
* Turn a GraphQL `errors` payload into the error to throw.
|
|
218
|
-
*
|
|
219
|
-
* @param errors Errors from the response envelope.
|
|
220
|
-
* @param statusText HTTP status text, used as the error type when GitHub gave a message.
|
|
221
|
-
* @param fallback Message when GitHub gave none.
|
|
222
186
|
*/
|
|
223
187
|
const graphqlError = (errors, statusText, fallback) => {
|
|
224
188
|
logger.error(errors);
|
|
@@ -246,7 +210,7 @@ const fetchTotalContributions = async (username, years, config) => {
|
|
|
246
210
|
if (contribRes.data.errors) {
|
|
247
211
|
throw graphqlError(contribRes.data.errors, contribRes.statusText, 'Something went wrong while trying to retrieve the contributions data using the GraphQL API.');
|
|
248
212
|
}
|
|
249
|
-
const user = contribRes.data.data
|
|
213
|
+
const { user } = contribRes.data.data;
|
|
250
214
|
if (!user) {
|
|
251
215
|
return 0;
|
|
252
216
|
}
|
|
@@ -278,25 +242,22 @@ const REPOS_CONTRIBUTED_TO_ERROR = 'Something went wrong while trying to retriev
|
|
|
278
242
|
*
|
|
279
243
|
* Whether private contributions are included depends on the used PAT.
|
|
280
244
|
*
|
|
281
|
-
* @param canonicalUsername Username as GitHub reports it; `nameWithOwner` uses its
|
|
282
|
-
* casing, which the raw query-string username need not match.
|
|
283
|
-
* @param years Contribution years to walk.
|
|
284
|
-
* @param includeOwnRepos Whether to count the user's own repositories.
|
|
285
|
-
* @param config Deployment config supplying the PAT pool.
|
|
286
245
|
* @returns Count of repositories.
|
|
287
246
|
*/
|
|
288
|
-
const fetchAllTimeReposContributedTo = async (
|
|
247
|
+
const fetchAllTimeReposContributedTo = async (
|
|
248
|
+
/** `nameWithOwner` uses GitHub's casing, which the query-string username need not match */
|
|
249
|
+
canonicalUsername, years, includeOwnRepos, config) => {
|
|
289
250
|
const repos = new Set();
|
|
290
|
-
let pending = years.map(getGitHubYearRange);
|
|
251
|
+
let pending = years.map((year) => getGitHubYearRange(year));
|
|
291
252
|
while (pending.length > 0) {
|
|
292
253
|
const nextPending = [];
|
|
293
254
|
for (const chunk of chunkArray(pending, MAX_RANGES_PER_REQUEST)) {
|
|
294
|
-
const
|
|
295
|
-
const res = await retryer(
|
|
255
|
+
const chunkFetcher = createGraphQLFetcher(buildReposContributedToDocument(chunk, includeOwnRepos), 'bearer');
|
|
256
|
+
const res = await retryer(chunkFetcher, { login: canonicalUsername, maxRepositories: MAX_REPOSITORIES_LIMIT }, config);
|
|
296
257
|
if (res.data.errors) {
|
|
297
258
|
throw graphqlError(res.data.errors, res.statusText, REPOS_CONTRIBUTED_TO_ERROR);
|
|
298
259
|
}
|
|
299
|
-
const user = res.data.data
|
|
260
|
+
const { user } = res.data.data;
|
|
300
261
|
if (!user) {
|
|
301
262
|
throw new CardError(REPOS_CONTRIBUTED_TO_ERROR, { code: 'upstream' });
|
|
302
263
|
}
|
|
@@ -347,26 +308,6 @@ const fetchAllTimeReposContributedTo = async (canonicalUsername, years, includeO
|
|
|
347
308
|
/**
|
|
348
309
|
* Fetch stats for a given username.
|
|
349
310
|
*
|
|
350
|
-
* @param props Fetcher props.
|
|
351
|
-
* @param props.username GitHub username.
|
|
352
|
-
* @param props.include_all_commits Include all commits.
|
|
353
|
-
* @param props.exclude_repo Repositories to exclude.
|
|
354
|
-
* @param props.include_merged_pull_requests Include merged pull requests.
|
|
355
|
-
* @param props.include_discussions Include discussions.
|
|
356
|
-
* @param props.include_discussions_answers Include discussions answers.
|
|
357
|
-
* @param props.commits_year Year to count total commits.
|
|
358
|
-
* @param props.repo Repositories to scope the REST search to.
|
|
359
|
-
* @param props.owner Owners to scope the REST search to.
|
|
360
|
-
* @param props.include_prs_authored Include count of PRs authored.
|
|
361
|
-
* @param props.include_prs_commented Include count of PRs commented.
|
|
362
|
-
* @param props.include_prs_reviewed Include count of PRs reviewed.
|
|
363
|
-
* @param props.include_issues_authored Include count of issues authored.
|
|
364
|
-
* @param props.include_issues_commented Include count of issues commented.
|
|
365
|
-
* @param props.ownerAffiliations Owner affiliations. Default: OWNER.
|
|
366
|
-
* @param props.include_contributions Include all-time contributions.
|
|
367
|
-
* @param props.include_all_time_contribs Include all-time count of repos contributed to.
|
|
368
|
-
* @param props.contribs_include_own_repos Include user-owned repos in contributed-to counts.
|
|
369
|
-
* @param config Deployment config supplying the PAT pool.
|
|
370
311
|
* @returns Stats data.
|
|
371
312
|
*/
|
|
372
313
|
const fetchStats = async ({ username, include_all_commits = false, exclude_repo = [], include_merged_pull_requests = false, include_discussions = false, include_discussions_answers = false, commits_year, repo = [], owner = [], include_prs_authored = false, include_prs_commented = false, include_prs_reviewed = false, include_issues_authored = false, include_issues_commented = false, ownerAffiliations = [], include_contributions = false, include_all_time_contribs = false, contribs_include_own_repos = false, }, config) => {
|
|
@@ -409,7 +350,7 @@ const fetchStats = async ({ username, include_all_commits = false, exclude_repo
|
|
|
409
350
|
// Catch GraphQL errors.
|
|
410
351
|
if (res.data.errors) {
|
|
411
352
|
logger.error(res.data.errors);
|
|
412
|
-
const firstError = res.data.errors
|
|
353
|
+
const [firstError] = res.data.errors;
|
|
413
354
|
if (firstError?.type === 'NOT_FOUND') {
|
|
414
355
|
throw new CardError(firstError.message || 'Could not fetch user.', {
|
|
415
356
|
code: 'not_found',
|
|
@@ -424,7 +365,7 @@ const fetchStats = async ({ username, include_all_commits = false, exclude_repo
|
|
|
424
365
|
}
|
|
425
366
|
throw new CardError('Something went wrong while trying to retrieve the stats data using the GraphQL API.', { code: 'upstream' });
|
|
426
367
|
}
|
|
427
|
-
const user = res.data.data
|
|
368
|
+
const { user } = res.data.data;
|
|
428
369
|
if (!user) {
|
|
429
370
|
throw new CardError('Could not fetch user.', {
|
|
430
371
|
code: 'not_found',
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import type { CardConfig } from '../common/config.
|
|
2
|
-
import type { TopLangData } from './types.
|
|
1
|
+
import type { CardConfig } from '../common/config.ts';
|
|
2
|
+
import type { TopLangData } from './types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Fetch top languages for a given username.
|
|
5
5
|
*
|
|
6
|
-
* @param props Fetcher props.
|
|
7
|
-
* @param props.username GitHub username.
|
|
8
|
-
* @param props.exclude_repo List of repositories to exclude. Default: [].
|
|
9
|
-
* @param props.size_weight Weightage to be given to size.
|
|
10
|
-
* @param props.count_weight Weightage to be given to count.
|
|
11
|
-
* @param props.ownerAffiliations The owner affiliations to filter by. Default: OWNER.
|
|
12
|
-
* @param config Deployment config supplying the PAT pool.
|
|
13
6
|
* @returns Top languages data.
|
|
14
7
|
*/
|
|
15
8
|
declare const fetchTopLanguages: ({ username, exclude_repo, size_weight, count_weight, ownerAffiliations, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-languages.d.ts","sourceRoot":"","sources":["../../src/fetchers/top-languages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAatD,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,YAAY,CAAC;AAIpD
|
|
1
|
+
{"version":3,"file":"top-languages.d.ts","sourceRoot":"","sources":["../../src/fetchers/top-languages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAatD,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,YAAY,CAAC;AAIpD;;;;GAIG;AACH,QAAA,MAAM,iBAAiB,8EAOlB;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACnC,UACO,UAAU,KACjB,OAAO,CAAC,WAAW,CAgFrB,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { CardError, USER_NOT_FOUND } from '../common/error.js';
|
|
2
|
-
import { wrapTextMultiline } from '../common/fmt.js';
|
|
3
2
|
import { createGraphQLFetcher } from '../common/http.js';
|
|
4
3
|
import { logger } from '../common/log.js';
|
|
5
4
|
import { parseOwnerAffiliations } from '../common/ops.js';
|
|
5
|
+
import { wrapTextMultiline } from '../common/render.js';
|
|
6
6
|
import { retryer } from '../common/retryer.js';
|
|
7
7
|
import { TopLanguagesDocument } from '../graphql/generated/top-languages.js';
|
|
8
8
|
const fetcher = createGraphQLFetcher(TopLanguagesDocument, 'token');
|
|
9
9
|
/**
|
|
10
10
|
* Fetch top languages for a given username.
|
|
11
11
|
*
|
|
12
|
-
* @param props Fetcher props.
|
|
13
|
-
* @param props.username GitHub username.
|
|
14
|
-
* @param props.exclude_repo List of repositories to exclude. Default: [].
|
|
15
|
-
* @param props.size_weight Weightage to be given to size.
|
|
16
|
-
* @param props.count_weight Weightage to be given to count.
|
|
17
|
-
* @param props.ownerAffiliations The owner affiliations to filter by. Default: OWNER.
|
|
18
|
-
* @param config Deployment config supplying the PAT pool.
|
|
19
12
|
* @returns Top languages data.
|
|
20
13
|
*/
|
|
21
14
|
const fetchTopLanguages = async ({ username, exclude_repo = [], size_weight = 1, count_weight = 0, ownerAffiliations = [], }, config) => {
|
|
@@ -29,7 +22,7 @@ const fetchTopLanguages = async ({ username, exclude_repo = [], size_weight = 1,
|
|
|
29
22
|
}, config);
|
|
30
23
|
if (res.data.errors) {
|
|
31
24
|
logger.error(res.data.errors);
|
|
32
|
-
const firstError = res.data.errors
|
|
25
|
+
const [firstError] = res.data.errors;
|
|
33
26
|
if (firstError?.type === 'NOT_FOUND') {
|
|
34
27
|
throw new CardError(firstError.message || 'Could not fetch user.', {
|
|
35
28
|
code: 'not_found',
|
|
@@ -47,43 +40,34 @@ const fetchTopLanguages = async ({ username, exclude_repo = [], size_weight = 1,
|
|
|
47
40
|
const repoToHide = {};
|
|
48
41
|
const allExcludedRepos = [...exclude_repo, ...config.excludeRepositories];
|
|
49
42
|
// populate repoToHide map for quick lookup while filtering out
|
|
50
|
-
|
|
43
|
+
for (const repoName of allExcludedRepos) {
|
|
51
44
|
repoToHide[repoName] = true;
|
|
52
|
-
}
|
|
45
|
+
}
|
|
53
46
|
// filter out repositories to be hidden
|
|
54
47
|
const repoNodes = (res.data.data.user?.repositories.nodes ?? []).filter((node) => !!node && !repoToHide[node.name]);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const languageEdges = repoNodes.reduce((acc, repo) => {
|
|
48
|
+
let languageEdges = [];
|
|
49
|
+
for (const repo of repoNodes) {
|
|
58
50
|
const edges = (repo.languages?.edges ?? []).filter((edge) => !!edge);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
if (edges.length > 0) {
|
|
52
|
+
languageEdges = [...edges, ...languageEdges];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// accumulate size and repo count per language, each read back off the language's own entry
|
|
62
56
|
const languageMap = {};
|
|
63
|
-
let repoCount = 0;
|
|
64
57
|
for (const edge of languageEdges) {
|
|
65
58
|
const existing = languageMap[edge.node.name];
|
|
66
|
-
// same language seen again: add to its size and bump count; else reset to 1
|
|
67
|
-
let langSize = edge.size;
|
|
68
|
-
if (existing && edge.node.name === existing.name) {
|
|
69
|
-
langSize = edge.size + existing.size;
|
|
70
|
-
repoCount += 1;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
repoCount = 1;
|
|
74
|
-
}
|
|
75
59
|
languageMap[edge.node.name] = {
|
|
76
60
|
name: edge.node.name,
|
|
77
61
|
color: edge.node.color,
|
|
78
|
-
size:
|
|
79
|
-
count:
|
|
62
|
+
size: edge.size + (existing?.size ?? 0),
|
|
63
|
+
count: (existing?.count ?? 0) + 1,
|
|
80
64
|
};
|
|
81
65
|
}
|
|
82
66
|
// comparison index calculation
|
|
83
67
|
for (const lang of Object.values(languageMap)) {
|
|
84
|
-
lang.size =
|
|
68
|
+
lang.size = lang.size ** size_weight * lang.count ** count_weight;
|
|
85
69
|
}
|
|
86
70
|
// return languages sorted by (weighted) size, descending
|
|
87
|
-
return Object.fromEntries(Object.entries(languageMap).
|
|
71
|
+
return Object.fromEntries(Object.entries(languageMap).toSorted(([, a], [, b]) => b.size - a.size));
|
|
88
72
|
};
|
|
89
73
|
export { fetchTopLanguages };
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import type { CardConfig } from '../common/config.
|
|
2
|
-
import type { WakaTimeData } from './types.
|
|
1
|
+
import type { CardConfig } from '../common/config.ts';
|
|
2
|
+
import type { WakaTimeData } from './types.ts';
|
|
3
3
|
/**
|
|
4
4
|
* WakaTime data fetcher.
|
|
5
5
|
*
|
|
6
6
|
* WakaTime needs no GitHub token; the config is here for the transport it carries.
|
|
7
7
|
*
|
|
8
|
-
* @param props Fetcher props.
|
|
9
|
-
* @param props.username WakaTime username.
|
|
10
|
-
* @param props.api_domain Optional WakaTime API domain (defaults to `wakatime.com`).
|
|
11
|
-
* @param config Deployment config supplying the transport.
|
|
12
8
|
* @returns WakaTime data response.
|
|
13
9
|
*/
|
|
14
10
|
declare const fetchWakatimeStats: ({ username, api_domain, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/fetchers/wakatime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/fetchers/wakatime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,8BAInB;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,UACO,UAAU,KACjB,OAAO,CAAC,YAAY,CA2BtB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|