@stats-organization/github-readme-stats-core 2.1.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/build/api/gist.d.ts +2 -7
  2. package/build/api/gist.d.ts.map +1 -1
  3. package/build/api/gist.js +9 -41
  4. package/build/api/index.d.ts +3 -8
  5. package/build/api/index.d.ts.map +1 -1
  6. package/build/api/index.js +23 -45
  7. package/build/api/pin.d.ts +2 -7
  8. package/build/api/pin.d.ts.map +1 -1
  9. package/build/api/pin.js +9 -41
  10. package/build/api/top-langs.d.ts +2 -7
  11. package/build/api/top-langs.d.ts.map +1 -1
  12. package/build/api/top-langs.js +11 -55
  13. package/build/api/wakatime.d.ts +2 -7
  14. package/build/api/wakatime.d.ts.map +1 -1
  15. package/build/api/wakatime.js +9 -41
  16. package/build/cards/common-options.d.ts +13 -0
  17. package/build/cards/common-options.d.ts.map +1 -0
  18. package/build/cards/common-options.js +1 -0
  19. package/build/cards/gist.d.ts +11 -16
  20. package/build/cards/gist.d.ts.map +1 -1
  21. package/build/cards/gist.js +26 -31
  22. package/build/cards/repo.d.ts +19 -16
  23. package/build/cards/repo.d.ts.map +1 -1
  24. package/build/cards/repo.js +58 -60
  25. package/build/cards/stats.d.ts +29 -46
  26. package/build/cards/stats.d.ts.map +1 -1
  27. package/build/cards/stats.js +113 -181
  28. package/build/cards/top-languages.d.ts +81 -77
  29. package/build/cards/top-languages.d.ts.map +1 -1
  30. package/build/cards/top-languages.js +174 -200
  31. package/build/cards/wakatime.d.ts +21 -11
  32. package/build/cards/wakatime.d.ts.map +1 -1
  33. package/build/cards/wakatime.js +73 -111
  34. package/build/common/Card.d.ts +34 -13
  35. package/build/common/Card.d.ts.map +1 -1
  36. package/build/common/Card.js +73 -40
  37. package/build/common/I18n.d.ts +4 -2
  38. package/build/common/I18n.d.ts.map +1 -1
  39. package/build/common/color.d.ts +60 -18
  40. package/build/common/color.d.ts.map +1 -1
  41. package/build/common/color.js +102 -5
  42. package/build/common/config.d.ts +2 -1
  43. package/build/common/config.d.ts.map +1 -1
  44. package/build/common/config.js +16 -26
  45. package/build/common/constants.d.ts +2 -1
  46. package/build/common/constants.d.ts.map +1 -1
  47. package/build/common/date.d.ts +37 -0
  48. package/build/common/date.d.ts.map +1 -0
  49. package/build/common/date.js +31 -0
  50. package/build/common/http.d.ts +25 -2
  51. package/build/common/http.d.ts.map +1 -1
  52. package/build/common/http.js +26 -3
  53. package/build/common/icons.d.ts +1 -0
  54. package/build/common/icons.d.ts.map +1 -1
  55. package/build/common/icons.js +1 -0
  56. package/build/common/languageColors.d.ts +11 -0
  57. package/build/common/languageColors.d.ts.map +1 -0
  58. package/build/common/languageColors.js +15 -0
  59. package/build/common/languageColors.json +1 -0
  60. package/build/common/ops.d.ts +3 -10
  61. package/build/common/ops.d.ts.map +1 -1
  62. package/build/common/ops.js +3 -15
  63. package/build/common/render.d.ts +43 -6
  64. package/build/common/render.d.ts.map +1 -1
  65. package/build/common/render.js +77 -11
  66. package/build/common/retryer.d.ts +3 -2
  67. package/build/common/retryer.d.ts.map +1 -1
  68. package/build/common/retryer.js +1 -0
  69. package/build/fetchers/gist.d.ts.map +1 -1
  70. package/build/fetchers/gist.js +8 -39
  71. package/build/fetchers/repo.d.ts +12 -11
  72. package/build/fetchers/repo.d.ts.map +1 -1
  73. package/build/fetchers/repo.js +26 -67
  74. package/build/fetchers/stats.d.ts +24 -17
  75. package/build/fetchers/stats.d.ts.map +1 -1
  76. package/build/fetchers/stats.js +302 -183
  77. package/build/fetchers/top-languages.d.ts +10 -15
  78. package/build/fetchers/top-languages.d.ts.map +1 -1
  79. package/build/fetchers/top-languages.js +52 -103
  80. package/build/fetchers/types.d.ts +24 -20
  81. package/build/fetchers/types.d.ts.map +1 -1
  82. package/build/fetchers/wakatime.d.ts +9 -5
  83. package/build/fetchers/wakatime.d.ts.map +1 -1
  84. package/build/fetchers/wakatime.js +8 -4
  85. package/build/graphql/contributionsDocument.d.ts +18 -0
  86. package/build/graphql/contributionsDocument.d.ts.map +1 -0
  87. package/build/graphql/contributionsDocument.js +30 -0
  88. package/build/graphql/generated/common.d.ts +42 -0
  89. package/build/graphql/generated/common.d.ts.map +1 -0
  90. package/build/graphql/generated/common.js +2 -0
  91. package/build/graphql/generated/gist.d.ts +44 -0
  92. package/build/graphql/generated/gist.d.ts.map +1 -0
  93. package/build/graphql/generated/gist.js +27 -0
  94. package/build/graphql/generated/repo.d.ts +67 -0
  95. package/build/graphql/generated/repo.d.ts.map +1 -0
  96. package/build/graphql/generated/repo.js +30 -0
  97. package/build/graphql/generated/stats.d.ts +150 -0
  98. package/build/graphql/generated/stats.d.ts.map +1 -0
  99. package/build/graphql/generated/stats.js +95 -0
  100. package/build/graphql/generated/top-languages.d.ts +54 -0
  101. package/build/graphql/generated/top-languages.d.ts.map +1 -0
  102. package/build/graphql/generated/top-languages.js +27 -0
  103. package/build/graphql/graphqlDocument.d.ts +22 -0
  104. package/build/graphql/graphqlDocument.d.ts.map +1 -0
  105. package/build/graphql/graphqlDocument.js +8 -0
  106. package/build/graphql/reposContributedToDocument.d.ts +27 -0
  107. package/build/graphql/reposContributedToDocument.d.ts.map +1 -0
  108. package/build/graphql/reposContributedToDocument.js +59 -0
  109. package/build/index.d.ts +3 -1
  110. package/build/index.d.ts.map +1 -1
  111. package/build/index.js +2 -1
  112. package/build/themes/index.d.ts +32 -0
  113. package/build/themes/index.d.ts.map +1 -1
  114. package/build/themes/index.js +28 -0
  115. package/build/translations.d.ts +17 -0
  116. package/build/translations.d.ts.map +1 -1
  117. package/build/translations.js +17 -0
  118. package/package.json +13 -7
  119. package/src/_github-username-regex.d.ts +4 -0
  120. package/src/api/gist.js +10 -46
  121. package/src/api/index.js +30 -51
  122. package/src/api/pin.js +10 -46
  123. package/src/api/top-langs.js +13 -60
  124. package/src/api/wakatime.js +10 -46
  125. package/src/cards/common-options.ts +13 -0
  126. package/src/cards/{gist.js → gist.ts} +37 -37
  127. package/src/cards/{repo.js → repo.ts} +86 -68
  128. package/src/cards/{stats.js → stats.ts} +168 -219
  129. package/src/cards/{top-languages.js → top-languages.ts} +309 -265
  130. package/src/cards/{wakatime.js → wakatime.ts} +136 -130
  131. package/src/common/Card.ts +94 -49
  132. package/src/common/I18n.ts +6 -2
  133. package/src/common/color.ts +163 -14
  134. package/src/common/config.ts +22 -29
  135. package/src/common/constants.ts +3 -1
  136. package/src/common/date.ts +45 -0
  137. package/src/common/http.ts +43 -3
  138. package/src/common/icons.ts +1 -0
  139. package/src/common/languageColors.json +1 -0
  140. package/src/common/languageColors.ts +19 -0
  141. package/src/common/ops.ts +8 -18
  142. package/src/common/render.ts +114 -14
  143. package/src/common/retryer.ts +6 -5
  144. package/src/fetchers/gist.ts +15 -72
  145. package/src/fetchers/repo.ts +114 -0
  146. package/src/fetchers/stats.ts +743 -0
  147. package/src/fetchers/top-languages.ts +135 -0
  148. package/src/fetchers/types.ts +28 -20
  149. package/src/fetchers/{wakatime.js → wakatime.ts} +19 -5
  150. package/src/graphql/contributionsDocument.ts +44 -0
  151. package/src/graphql/generated/common.ts +26 -0
  152. package/src/graphql/generated/gist.ts +59 -0
  153. package/src/graphql/generated/repo.ts +90 -0
  154. package/src/graphql/generated/stats.ts +194 -0
  155. package/src/graphql/generated/top-languages.ts +75 -0
  156. package/src/graphql/graphqlDocument.ts +25 -0
  157. package/src/graphql/queries/gist.graphql +25 -0
  158. package/src/graphql/queries/repo.graphql +28 -0
  159. package/src/graphql/queries/stats.graphql +120 -0
  160. package/src/graphql/queries/top-languages.graphql +34 -0
  161. package/src/graphql/reposContributedToDocument.ts +86 -0
  162. package/src/index.ts +3 -1
  163. package/src/themes/index.ts +33 -0
  164. package/src/translations.ts +17 -0
  165. package/src/cards/types.d.ts +0 -78
  166. package/src/fetchers/repo.js +0 -161
  167. package/src/fetchers/stats.js +0 -473
  168. package/src/fetchers/top-languages.js +0 -175
  169. package/src/themes/README.md +0 -229
@@ -1,4 +1,19 @@
1
1
  import type { AxiosRequestConfig, AxiosResponse } from "axios";
2
+ import type { GraphQLDocument } from "../graphql/graphqlDocument.js";
3
+ /** Response of a GraphQL call: the envelope the GitHub API wraps results in. */
4
+ type GraphQLResponse<TResult> = AxiosResponse<{
5
+ data: TResult;
6
+ errors?: Array<{
7
+ type?: string;
8
+ message?: string;
9
+ }>;
10
+ }>;
11
+ /**
12
+ * @param document Generated query document.
13
+ * @param scheme `Authorization` scheme for the token.
14
+ * @returns A fetcher `retryer` can drive.
15
+ */
16
+ declare const createGraphQLFetcher: <TResult, TVariables>(document: GraphQLDocument<TResult, TVariables>, scheme: "bearer" | "token") => (variables: TVariables, token: string) => Promise<GraphQLResponse<TResult>>;
2
17
  /** Body of a GraphQL request sent to the GitHub API. */
3
18
  interface GraphQLRequest {
4
19
  /** The GraphQL query. */
@@ -7,12 +22,20 @@ interface GraphQLRequest {
7
22
  variables: Record<string, unknown>;
8
23
  }
9
24
  /**
10
- * Send GraphQL request to GitHub API.
25
+ * Send an untyped GraphQL request to the GitHub API.
11
26
  *
12
27
  * @param data Request data.
13
28
  * @param headers Request headers.
14
29
  * @returns Request response.
30
+ *
31
+ * @description Superseded by {@link createGraphQLFetcher}.
32
+ * Still used by the backend status endpoints for their own `rateLimit` query,
33
+ * and part of this package's published API.
34
+ *
35
+ * @todo consider dropping this once those endpoints post through axios directly,
36
+ * which they already depend on.
15
37
  */
16
38
  declare const request: (data: GraphQLRequest, headers: NonNullable<AxiosRequestConfig["headers"]>) => Promise<AxiosResponse>;
17
- export { request };
39
+ export { createGraphQLFetcher, request };
40
+ export type { GraphQLResponse };
18
41
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/common/http.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE/D,wDAAwD;AACxD,UAAU,cAAc;IACtB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;GAMG;AACH,QAAA,MAAM,OAAO,GACX,MAAM,cAAc,EACpB,SAAS,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,KAClD,OAAO,CAAC,aAAa,CAOvB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/common/http.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAIrE,gFAAgF;AAChF,KAAK,eAAe,CAAC,OAAO,IAAI,aAAa,CAAC;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD,CAAC,CAAC;AAEH;;;;GAIG;AACH,QAAA,MAAM,oBAAoB,GAAI,OAAO,EAAE,UAAU,EAC/C,UAAU,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,EAC9C,QAAQ,QAAQ,GAAG,OAAO,MAGxB,WAAW,UAAU,EACrB,OAAO,MAAM,KACZ,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAQpC,CAAC;AAEF,wDAAwD;AACxD,UAAU,cAAc;IACtB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,OAAO,GACX,MAAM,cAAc,EACpB,SAAS,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,KAClD,OAAO,CAAC,aAAa,CAOvB,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -1,17 +1,40 @@
1
1
  import axios from "axios";
2
+ const GITHUB_GRAPHQL_API = "https://api.github.com/graphql";
2
3
  /**
3
- * Send GraphQL request to GitHub API.
4
+ * @param document Generated query document.
5
+ * @param scheme `Authorization` scheme for the token.
6
+ * @returns A fetcher `retryer` can drive.
7
+ */
8
+ const createGraphQLFetcher = (document, scheme) => {
9
+ return (variables, token) => {
10
+ return axios({
11
+ url: GITHUB_GRAPHQL_API,
12
+ method: "post",
13
+ headers: { Authorization: `${scheme} ${token}` },
14
+ data: { query: document.text, variables },
15
+ });
16
+ };
17
+ };
18
+ /**
19
+ * Send an untyped GraphQL request to the GitHub API.
4
20
  *
5
21
  * @param data Request data.
6
22
  * @param headers Request headers.
7
23
  * @returns Request response.
24
+ *
25
+ * @description Superseded by {@link createGraphQLFetcher}.
26
+ * Still used by the backend status endpoints for their own `rateLimit` query,
27
+ * and part of this package's published API.
28
+ *
29
+ * @todo consider dropping this once those endpoints post through axios directly,
30
+ * which they already depend on.
8
31
  */
9
32
  const request = (data, headers) => {
10
33
  return axios({
11
- url: "https://api.github.com/graphql",
34
+ url: GITHUB_GRAPHQL_API,
12
35
  method: "post",
13
36
  headers,
14
37
  data,
15
38
  });
16
39
  };
17
- export { request };
40
+ export { createGraphQLFetcher, request };
@@ -12,6 +12,7 @@ declare const icons: {
12
12
  discussions_started: string;
13
13
  discussions_answered: string;
14
14
  comments: string;
15
+ contributions: string;
15
16
  gist: string;
16
17
  };
17
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/common/icons.ts"],"names":[],"mappings":"AA0BA,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;CAeV,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,QAAQ,GACZ,UAAU,MAAM,EAChB,WAAW,MAAM,EACjB,YAAY,MAAM,KACjB,MAyBF,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/common/icons.ts"],"names":[],"mappings":"AA0BA,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;CAgBV,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,QAAQ,GACZ,UAAU,MAAM,EAChB,WAAW,MAAM,EACjB,YAAY,MAAM,KACjB,MAyBF,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC"}
@@ -37,6 +37,7 @@ const icons = {
37
37
  discussions_started: `<path fill-rule="evenodd" d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z" />`,
38
38
  discussions_answered: `<path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" />`,
39
39
  comments: `<path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z" />`,
40
+ contributions: `<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"/>`,
40
41
  gist: `<path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z" />`,
41
42
  };
42
43
  /**
@@ -0,0 +1,11 @@
1
+ /** Shown for languages missing from the generated table, and for a null API color. */
2
+ declare const DEFAULT_LANG_COLOR = "#858585";
3
+ /**
4
+ * Resolves a language's brand color from the generated table.
5
+ *
6
+ * @param name Language name as GitHub spells it.
7
+ * @returns The language's hex color, or the default gray when it is unknown.
8
+ */
9
+ declare const getLanguageColor: (name: string) => string;
10
+ export { DEFAULT_LANG_COLOR, getLanguageColor };
11
+ //# sourceMappingURL=languageColors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languageColors.d.ts","sourceRoot":"","sources":["../../src/common/languageColors.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,QAAA,MAAM,kBAAkB,YAAY,CAAC;AAKrC;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAExC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import languageColorsJson from "./languageColors.json" with { type: "json" };
2
+ /** Shown for languages missing from the generated table, and for a null API color. */
3
+ const DEFAULT_LANG_COLOR = "#858585";
4
+ // The generated JSON types has literal keys; index it as a plain lookup table.
5
+ const languageColors = languageColorsJson;
6
+ /**
7
+ * Resolves a language's brand color from the generated table.
8
+ *
9
+ * @param name Language name as GitHub spells it.
10
+ * @returns The language's hex color, or the default gray when it is unknown.
11
+ */
12
+ const getLanguageColor = (name) => {
13
+ return languageColors[name] ?? DEFAULT_LANG_COLOR;
14
+ };
15
+ export { DEFAULT_LANG_COLOR, getLanguageColor };
@@ -212,6 +212,7 @@
212
212
  "Glimmer JS": "#F5835F",
213
213
  "Glimmer TS": "#3178c6",
214
214
  "Glyph": "#c1ac7f",
215
+ "Gno": "#226c57",
215
216
  "Gnuplot": "#f0a9f0",
216
217
  "Go": "#00ADD8",
217
218
  "Go Checksums": "#00ADD8",
@@ -1,3 +1,4 @@
1
+ import type { RepositoryAffiliation } from "../graphql/generated/common.js";
1
2
  /**
2
3
  * Returns boolean if value is either "true" or "false" else the value as it is.
3
4
  *
@@ -44,14 +45,6 @@ declare const chunkArray: <T>(arr: Array<T>, perChunk: number) => Array<Array<T>
44
45
  * @returns String with emoji parsed.
45
46
  */
46
47
  declare const parseEmojis: (str: string) => string;
47
- /**
48
- * Get diff in minutes between two dates.
49
- *
50
- * @param d1 First date.
51
- * @param d2 Second date.
52
- * @returns Number of minutes between the two dates.
53
- */
54
- declare const dateDiff: (d1: Date, d2: Date) => number;
55
48
  /**
56
49
  * Parse owner affiliations.
57
50
  *
@@ -60,7 +53,7 @@ declare const dateDiff: (d1: Date, d2: Date) => number;
60
53
  *
61
54
  * @throws {CustomError} If affiliations contains invalid values.
62
55
  */
63
- declare const parseOwnerAffiliations: (affiliations: Array<string>) => Array<string>;
56
+ declare const parseOwnerAffiliations: (affiliations: Array<string>) => Array<RepositoryAffiliation>;
64
57
  declare const buildSearchFilter: (repos?: Array<string> | string, owners?: Array<string> | string) => string;
65
- export { parseBoolean, parseArray, clampValue, lowercaseTrim, chunkArray, parseEmojis, dateDiff, parseOwnerAffiliations, buildSearchFilter, };
58
+ export { parseBoolean, parseArray, clampValue, lowercaseTrim, chunkArray, parseEmojis, parseOwnerAffiliations, buildSearchFilter, };
66
59
  //# sourceMappingURL=ops.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/common/ops.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,QAAA,MAAM,YAAY,GAAI,OAAO,MAAM,GAAG,OAAO,KAAG,OAAO,GAAG,SAazD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,KAAK,CAAC,MAAM,CAK7C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,UAAU,GACd,QAAQ,MAAM,GAAG,MAAM,EACvB,KAAK,MAAM,EACX,KAAK,MAAM,KACV,MAKF,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAAmC,CAAC;AAE1E;;;;;;;GAOG;AACH,QAAA,MAAM,UAAU,GAAI,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAQtE,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAOlC,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,QAAQ,GAAI,IAAI,IAAI,EAAE,IAAI,IAAI,KAAG,MAKtC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,sBAAsB,GAAI,cAAc,KAAK,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,MAAM,CAmBzE,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,QAAO,KAAK,CAAC,MAAM,CAAC,GAAG,MAAW,EAClC,SAAQ,KAAK,CAAC,MAAM,CAAC,GAAG,MAAW,KAClC,MAUF,CAAC;AAEF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,QAAQ,EACR,sBAAsB,EACtB,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/common/ops.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAK5E;;;;;GAKG;AACH,QAAA,MAAM,YAAY,GAAI,OAAO,MAAM,GAAG,OAAO,KAAG,OAAO,GAAG,SAazD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,KAAK,CAAC,MAAM,CAK7C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,UAAU,GACd,QAAQ,MAAM,GAAG,MAAM,EACvB,KAAK,MAAM,EACX,KAAK,MAAM,KACV,MAKF,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAAmC,CAAC;AAE1E;;;;;;;GAOG;AACH,QAAA,MAAM,UAAU,GAAI,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAQtE,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAOlC,CAAC;AAKF;;;;;;;GAOG;AACH,QAAA,MAAM,sBAAsB,GAC1B,cAAc,KAAK,CAAC,MAAM,CAAC,KAC1B,KAAK,CAAC,qBAAqB,CAiB7B,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,QAAO,KAAK,CAAC,MAAM,CAAC,GAAG,MAAW,EAClC,SAAQ,KAAK,CAAC,MAAM,CAAC,GAAG,MAAW,KAClC,MAUF,CAAC;AAEF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAClB,CAAC"}
@@ -85,19 +85,7 @@ const parseEmojis = (str) => {
85
85
  return toEmoji.get(emoji) || "";
86
86
  });
87
87
  };
88
- /**
89
- * Get diff in minutes between two dates.
90
- *
91
- * @param d1 First date.
92
- * @param d2 Second date.
93
- * @returns Number of minutes between the two dates.
94
- */
95
- const dateDiff = (d1, d2) => {
96
- const date1 = new Date(d1);
97
- const date2 = new Date(d2);
98
- const diff = date1.getTime() - date2.getTime();
99
- return Math.round(diff / (1000 * 60));
100
- };
88
+ const isOwnerAffiliation = (value) => OWNER_AFFILIATIONS.some((affiliation) => affiliation === value);
101
89
  /**
102
90
  * Parse owner affiliations.
103
91
  *
@@ -114,7 +102,7 @@ const parseOwnerAffiliations = (affiliations) => {
114
102
  ? affiliations.map((affiliation) => affiliation.toUpperCase())
115
103
  : ["OWNER"];
116
104
  // Check if ownerAffiliations contains valid values.
117
- if (normalized.some((affiliation) => !OWNER_AFFILIATIONS.includes(affiliation))) {
105
+ if (!normalized.every(isOwnerAffiliation)) {
118
106
  throw new CustomError("Invalid query parameter", CustomError.INVALID_AFFILIATION);
119
107
  }
120
108
  return normalized;
@@ -128,4 +116,4 @@ const buildSearchFilter = (repos = [], owners = []) => {
128
116
  : "";
129
117
  return repoFilter + orgFilter;
130
118
  };
131
- export { parseBoolean, parseArray, clampValue, lowercaseTrim, chunkArray, parseEmojis, dateDiff, parseOwnerAffiliations, buildSearchFilter, };
119
+ export { parseBoolean, parseArray, clampValue, lowercaseTrim, chunkArray, parseEmojis, parseOwnerAffiliations, buildSearchFilter, };
@@ -32,19 +32,18 @@ declare const createLanguageNode: (langName: string, langColor: string) => strin
32
32
  * @param params.x X-axis position.
33
33
  * @param params.y Y-axis position.
34
34
  * @param params.width Width of progress bar.
35
- * @param params.color Progress color.
35
+ * @param params.color Optional foreground color as an inline fill fallback.
36
+ * When omitted, the color must be set via a `.lang-progress` CSS rule.
36
37
  * @param params.progress Progress value.
37
- * @param params.progressBarBackgroundColor Progress bar bg color.
38
38
  * @param params.delay Delay before animation starts.
39
39
  * @returns Progress node.
40
40
  */
41
- declare const createProgressNode: ({ x, y, width, color, progress, progressBarBackgroundColor, delay, }: {
41
+ declare const createProgressNode: ({ x, y, width, color, progress, delay, }: {
42
42
  x: number;
43
43
  y: number;
44
44
  width: number;
45
- color: string;
45
+ color?: string;
46
46
  progress: number;
47
- progressBarBackgroundColor: string;
48
47
  delay: number;
49
48
  }) => string;
50
49
  /**
@@ -95,6 +94,44 @@ declare const wrappedTextStyles: (color: string) => string;
95
94
  * @returns Icon with label SVG object.
96
95
  */
97
96
  declare const iconWithLabel: (icon: string, label: number | string, testid: string, iconSize: number) => string;
97
+ /**
98
+ * Create a labelled stat text item
99
+ * (a label and its value, optionally with an icon and link).
100
+ * Shared by the stats and repo cards.
101
+ *
102
+ * The caller must ensure that the passed `icon` and `link` are properly sanitized!
103
+ *
104
+ * @param params Object that contains the createTextNode parameters.
105
+ * @param params.icon The sanitized icon to display.
106
+ * @param params.label The label to display.
107
+ * @param params.value The value to display.
108
+ * @param params.id The id of the stat.
109
+ * @param params.unitSymbol The unit symbol of the stat.
110
+ * @param params.index The index of the stat.
111
+ * @param params.showIcons Whether to show icons.
112
+ * @param params.shiftValuePos Number of pixels the value has to be shifted to the right.
113
+ * @param params.bold Whether to bold the label.
114
+ * @param params.numberFormat The format of numbers on card.
115
+ * @param params.numberPrecision The precision of numbers on card.
116
+ * @param params.link Sanitized url to link to.
117
+ * @param params.labelXOffset horizontal offset for label.
118
+ * @returns The stats card text item SVG object.
119
+ */
120
+ declare const createTextNode: ({ icon, label, value, id, unitSymbol, index, showIcons, shiftValuePos, bold, numberFormat, numberPrecision, link, labelXOffset, }: {
121
+ icon: string;
122
+ label: string;
123
+ value: number | string;
124
+ id: string;
125
+ unitSymbol?: string | undefined;
126
+ index: number;
127
+ showIcons: boolean;
128
+ shiftValuePos: number;
129
+ bold: boolean;
130
+ numberFormat: string;
131
+ numberPrecision?: number | undefined;
132
+ link?: string | undefined;
133
+ labelXOffset?: number;
134
+ }) => string;
98
135
  /**
99
136
  * Renders error message on the card.
100
137
  *
@@ -155,5 +192,5 @@ declare const splitWrappedText: (text: string, fontSize: number, maxWidth: numbe
155
192
  * @returns Estimated line count, at least 1, at most `maxLines`.
156
193
  */
157
194
  declare const countWrappedLines: (text: string, fontSize: number, maxWidth: number, maxLines: number) => number;
158
- export { renderError, createLanguageNode, createProgressNode, iconWithLabel, flexLayout, measureText, splitWrappedText, countWrappedLines, wrappedTextNode, wrappedTextStyles, };
195
+ export { renderError, createLanguageNode, createProgressNode, createTextNode, iconWithLabel, flexLayout, measureText, splitWrappedText, countWrappedLines, wrappedTextNode, wrappedTextStyles, };
159
196
  //# sourceMappingURL=render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,UAAU,GAAI,mCAKjB;IACD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACvB,KAAG,KAAK,CAAC,MAAM,CAgBf,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,GAAI,UAAU,MAAM,EAAE,WAAW,MAAM,KAAG,MAWjE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,kBAAkB,GAAI,sEAQzB;IACD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B,EAAE,MAAM,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,MAsCH,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,eAAe,GAAI,8DAStB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,MAyBH,CAAC;AAEF;;;;;;;;GAQG;AACH,QAAA,MAAM,iBAAiB,GAAI,OAAO,MAAM,KAAG,MAmB1C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,QAAA,MAAM,aAAa,GACjB,MAAM,MAAM,EACZ,OAAO,MAAM,GAAG,MAAM,EACtB,QAAQ,MAAM,EACd,UAAU,MAAM,KACf,MAuBF,CAAC;AAUF;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,WAAW,GAAI,+CAIlB;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,CAAC;CACH,KAAG,MA0CH,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,iBAAa,KAAG,MA2DjD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,gBAAgB,GACpB,MAAM,MAAM,EACZ,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,KAAK,CAAC,MAAM,CAkFd,CAAC;AAEF;;;;;;;;;GASG;AACH,QAAA,MAAM,iBAAiB,GACrB,MAAM,MAAM,EACZ,UAAU,MAAM,EAChB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,MAKF,CAAC;AAEF,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { getCardColors, isPrefixedHexColor } from "./color.js";
2
2
  import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js";
3
+ import { kFormatter } from "./fmt.js";
3
4
  import { encodeHTML } from "./html.js";
4
5
  import { clampValue } from "./ops.js";
5
6
  /**
@@ -56,19 +57,16 @@ const createLanguageNode = (langName, langColor) => {
56
57
  * @param params.x X-axis position.
57
58
  * @param params.y Y-axis position.
58
59
  * @param params.width Width of progress bar.
59
- * @param params.color Progress color.
60
+ * @param params.color Optional foreground color as an inline fill fallback.
61
+ * When omitted, the color must be set via a `.lang-progress` CSS rule.
60
62
  * @param params.progress Progress value.
61
- * @param params.progressBarBackgroundColor Progress bar bg color.
62
63
  * @param params.delay Delay before animation starts.
63
64
  * @returns Progress node.
64
65
  */
65
- const createProgressNode = ({ x, y, width, color, progress, progressBarBackgroundColor, delay, }) => {
66
- if (!isPrefixedHexColor(color)) {
66
+ const createProgressNode = ({ x, y, width, color, progress, delay, }) => {
67
+ if (color !== undefined && !isPrefixedHexColor(color)) {
67
68
  throw new Error(`Invalid progress color: "${color}"`);
68
69
  }
69
- if (!isPrefixedHexColor(progressBarBackgroundColor)) {
70
- throw new Error(`Invalid progress bar background color: "${progressBarBackgroundColor}"`);
71
- }
72
70
  if (!Number.isFinite(width)) {
73
71
  throw new Error(`Invalid width: "${width}"`);
74
72
  }
@@ -84,11 +82,11 @@ const createProgressNode = ({ x, y, width, color, progress, progressBarBackgroun
84
82
  const progressPercentage = clampValue(progress, 2, 100);
85
83
  return `
86
84
  <svg width="${width}" x="${x}" y="${y}">
87
- <rect data-testid="progress-background" rx="5" ry="5" x="0" y="0" width="${width}" height="8" fill="${progressBarBackgroundColor}"></rect>
85
+ <rect data-testid="progress-background" class="progress-background" rx="5" ry="5" x="0" y="0" width="${width}" height="8"></rect>
88
86
  <svg data-testid="lang-progress" width="${progressPercentage}%">
89
87
  <rect
90
88
  height="8"
91
- fill="${color}"
89
+ ${color === undefined ? "" : `fill="${color}"`}
92
90
  rx="5" ry="5" x="0" y="0"
93
91
  class="lang-progress"
94
92
  style="animation-delay: ${delay}ms;"
@@ -197,6 +195,75 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
197
195
  const text = `<text data-testid="${encodeHTML(testid)}" class="gray">${encodeHTML(String(label))}</text>`;
198
196
  return flexLayout({ items: [iconSvg, text], gap: 20 }).join("");
199
197
  };
198
+ /**
199
+ * Create a labelled stat text item
200
+ * (a label and its value, optionally with an icon and link).
201
+ * Shared by the stats and repo cards.
202
+ *
203
+ * The caller must ensure that the passed `icon` and `link` are properly sanitized!
204
+ *
205
+ * @param params Object that contains the createTextNode parameters.
206
+ * @param params.icon The sanitized icon to display.
207
+ * @param params.label The label to display.
208
+ * @param params.value The value to display.
209
+ * @param params.id The id of the stat.
210
+ * @param params.unitSymbol The unit symbol of the stat.
211
+ * @param params.index The index of the stat.
212
+ * @param params.showIcons Whether to show icons.
213
+ * @param params.shiftValuePos Number of pixels the value has to be shifted to the right.
214
+ * @param params.bold Whether to bold the label.
215
+ * @param params.numberFormat The format of numbers on card.
216
+ * @param params.numberPrecision The precision of numbers on card.
217
+ * @param params.link Sanitized url to link to.
218
+ * @param params.labelXOffset horizontal offset for label.
219
+ * @returns The stats card text item SVG object.
220
+ */
221
+ const createTextNode = ({ icon, label, value, id, unitSymbol, index, showIcons, shiftValuePos, bold, numberFormat, numberPrecision, link, labelXOffset = 25, }) => {
222
+ if (!Number.isFinite(labelXOffset)) {
223
+ throw new Error(`Invalid labelXOffset: "${labelXOffset}"`);
224
+ }
225
+ if (!Number.isFinite(shiftValuePos)) {
226
+ throw new Error(`Invalid shiftValuePos: "${shiftValuePos}"`);
227
+ }
228
+ if (!Number.isFinite(index)) {
229
+ throw new Error(`Invalid index: "${index}"`);
230
+ }
231
+ const precision = numberPrecision !== undefined && Number.isFinite(numberPrecision)
232
+ ? clampValue(numberPrecision, 0, 2)
233
+ : undefined;
234
+ // `long` format and the percentage stat keep the raw value; everything else
235
+ // (always a number here) is abbreviated via kFormatter.
236
+ const rawValue = numberFormat.toLowerCase() === "long" || id === "prs_merged_percentage";
237
+ const kValue = rawValue || typeof value !== "number"
238
+ ? value
239
+ : kFormatter(value, precision);
240
+ const staggerDelay = (index + 3) * 150;
241
+ const boldClass = bold ? " bold" : "not_bold";
242
+ const valueX = (showIcons ? 140 : 120) + (bold ? 5 : 0) + shiftValuePos;
243
+ const unit = unitSymbol ? ` ${unitSymbol}` : "";
244
+ const labelOffset = showIcons ? `x="${labelXOffset}"` : "";
245
+ const iconSvg = showIcons
246
+ ? `
247
+ <svg data-testid="icon" class="icon" viewBox="0 0 16 16" version="1.1" width="16" height="16">
248
+ ${icon}
249
+ </svg>
250
+ `
251
+ : "";
252
+ const content = `
253
+ ${iconSvg}
254
+ <text class="stat ${boldClass}" ${labelOffset} y="12.5">${encodeHTML(label)}:</text>
255
+ <text
256
+ class="stat ${boldClass}"
257
+ x="${valueX}"
258
+ y="12.5"
259
+ data-testid="${id}"
260
+ >${kValue}${unit}</text>`;
261
+ const inner = link ? `<a href="${link}">${content}</a>` : content;
262
+ return `
263
+ <g class="stagger" style="animation-delay: ${staggerDelay}ms" transform="translate(25, 0)">${inner}
264
+ </g>
265
+ `;
266
+ };
200
267
  // Script parameters.
201
268
  const ERROR_CARD_LENGTH = 576.5;
202
269
  const UPSTREAM_API_ERRORS = [
@@ -220,7 +287,6 @@ const UPSTREAM_API_ERRORS = [
220
287
  */
221
288
  const renderError = ({ message, secondaryMessage = "", renderOptions = {}, }) => {
222
289
  const { title_color, text_color, bg_color, border_color, theme = "default", show_repo_link = true, } = renderOptions;
223
- // returns theme based colors with proper overrides and defaults
224
290
  const { titleColor, textColor, bgColor, borderColor } = getCardColors({
225
291
  title_color,
226
292
  text_color,
@@ -408,4 +474,4 @@ const splitWrappedText = (text, fontSize, maxWidth) => {
408
474
  const countWrappedLines = (text, fontSize, maxWidth, maxLines) => {
409
475
  return Math.min(Math.max(1, splitWrappedText(text, fontSize, maxWidth).length), maxLines);
410
476
  };
411
- export { renderError, createLanguageNode, createProgressNode, iconWithLabel, flexLayout, measureText, splitWrappedText, countWrappedLines, wrappedTextNode, wrappedTextStyles, };
477
+ export { renderError, createLanguageNode, createProgressNode, createTextNode, iconWithLabel, flexLayout, measureText, splitWrappedText, countWrappedLines, wrappedTextNode, wrappedTextStyles, };
@@ -18,16 +18,17 @@ interface ResponseErrors {
18
18
  * Defaults to `unknown` (error fields only) for callers that don't care about the payload.
19
19
  */
20
20
  type FetcherResponse<TData = unknown> = AxiosResponse<TData & ResponseErrors>;
21
- type FetcherFunction<TData = unknown> = (variables: Record<string, unknown>, token: string, retriesForTests?: number) => Promise<FetcherResponse<TData>>;
21
+ type FetcherFunction<TData = unknown, TVariables = Record<string, unknown>> = (variables: TVariables, token: string, retriesForTests?: number) => Promise<FetcherResponse<TData>>;
22
22
  /**
23
23
  * Try to execute the fetcher function until it succeeds or the max number of retries is reached.
24
24
  *
25
25
  * @template TData Shape of `response.data` returned by the fetcher.
26
+ * @template TVariables Variables the fetcher accepts.
26
27
  * @param fetcher The fetcher function.
27
28
  * @param variables Object with arguments to pass to the fetcher function.
28
29
  * @param pat Optional PAT override.
29
30
  * @returns The response from the fetcher function.
30
31
  */
31
- declare const retryer: <TData = unknown>(fetcher: FetcherFunction<TData>, variables: Record<string, unknown>, pat?: string | null) => Promise<FetcherResponse<TData>>;
32
+ declare const retryer: <TData = unknown, TVariables = Record<string, unknown>>(fetcher: FetcherFunction<TData, TVariables>, variables: TVariables, pat?: string | null) => Promise<FetcherResponse<TData>>;
32
33
  export { retryer };
33
34
  //# sourceMappingURL=retryer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retryer.d.ts","sourceRoot":"","sources":["../../src/common/retryer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAM3C;;;;GAIG;AACH,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAgBD;;;;;GAKG;AACH,KAAK,eAAe,CAAC,KAAK,GAAG,OAAO,IAAI,aAAa,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC;AAE9E,KAAK,eAAe,CAAC,KAAK,GAAG,OAAO,IAAI,CACtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,MAAM,KACrB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;AAErC;;;;;;;;GAQG;AACH,QAAA,MAAM,OAAO,GAAU,KAAK,GAAG,OAAO,EACpC,SAAS,eAAe,CAAC,KAAK,CAAC,EAC/B,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,MAAK,MAAM,GAAG,IAAW,KACxB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAiEhC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"retryer.d.ts","sourceRoot":"","sources":["../../src/common/retryer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAM3C;;;;GAIG;AACH,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAgBD;;;;;GAKG;AACH,KAAK,eAAe,CAAC,KAAK,GAAG,OAAO,IAAI,aAAa,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC;AAE9E,KAAK,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAC5E,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,MAAM,KACrB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;AAErC;;;;;;;;;GASG;AACH,QAAA,MAAM,OAAO,GAAU,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,SAAS,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,EAC3C,WAAW,UAAU,EACrB,MAAK,MAAM,GAAG,IAAW,KACxB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAiEhC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -18,6 +18,7 @@ function getRandomInt(max) {
18
18
  * Try to execute the fetcher function until it succeeds or the max number of retries is reached.
19
19
  *
20
20
  * @template TData Shape of `response.data` returned by the fetcher.
21
+ * @template TVariables Variables the fetcher accepts.
21
22
  * @param fetcher The fetcher function.
22
23
  * @param variables Object with arguments to pass to the fetcher function.
23
24
  * @param pat Optional PAT override.
@@ -1 +1 @@
1
- {"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/fetchers/gist.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA6F3C;;;;;;GAMG;AACH,QAAA,MAAM,SAAS,GACb,IAAI,MAAM,EACV,MAAK,MAAM,GAAG,IAAW,KACxB,OAAO,CAAC,QAAQ,CAwBlB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"gist.d.ts","sourceRoot":"","sources":["../../src/fetchers/gist.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkC3C;;;;;;GAMG;AACH,QAAA,MAAM,SAAS,GACb,IAAI,MAAM,EACV,MAAK,MAAM,GAAG,IAAW,KACxB,OAAO,CAAC,QAAQ,CA0BlB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,39 +1,8 @@
1
1
  import { MissingParamError } from "../common/error.js";
2
- import { request } from "../common/http.js";
2
+ import { createGraphQLFetcher } from "../common/http.js";
3
3
  import { retryer } from "../common/retryer.js";
4
- const QUERY = `
5
- query gistInfo($gistName: String!) {
6
- viewer {
7
- gist(name: $gistName) {
8
- description
9
- owner {
10
- login
11
- }
12
- stargazerCount
13
- forks {
14
- totalCount
15
- }
16
- files {
17
- name
18
- language {
19
- name
20
- }
21
- size
22
- }
23
- }
24
- }
25
- }
26
- `;
27
- /**
28
- * Gist data fetcher.
29
- *
30
- * @param variables Fetcher variables.
31
- * @param token GitHub token.
32
- * @returns The response.
33
- */
34
- const fetcher = (variables, token) => {
35
- return request({ query: QUERY, variables }, { Authorization: `token ${token}` });
36
- };
4
+ import { GistInfoDocument } from "../graphql/generated/gist.js";
5
+ const fetcher = createGraphQLFetcher(GistInfoDocument, "token");
37
6
  /**
38
7
  * This function calculates the primary language of a gist by files size.
39
8
  *
@@ -45,7 +14,7 @@ const calculatePrimaryLanguage = (files) => {
45
14
  for (const file of files) {
46
15
  if (file.language) {
47
16
  languages[file.language.name] =
48
- (languages[file.language.name] ?? 0) + file.size;
17
+ (languages[file.language.name] ?? 0) + (file.size ?? 0);
49
18
  }
50
19
  }
51
20
  let primaryLanguage = null;
@@ -77,15 +46,15 @@ const fetchGist = async (id, pat = null) => {
77
46
  if (!gist) {
78
47
  throw new Error("Gist not found");
79
48
  }
80
- const firstFile = gist.files[0];
81
- if (!firstFile) {
49
+ const firstFile = gist.files?.[0];
50
+ if (!firstFile?.name) {
82
51
  throw new Error("Gist has no files");
83
52
  }
84
53
  return {
85
54
  name: firstFile.name,
86
- nameWithOwner: `${gist.owner.login}/${firstFile.name}`,
55
+ nameWithOwner: `${gist.owner?.login ?? ""}/${firstFile.name}`,
87
56
  description: gist.description,
88
- language: calculatePrimaryLanguage(gist.files),
57
+ language: calculatePrimaryLanguage(gist.files?.filter((file) => !!file) ?? []),
89
58
  starsCount: gist.stargazerCount,
90
59
  forksCount: gist.forks.totalCount,
91
60
  };
@@ -1,16 +1,17 @@
1
- /**
2
- * Repository data.
3
- */
4
- export type RepositoryData = any;
5
- /**
6
- * @typedef {import("./types").RepositoryData} RepositoryData Repository data.
7
- */
1
+ import type { RepositoryData } from "./types.js";
8
2
  /**
9
3
  * Fetch repository data.
10
4
  *
11
- * @param {string} username GitHub username.
12
- * @param {string} reponame GitHub repository name.
13
- * @returns {Promise<RepositoryData>} Repository data.
5
+ * @param username GitHub username.
6
+ * @param reponame GitHub repository name.
7
+ * @param include_prs_authored Include count of PRs authored.
8
+ * @param include_prs_commented Include count of PRs commented.
9
+ * @param include_prs_reviewed Include count of PRs reviewed.
10
+ * @param include_issues_authored Include count of issues authored.
11
+ * @param include_issues_commented Include count of issues commented.
12
+ * @param pat Optional PAT override.
13
+ * @returns Repository data.
14
14
  */
15
- export function fetchRepo(username: string, reponame: string, include_prs_authored?: boolean, include_prs_commented?: boolean, include_prs_reviewed?: boolean, include_issues_authored?: boolean, include_issues_commented?: boolean, pat?: null): Promise<RepositoryData>;
15
+ declare const fetchRepo: (username: string, reponame: string, include_prs_authored?: boolean, include_prs_commented?: boolean, include_prs_reviewed?: boolean, include_issues_authored?: boolean, include_issues_commented?: boolean, pat?: string | null) => Promise<RepositoryData>;
16
+ export { fetchRepo };
16
17
  //# sourceMappingURL=repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/fetchers/repo.js"],"names":[],"mappings":";;;;AAuDA;;GAEG;AAEH;;;;;;GAMG;AACH,oCAJW,MAAM,YACN,MAAM,uLACJ,OAAO,CAAC,cAAc,CAAC,CA8FnC"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/fetchers/repo.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,SAAS,GACb,UAAU,MAAM,EAChB,UAAU,MAAM,EAChB,8BAA4B,EAC5B,+BAA6B,EAC7B,8BAA4B,EAC5B,iCAA+B,EAC/B,kCAAgC,EAChC,MAAK,MAAM,GAAG,IAAW,KACxB,OAAO,CAAC,cAAc,CA6ExB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}