@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.
Files changed (208) hide show
  1. package/README.md +0 -10
  2. package/build/api/api-result.d.ts +6 -7
  3. package/build/api/api-result.d.ts.map +1 -1
  4. package/build/api/api-result.js +4 -5
  5. package/build/api/gist.d.ts +3 -10
  6. package/build/api/gist.d.ts.map +1 -1
  7. package/build/api/gist.js +4 -11
  8. package/build/api/index.d.ts +12 -12
  9. package/build/api/params.d.ts +11 -8
  10. package/build/api/params.d.ts.map +1 -1
  11. package/build/api/params.js +16 -14
  12. package/build/api/pin.d.ts +3 -19
  13. package/build/api/pin.d.ts.map +1 -1
  14. package/build/api/pin.js +6 -22
  15. package/build/api/stats.d.ts +10 -4
  16. package/build/api/stats.d.ts.map +1 -1
  17. package/build/api/stats.js +6 -32
  18. package/build/api/top-langs.d.ts +12 -6
  19. package/build/api/top-langs.d.ts.map +1 -1
  20. package/build/api/top-langs.js +6 -26
  21. package/build/api/wakatime.d.ts +13 -5
  22. package/build/api/wakatime.d.ts.map +1 -1
  23. package/build/api/wakatime.js +4 -21
  24. package/build/calculateRank.d.ts +0 -9
  25. package/build/calculateRank.d.ts.map +1 -1
  26. package/build/calculateRank.js +12 -17
  27. package/build/cards/gist.d.ts +2 -4
  28. package/build/cards/gist.d.ts.map +1 -1
  29. package/build/cards/gist.js +27 -36
  30. package/build/cards/options.d.ts +1 -1
  31. package/build/cards/repo.d.ts +2 -4
  32. package/build/cards/repo.d.ts.map +1 -1
  33. package/build/cards/repo.js +61 -93
  34. package/build/cards/stats.d.ts +3 -8
  35. package/build/cards/stats.d.ts.map +1 -1
  36. package/build/cards/stats.js +119 -165
  37. package/build/cards/top-languages.d.ts +5 -31
  38. package/build/cards/top-languages.d.ts.map +1 -1
  39. package/build/cards/top-languages.js +176 -384
  40. package/build/cards/wakatime.d.ts +4 -6
  41. package/build/cards/wakatime.d.ts.map +1 -1
  42. package/build/cards/wakatime.js +118 -185
  43. package/build/common/Card.d.ts +14 -62
  44. package/build/common/Card.d.ts.map +1 -1
  45. package/build/common/Card.js +97 -199
  46. package/build/common/I18n.d.ts +0 -6
  47. package/build/common/I18n.d.ts.map +1 -1
  48. package/build/common/I18n.js +3 -6
  49. package/build/common/color.d.ts +4 -17
  50. package/build/common/color.d.ts.map +1 -1
  51. package/build/common/color.js +67 -49
  52. package/build/common/config.d.ts +4 -14
  53. package/build/common/config.d.ts.map +1 -1
  54. package/build/common/config.js +3 -16
  55. package/build/common/constants.d.ts +4 -2
  56. package/build/common/constants.d.ts.map +1 -1
  57. package/build/common/constants.js +3 -1
  58. package/build/common/date.d.ts +0 -2
  59. package/build/common/date.d.ts.map +1 -1
  60. package/build/common/date.js +0 -2
  61. package/build/common/emojiMap.d.ts +8 -0
  62. package/build/common/emojiMap.d.ts.map +1 -0
  63. package/build/common/emojiMap.js +10 -0
  64. package/build/common/emojiMap.json +1915 -0
  65. package/build/common/error.d.ts +1 -10
  66. package/build/common/error.d.ts.map +1 -1
  67. package/build/common/error.js +1 -10
  68. package/build/common/fmt.d.ts +3 -15
  69. package/build/common/fmt.d.ts.map +1 -1
  70. package/build/common/fmt.js +7 -35
  71. package/build/common/http.d.ts +2 -7
  72. package/build/common/http.d.ts.map +1 -1
  73. package/build/common/http.js +8 -17
  74. package/build/common/icons.d.ts +18 -20
  75. package/build/common/icons.d.ts.map +1 -1
  76. package/build/common/icons.js +103 -67
  77. package/build/common/languageColors.d.ts +0 -1
  78. package/build/common/languageColors.d.ts.map +1 -1
  79. package/build/common/languageColors.js +1 -4
  80. package/build/common/languageColors.json +18 -2
  81. package/build/common/ops.d.ts +3 -14
  82. package/build/common/ops.d.ts.map +1 -1
  83. package/build/common/ops.js +19 -30
  84. package/build/common/render.d.ts +28 -82
  85. package/build/common/render.d.ts.map +1 -1
  86. package/build/common/render.js +175 -211
  87. package/build/common/retryer.d.ts +2 -7
  88. package/build/common/retryer.d.ts.map +1 -1
  89. package/build/common/retryer.js +4 -11
  90. package/build/fetchers/gist.d.ts +2 -5
  91. package/build/fetchers/gist.d.ts.map +1 -1
  92. package/build/fetchers/gist.js +1 -5
  93. package/build/fetchers/index.d.ts +12 -12
  94. package/build/fetchers/repo.d.ts +2 -11
  95. package/build/fetchers/repo.d.ts.map +1 -1
  96. package/build/fetchers/repo.js +20 -33
  97. package/build/fetchers/stats.d.ts +2 -32
  98. package/build/fetchers/stats.d.ts.map +1 -1
  99. package/build/fetchers/stats.js +27 -86
  100. package/build/fetchers/top-languages.d.ts +2 -9
  101. package/build/fetchers/top-languages.d.ts.map +1 -1
  102. package/build/fetchers/top-languages.js +15 -31
  103. package/build/fetchers/types.d.ts +1 -1
  104. package/build/fetchers/wakatime.d.ts +2 -6
  105. package/build/fetchers/wakatime.d.ts.map +1 -1
  106. package/build/fetchers/wakatime.js +1 -5
  107. package/build/graphql/contributionsDocument.d.ts +3 -3
  108. package/build/graphql/contributionsDocument.d.ts.map +1 -1
  109. package/build/graphql/contributionsDocument.js +0 -1
  110. package/build/graphql/generated/gist.d.ts +1 -1
  111. package/build/graphql/generated/repo.d.ts +1 -1
  112. package/build/graphql/generated/stats.d.ts +3 -3
  113. package/build/graphql/generated/top-languages.d.ts +2 -2
  114. package/build/graphql/graphqlDocument.d.ts +0 -1
  115. package/build/graphql/graphqlDocument.d.ts.map +1 -1
  116. package/build/graphql/graphqlDocument.js +0 -1
  117. package/build/graphql/reposContributedToDocument.d.ts +4 -5
  118. package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
  119. package/build/graphql/reposContributedToDocument.js +0 -2
  120. package/build/markup/css.d.ts +35 -0
  121. package/build/markup/css.d.ts.map +1 -0
  122. package/build/markup/css.js +64 -0
  123. package/build/markup/element.d.ts +41 -0
  124. package/build/markup/element.d.ts.map +1 -0
  125. package/build/markup/element.js +127 -0
  126. package/build/markup/html.d.ts +13 -0
  127. package/build/markup/html.d.ts.map +1 -0
  128. package/build/markup/html.js +27 -0
  129. package/build/markup/index.d.ts +9 -0
  130. package/build/markup/index.d.ts.map +1 -0
  131. package/build/markup/index.js +6 -0
  132. package/build/markup/serialize.d.ts +16 -0
  133. package/build/markup/serialize.d.ts.map +1 -0
  134. package/build/markup/serialize.js +17 -0
  135. package/build/themes/index.d.ts +332 -333
  136. package/build/themes/index.d.ts.map +1 -1
  137. package/build/themes/index.js +1 -1
  138. package/build/translations.d.ts +2 -6
  139. package/build/translations.d.ts.map +1 -1
  140. package/build/translations.js +621 -628
  141. package/package.json +17 -26
  142. package/src/api/api-result.ts +10 -9
  143. package/src/api/gist.ts +11 -18
  144. package/src/api/index.ts +12 -12
  145. package/src/api/params.ts +27 -21
  146. package/src/api/pin.ts +13 -28
  147. package/src/api/stats.ts +13 -39
  148. package/src/api/top-langs.ts +13 -33
  149. package/src/api/wakatime.ts +11 -28
  150. package/src/calculateRank.ts +12 -23
  151. package/src/cards/gist.ts +40 -43
  152. package/src/cards/options.ts +1 -1
  153. package/src/cards/repo.ts +97 -107
  154. package/src/cards/stats.ts +165 -184
  155. package/src/cards/top-languages.ts +297 -413
  156. package/src/cards/wakatime.ts +193 -221
  157. package/src/common/Card.ts +165 -217
  158. package/src/common/I18n.ts +3 -6
  159. package/src/common/color.ts +80 -57
  160. package/src/common/config.ts +5 -18
  161. package/src/common/constants.ts +5 -2
  162. package/src/common/date.ts +0 -2
  163. package/src/common/emojiMap.json +1915 -0
  164. package/src/common/emojiMap.ts +13 -0
  165. package/src/common/error.ts +2 -11
  166. package/src/common/fmt.ts +7 -44
  167. package/src/common/http.ts +9 -15
  168. package/src/common/icons.ts +117 -42
  169. package/src/common/languageColors.json +18 -2
  170. package/src/common/languageColors.ts +1 -4
  171. package/src/common/ops.ts +26 -34
  172. package/src/common/render.ts +279 -232
  173. package/src/common/retryer.ts +8 -15
  174. package/src/fetchers/gist.ts +8 -12
  175. package/src/fetchers/index.ts +12 -12
  176. package/src/fetchers/repo.ts +27 -40
  177. package/src/fetchers/stats.ts +44 -102
  178. package/src/fetchers/top-languages.ts +26 -40
  179. package/src/fetchers/types.ts +1 -1
  180. package/src/fetchers/wakatime.ts +5 -9
  181. package/src/graphql/contributionsDocument.ts +7 -5
  182. package/src/graphql/generated/gist.ts +1 -1
  183. package/src/graphql/generated/repo.ts +1 -1
  184. package/src/graphql/generated/stats.ts +2 -2
  185. package/src/graphql/generated/top-languages.ts +2 -2
  186. package/src/graphql/graphqlDocument.ts +0 -1
  187. package/src/graphql/reposContributedToDocument.ts +6 -7
  188. package/src/markup/css.ts +118 -0
  189. package/src/markup/element.ts +246 -0
  190. package/src/markup/html.ts +34 -0
  191. package/src/markup/index.ts +9 -0
  192. package/src/markup/serialize.ts +27 -0
  193. package/src/themes/index.ts +1 -1
  194. package/src/translations.ts +622 -629
  195. package/build/cards/index.d.ts +0 -11
  196. package/build/cards/index.d.ts.map +0 -1
  197. package/build/cards/index.js +0 -7
  198. package/build/common/html.d.ts +0 -8
  199. package/build/common/html.d.ts.map +0 -1
  200. package/build/common/html.js +0 -14
  201. package/build/index.d.ts +0 -15
  202. package/build/index.d.ts.map +0 -1
  203. package/build/index.js +0 -10
  204. package/src/_emoji-name-map.d.ts +0 -10
  205. package/src/_github-username-regex.d.ts +0 -4
  206. package/src/cards/index.ts +0 -21
  207. package/src/common/html.ts +0 -17
  208. package/src/index.ts +0 -18
@@ -1,11 +1,8 @@
1
- import type { CardConfig } from '../common/config.js';
2
- import type { GistData } from './types.js';
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;AA+B3C;;;;;;;GAOG;AACH,QAAA,MAAM,SAAS,GACb,QAAQ;IAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EAClC,QAAQ,UAAU,KACjB,OAAO,CAAC,QAAQ,CA8BlB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,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"}
@@ -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.gist;
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.js';
2
- export { fetchRepo } from './repo.js';
3
- export { fetchRepoUserStats, fetchStats } from './stats.js';
4
- export { fetchTopLanguages } from './top-languages.js';
5
- export { fetchWakatimeStats } from './wakatime.js';
6
- export type { GistData, Lang, RepoUserStats, RepositoryData, StatsData, TopLangData, WakaTimeData, WakaTimeLang, } from './types.js';
7
- export { CardConfig } from '../common/config.js';
8
- export type { CardConfigInit, PersonalAccessToken } from '../common/config.js';
9
- export type { FetchLike } from '../common/http.js';
10
- export { retryer } from '../common/retryer.js';
11
- export { CardError } from '../common/error.js';
12
- export type { ErrorCode } from '../common/error.js';
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
@@ -1,17 +1,8 @@
1
- import type { CardConfig } from '../common/config.js';
2
- import type { RepositoryData } from './types.js';
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;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,SAAS,GACb,+IAQG;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,EACD,QAAQ,UAAU,KACjB,OAAO,CAAC,cAAc,CA2FxB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
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"}
@@ -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
- let owner = username;
24
- if (reponame && reponame.includes('/')) {
25
- const [parsedOwner, parsedRepo] = reponame.split('/');
26
- owner = parsedOwner ?? '';
27
- reponame = parsedRepo ?? '';
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
- if (owner && !username) {
30
- username = owner;
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 (!username) {
26
+ if (!login) {
39
27
  throw CardError.missingParam(['username'], urlExample);
40
28
  }
41
- if (!reponame) {
29
+ if (!repo) {
42
30
  throw CardError.missingParam(['repo'], urlExample);
43
31
  }
44
- // the guards above leave `username` set, and `owner` mirrors it when `repo` carried none
45
- const repoOwner = owner ?? username;
46
- const res = await retryer(fetcher, { login: repoOwner, repo: reponame }, config);
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.repository;
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}/${reponame}`],
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.repository;
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}/${reponame}`],
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.js';
2
- import type { RepoUserStats, StatsData } from './types.js';
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":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAuBtD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA+M3D;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,kBAAkB,GACtB,kJASG;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,EACD,QAAQ,UAAU,KACjB,OAAO,CAAC,aAAa,CA+DvB,CAAC;AAsLF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,QAAA,MAAM,UAAU,GACd,oXAmBG;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,EACD,QAAQ,UAAU,KACjB,OAAO,CAAC,SAAS,CA+JnB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC"}
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"}
@@ -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
- // deep copy to avoid mutating the response cached by the frontend
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 (!githubUsernameRegex.test(username)) {
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 (err) {
140
- logger.log(err);
141
- throw err;
117
+ catch (error) {
118
+ logger.log(error);
119
+ throw error;
142
120
  }
143
121
  const totalCount = res.data.total_count;
144
- if (totalCount === undefined || isNaN(totalCount)) {
145
- logger.error('GitHub error: ' + JSON.stringify(res.data));
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.user;
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 (canonicalUsername, years, includeOwnRepos, config) => {
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 fetcher = createGraphQLFetcher(buildReposContributedToDocument(chunk, includeOwnRepos), 'bearer');
295
- const res = await retryer(fetcher, { login: canonicalUsername, maxRepositories: MAX_REPOSITORIES_LIMIT }, config);
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.user;
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[0];
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.user;
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.js';
2
- import type { TopLangData } from './types.js';
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;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,iBAAiB,GACrB,2EAMG;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,EACD,QAAQ,UAAU,KACjB,OAAO,CAAC,WAAW,CAuFrB,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
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[0];
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
- allExcludedRepos.forEach((repoName) => {
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
- // flatten edges across repos. Order matters: `concat(acc)` prepends, and the
56
- // shared repoCount below depends on visitation order.
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
- return edges.length > 0 ? edges.concat(acc) : acc;
60
- }, []);
61
- // accumulate size and repo count per language
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: langSize,
79
- count: repoCount,
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 = Math.pow(lang.size, size_weight) * Math.pow(lang.count, count_weight);
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).sort(([, a], [, b]) => b.size - a.size));
71
+ return Object.fromEntries(Object.entries(languageMap).toSorted(([, a], [, b]) => b.size - a.size));
88
72
  };
89
73
  export { fetchTopLanguages };
@@ -1,4 +1,4 @@
1
- import type { RepoInfoFragment } from '../graphql/generated/repo.js';
1
+ import type { RepoInfoFragment } from '../graphql/generated/repo.ts';
2
2
  export interface GistData {
3
3
  name: string;
4
4
  nameWithOwner: string;
@@ -1,14 +1,10 @@
1
- import type { CardConfig } from '../common/config.js';
2
- import type { WakaTimeData } from './types.js';
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;;;;;;;;;;GAUG;AACH,QAAA,MAAM,kBAAkB,GACtB,2BAGG;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,EACD,QAAQ,UAAU,KACjB,OAAO,CAAC,YAAY,CA2BtB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
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"}