@stats-forge/github-stats-forge-core 0.0.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) 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/contributed-to.d.ts +23 -0
  6. package/build/api/contributed-to.d.ts.map +1 -0
  7. package/build/api/contributed-to.js +43 -0
  8. package/build/api/gist.d.ts +8 -22
  9. package/build/api/gist.d.ts.map +1 -1
  10. package/build/api/gist.js +14 -36
  11. package/build/api/handler.d.ts +16 -0
  12. package/build/api/handler.d.ts.map +1 -0
  13. package/build/api/handler.js +29 -0
  14. package/build/api/index.d.ts +13 -12
  15. package/build/api/index.d.ts.map +1 -1
  16. package/build/api/index.js +1 -0
  17. package/build/api/params.d.ts +21 -12
  18. package/build/api/params.d.ts.map +1 -1
  19. package/build/api/params.js +41 -19
  20. package/build/api/pin.d.ts +11 -31
  21. package/build/api/pin.d.ts.map +1 -1
  22. package/build/api/pin.js +35 -63
  23. package/build/api/stats.d.ts +15 -16
  24. package/build/api/stats.d.ts.map +1 -1
  25. package/build/api/stats.js +60 -99
  26. package/build/api/top-langs.d.ts +13 -18
  27. package/build/api/top-langs.d.ts.map +1 -1
  28. package/build/api/top-langs.js +35 -72
  29. package/build/api/wakatime.d.ts +11 -17
  30. package/build/api/wakatime.d.ts.map +1 -1
  31. package/build/api/wakatime.js +27 -64
  32. package/build/calculateRank.d.ts +0 -9
  33. package/build/calculateRank.d.ts.map +1 -1
  34. package/build/calculateRank.js +12 -17
  35. package/build/cards/contributed-to.d.ts +19 -0
  36. package/build/cards/contributed-to.d.ts.map +1 -0
  37. package/build/cards/contributed-to.js +242 -0
  38. package/build/cards/gist.d.ts +3 -4
  39. package/build/cards/gist.d.ts.map +1 -1
  40. package/build/cards/gist.js +38 -43
  41. package/build/cards/options.d.ts +1 -1
  42. package/build/cards/repo.d.ts +14 -5
  43. package/build/cards/repo.d.ts.map +1 -1
  44. package/build/cards/repo.js +93 -103
  45. package/build/cards/stats.d.ts +18 -11
  46. package/build/cards/stats.d.ts.map +1 -1
  47. package/build/cards/stats.js +191 -222
  48. package/build/cards/top-languages.d.ts +18 -33
  49. package/build/cards/top-languages.d.ts.map +1 -1
  50. package/build/cards/top-languages.js +196 -387
  51. package/build/cards/wakatime.d.ts +17 -8
  52. package/build/cards/wakatime.d.ts.map +1 -1
  53. package/build/cards/wakatime.js +133 -187
  54. package/build/common/Card.d.ts +20 -59
  55. package/build/common/Card.d.ts.map +1 -1
  56. package/build/common/Card.js +131 -198
  57. package/build/common/I18n.d.ts +1 -7
  58. package/build/common/I18n.d.ts.map +1 -1
  59. package/build/common/I18n.js +7 -8
  60. package/build/common/brand.d.ts +76 -0
  61. package/build/common/brand.d.ts.map +1 -0
  62. package/build/common/brand.js +73 -0
  63. package/build/common/color.d.ts +4 -17
  64. package/build/common/color.d.ts.map +1 -1
  65. package/build/common/color.js +67 -49
  66. package/build/common/config.d.ts +4 -14
  67. package/build/common/config.d.ts.map +1 -1
  68. package/build/common/config.js +3 -16
  69. package/build/common/constants.d.ts +6 -2
  70. package/build/common/constants.d.ts.map +1 -1
  71. package/build/common/constants.js +5 -1
  72. package/build/common/date.d.ts +50 -5
  73. package/build/common/date.d.ts.map +1 -1
  74. package/build/common/date.js +104 -4
  75. package/build/common/emojiMap.d.ts +8 -0
  76. package/build/common/emojiMap.d.ts.map +1 -0
  77. package/build/common/emojiMap.js +10 -0
  78. package/build/common/emojiMap.json +1915 -0
  79. package/build/common/error.d.ts +1 -10
  80. package/build/common/error.d.ts.map +1 -1
  81. package/build/common/error.js +1 -10
  82. package/build/common/fmt.d.ts +3 -15
  83. package/build/common/fmt.d.ts.map +1 -1
  84. package/build/common/fmt.js +7 -35
  85. package/build/common/http.d.ts +2 -7
  86. package/build/common/http.d.ts.map +1 -1
  87. package/build/common/http.js +8 -17
  88. package/build/common/icons.d.ts +20 -20
  89. package/build/common/icons.d.ts.map +1 -1
  90. package/build/common/icons.js +108 -67
  91. package/build/common/languageColors.d.ts +0 -1
  92. package/build/common/languageColors.d.ts.map +1 -1
  93. package/build/common/languageColors.js +1 -4
  94. package/build/common/languageColors.json +18 -2
  95. package/build/common/ops.d.ts +11 -17
  96. package/build/common/ops.d.ts.map +1 -1
  97. package/build/common/ops.js +22 -39
  98. package/build/common/render.d.ts +34 -82
  99. package/build/common/render.d.ts.map +1 -1
  100. package/build/common/render.js +225 -259
  101. package/build/common/retryer.d.ts +2 -7
  102. package/build/common/retryer.d.ts.map +1 -1
  103. package/build/common/retryer.js +4 -11
  104. package/build/fetchers/contributed-to.d.ts +62 -0
  105. package/build/fetchers/contributed-to.d.ts.map +1 -0
  106. package/build/fetchers/contributed-to.js +184 -0
  107. package/build/fetchers/gist.d.ts +2 -5
  108. package/build/fetchers/gist.d.ts.map +1 -1
  109. package/build/fetchers/gist.js +1 -5
  110. package/build/fetchers/graphql-error.d.ts +13 -0
  111. package/build/fetchers/graphql-error.d.ts.map +1 -0
  112. package/build/fetchers/graphql-error.js +29 -0
  113. package/build/fetchers/index.d.ts +13 -12
  114. package/build/fetchers/index.d.ts.map +1 -1
  115. package/build/fetchers/index.js +1 -0
  116. package/build/fetchers/repo.d.ts +2 -11
  117. package/build/fetchers/repo.d.ts.map +1 -1
  118. package/build/fetchers/repo.js +20 -33
  119. package/build/fetchers/stats.d.ts +16 -40
  120. package/build/fetchers/stats.d.ts.map +1 -1
  121. package/build/fetchers/stats.js +89 -271
  122. package/build/fetchers/top-languages.d.ts +2 -9
  123. package/build/fetchers/top-languages.d.ts.map +1 -1
  124. package/build/fetchers/top-languages.js +16 -47
  125. package/build/fetchers/types.d.ts +25 -1
  126. package/build/fetchers/types.d.ts.map +1 -1
  127. package/build/fetchers/wakatime.d.ts +2 -6
  128. package/build/fetchers/wakatime.d.ts.map +1 -1
  129. package/build/fetchers/wakatime.js +1 -5
  130. package/build/graphql/contributionsCollection.d.ts +9 -0
  131. package/build/graphql/contributionsCollection.d.ts.map +1 -0
  132. package/build/graphql/contributionsCollection.js +12 -0
  133. package/build/graphql/contributionsDocument.d.ts +6 -6
  134. package/build/graphql/contributionsDocument.d.ts.map +1 -1
  135. package/build/graphql/contributionsDocument.js +8 -16
  136. package/build/graphql/generated/contributed-to.d.ts +22 -0
  137. package/build/graphql/generated/contributed-to.d.ts.map +1 -0
  138. package/build/graphql/generated/contributed-to.js +11 -0
  139. package/build/graphql/generated/gist.d.ts +1 -1
  140. package/build/graphql/generated/repo.d.ts +1 -1
  141. package/build/graphql/generated/stats.d.ts +16 -4
  142. package/build/graphql/generated/stats.d.ts.map +1 -1
  143. package/build/graphql/generated/stats.js +2 -2
  144. package/build/graphql/generated/top-languages.d.ts +2 -2
  145. package/build/graphql/graphqlDocument.d.ts +1 -2
  146. package/build/graphql/graphqlDocument.d.ts.map +1 -1
  147. package/build/graphql/graphqlDocument.js +0 -1
  148. package/build/graphql/reposContributedToDocument.d.ts +4 -5
  149. package/build/graphql/reposContributedToDocument.d.ts.map +1 -1
  150. package/build/graphql/reposContributedToDocument.js +11 -7
  151. package/build/markup/css.d.ts +35 -0
  152. package/build/markup/css.d.ts.map +1 -0
  153. package/build/markup/css.js +64 -0
  154. package/build/markup/element.d.ts +41 -0
  155. package/build/markup/element.d.ts.map +1 -0
  156. package/build/markup/element.js +127 -0
  157. package/build/markup/html.d.ts +13 -0
  158. package/build/markup/html.d.ts.map +1 -0
  159. package/build/markup/html.js +27 -0
  160. package/build/markup/index.d.ts +9 -0
  161. package/build/markup/index.d.ts.map +1 -0
  162. package/build/markup/index.js +6 -0
  163. package/build/markup/serialize.d.ts +16 -0
  164. package/build/markup/serialize.d.ts.map +1 -0
  165. package/build/markup/serialize.js +17 -0
  166. package/build/themes/index.d.ts +332 -333
  167. package/build/themes/index.d.ts.map +1 -1
  168. package/build/themes/index.js +1 -1
  169. package/build/translations.d.ts +66 -7
  170. package/build/translations.d.ts.map +1 -1
  171. package/build/translations.js +686 -629
  172. package/package.json +17 -26
  173. package/src/api/api-result.ts +10 -9
  174. package/src/api/contributed-to.ts +84 -0
  175. package/src/api/gist.ts +22 -46
  176. package/src/api/handler.ts +42 -0
  177. package/src/api/index.ts +13 -12
  178. package/src/api/params.ts +74 -29
  179. package/src/api/pin.ts +38 -65
  180. package/src/api/stats.ts +81 -118
  181. package/src/api/top-langs.ts +38 -80
  182. package/src/api/wakatime.ts +35 -73
  183. package/src/calculateRank.ts +12 -23
  184. package/src/cards/contributed-to.ts +373 -0
  185. package/src/cards/gist.ts +55 -49
  186. package/src/cards/options.ts +1 -1
  187. package/src/cards/repo.ts +134 -120
  188. package/src/cards/stats.ts +262 -252
  189. package/src/cards/top-languages.ts +315 -422
  190. package/src/cards/wakatime.ts +207 -225
  191. package/src/common/Card.ts +207 -214
  192. package/src/common/I18n.ts +7 -8
  193. package/src/common/brand.ts +109 -0
  194. package/src/common/color.ts +80 -57
  195. package/src/common/config.ts +5 -18
  196. package/src/common/constants.ts +8 -2
  197. package/src/common/date.ts +135 -5
  198. package/src/common/emojiMap.json +1915 -0
  199. package/src/common/emojiMap.ts +13 -0
  200. package/src/common/error.ts +2 -11
  201. package/src/common/fmt.ts +7 -44
  202. package/src/common/http.ts +9 -15
  203. package/src/common/icons.ts +122 -42
  204. package/src/common/languageColors.json +18 -2
  205. package/src/common/languageColors.ts +1 -4
  206. package/src/common/ops.ts +31 -48
  207. package/src/common/render.ts +334 -284
  208. package/src/common/retryer.ts +8 -15
  209. package/src/fetchers/contributed-to.ts +271 -0
  210. package/src/fetchers/gist.ts +8 -12
  211. package/src/fetchers/graphql-error.ts +36 -0
  212. package/src/fetchers/index.ts +15 -12
  213. package/src/fetchers/repo.ts +27 -40
  214. package/src/fetchers/stats.ts +157 -366
  215. package/src/fetchers/top-languages.ts +27 -55
  216. package/src/fetchers/types.ts +27 -1
  217. package/src/fetchers/wakatime.ts +5 -9
  218. package/src/graphql/contributionsCollection.ts +18 -0
  219. package/src/graphql/contributionsDocument.ts +14 -19
  220. package/src/graphql/generated/contributed-to.ts +25 -0
  221. package/src/graphql/generated/gist.ts +1 -1
  222. package/src/graphql/generated/repo.ts +1 -1
  223. package/src/graphql/generated/stats.ts +21 -8
  224. package/src/graphql/generated/top-languages.ts +2 -2
  225. package/src/graphql/graphqlDocument.ts +1 -2
  226. package/src/graphql/queries/contributed-to.graphql +8 -0
  227. package/src/graphql/queries/stats.graphql +14 -2
  228. package/src/graphql/reposContributedToDocument.ts +16 -15
  229. package/src/markup/css.ts +118 -0
  230. package/src/markup/element.ts +246 -0
  231. package/src/markup/html.ts +34 -0
  232. package/src/markup/index.ts +9 -0
  233. package/src/markup/serialize.ts +27 -0
  234. package/src/themes/index.ts +1 -1
  235. package/src/translations.ts +699 -629
  236. package/build/cards/index.d.ts +0 -11
  237. package/build/cards/index.d.ts.map +0 -1
  238. package/build/cards/index.js +0 -7
  239. package/build/common/html.d.ts +0 -8
  240. package/build/common/html.d.ts.map +0 -1
  241. package/build/common/html.js +0 -14
  242. package/build/index.d.ts +0 -15
  243. package/build/index.d.ts.map +0 -1
  244. package/build/index.js +0 -10
  245. package/src/_emoji-name-map.d.ts +0 -10
  246. package/src/_github-username-regex.d.ts +0 -4
  247. package/src/cards/index.ts +0 -21
  248. package/src/common/html.ts +0 -17
  249. package/src/index.ts +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/cards/repo.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AASnE,UAAU,eAAgB,SAAQ,iBAAiB;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsCD;;;;;;GAMG;AACH,QAAA,MAAM,cAAc,GAClB,MAAM,cAAc,EACpB,UAAS,WAAW,CAAC,eAAe,CAAM,KACzC,MA4RF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/cards/repo.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAmBnE,UAAU,eAAgB,SAAQ,iBAAiB;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuCD;;;;GAIG;AACH,QAAA,MAAM,UAAU,SAAU,cAAc,YAAW,WAAW,CAAC,eAAe,CAAC,KAAQ,MAoRtF,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,cAAc;;QAEhB,IAAI;QACJ,aAAa;;CAEf,CAAC;AAEH,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -1,54 +1,53 @@
1
+ import { CARD_ICON, CARD_WIDTH, FONT_SIZE, FONT_WEIGHT, font } from '../common/brand.js';
1
2
  import { Card } from '../common/Card.js';
2
3
  import { getLightDarkColors } from '../common/color.js';
3
- import { kFormatter, wrapTextMultiline } from '../common/fmt.js';
4
- import { encodeHTML } from '../common/html.js';
4
+ import { kFormatter } from '../common/fmt.js';
5
5
  import { I18n } from '../common/I18n.js';
6
6
  import { icons } from '../common/icons.js';
7
7
  import { buildSearchFilter, clampValue, parseEmojis } from '../common/ops.js';
8
- import { countWrappedLines, createLanguageNode, createTextNode, flexLayout, iconWithLabel, measureText, wrappedTextNode, wrappedTextStyles, } from '../common/render.js';
8
+ import { NUMBER_FORMATS, countWrappedLines, wrapTextMultiline, createLanguageNode, createTextNode, flexLayout, iconWithLabel, measureText, wrappedTextNode, wrappedTextStyles, } from '../common/render.js';
9
+ import { el, rule } from '../markup/index.js';
9
10
  import { repoCardLocales } from '../translations.js';
10
11
  const ICON_SIZE = 16;
11
- const CARD_DEFAULT_WIDTH = 400;
12
+ const CARD_DEFAULT_WIDTH = CARD_WIDTH.standard;
12
13
  const X_OFFSET = 25;
13
- const DESCRIPTION_FONT_SIZE = 13;
14
+ const DESCRIPTION_FONT_SIZE = FONT_SIZE.meta;
14
15
  const DESCRIPTION_LINE_HEIGHT_PX = 16;
15
16
  const DESCRIPTION_MAX_LINES = 3;
17
+ /** Stats the card draws only when `show` names them. */
18
+ const REPO_SHOW_STATS = [
19
+ 'prs_authored',
20
+ 'prs_commented',
21
+ 'prs_reviewed',
22
+ 'issues_authored',
23
+ 'issues_commented',
24
+ ];
16
25
  /**
17
26
  * Retrieves the repository description and wraps it to fit the card width.
18
27
  *
19
- * @param label The repository description.
20
- * @param xOffset Horizontal offset of the badge.
21
28
  * @returns Wrapped repo description SVG object.
22
29
  */
23
30
  const getBadgeSVG = (label, xOffset = 0) => {
24
31
  if (!Number.isFinite(xOffset)) {
25
- throw new Error(`Invalid xOffset: "${xOffset}"`);
32
+ throw new TypeError(`Invalid xOffset: "${xOffset}"`);
26
33
  }
27
- return `
28
- <g data-testid="badge" class="badge" transform="translate(${320 + xOffset}, -18)">
29
- <rect stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
30
- <text
31
- x="23" y="-5"
32
- alignment-baseline="central"
33
- dominant-baseline="central"
34
- text-anchor="middle"
35
- >
36
- ${encodeHTML(label)}
37
- </text>
38
- </g>
39
- `;
34
+ return el('g', { 'data-testid': 'badge', class: 'badge', transform: `translate(${320 + xOffset}, -18)` }, el('rect', { 'stroke-width': 1, width: 70, height: 20, x: -12, y: -14, ry: 10, rx: 10 }), el('text', {
35
+ x: 23,
36
+ y: -5,
37
+ 'alignment-baseline': 'central',
38
+ 'dominant-baseline': 'central',
39
+ 'text-anchor': 'middle',
40
+ }, label));
40
41
  };
41
42
  /**
42
43
  * Renders repository card details.
43
44
  *
44
- * @param repo Repository data.
45
- * @param options Card options.
46
45
  * @returns Repository card SVG object.
47
46
  */
48
- const renderRepoCard = (repo, options = {}) => {
47
+ const renderCard = (repo, options = {}) => {
49
48
  const { name, nameWithOwner, description, primaryLanguage, isArchived, isTemplate, stargazerCount, forkCount, totalPRsAuthored, totalPRsCommented, totalPRsReviewed, totalIssuesAuthored, totalIssuesCommented, } = repo;
50
49
  const { hide_border = false, card_width_input, show_owner = false, browser_rendering = false, show = [], show_icons = true, number_format = 'short', text_bold = false, line_height = 22, username, theme = 'default_repocard', border_radius, locale, description_lines_count, } = options;
51
- const card_width = card_width_input && !isNaN(card_width_input)
50
+ const card_width = card_width_input && !Number.isNaN(card_width_input)
52
51
  ? card_width_input
53
52
  : show.length >= 2
54
53
  ? CARD_DEFAULT_WIDTH + 30
@@ -57,10 +56,12 @@ const renderRepoCard = (repo, options = {}) => {
57
56
  locale,
58
57
  translations: repoCardLocales,
59
58
  });
59
+ // Typed against the exported list, so a stat drawn here cannot be missing from it.
60
+ const shows = (stat) => show.includes(stat);
60
61
  const repoFilter = encodeURIComponent(buildSearchFilter([nameWithOwner], []));
61
62
  const encodedUsername = encodeURIComponent(username ?? '');
62
63
  const STATS = {};
63
- if (show.includes('prs_authored')) {
64
+ if (shows('prs_authored')) {
64
65
  STATS['prs_authored'] = {
65
66
  icon: icons.prs,
66
67
  label: i18n.t('repocard.prs-authored'),
@@ -69,7 +70,7 @@ const renderRepoCard = (repo, options = {}) => {
69
70
  link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&amp;type=pullrequests`,
70
71
  };
71
72
  }
72
- if (show.includes('prs_commented')) {
73
+ if (shows('prs_commented')) {
73
74
  STATS['prs_commented'] = {
74
75
  icon: icons.comments,
75
76
  label: i18n.t('repocard.prs-commented'),
@@ -78,7 +79,7 @@ const renderRepoCard = (repo, options = {}) => {
78
79
  link: `https://github.com/search?q=${repoFilter}commenter%3A${encodedUsername}+-author%3A${encodedUsername}&amp;type=pullrequests`,
79
80
  };
80
81
  }
81
- if (show.includes('prs_reviewed')) {
82
+ if (shows('prs_reviewed')) {
82
83
  STATS['prs_reviewed'] = {
83
84
  icon: icons.reviews,
84
85
  label: i18n.t('repocard.prs-reviewed'),
@@ -87,7 +88,7 @@ const renderRepoCard = (repo, options = {}) => {
87
88
  link: `https://github.com/search?q=${repoFilter}reviewed-by%3A${encodedUsername}+-author%3A${encodedUsername}&amp;type=pullrequests`,
88
89
  };
89
90
  }
90
- if (show.includes('issues_authored')) {
91
+ if (shows('issues_authored')) {
91
92
  STATS['issues_authored'] = {
92
93
  icon: icons.issues,
93
94
  label: i18n.t('repocard.issues-authored'),
@@ -96,7 +97,7 @@ const renderRepoCard = (repo, options = {}) => {
96
97
  link: `https://github.com/search?q=${repoFilter}author%3A${encodedUsername}&amp;type=issues`,
97
98
  };
98
99
  }
99
- if (show.includes('issues_commented')) {
100
+ if (shows('issues_commented')) {
100
101
  STATS['issues_commented'] = {
101
102
  icon: icons.discussions_started,
102
103
  label: i18n.t('repocard.issues-commented'),
@@ -121,12 +122,12 @@ const renderRepoCard = (repo, options = {}) => {
121
122
  link: stat.link,
122
123
  labelXOffset: 23,
123
124
  }));
124
- const extraLHeight = parseInt(String(line_height), 10);
125
+ const extraLHeight = Number.parseInt(String(line_height), 10);
125
126
  const lineHeight = 10;
126
127
  const header = show_owner ? nameWithOwner : name;
127
- const langName = (primaryLanguage && primaryLanguage.name) || 'Unspecified';
128
- const langColor = (primaryLanguage && primaryLanguage.color) || '#333';
129
- const desc = parseEmojis(description || 'No description provided');
128
+ const langName = primaryLanguage?.name || i18n.t('repocard.unspecified-language');
129
+ const langColor = primaryLanguage?.color || '#333';
130
+ const desc = parseEmojis(description || i18n.t('repocard.no-description'));
130
131
  const descriptionBoxWidth = card_width - 2 * X_OFFSET;
131
132
  let descriptionLinesCount;
132
133
  let descriptionSvg;
@@ -157,19 +158,12 @@ const renderRepoCard = (repo, options = {}) => {
157
158
  descriptionLinesCount = description_lines_count
158
159
  ? clampValue(description_lines_count, 1, DESCRIPTION_MAX_LINES)
159
160
  : multiLineDescription.length;
160
- descriptionSvg = multiLineDescription
161
- .map((line) => `<tspan dy="1.2em" x="${X_OFFSET}">${encodeHTML(line)}</tspan>`)
162
- .join('');
163
- descriptionSvg = `<text class="description" x="${X_OFFSET}" y="-5">
164
- ${descriptionSvg}
165
- </text>`;
161
+ descriptionSvg = el('text', { class: 'description', x: X_OFFSET, y: -5 }, multiLineDescription.map((line) => el('tspan', { dy: '1.2em', x: X_OFFSET }, line)));
166
162
  }
167
- const extraHeight = Object.keys(STATS).length
168
- ? -7 + (Math.ceil(statItems.length / 2) + 1) * extraLHeight
169
- : 0;
163
+ const extraHeight = Object.keys(STATS).length > 0 ? -7 + (Math.ceil(statItems.length / 2) + 1) * extraLHeight : 0;
170
164
  const height = (descriptionLinesCount > 1 ? 120 : 110) + descriptionLinesCount * lineHeight + extraHeight;
171
165
  const { lightColors, darkColors } = getLightDarkColors({ ...options, theme });
172
- const svgLanguage = primaryLanguage ? createLanguageNode(langName, langColor) : '';
166
+ const svgLanguage = primaryLanguage ? createLanguageNode(langName, langColor) : undefined;
173
167
  const totalStars = kFormatter(stargazerCount);
174
168
  const totalForks = kFormatter(forkCount);
175
169
  const svgStars = iconWithLabel(icons.star, totalStars, 'stargazers', ICON_SIZE);
@@ -182,27 +176,19 @@ const renderRepoCard = (repo, options = {}) => {
182
176
  ICON_SIZE + measureText(`${totalForks}`, 12),
183
177
  ],
184
178
  gap: 25,
185
- }).join('');
179
+ });
186
180
  const extraRows = [];
187
181
  for (let i = 0; i < statItems.length; i += 2) {
188
182
  extraRows.push(flexLayout({
189
183
  items: statItems.slice(i, i + 2),
190
184
  gap: 210,
191
185
  direction: 'row',
192
- }).join(''));
186
+ }));
193
187
  }
194
- const extraItems = `
195
- <svg x="0" y="0"><g transform="translate(-3, ${height - 52 - extraHeight})">
196
- ${flexLayout({
197
- items: extraRows,
198
- gap: extraLHeight,
199
- direction: 'column',
200
- }).join('')}
201
- </g></svg>
202
- `;
188
+ const extraItems = el('svg', { x: 0, y: 0 }, el('g', { transform: `translate(-3, ${height - 52 - extraHeight})` }, flexLayout({ items: extraRows, gap: extraLHeight, direction: 'column' })));
203
189
  const card = new Card({
204
190
  defaultTitle: header.length > 35 ? `${header.slice(0, 35)}...` : header,
205
- titlePrefixIcon: icons.contribs,
191
+ titlePrefixIcon: CARD_ICON.repo,
206
192
  width: card_width,
207
193
  height,
208
194
  border_radius,
@@ -212,39 +198,36 @@ const renderRepoCard = (repo, options = {}) => {
212
198
  card.setHideBorder(hide_border);
213
199
  card.setHideTitle(false);
214
200
  card.setCSS({
215
- light: ({ textColor, iconColor }) => `
216
- .description {
217
- font: 400 ${DESCRIPTION_FONT_SIZE}px 'Segoe UI', Ubuntu, Sans-Serif;fill: ${textColor};
218
- ${browser_rendering ? wrappedTextStyles(textColor) : ''}
219
- }
220
- .gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
221
- .badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
222
- .badge rect { opacity: 0.2; stroke: ${textColor} }
223
- .badge text { fill: ${textColor} }
224
-
225
- .stat { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
226
- .stagger {
227
- opacity: 0;
228
- animation: fadeInAnimation 0.3s ease-in-out forwards;
229
- }
230
- .not_bold { font-weight: 400 }
231
- .bold { font-weight: 700 }
232
- .icon {
233
- fill: ${iconColor};
234
- display: block;
235
- }
236
- `,
237
- dark: ({ textColor, iconColor }) => `
238
- .description {
239
- fill: ${textColor};
240
- ${browser_rendering ? wrappedTextStyles(textColor) : ''}
241
- }
242
- .gray { fill: ${textColor} }
243
- .badge rect { stroke: ${textColor} }
244
- .badge text { fill: ${textColor} }
245
- .stat { fill: ${textColor} }
246
- .icon { fill: ${iconColor}; }
247
- `,
201
+ light: ({ textColor, iconColor }) => [
202
+ rule('.description', {
203
+ font: font('regular', 'meta'),
204
+ fill: textColor,
205
+ ...(browser_rendering ? wrappedTextStyles(textColor) : {}),
206
+ }),
207
+ rule('.gray', { font: font('regular', 'small'), fill: textColor }),
208
+ rule('.badge', { font: font('semibold', 'micro') }),
209
+ rule('.badge rect', { opacity: 0.2, stroke: textColor }),
210
+ rule('.badge text', { fill: textColor }),
211
+ rule('.stat', { font: font('regular', 'small'), fill: textColor }),
212
+ rule('.stagger', {
213
+ opacity: 0,
214
+ animation: 'fadeInAnimation 0.3s ease-in-out forwards',
215
+ }),
216
+ rule('.not_bold', { 'font-weight': FONT_WEIGHT.regular }),
217
+ rule('.bold', { 'font-weight': FONT_WEIGHT.semibold }),
218
+ rule('.icon', { fill: iconColor, display: 'block' }),
219
+ ],
220
+ dark: ({ textColor, iconColor }) => [
221
+ rule('.description', {
222
+ fill: textColor,
223
+ ...(browser_rendering ? wrappedTextStyles(textColor) : {}),
224
+ }),
225
+ rule('.gray', { fill: textColor }),
226
+ rule('.badge rect', { stroke: textColor }),
227
+ rule('.badge text', { fill: textColor }),
228
+ rule('.stat', { fill: textColor }),
229
+ rule('.icon', { fill: iconColor }),
230
+ ],
248
231
  });
249
232
  const extraStatLabels = Object.values(STATS)
250
233
  .map((stat) => `${stat.label}: ${stat.value ?? 0}`)
@@ -258,19 +241,26 @@ const renderRepoCard = (repo, options = {}) => {
258
241
  title: card.title,
259
242
  desc: [`${desc}.`, primaryLanguage ? langName : '', extraStatLabels].filter(Boolean).join(', '),
260
243
  });
261
- return card.render(`
262
- ${isTemplate
263
- ? getBadgeSVG(i18n.t('repocard.template'), card_width - CARD_DEFAULT_WIDTH)
264
- : isArchived
265
- ? getBadgeSVG(i18n.t('repocard.archived'), card_width - CARD_DEFAULT_WIDTH)
266
- : ''}
267
-
268
- ${descriptionSvg}
269
-
270
- <g transform="translate(30, ${height - 75 - extraHeight})">
271
- ${starAndForkCount}
272
- </g>
273
- ${extraItems}
274
- `);
244
+ return card.render([
245
+ isTemplate
246
+ ? getBadgeSVG(i18n.t('repocard.template'), card_width - CARD_DEFAULT_WIDTH)
247
+ : isArchived
248
+ ? getBadgeSVG(i18n.t('repocard.archived'), card_width - CARD_DEFAULT_WIDTH)
249
+ : undefined,
250
+ descriptionSvg,
251
+ el('g', { transform: `translate(30, ${height - 75 - extraHeight})` }, starAndForkCount),
252
+ extraItems,
253
+ ]);
275
254
  };
255
+ /**
256
+ * The card, and the values each of its options accepts, keyed by the option's own name.
257
+ * They ride on the renderer so a list cannot be found without what draws it;
258
+ * the api handler forwards them onto its own export, which is what a UI reads.
259
+ */
260
+ const renderRepoCard = Object.assign(renderCard, {
261
+ OPTIONS: {
262
+ show: REPO_SHOW_STATS,
263
+ number_format: NUMBER_FORMATS,
264
+ },
265
+ });
276
266
  export { renderRepoCard };
@@ -1,7 +1,7 @@
1
- import type { StatsData } from '../fetchers/types.js';
2
- import type { CardOptions, CommonCardOptions } from './options.js';
1
+ import type { StatsData } from '../fetchers/types.ts';
2
+ import type { CardOptions, CommonCardOptions } from './options.ts';
3
3
  /** Rank indicators the card can draw; the api validates `rank_icon` against this. */
4
- declare const RANK_ICONS: readonly ["default", "github", "percentile"];
4
+ declare const RANK_ICONS: readonly ['default', 'github', 'percentile'];
5
5
  type RankIcon = (typeof RANK_ICONS)[number];
6
6
  interface StatCardOptions extends CommonCardOptions {
7
7
  locale: string;
@@ -11,7 +11,6 @@ interface StatCardOptions extends CommonCardOptions {
11
11
  card_width: number;
12
12
  hide_rank: boolean;
13
13
  include_all_commits: boolean;
14
- commits_year: number;
15
14
  line_height: number | string;
16
15
  custom_title: string;
17
16
  disable_animations: boolean;
@@ -25,13 +24,21 @@ interface StatCardOptions extends CommonCardOptions {
25
24
  /**
26
25
  * Renders the stats card.
27
26
  *
28
- * @param stats The stats data.
29
- * @param options The card options.
30
- * @param username GitHub username, used to build stat search links.
31
- * @param repo Repositories to scope the search links to.
32
- * @param owner Owners to scope the search links to.
33
27
  * @returns The stats card SVG object.
34
28
  */
35
- declare const renderStatsCard: (stats: StatsData, options?: CardOptions<StatCardOptions>, username?: string, repo?: Array<string>, owner?: Array<string>) => string;
36
- export { RANK_ICONS, renderStatsCard };
29
+ declare const renderCard: (stats: StatsData, options?: CardOptions<StatCardOptions>, username?: string, repo?: Array<string>, owner?: Array<string>) => string;
30
+ /**
31
+ * The card, and the values each of its options accepts, keyed by the option's own name.
32
+ * They ride on the renderer so a list cannot be found without what draws it;
33
+ * the api handler forwards them onto its own export, which is what a UI reads.
34
+ */
35
+ declare const renderStatsCard: typeof renderCard & {
36
+ OPTIONS: {
37
+ rank_icon: readonly ["default", "github", "percentile"];
38
+ show: readonly ["contributions", "prs_merged", "prs_merged_percentage", "reviews", "discussions_started", "discussions_answered", "prs_authored", "prs_commented", "prs_reviewed", "issues_authored", "issues_commented", "all_time_contribs"];
39
+ hide: readonly ["stars", "commits", "prs", "issues", "contribs"];
40
+ number_format: readonly ["short", "long"];
41
+ };
42
+ };
43
+ export { renderStatsCard };
37
44
  //# sourceMappingURL=stats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/cards/stats.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AASnE,qFAAqF;AACrF,QAAA,MAAM,UAAU,8CAA+C,CAAC;AAChE,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5C,UAAU,eAAgB,SAAQ,iBAAiB;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AAiLD;;;;;;;;;GASG;AACH,QAAA,MAAM,eAAe,GACnB,OAAO,SAAS,EAChB,UAAS,WAAW,CAAC,eAAe,CAAM,EAC1C,WAAW,MAAM,EACjB,OAAM,KAAK,CAAC,MAAM,CAAM,EACxB,QAAO,KAAK,CAAC,MAAM,CAAM,KACxB,MAyXF,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/cards/stats.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAKtD,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAqBnE,qFAAqF;AACrF,QAAA,MAAM,UAAU,YAAI,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAU,CAAC;AAChE,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AA0B5C,UAAU,eAAgB,SAAQ,iBAAiB;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AA8ID;;;;GAIG;AACH,QAAA,MAAM,UAAU,UACP,SAAS,YACP,WAAW,CAAC,eAAe,CAAC,aAC1B,MAAM,SACX,KAAK,CAAC,MAAM,CAAC,UACZ,KAAK,CAAC,MAAM,CAAC,KACnB,MA8WF,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,eAAe;;QAEjB,SAAS;QACT,IAAI;QACJ,IAAI;QACJ,aAAa;;CAEf,CAAC;AAEH,OAAO,EAAE,eAAe,EAAE,CAAC"}