@stats-forge/github-stats-forge-core 0.0.1

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 (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/build/api/api-result.d.ts +44 -0
  4. package/build/api/api-result.d.ts.map +1 -0
  5. package/build/api/api-result.js +33 -0
  6. package/build/api/gist.d.ts +29 -0
  7. package/build/api/gist.d.ts.map +1 -0
  8. package/build/api/gist.js +52 -0
  9. package/build/api/index.d.ts +13 -0
  10. package/build/api/index.d.ts.map +1 -0
  11. package/build/api/index.js +8 -0
  12. package/build/api/params.d.ts +93 -0
  13. package/build/api/params.d.ts.map +1 -0
  14. package/build/api/params.js +145 -0
  15. package/build/api/pin.d.ts +47 -0
  16. package/build/api/pin.d.ts.map +1 -0
  17. package/build/api/pin.js +87 -0
  18. package/build/api/stats.d.ts +42 -0
  19. package/build/api/stats.d.ts.map +1 -0
  20. package/build/api/stats.js +132 -0
  21. package/build/api/top-langs.d.ts +37 -0
  22. package/build/api/top-langs.d.ts.map +1 -0
  23. package/build/api/top-langs.js +101 -0
  24. package/build/api/wakatime.d.ts +34 -0
  25. package/build/api/wakatime.d.ts.map +1 -0
  26. package/build/api/wakatime.js +91 -0
  27. package/build/calculateRank.d.ts +29 -0
  28. package/build/calculateRank.d.ts.map +1 -0
  29. package/build/calculateRank.js +58 -0
  30. package/build/cards/gist.d.ts +16 -0
  31. package/build/cards/gist.d.ts.map +1 -0
  32. package/build/cards/gist.js +119 -0
  33. package/build/cards/index.d.ts +11 -0
  34. package/build/cards/index.d.ts.map +1 -0
  35. package/build/cards/index.js +7 -0
  36. package/build/cards/options.d.ts +19 -0
  37. package/build/cards/options.d.ts.map +1 -0
  38. package/build/cards/options.js +1 -0
  39. package/build/cards/repo.d.ts +25 -0
  40. package/build/cards/repo.d.ts.map +1 -0
  41. package/build/cards/repo.js +276 -0
  42. package/build/cards/stats.d.ts +37 -0
  43. package/build/cards/stats.d.ts.map +1 -0
  44. package/build/cards/stats.js +457 -0
  45. package/build/cards/top-languages.d.ts +153 -0
  46. package/build/cards/top-languages.d.ts.map +1 -0
  47. package/build/cards/top-languages.js +805 -0
  48. package/build/cards/wakatime.d.ts +31 -0
  49. package/build/cards/wakatime.d.ts.map +1 -0
  50. package/build/cards/wakatime.js +376 -0
  51. package/build/common/Card.d.ts +121 -0
  52. package/build/common/Card.d.ts.map +1 -0
  53. package/build/common/Card.js +305 -0
  54. package/build/common/I18n.d.ts +27 -0
  55. package/build/common/I18n.d.ts.map +1 -0
  56. package/build/common/I18n.js +35 -0
  57. package/build/common/color.d.ts +112 -0
  58. package/build/common/color.d.ts.map +1 -0
  59. package/build/common/color.js +188 -0
  60. package/build/common/config.d.ts +53 -0
  61. package/build/common/config.d.ts.map +1 -0
  62. package/build/common/config.js +87 -0
  63. package/build/common/constants.d.ts +7 -0
  64. package/build/common/constants.d.ts.map +1 -0
  65. package/build/common/constants.js +9 -0
  66. package/build/common/date.d.ts +29 -0
  67. package/build/common/date.d.ts.map +1 -0
  68. package/build/common/date.js +23 -0
  69. package/build/common/error.d.ts +87 -0
  70. package/build/common/error.d.ts.map +1 -0
  71. package/build/common/error.js +108 -0
  72. package/build/common/fmt.d.ts +28 -0
  73. package/build/common/fmt.d.ts.map +1 -0
  74. package/build/common/fmt.js +68 -0
  75. package/build/common/html.d.ts +8 -0
  76. package/build/common/html.d.ts.map +1 -0
  77. package/build/common/html.js +14 -0
  78. package/build/common/http.d.ts +53 -0
  79. package/build/common/http.d.ts.map +1 -0
  80. package/build/common/http.js +47 -0
  81. package/build/common/icons.d.ts +28 -0
  82. package/build/common/icons.d.ts.map +1 -0
  83. package/build/common/icons.js +77 -0
  84. package/build/common/languageColors.d.ts +11 -0
  85. package/build/common/languageColors.d.ts.map +1 -0
  86. package/build/common/languageColors.js +15 -0
  87. package/build/common/languageColors.json +678 -0
  88. package/build/common/log.d.ts +9 -0
  89. package/build/common/log.d.ts.map +1 -0
  90. package/build/common/log.js +8 -0
  91. package/build/common/ops.d.ts +59 -0
  92. package/build/common/ops.d.ts.map +1 -0
  93. package/build/common/ops.js +115 -0
  94. package/build/common/render.d.ts +196 -0
  95. package/build/common/render.d.ts.map +1 -0
  96. package/build/common/render.js +474 -0
  97. package/build/common/retryer.d.ts +36 -0
  98. package/build/common/retryer.d.ts.map +1 -0
  99. package/build/common/retryer.js +67 -0
  100. package/build/fetchers/gist.d.ts +15 -0
  101. package/build/fetchers/gist.d.ts.map +1 -0
  102. package/build/fetchers/gist.js +68 -0
  103. package/build/fetchers/index.d.ts +13 -0
  104. package/build/fetchers/index.d.ts.map +1 -0
  105. package/build/fetchers/index.js +10 -0
  106. package/build/fetchers/repo.d.ts +27 -0
  107. package/build/fetchers/repo.d.ts.map +1 -0
  108. package/build/fetchers/repo.js +100 -0
  109. package/build/fetchers/stats.d.ts +74 -0
  110. package/build/fetchers/stats.d.ts.map +1 -0
  111. package/build/fetchers/stats.js +498 -0
  112. package/build/fetchers/top-languages.d.ts +23 -0
  113. package/build/fetchers/top-languages.d.ts.map +1 -0
  114. package/build/fetchers/top-languages.js +89 -0
  115. package/build/fetchers/types.d.ts +130 -0
  116. package/build/fetchers/types.d.ts.map +1 -0
  117. package/build/fetchers/types.js +1 -0
  118. package/build/fetchers/wakatime.d.ts +19 -0
  119. package/build/fetchers/wakatime.d.ts.map +1 -0
  120. package/build/fetchers/wakatime.js +36 -0
  121. package/build/graphql/contributionsDocument.d.ts +18 -0
  122. package/build/graphql/contributionsDocument.d.ts.map +1 -0
  123. package/build/graphql/contributionsDocument.js +30 -0
  124. package/build/graphql/generated/common.d.ts +42 -0
  125. package/build/graphql/generated/common.d.ts.map +1 -0
  126. package/build/graphql/generated/common.js +2 -0
  127. package/build/graphql/generated/gist.d.ts +44 -0
  128. package/build/graphql/generated/gist.d.ts.map +1 -0
  129. package/build/graphql/generated/gist.js +27 -0
  130. package/build/graphql/generated/repo.d.ts +67 -0
  131. package/build/graphql/generated/repo.d.ts.map +1 -0
  132. package/build/graphql/generated/repo.js +30 -0
  133. package/build/graphql/generated/stats.d.ts +150 -0
  134. package/build/graphql/generated/stats.d.ts.map +1 -0
  135. package/build/graphql/generated/stats.js +95 -0
  136. package/build/graphql/generated/top-languages.d.ts +54 -0
  137. package/build/graphql/generated/top-languages.d.ts.map +1 -0
  138. package/build/graphql/generated/top-languages.js +27 -0
  139. package/build/graphql/graphqlDocument.d.ts +22 -0
  140. package/build/graphql/graphqlDocument.d.ts.map +1 -0
  141. package/build/graphql/graphqlDocument.js +8 -0
  142. package/build/graphql/reposContributedToDocument.d.ts +27 -0
  143. package/build/graphql/reposContributedToDocument.d.ts.map +1 -0
  144. package/build/graphql/reposContributedToDocument.js +59 -0
  145. package/build/index.d.ts +15 -0
  146. package/build/index.d.ts.map +1 -0
  147. package/build/index.js +10 -0
  148. package/build/themes/index.d.ts +505 -0
  149. package/build/themes/index.d.ts.map +1 -0
  150. package/build/themes/index.js +505 -0
  151. package/build/translations.d.ts +1153 -0
  152. package/build/translations.d.ts.map +1 -0
  153. package/build/translations.js +1156 -0
  154. package/package.json +114 -0
  155. package/src/_emoji-name-map.d.ts +10 -0
  156. package/src/_github-username-regex.d.ts +4 -0
  157. package/src/api/api-result.ts +69 -0
  158. package/src/api/gist.ts +66 -0
  159. package/src/api/index.ts +16 -0
  160. package/src/api/params.ts +221 -0
  161. package/src/api/pin.ts +126 -0
  162. package/src/api/stats.ts +195 -0
  163. package/src/api/top-langs.ts +150 -0
  164. package/src/api/wakatime.ts +130 -0
  165. package/src/calculateRank.ts +91 -0
  166. package/src/cards/gist.ts +169 -0
  167. package/src/cards/index.ts +21 -0
  168. package/src/cards/options.ts +18 -0
  169. package/src/cards/repo.ts +376 -0
  170. package/src/cards/stats.ts +615 -0
  171. package/src/cards/top-languages.ts +1077 -0
  172. package/src/cards/wakatime.ts +501 -0
  173. package/src/common/Card.ts +364 -0
  174. package/src/common/I18n.ts +51 -0
  175. package/src/common/color.ts +296 -0
  176. package/src/common/config.ts +118 -0
  177. package/src/common/constants.ts +12 -0
  178. package/src/common/date.ts +34 -0
  179. package/src/common/error.ts +163 -0
  180. package/src/common/fmt.ts +86 -0
  181. package/src/common/html.ts +17 -0
  182. package/src/common/http.ts +98 -0
  183. package/src/common/icons.ts +80 -0
  184. package/src/common/languageColors.json +678 -0
  185. package/src/common/languageColors.ts +19 -0
  186. package/src/common/log.ts +12 -0
  187. package/src/common/ops.ts +145 -0
  188. package/src/common/render.ts +641 -0
  189. package/src/common/retryer.ts +111 -0
  190. package/src/fetchers/gist.ts +82 -0
  191. package/src/fetchers/index.ts +25 -0
  192. package/src/fetchers/repo.ts +140 -0
  193. package/src/fetchers/stats.ts +742 -0
  194. package/src/fetchers/top-languages.ts +134 -0
  195. package/src/fetchers/types.ts +136 -0
  196. package/src/fetchers/wakatime.ts +56 -0
  197. package/src/graphql/contributionsDocument.ts +44 -0
  198. package/src/graphql/generated/common.ts +26 -0
  199. package/src/graphql/generated/gist.ts +56 -0
  200. package/src/graphql/generated/repo.ts +79 -0
  201. package/src/graphql/generated/stats.ts +180 -0
  202. package/src/graphql/generated/top-languages.ts +66 -0
  203. package/src/graphql/graphqlDocument.ts +25 -0
  204. package/src/graphql/queries/gist.graphql +25 -0
  205. package/src/graphql/queries/repo.graphql +28 -0
  206. package/src/graphql/queries/stats.graphql +113 -0
  207. package/src/graphql/queries/top-languages.graphql +27 -0
  208. package/src/graphql/reposContributedToDocument.ts +83 -0
  209. package/src/index.ts +18 -0
  210. package/src/themes/index.ts +519 -0
  211. package/src/translations.ts +1169 -0
@@ -0,0 +1,180 @@
1
+ // Generated file — see .github/CONTRIBUTING.md
2
+
3
+ /** Internal type. DO NOT USE DIRECTLY. */
4
+ type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
5
+ import { graphqlDocument } from '../graphqlDocument.js';
6
+
7
+ import type * as Types from './common.js';
8
+ export type RepoNodeFragment = { name: string; stargazerCount: number };
9
+
10
+ export type RepoStarsFragment = {
11
+ repositories: {
12
+ totalCount: number;
13
+ nodes: Array<{ name: string; stargazerCount: number } | null> | null;
14
+ pageInfo: { hasNextPage: boolean; endCursor: string | null };
15
+ };
16
+ };
17
+
18
+ export type UserReposQueryVariables = Exact<{
19
+ login: string;
20
+ after?: string | null | undefined;
21
+ ownerAffiliations?:
22
+ | Array<Types.RepositoryAffiliation | null | undefined>
23
+ | Types.RepositoryAffiliation
24
+ | null
25
+ | undefined;
26
+ }>;
27
+
28
+ export type UserReposQuery = {
29
+ user: {
30
+ repositories: {
31
+ totalCount: number;
32
+ nodes: Array<{ name: string; stargazerCount: number } | null> | null;
33
+ pageInfo: { hasNextPage: boolean; endCursor: string | null };
34
+ };
35
+ } | null;
36
+ };
37
+
38
+ export type UserInfoQueryVariables = Exact<{
39
+ login: string;
40
+ after?: string | null | undefined;
41
+ includeMergedPullRequests: boolean;
42
+ includeDiscussions: boolean;
43
+ includeDiscussionsAnswers: boolean;
44
+ startTime?: string | null | undefined;
45
+ ownerAffiliations?:
46
+ | Array<Types.RepositoryAffiliation | null | undefined>
47
+ | Types.RepositoryAffiliation
48
+ | null
49
+ | undefined;
50
+ includeUserRepositories: boolean;
51
+ }>;
52
+
53
+ export type UserInfoQuery = {
54
+ user: {
55
+ name: string | null;
56
+ login: string;
57
+ commits: { totalCommitContributions: number };
58
+ reviews: { totalPullRequestReviewContributions: number };
59
+ repositoriesContributedTo: { totalCount: number };
60
+ pullRequests: { totalCount: number };
61
+ mergedPullRequests?: { totalCount: number };
62
+ openIssues: { totalCount: number };
63
+ closedIssues: { totalCount: number };
64
+ followers: { totalCount: number };
65
+ repositoryDiscussions?: { totalCount: number };
66
+ repositoryDiscussionComments?: { totalCount: number };
67
+ contributionsCollection: { contributionYears: Array<number> };
68
+ repositories: {
69
+ totalCount: number;
70
+ nodes: Array<{ name: string; stargazerCount: number } | null> | null;
71
+ pageInfo: { hasNextPage: boolean; endCursor: string | null };
72
+ };
73
+ } | null;
74
+ };
75
+
76
+ export type YearContributionsFragment = { contributionCalendar: { totalContributions: number } };
77
+
78
+ export type RangeContributionsByRepoFragment = {
79
+ commitContributionsByRepository: Array<{ repository: { nameWithOwner: string } }>;
80
+ issueContributionsByRepository: Array<{ repository: { nameWithOwner: string } }>;
81
+ pullRequestContributionsByRepository: Array<{ repository: { nameWithOwner: string } }>;
82
+ repositoryContributions?: {
83
+ nodes: Array<{ repository: { nameWithOwner: string } } | null> | null;
84
+ };
85
+ };
86
+
87
+ export const UserReposDocument = graphqlDocument<UserReposQuery, UserReposQueryVariables>(`
88
+ query userRepos($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
89
+ user(login: $login) {
90
+ ...RepoStars
91
+ }
92
+ }
93
+ fragment RepoStars on User {
94
+ repositories(
95
+ first: 100
96
+ after: $after
97
+ ownerAffiliations: $ownerAffiliations
98
+ orderBy: {direction: DESC, field: STARGAZERS}
99
+ ) {
100
+ totalCount
101
+ nodes {
102
+ ...RepoNode
103
+ }
104
+ pageInfo {
105
+ hasNextPage
106
+ endCursor
107
+ }
108
+ }
109
+ }
110
+ fragment RepoNode on Repository {
111
+ name
112
+ stargazerCount
113
+ }`);
114
+
115
+ export const UserInfoDocument = graphqlDocument<UserInfoQuery, UserInfoQueryVariables>(`
116
+ query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $startTime: DateTime = null, $ownerAffiliations: [RepositoryAffiliation], $includeUserRepositories: Boolean!) {
117
+ user(login: $login) {
118
+ name
119
+ login
120
+ commits: contributionsCollection(from: $startTime) {
121
+ totalCommitContributions
122
+ }
123
+ reviews: contributionsCollection {
124
+ totalPullRequestReviewContributions
125
+ }
126
+ repositoriesContributedTo(
127
+ first: 1
128
+ contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]
129
+ includeUserRepositories: $includeUserRepositories
130
+ ) {
131
+ totalCount
132
+ }
133
+ pullRequests(first: 1) {
134
+ totalCount
135
+ }
136
+ mergedPullRequests: pullRequests(states: MERGED) @include(if: $includeMergedPullRequests) {
137
+ totalCount
138
+ }
139
+ openIssues: issues(states: OPEN) {
140
+ totalCount
141
+ }
142
+ closedIssues: issues(states: CLOSED) {
143
+ totalCount
144
+ }
145
+ followers {
146
+ totalCount
147
+ }
148
+ repositoryDiscussions @include(if: $includeDiscussions) {
149
+ totalCount
150
+ }
151
+ repositoryDiscussionComments(onlyAnswers: true) @include(if: $includeDiscussionsAnswers) {
152
+ totalCount
153
+ }
154
+ contributionsCollection {
155
+ contributionYears
156
+ }
157
+ ...RepoStars
158
+ }
159
+ }
160
+ fragment RepoStars on User {
161
+ repositories(
162
+ first: 100
163
+ after: $after
164
+ ownerAffiliations: $ownerAffiliations
165
+ orderBy: {direction: DESC, field: STARGAZERS}
166
+ ) {
167
+ totalCount
168
+ nodes {
169
+ ...RepoNode
170
+ }
171
+ pageInfo {
172
+ hasNextPage
173
+ endCursor
174
+ }
175
+ }
176
+ }
177
+ fragment RepoNode on Repository {
178
+ name
179
+ stargazerCount
180
+ }`);
@@ -0,0 +1,66 @@
1
+ // Generated file — see .github/CONTRIBUTING.md
2
+
3
+ /** Internal type. DO NOT USE DIRECTLY. */
4
+ type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
5
+ import { graphqlDocument } from '../graphqlDocument.js';
6
+
7
+ import type * as Types from './common.js';
8
+ export type TopLanguageFragment = { size: number; node: { color: string | null; name: string } };
9
+
10
+ export type TopLanguagesRepositoryFragment = {
11
+ name: string;
12
+ languages: {
13
+ edges: Array<{ size: number; node: { color: string | null; name: string } } | null> | null;
14
+ } | null;
15
+ };
16
+
17
+ export type TopLanguagesQueryVariables = Exact<{
18
+ login: string;
19
+ ownerAffiliations?:
20
+ | Array<Types.RepositoryAffiliation | null | undefined>
21
+ | Types.RepositoryAffiliation
22
+ | null
23
+ | undefined;
24
+ }>;
25
+
26
+ export type TopLanguagesQuery = {
27
+ user: {
28
+ repositories: {
29
+ nodes: Array<{
30
+ name: string;
31
+ languages: {
32
+ edges: Array<{
33
+ size: number;
34
+ node: { color: string | null; name: string };
35
+ } | null> | null;
36
+ } | null;
37
+ } | null> | null;
38
+ };
39
+ } | null;
40
+ };
41
+
42
+ export const TopLanguagesDocument = graphqlDocument<TopLanguagesQuery, TopLanguagesQueryVariables>(`
43
+ query topLanguages($login: String!, $ownerAffiliations: [RepositoryAffiliation]) {
44
+ user(login: $login) {
45
+ repositories(ownerAffiliations: $ownerAffiliations, isFork: false, first: 100) {
46
+ nodes {
47
+ ...TopLanguagesRepository
48
+ }
49
+ }
50
+ }
51
+ }
52
+ fragment TopLanguagesRepository on Repository {
53
+ name
54
+ languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
55
+ edges {
56
+ ...TopLanguage
57
+ }
58
+ }
59
+ }
60
+ fragment TopLanguage on LanguageEdge {
61
+ size
62
+ node {
63
+ color
64
+ name
65
+ }
66
+ }`);
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A GraphQL query paired with the types of its result and variables.
3
+ *
4
+ * `text` is what goes over the wire; the other two members only carry types and are never assigned.
5
+ * Documents are generated from `queries/*.graphql`
6
+ * See `scripts/generate-graphql-types.js`.
7
+ */
8
+ interface GraphQLDocument<TResult, TVariables> {
9
+ readonly text: string;
10
+ readonly __result?: TResult;
11
+ readonly __variables?: TVariables;
12
+ }
13
+
14
+ /**
15
+ * Build a typed document.
16
+ *
17
+ * @param text The query text, including every fragment it spreads.
18
+ * @returns The document to pass to the function created by `createGraphQLFetcher`.
19
+ */
20
+ const graphqlDocument = <TResult, TVariables>(
21
+ text: string,
22
+ ): GraphQLDocument<TResult, TVariables> => ({ text });
23
+
24
+ export { graphqlDocument };
25
+ export type { GraphQLDocument };
@@ -0,0 +1,25 @@
1
+ fragment GistFileInfo on GistFile {
2
+ name
3
+ language {
4
+ name
5
+ }
6
+ size
7
+ }
8
+
9
+ query gistInfo($gistName: String!) {
10
+ viewer {
11
+ gist(name: $gistName) {
12
+ description
13
+ owner {
14
+ login
15
+ }
16
+ stargazerCount
17
+ forks {
18
+ totalCount
19
+ }
20
+ files {
21
+ ...GistFileInfo
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,28 @@
1
+ fragment RepoInfo on Repository {
2
+ name
3
+ nameWithOwner
4
+ isPrivate
5
+ isArchived
6
+ isTemplate
7
+ stargazerCount
8
+ description
9
+ primaryLanguage {
10
+ color
11
+ id
12
+ name
13
+ }
14
+ forkCount
15
+ }
16
+
17
+ query getRepo($login: String!, $repo: String!) {
18
+ user(login: $login) {
19
+ repository(name: $repo) {
20
+ ...RepoInfo
21
+ }
22
+ }
23
+ organization(login: $login) {
24
+ repository(name: $repo) {
25
+ ...RepoInfo
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,113 @@
1
+ fragment RepoNode on Repository {
2
+ name
3
+ stargazerCount
4
+ }
5
+
6
+ fragment RepoStars on User {
7
+ repositories(
8
+ first: 100
9
+ after: $after
10
+ ownerAffiliations: $ownerAffiliations
11
+ orderBy: { direction: DESC, field: STARGAZERS }
12
+ ) {
13
+ totalCount
14
+ nodes {
15
+ ...RepoNode
16
+ }
17
+ pageInfo {
18
+ hasNextPage
19
+ endCursor
20
+ }
21
+ }
22
+ }
23
+
24
+ query userRepos($login: String!, $after: String, $ownerAffiliations: [RepositoryAffiliation]) {
25
+ user(login: $login) {
26
+ ...RepoStars
27
+ }
28
+ }
29
+
30
+ query userInfo(
31
+ $login: String!
32
+ $after: String
33
+ $includeMergedPullRequests: Boolean!
34
+ $includeDiscussions: Boolean!
35
+ $includeDiscussionsAnswers: Boolean!
36
+ $startTime: DateTime = null
37
+ $ownerAffiliations: [RepositoryAffiliation]
38
+ $includeUserRepositories: Boolean!
39
+ ) {
40
+ user(login: $login) {
41
+ name
42
+ login
43
+ commits: contributionsCollection(from: $startTime) {
44
+ totalCommitContributions
45
+ }
46
+ reviews: contributionsCollection {
47
+ totalPullRequestReviewContributions
48
+ }
49
+ repositoriesContributedTo(
50
+ first: 1
51
+ contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]
52
+ includeUserRepositories: $includeUserRepositories
53
+ ) {
54
+ totalCount
55
+ }
56
+ pullRequests(first: 1) {
57
+ totalCount
58
+ }
59
+ mergedPullRequests: pullRequests(states: MERGED) @include(if: $includeMergedPullRequests) {
60
+ totalCount
61
+ }
62
+ openIssues: issues(states: OPEN) {
63
+ totalCount
64
+ }
65
+ closedIssues: issues(states: CLOSED) {
66
+ totalCount
67
+ }
68
+ followers {
69
+ totalCount
70
+ }
71
+ repositoryDiscussions @include(if: $includeDiscussions) {
72
+ totalCount
73
+ }
74
+ repositoryDiscussionComments(onlyAnswers: true) @include(if: $includeDiscussionsAnswers) {
75
+ totalCount
76
+ }
77
+ contributionsCollection {
78
+ contributionYears
79
+ }
80
+ ...RepoStars
81
+ }
82
+ }
83
+
84
+ fragment YearContributions on ContributionsCollection {
85
+ contributionCalendar {
86
+ totalContributions
87
+ }
88
+ }
89
+
90
+ fragment RangeContributionsByRepo on ContributionsCollection {
91
+ commitContributionsByRepository(maxRepositories: $maxRepositories) {
92
+ repository {
93
+ nameWithOwner
94
+ }
95
+ }
96
+ issueContributionsByRepository(maxRepositories: $maxRepositories) {
97
+ repository {
98
+ nameWithOwner
99
+ }
100
+ }
101
+ pullRequestContributionsByRepository(maxRepositories: $maxRepositories) {
102
+ repository {
103
+ nameWithOwner
104
+ }
105
+ }
106
+ repositoryContributions(first: $maxRepositories) @include(if: $includeOwnRepos) {
107
+ nodes {
108
+ repository {
109
+ nameWithOwner
110
+ }
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,27 @@
1
+ fragment TopLanguage on LanguageEdge {
2
+ size
3
+ node {
4
+ color
5
+ name
6
+ }
7
+ }
8
+
9
+ fragment TopLanguagesRepository on Repository {
10
+ name
11
+ languages(first: 10, orderBy: { field: SIZE, direction: DESC }) {
12
+ edges {
13
+ ...TopLanguage
14
+ }
15
+ }
16
+ }
17
+
18
+ query topLanguages($login: String!, $ownerAffiliations: [RepositoryAffiliation]) {
19
+ user(login: $login) {
20
+ # do not fetch forks
21
+ repositories(ownerAffiliations: $ownerAffiliations, isFork: false, first: 100) {
22
+ nodes {
23
+ ...TopLanguagesRepository
24
+ }
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,83 @@
1
+ import type { GitHubDateRange } from '../common/date.js';
2
+ import { toGitHubDateTime } from '../common/date.js';
3
+
4
+ import type { RangeContributionsByRepoFragment } from './generated/stats.js';
5
+ import { graphqlDocument } from './graphqlDocument.js';
6
+
7
+ /** max value GitHub allows for `first/maxRepositories` */
8
+ const MAX_REPOSITORIES_LIMIT = 100;
9
+
10
+ interface ReposContributedToQueryVariables {
11
+ login: string;
12
+ maxRepositories: number;
13
+ }
14
+
15
+ interface ReposContributedToQuery {
16
+ user: Record<`range_${number}`, RangeContributionsByRepoFragment> | null;
17
+ }
18
+
19
+ /**
20
+ * Build a query for the repositories a user contributed to within multiple time
21
+ * ranges. One aliased `contributionsCollection` field per range, so all ranges
22
+ * are fetched in a single request. The shape is only known at runtime.
23
+ *
24
+ * Mirrors the `contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]`
25
+ * filter used by `repositoriesContributedTo` in `stats.graphql`.
26
+ *
27
+ * @param ranges Ranges to fetch, one `range_<index>` alias each.
28
+ * @param includeOwnRepos Whether to select `repositoryContributions`.
29
+ * @returns Document for `createGraphQLFetcher`.
30
+ */
31
+ const buildReposContributedToDocument = (
32
+ ranges: Array<GitHubDateRange>,
33
+ includeOwnRepos: boolean,
34
+ ) => {
35
+ const rangeFields = ranges
36
+ .map(
37
+ ({ from, to }, index) =>
38
+ `range_${index}: contributionsCollection(from: "${toGitHubDateTime(from)}", to: "${toGitHubDateTime(to)}") { ...RangeContributionsByRepo }`,
39
+ )
40
+ .join('\n');
41
+
42
+ // `repositoryContributions` only ever returns repos the user owns,
43
+ // so it is left out rather than gated with @include: an excluded field still counts toward the query's node cost.
44
+ // stats.graphql carries the directive so the generated type marks the field optional.
45
+ const ownRepoField = includeOwnRepos
46
+ ? `repositoryContributions(first: $maxRepositories) {
47
+ nodes {
48
+ repository {
49
+ nameWithOwner
50
+ }
51
+ }
52
+ }`
53
+ : '';
54
+
55
+ // fragment must match queries/stats.graphql, which generates its type
56
+ return graphqlDocument<ReposContributedToQuery, ReposContributedToQueryVariables>(`
57
+ query userReposContributedTo($login: String!, $maxRepositories: Int!) {
58
+ user(login: $login) {
59
+ ${rangeFields}
60
+ }
61
+ }
62
+ fragment RangeContributionsByRepo on ContributionsCollection {
63
+ commitContributionsByRepository(maxRepositories: $maxRepositories) {
64
+ repository {
65
+ nameWithOwner
66
+ }
67
+ }
68
+ issueContributionsByRepository(maxRepositories: $maxRepositories) {
69
+ repository {
70
+ nameWithOwner
71
+ }
72
+ }
73
+ pullRequestContributionsByRepository(maxRepositories: $maxRepositories) {
74
+ repository {
75
+ nameWithOwner
76
+ }
77
+ }
78
+ ${ownRepoField}
79
+ }`);
80
+ };
81
+
82
+ export { buildReposContributedToDocument, MAX_REPOSITORIES_LIMIT };
83
+ export type { ReposContributedToQuery };
package/src/index.ts ADDED
@@ -0,0 +1,18 @@
1
+ export { fetchWakatimeStats } from './fetchers/wakatime.js';
2
+ export { retryer } from './common/retryer.js';
3
+
4
+ export { renderError } from './common/render.js';
5
+
6
+ export type { ApiError, ApiResult } from './api/api-result.js';
7
+ export { gist } from './api/gist.js';
8
+ export { stats } from './api/stats.js';
9
+ export { pin } from './api/pin.js';
10
+ export { topLangs } from './api/top-langs.js';
11
+ export { wakatime } from './api/wakatime.js';
12
+
13
+ export { CardConfig } from './common/config.js';
14
+ export type { PersonalAccessToken } from './common/config.js';
15
+ export type { FetchLike } from './common/http.js';
16
+
17
+ export { themes } from './themes/index.js';
18
+ export type { ThemeName } from './themes/index.js';