@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
@@ -3,7 +3,6 @@
3
3
  * (`"f00"`, `"ffffff"`). This is the form user-supplied color params and
4
4
  * gradient stops arrive in.
5
5
  *
6
- * @param value Value to check.
7
6
  * @returns True if the value is a bare hex color.
8
7
  */
9
8
  declare const isBareHexColor: (value: unknown) => boolean;
@@ -12,7 +11,6 @@ declare const isBareHexColor: (value: unknown) => boolean;
12
11
  * is the form colors take once resolved by {@link getCardColors}, i.e. right
13
12
  * before they are written into the SVG.
14
13
  *
15
- * @param value Value to check.
16
14
  * @returns True if the value is a `#`-prefixed hex color.
17
15
  */
18
16
  declare const isPrefixedHexColor: (value: unknown) => boolean;
@@ -21,14 +19,12 @@ declare const isPrefixedHexColor: (value: unknown) => boolean;
21
19
  * followed by at least two bare-hex color stops, e.g. `["90", "f00", "0f0"]`.
22
20
  * The angle is written into the SVG `gradientTransform="rotate(...)"`.
23
21
  *
24
- * @param parts Gradient parts: `[angle, ...stops]`.
25
22
  * @returns True if the parts form a valid gradient.
26
23
  */
27
24
  declare const isValidGradient: (parts: Array<string>) => boolean;
28
25
  /**
29
26
  * Checks if a string is a valid input for a color or gradient.
30
27
  *
31
- * @param color String to check, may be null or undefined.
32
28
  * @returns True if the given string is a valid input.
33
29
  */
34
30
  declare const isValidColorInput: (color: string | null | undefined) => boolean;
@@ -57,8 +53,8 @@ interface CardColors {
57
53
  * Single source of truth: the param types and {@link COLOR_PARAM_KEYS} are all
58
54
  * derived from this, so adding a param here is enough.
59
55
  */
60
- declare const BASE_COLOR_KEYS: readonly ["title_color", "icon_color", "text_color", "bg_color", "border_color", "ring_color", "prog_bar_bg_color", "theme"];
61
- declare const THEME_VARIANTS: readonly ["light", "dark"];
56
+ declare const BASE_COLOR_KEYS: readonly ['title_color', 'icon_color', 'text_color', 'bg_color', 'border_color', 'ring_color', 'prog_bar_bg_color', 'theme'];
57
+ declare const THEME_VARIANTS: readonly ['light', 'dark'];
62
58
  type BaseColorKey = (typeof BASE_COLOR_KEYS)[number];
63
59
  type ThemeVariant = (typeof THEME_VARIANTS)[number];
64
60
  /**
@@ -70,15 +66,6 @@ type ColorInput = Partial<Record<BaseColorKey, string | undefined>>;
70
66
  /**
71
67
  * Returns theme based colors with proper overrides and defaults.
72
68
  *
73
- * @param props Function arguments.
74
- * @param props.title_color Card title color.
75
- * @param props.text_color Card text color.
76
- * @param props.icon_color Card icon color.
77
- * @param props.bg_color Card background color.
78
- * @param props.border_color Card border color.
79
- * @param props.ring_color Card ring color.
80
- * @param props.prog_bar_bg_color Progress bar background color.
81
- * @param props.theme Card theme.
82
69
  * @returns Card colors.
83
70
  */
84
71
  declare const getCardColors: ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, prog_bar_bg_color, theme, }: ColorInput) => CardColors;
@@ -94,9 +81,9 @@ type LightDarkColorParams = Partial<Record<`${BaseColorKey}_${ThemeVariant}`, st
94
81
  * Anything a mode does not override falls back to the general params,
95
82
  * so a partial override such as `bg_color_dark` alone keeps every other color from the base theme.
96
83
  *
97
- * When no `_light` / `_dark` param is provided at all, `darkColors` is `null` and the caller emits no dark-mode block.
84
+ * When no `_light` / `_dark` param is provided at all,
85
+ * `darkColors` is `null` and the caller emits no dark-mode block.
98
86
  *
99
- * @param params Raw query params, containing both general and `_light`/`_dark` suffixed colors and themes.
100
87
  * @returns `{ lightColors, darkColors }`, resolved colors for both light and dark mode
101
88
  */
102
89
  declare const getLightDarkColors: (params: ColorInput & LightDarkColorParams) => {
@@ -1 +1 @@
1
- {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/common/color.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,OAExC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAE5C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,eAAe,GAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAG,OAS/C,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,iBAAiB,GAAI,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OAK7D,CAAC;AAyBF;;GAEG;AACH,UAAU,UAAU;IAClB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,QAAA,MAAM,eAAe,8HASX,CAAC;AAEX,QAAA,MAAM,cAAc,4BAA6B,CAAC;AAElD,KAAK,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,KAAK,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD;;;;GAIG;AACH,KAAK,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,aAAa,GAAI,wGASpB,UAAU,KAAG,UAoDf,CAAC;AAEF,KAAK,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,IAAI,YAAY,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAenG;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,kBAAkB,GACtB,QAAQ,UAAU,GAAG,oBAAoB,KACxC;IAAE,WAAW,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;CAmB1D,CAAC;AAEF,KAAK,WAAW,GAAG,UAAU,GAAG,oBAAoB,CAAC;AAErD,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,WAAW,CAKtD,CAAC;AAEF,+DAA+D;AAC/D,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,WAAW,CAGtD,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAExC,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAIlB,eAAe,EACf,cAAc,EACd,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/common/color.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,QAAA,MAAM,cAAc,UAAW,OAAO,KAAG,OACW,CAAC;AAErD;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,UAAW,OAAO,KAAG,OACyC,CAAC;AAEvF;;;;;;GAMG;AACH,QAAA,MAAM,eAAe,UAAW,KAAK,CAAC,MAAM,CAAC,KAAG,OAS/C,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,iBAAiB,UAAW,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OAK7D,CAAC;AA8DF;;GAEG;AACH,UAAU,UAAU;IAClB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,QAAA,MAAM,eAAe,YACnB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,OAAO,CACC,CAAC;AAEX,QAAA,MAAM,cAAc,YAAI,OAAO,EAAE,MAAM,CAAU,CAAC;AAElD,KAAK,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,KAAK,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD;;;;GAIG;AACH,KAAK,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAEpE;;;;GAIG;AACH,QAAA,MAAM,aAAa,2GAShB,UAAU,KAAG,UA+Cf,CAAC;AAEF,KAAK,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,IAAI,YAAY,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AA8BnG;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,kBAAkB,WACd,UAAU,GAAG,oBAAoB,KACxC;IAAE,WAAW,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;CAU1D,CAAC;AAEF,KAAK,WAAW,GAAG,UAAU,GAAG,oBAAoB,CAAC;AAErD,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,WAAW,CAKtD,CAAC;AAEF,+DAA+D;AAC/D,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,WAAW,CAGtD,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAExC,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAIlB,eAAe,EACf,cAAc,EACd,gBAAgB,GACjB,CAAC"}
@@ -1,34 +1,27 @@
1
1
  import { isThemeName, themes } from '../themes/index.js';
2
2
  /** Matches a 3-, 4-, 6-, or 8-digit hex color with no leading `#`. */
3
- const HEX_COLOR = /^([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{3})$/;
3
+ const HEX_COLOR = /^(?<digits>[A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{3})$/;
4
4
  /**
5
5
  * Checks if a value is a bare hex color, i.e. hex digits with no `#` prefix
6
6
  * (`"f00"`, `"ffffff"`). This is the form user-supplied color params and
7
7
  * gradient stops arrive in.
8
8
  *
9
- * @param value Value to check.
10
9
  * @returns True if the value is a bare hex color.
11
10
  */
12
- const isBareHexColor = (value) => {
13
- return typeof value === 'string' && HEX_COLOR.test(value);
14
- };
11
+ const isBareHexColor = (value) => typeof value === 'string' && HEX_COLOR.test(value);
15
12
  /**
16
13
  * Checks if a value is a `#`-prefixed hex color (`"#f00"`, `"#ffffff"`). This
17
14
  * is the form colors take once resolved by {@link getCardColors}, i.e. right
18
15
  * before they are written into the SVG.
19
16
  *
20
- * @param value Value to check.
21
17
  * @returns True if the value is a `#`-prefixed hex color.
22
18
  */
23
- const isPrefixedHexColor = (value) => {
24
- return typeof value === 'string' && value.startsWith('#') && HEX_COLOR.test(value.slice(1));
25
- };
19
+ const isPrefixedHexColor = (value) => typeof value === 'string' && value.startsWith('#') && HEX_COLOR.test(value.slice(1));
26
20
  /**
27
21
  * Checks if the given parts form a valid gradient: a finite numeric angle
28
22
  * followed by at least two bare-hex color stops, e.g. `["90", "f00", "0f0"]`.
29
23
  * The angle is written into the SVG `gradientTransform="rotate(...)"`.
30
24
  *
31
- * @param parts Gradient parts: `[angle, ...stops]`.
32
25
  * @returns True if the parts form a valid gradient.
33
26
  */
34
27
  const isValidGradient = (parts) => {
@@ -37,12 +30,11 @@ const isValidGradient = (parts) => {
37
30
  angle !== undefined &&
38
31
  angle.trim() !== '' &&
39
32
  Number.isFinite(Number(angle)) &&
40
- stops.every(isBareHexColor));
33
+ stops.every((stop) => isBareHexColor(stop)));
41
34
  };
42
35
  /**
43
36
  * Checks if a string is a valid input for a color or gradient.
44
37
  *
45
- * @param color String to check, may be null or undefined.
46
38
  * @returns True if the given string is a valid input.
47
39
  */
48
40
  const isValidColorInput = (color) => {
@@ -54,11 +46,9 @@ const isValidColorInput = (color) => {
54
46
  /**
55
47
  * Retrieves a gradient if color has more than one valid hex codes else a single color.
56
48
  *
57
- * @param color The color to parse.
58
- * @param fallbackColor The fallback color.
59
49
  * @returns The gradient or color.
60
50
  */
61
- const fallbackColor = (color, fallbackColor) => {
51
+ const fallbackColor = (color, fallback) => {
62
52
  const colors = color ? color.split(',') : [];
63
53
  if (colors.length > 1 && isValidGradient(colors)) {
64
54
  return colors;
@@ -66,7 +56,39 @@ const fallbackColor = (color, fallbackColor) => {
66
56
  if (color !== undefined && isBareHexColor(color)) {
67
57
  return `#${color}`;
68
58
  }
69
- return fallbackColor;
59
+ return fallback;
60
+ };
61
+ /** Border a light background gets when neither the user nor the theme names one. */
62
+ const LIGHT_BG_BORDER = '#0000001f';
63
+ /** Border a dark background gets when neither the user nor the theme names one. */
64
+ const DARK_BG_BORDER = '#ffffff26';
65
+ /** Border a see-through background gets: neutral, since the page behind it decides the contrast. */
66
+ const TRANSLUCENT_BG_BORDER = '#8b949e59';
67
+ /**
68
+ * @returns Its `[r, g, b, a]` channels, each on 0–1.
69
+ */
70
+ const hexChannels = (hex) => {
71
+ const digits = hex.slice(1);
72
+ const expanded = digits.length <= 4 ? [...digits].map((digit) => digit + digit).join('') : digits;
73
+ const channel = (index) => Number.parseInt(expanded.slice(index * 2, index * 2 + 2), 16) / 255;
74
+ return [channel(0), channel(1), channel(2), expanded.length === 8 ? channel(3) : 1];
75
+ };
76
+ /**
77
+ * Derives a border from the background, so a dark card never gets a light hairline.
78
+ *
79
+ * @returns A translucent `#`-prefixed hex border color.
80
+ */
81
+ const borderColorFor = (bgColor) => {
82
+ // A gradient is judged by its first stop.
83
+ const hex = typeof bgColor === 'string' ? bgColor : `#${bgColor[1] ?? ''}`;
84
+ if (!isPrefixedHexColor(hex)) {
85
+ return LIGHT_BG_BORDER;
86
+ }
87
+ const [r, g, b, a] = hexChannels(hex);
88
+ if (a < 0.5) {
89
+ return TRANSLUCENT_BG_BORDER;
90
+ }
91
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b < 0.5 ? DARK_BG_BORDER : LIGHT_BG_BORDER;
70
92
  };
71
93
  /**
72
94
  * Every color param a card accepts, before any `_light` / `_dark` suffix.
@@ -88,30 +110,18 @@ const THEME_VARIANTS = ['light', 'dark'];
88
110
  /**
89
111
  * Returns theme based colors with proper overrides and defaults.
90
112
  *
91
- * @param props Function arguments.
92
- * @param props.title_color Card title color.
93
- * @param props.text_color Card text color.
94
- * @param props.icon_color Card icon color.
95
- * @param props.bg_color Card background color.
96
- * @param props.border_color Card border color.
97
- * @param props.ring_color Card ring color.
98
- * @param props.prog_bar_bg_color Progress bar background color.
99
- * @param props.theme Card theme.
100
113
  * @returns Card colors.
101
114
  */
102
115
  const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, prog_bar_bg_color, theme, }) => {
103
116
  const defaultTheme = themes.default;
104
117
  const selectedTheme = isThemeName(theme) ? themes[theme] : defaultTheme;
105
- const defaultBorderColor = 'border_color' in selectedTheme ? selectedTheme.border_color : defaultTheme.border_color;
106
- // get the color provided by the user else the theme color
107
- // finally if both colors are invalid fallback to default theme
108
- const titleColor = fallbackColor(title_color || selectedTheme.title_color, '#' + defaultTheme.title_color);
109
- // get the color provided by the user else the theme color
110
- // finally if both colors are invalid we use the titleColor
111
- const iconColor = fallbackColor(icon_color || selectedTheme.icon_color, '#' + defaultTheme.icon_color);
112
- const textColor = fallbackColor(text_color || selectedTheme.text_color, '#' + defaultTheme.text_color);
113
- const bgColor = fallbackColor(bg_color || selectedTheme.bg_color, '#' + defaultTheme.bg_color);
114
- const borderColor = fallbackColor(border_color || defaultBorderColor, '#' + defaultBorderColor);
118
+ const themeBorderColor = 'border_color' in selectedTheme ? selectedTheme.border_color : undefined;
119
+ // Each color is the user's, else the selected theme's, else the default theme's.
120
+ const titleColor = fallbackColor(title_color || selectedTheme.title_color, `#${defaultTheme.title_color}`);
121
+ const iconColor = fallbackColor(icon_color || selectedTheme.icon_color, `#${defaultTheme.icon_color}`);
122
+ const textColor = fallbackColor(text_color || selectedTheme.text_color, `#${defaultTheme.text_color}`);
123
+ const bgColor = fallbackColor(bg_color || selectedTheme.bg_color, `#${defaultTheme.bg_color}`);
124
+ const borderColor = fallbackColor(border_color || themeBorderColor, borderColorFor(bgColor));
115
125
  // No theme defines `ring_color`, so it falls back to the title color.
116
126
  const ringColor = fallbackColor(ring_color, titleColor);
117
127
  // No theme defines `prog_bar_bg_color`, so it falls back to "#ddd".
@@ -122,7 +132,7 @@ const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_c
122
132
  typeof progBarBgColor !== 'string' ||
123
133
  typeof iconColor !== 'string' ||
124
134
  typeof borderColor !== 'string') {
125
- throw new Error('Unexpected behavior, all colors except background should be string.');
135
+ throw new TypeError('Unexpected behavior, all colors except background should be string.');
126
136
  }
127
137
  return {
128
138
  titleColor,
@@ -138,11 +148,23 @@ const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_c
138
148
  * Returns the light- or dark-mode-specific color params, given a set of
139
149
  * raw query params. Also removes the "_light" or "_dark" suffixes.
140
150
  *
141
- * @param params Raw query params with optional `_light` / `_dark` suffixes.
142
- * @param suffix `"_light"` or `"_dark"`.
143
151
  * @returns ColorInput with the suffix stripped, ready for `getCardColors`.
144
152
  */
145
- const extractLightDarkColors = (params, suffix) => Object.fromEntries(BASE_COLOR_KEYS.map((key) => [key, params[`${key}${suffix}`]]));
153
+ const extractLightDarkColors = (params, suffix) => {
154
+ const colors = {};
155
+ for (const key of BASE_COLOR_KEYS) {
156
+ const value = params[`${key}${suffix}`];
157
+ if (value !== undefined) {
158
+ colors[key] = value;
159
+ }
160
+ }
161
+ return colors;
162
+ };
163
+ /**
164
+ * Every suffixed key, so asking "any per-scheme colors at all?" is one pass over names,
165
+ * not two objects built to be thrown away.
166
+ */
167
+ const MODE_OVERRIDE_KEYS = THEME_VARIANTS.flatMap((variant) => BASE_COLOR_KEYS.map((key) => `${key}_${variant}`));
146
168
  /**
147
169
  * Returns resolved colors for both light and dark mode given all input params.
148
170
  *
@@ -154,23 +176,19 @@ const extractLightDarkColors = (params, suffix) => Object.fromEntries(BASE_COLOR
154
176
  * Anything a mode does not override falls back to the general params,
155
177
  * so a partial override such as `bg_color_dark` alone keeps every other color from the base theme.
156
178
  *
157
- * When no `_light` / `_dark` param is provided at all, `darkColors` is `null` and the caller emits no dark-mode block.
179
+ * When no `_light` / `_dark` param is provided at all,
180
+ * `darkColors` is `null` and the caller emits no dark-mode block.
158
181
  *
159
- * @param params Raw query params, containing both general and `_light`/`_dark` suffixed colors and themes.
160
182
  * @returns `{ lightColors, darkColors }`, resolved colors for both light and dark mode
161
183
  */
162
184
  const getLightDarkColors = (params) => {
163
- const lightOverrides = extractLightDarkColors(params, '_light');
164
- const darkOverrides = extractLightDarkColors(params, '_dark');
165
- const hasModeOverrides = Object.values(lightOverrides).some((v) => v !== undefined) ||
166
- Object.values(darkOverrides).some((v) => v !== undefined);
167
- if (!hasModeOverrides) {
185
+ // The common case is no per-scheme params at all, so it never builds the overrides.
186
+ if (!MODE_OVERRIDE_KEYS.some((key) => params[key] !== undefined)) {
168
187
  return { lightColors: getCardColors(params), darkColors: null };
169
188
  }
170
- const defined = (obj) => Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
171
189
  return {
172
- lightColors: getCardColors({ ...params, ...defined(lightOverrides) }),
173
- darkColors: getCardColors({ ...params, ...defined(darkOverrides) }),
190
+ lightColors: getCardColors({ ...params, ...extractLightDarkColors(params, '_light') }),
191
+ darkColors: getCardColors({ ...params, ...extractLightDarkColors(params, '_dark') }),
174
192
  };
175
193
  };
176
194
  const COLOR_PARAM_KEYS = [
@@ -1,4 +1,4 @@
1
- import type { FetchLike } from './http.js';
1
+ import type { FetchLike } from './http.ts';
2
2
  type Env = Record<string, string | undefined>;
3
3
  interface PersonalAccessToken {
4
4
  /** Env variable the token came from — the retryer logs this name, never the value. */
@@ -32,21 +32,11 @@ export declare class CardConfig {
32
32
  /** Transport every fetcher sends through; defaults to `globalThis.fetch`. */
33
33
  readonly fetch: FetchLike;
34
34
  constructor(init?: CardConfigInit);
35
- /**
36
- * @param env Environment variables to read — the host passes `process.env` or an equivalent.
37
- * @returns Config for this deployment.
38
- */
35
+ /** @returns Config for this deployment. */
39
36
  static fromEnv(env: Env): CardConfig;
40
- /**
41
- * @param id Username or gist id being requested.
42
- * @param kind Which allowlist applies.
43
- * @returns Whether this deployment serves the id.
44
- */
37
+ /** @returns Whether this deployment serves the id. */
45
38
  isAllowed(id: string, kind: 'username' | 'gist'): boolean;
46
- /**
47
- * @param overrides Fields to replace.
48
- * @returns A copy with `overrides` applied — how a host swaps in a user's PAT per request.
49
- */
39
+ /** @returns A copy with `overrides` applied — how a host swaps in a user's PAT per request. */
50
40
  with(overrides: CardConfigInit): CardConfig;
51
41
  }
52
42
  export type { PersonalAccessToken, CardConfigInit };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/common/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,UAAU,mBAAmB;IAC3B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,iBAAiB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACtD,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAClD,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AA8BD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAClD,oEAAoE;IACpE,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC9D,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,mBAAmB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,mFAAmF;IACnF,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;gBAEd,IAAI,GAAE,cAAmB;IASrC;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU;IAUpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO;IAKzD;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,UAAU;CAW5C;AAED,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/common/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,UAAU,mBAAmB;IAC3B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,iBAAiB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACtD,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAClD,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AA2BD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAClD,oEAAoE;IACpE,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC9D,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,mBAAmB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,mFAAmF;IACnF,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAE1B,YAAY,IAAI,GAAE,cAAmB,EAOpC;IAED,2CAA2C;IAC3C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAQnC;IAED,sDAAsD;IACtD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAGxD;IAED,+FAA+F;IAC/F,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,UAAU,CAU1C;CACF;AAED,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC"}
@@ -1,11 +1,9 @@
1
1
  import { defaultFetch } from './http.js';
2
2
  /**
3
- * @param value Comma-separated string.
4
3
  * @returns Parsed string values.
5
4
  */
6
5
  const parseCsv = (value) => value ? value.split(',') : undefined;
7
6
  /**
8
- * @param value Raw `FETCH_MULTI_PAGE_STARS` value.
9
7
  * @returns Page limit: `"true"` means every page, a positive number caps the pages, anything else means one.
10
8
  */
11
9
  const parseFetchMultiPageStars = (value) => {
@@ -16,7 +14,6 @@ const parseFetchMultiPageStars = (value) => {
16
14
  return limit > 0 ? limit : 1;
17
15
  };
18
16
  /**
19
- * @param env Environment variables to inspect.
20
17
  * @returns Personal access tokens found in the environment.
21
18
  */
22
19
  const parsePATsFromEnv = (env) => Object.keys(env)
@@ -47,10 +44,7 @@ export class CardConfig {
47
44
  this.fetchMultiPageStars = init.fetchMultiPageStars ?? 1;
48
45
  this.fetch = init.fetch ?? defaultFetch;
49
46
  }
50
- /**
51
- * @param env Environment variables to read — the host passes `process.env` or an equivalent.
52
- * @returns Config for this deployment.
53
- */
47
+ /** @returns Config for this deployment. */
54
48
  static fromEnv(env) {
55
49
  return new CardConfig({
56
50
  pats: parsePATsFromEnv(env),
@@ -60,19 +54,12 @@ export class CardConfig {
60
54
  fetchMultiPageStars: parseFetchMultiPageStars(env['FETCH_MULTI_PAGE_STARS']),
61
55
  });
62
56
  }
63
- /**
64
- * @param id Username or gist id being requested.
65
- * @param kind Which allowlist applies.
66
- * @returns Whether this deployment serves the id.
67
- */
57
+ /** @returns Whether this deployment serves the id. */
68
58
  isAllowed(id, kind) {
69
59
  const list = kind === 'gist' ? this.gistAllowlist : this.usernameAllowlist;
70
60
  return list === undefined || list.includes(id);
71
61
  }
72
- /**
73
- * @param overrides Fields to replace.
74
- * @returns A copy with `overrides` applied — how a host swaps in a user's PAT per request.
75
- */
62
+ /** @returns A copy with `overrides` applied — how a host swaps in a user's PAT per request. */
76
63
  with(overrides) {
77
64
  return new CardConfig({
78
65
  pats: this.pats,
@@ -1,7 +1,11 @@
1
- import type { RepositoryAffiliation } from '../graphql/generated/common.js';
1
+ import type { RepositoryAffiliation } from '../graphql/generated/common.ts';
2
+ /** The year GitHub launched, and so the earliest one a card can be asked to count from. */
3
+ declare const GITHUB_EPOCH_YEAR = 2008;
4
+ /** A GitHub login: alphanumerics and single inner hyphens, 39 characters at most. */
5
+ declare const GITHUB_USERNAME_PATTERN: RegExp;
2
6
  /**
3
7
  * Valid owner affiliations for GitHub API queries.
4
8
  */
5
9
  declare const OWNER_AFFILIATIONS: Array<RepositoryAffiliation>;
6
- export { OWNER_AFFILIATIONS };
10
+ export { GITHUB_EPOCH_YEAR, GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
7
11
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,qBAAqB,CAIpD,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,2FAA2F;AAC3F,QAAA,MAAM,iBAAiB,OAAO,CAAC;AAE/B,qFAAqF;AACrF,QAAA,MAAM,uBAAuB,QAA6C,CAAC;AAE3E;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,qBAAqB,CAIpD,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,3 +1,7 @@
1
+ /** The year GitHub launched, and so the earliest one a card can be asked to count from. */
2
+ const GITHUB_EPOCH_YEAR = 2008;
3
+ /** A GitHub login: alphanumerics and single inner hyphens, 39 characters at most. */
4
+ const GITHUB_USERNAME_PATTERN = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i;
1
5
  /**
2
6
  * Valid owner affiliations for GitHub API queries.
3
7
  */
@@ -6,4 +10,4 @@ const OWNER_AFFILIATIONS = [
6
10
  'COLLABORATOR',
7
11
  'ORGANIZATION_MEMBER',
8
12
  ];
9
- export { OWNER_AFFILIATIONS };
13
+ export { GITHUB_EPOCH_YEAR, GITHUB_USERNAME_PATTERN, OWNER_AFFILIATIONS };
@@ -1,4 +1,5 @@
1
- /** A span between two dates, as GitHub's range arguments take it. */
1
+ /** @file A range reaches GitHub one calendar year at a time; `contributionsCollection` refuses a longer one. */
2
+ /** A range between two dates, as GitHub's range arguments take it. */
2
3
  interface GitHubDateRange {
3
4
  /** Start of the range, inclusive. */
4
5
  from: Date;
@@ -9,21 +10,65 @@ interface GitHubDateRange {
9
10
  * Format a date as a GitHub `DateTime` scalar.
10
11
  * Seconds precision, no milliseconds.
11
12
  *
12
- * @param date Date to format.
13
13
  * @returns e.g. `2024-01-01T00:00:00Z`.
14
14
  */
15
15
  declare const toGitHubDateTime: (date: Date) => string;
16
16
  /**
17
- * The full UTC span of a calendar year, both ends inclusive.
17
+ * The full UTC range of a calendar year, both ends inclusive.
18
18
  *
19
19
  * The end matters to callers that would otherwise leave a range open:
20
20
  * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
21
21
  * which pulls the next 1st of January into the year.
22
22
  *
23
- * @param year Four-digit year.
24
23
  * @returns The range covering it.
25
24
  */
26
25
  declare const getGitHubYearRange: (year: number) => GitHubDateRange;
27
- export { getGitHubYearRange, toGitHubDateTime };
26
+ /**
27
+ * The widest range a card can be asked for: GitHub's first year through the end of this one.
28
+ * The far end is the end of the year, not today, because a bare `to=2026` widens to its 31st of December.
29
+ *
30
+ * @returns The range, in UTC.
31
+ */
32
+ declare const getWidestRange: () => GitHubDateRange;
33
+ /**
34
+ * The range a card counts within, from the ends the query named.
35
+ *
36
+ * @returns The range, each open end filled from {@link getWidestRange}.
37
+ */
38
+ declare const toRange: (from: Date | undefined, to: Date | undefined) => GitHubDateRange;
39
+ /**
40
+ * Read one end of a range, written as `2024`, `2024-03` or `2024-03-15`.
41
+ * A partial date covers the whole of what it names, so `2024` starts on the 1st of January
42
+ * and ends on the 31st of December.
43
+ *
44
+ * @returns The instant, or `undefined` when the text does not name a date that exists.
45
+ */
46
+ declare const parseRangeDate: (value: string, end: 'from' | 'to') => Date | undefined;
47
+ /**
48
+ * Split a range into one per calendar year, each clipped to it.
49
+ *
50
+ * @returns Them, oldest first; empty when the range is inverted.
51
+ */
52
+ declare const toYearRanges: ({ from, to }: GitHubDateRange) => Array<GitHubDateRange>;
53
+ /**
54
+ * Whole years as a card writes them.
55
+ *
56
+ * @returns e.g. `2024` or `2020–2024`.
57
+ */
58
+ declare const formatYears: (first: number, last: number) => string;
59
+ /**
60
+ * A range as a card writes it, at the coarsest granularity that stays true.
61
+ *
62
+ * @returns e.g. `2024`, `2020–2024` or `2024-03-15 – 2024-06-30`.
63
+ */
64
+ declare const formatRange: ({ from, to }: GitHubDateRange) => string;
65
+ /**
66
+ * The ranges a walk asks GitHub for: one per calendar year the account contributed in.
67
+ * Ordered here, which is what makes a walk's ties chronological.
68
+ *
69
+ * @returns Them, oldest first.
70
+ */
71
+ declare const toContributionRanges: (contributionYears: ReadonlyArray<number>, range: GitHubDateRange) => Array<GitHubDateRange>;
72
+ export { formatRange, formatYears, getWidestRange, getGitHubYearRange, parseRangeDate, toContributionRanges, toGitHubDateTime, toRange, toYearRanges, };
28
73
  export type { GitHubDateRange };
29
74
  //# sourceMappingURL=date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/common/date.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,UAAU,eAAe;IACvB,qCAAqC;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,mCAAmC;IACnC,EAAE,EAAE,IAAI,CAAC;CACV;AAED;;;;;;GAMG;AACH,QAAA,MAAM,gBAAgB,GAAI,MAAM,IAAI,KAAG,MAA+C,CAAC;AAEvF;;;;;;;;;GASG;AACH,QAAA,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,eAGzC,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/common/date.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAIhH,sEAAsE;AACtE,UAAU,eAAe;IACvB,qCAAqC;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,mCAAmC;IACnC,EAAE,EAAE,IAAI,CAAC;CACV;AAKD;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,SAAU,IAAI,KAAG,MAA+C,CAAC;AAEvF;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB,SAAU,MAAM,KAAG,eAGzC,CAAC;AAEH;;;;;GAKG;AACH,QAAA,MAAM,cAAc,QAAO,eAGzB,CAAC;AAEH;;;;GAIG;AACH,QAAA,MAAM,OAAO,SAAU,IAAI,GAAG,SAAS,MAAM,IAAI,GAAG,SAAS,KAAG,eAG/D,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,cAAc,UAAW,MAAM,OAAO,MAAM,GAAG,IAAI,KAAG,IAAI,GAAG,SA2BlE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,YAAY,iBAAkB,eAAe,KAAG,KAAK,CAAC,eAAe,CAW1E,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,WAAW,UAAW,MAAM,QAAQ,MAAM,KAAG,MACD,CAAC;AAEnD;;;;GAIG;AACH,QAAA,MAAM,WAAW,iBAAkB,eAAe,KAAG,MAWpD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB,sBACL,aAAa,CAAC,MAAM,CAAC,SACjC,eAAe,KACrB,KAAK,CAAC,eAAe,CAGvB,CAAC;AAEF,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,OAAO,EACP,YAAY,GACb,CAAC;AACF,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -1,23 +1,123 @@
1
+ /** @file A range reaches GitHub one calendar year at a time; `contributionsCollection` refuses a longer one. */
2
+ import { GITHUB_EPOCH_YEAR } from './constants.js';
3
+ /** A year, a year and month, or a full date. */
4
+ const RANGE_DATE_PATTERN = /^(?<year>\d{4})(?:-(?<month>\d{2})(?:-(?<day>\d{2}))?)?$/;
1
5
  /**
2
6
  * Format a date as a GitHub `DateTime` scalar.
3
7
  * Seconds precision, no milliseconds.
4
8
  *
5
- * @param date Date to format.
6
9
  * @returns e.g. `2024-01-01T00:00:00Z`.
7
10
  */
8
11
  const toGitHubDateTime = (date) => `${date.toISOString().slice(0, 19)}Z`;
9
12
  /**
10
- * The full UTC span of a calendar year, both ends inclusive.
13
+ * The full UTC range of a calendar year, both ends inclusive.
11
14
  *
12
15
  * The end matters to callers that would otherwise leave a range open:
13
16
  * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
14
17
  * which pulls the next 1st of January into the year.
15
18
  *
16
- * @param year Four-digit year.
17
19
  * @returns The range covering it.
18
20
  */
19
21
  const getGitHubYearRange = (year) => ({
20
22
  from: new Date(Date.UTC(year, 0, 1)),
21
23
  to: new Date(Date.UTC(year, 11, 31, 23, 59, 59)),
22
24
  });
23
- export { getGitHubYearRange, toGitHubDateTime };
25
+ /**
26
+ * The widest range a card can be asked for: GitHub's first year through the end of this one.
27
+ * The far end is the end of the year, not today, because a bare `to=2026` widens to its 31st of December.
28
+ *
29
+ * @returns The range, in UTC.
30
+ */
31
+ const getWidestRange = () => ({
32
+ from: getGitHubYearRange(GITHUB_EPOCH_YEAR).from,
33
+ to: getGitHubYearRange(new Date().getUTCFullYear()).to,
34
+ });
35
+ /**
36
+ * The range a card counts within, from the ends the query named.
37
+ *
38
+ * @returns The range, each open end filled from {@link getWidestRange}.
39
+ */
40
+ const toRange = (from, to) => {
41
+ const widest = getWidestRange();
42
+ return { from: from ?? widest.from, to: to ?? widest.to };
43
+ };
44
+ /**
45
+ * Read one end of a range, written as `2024`, `2024-03` or `2024-03-15`.
46
+ * A partial date covers the whole of what it names, so `2024` starts on the 1st of January
47
+ * and ends on the 31st of December.
48
+ *
49
+ * @returns The instant, or `undefined` when the text does not name a date that exists.
50
+ */
51
+ const parseRangeDate = (value, end) => {
52
+ const match = RANGE_DATE_PATTERN.exec(value);
53
+ if (!match) {
54
+ return undefined;
55
+ }
56
+ const { year: yearText, month: monthText, day: dayText } = match.groups ?? {};
57
+ const year = Number(yearText);
58
+ const month = monthText === undefined ? 1 : Number(monthText);
59
+ const day = dayText === undefined ? 1 : Number(dayText);
60
+ const start = new Date(Date.UTC(year, month - 1, day));
61
+ // Date.UTC rolls an impossible date forward rather than refusing it
62
+ if (start.getUTCMonth() + 1 !== month || start.getUTCDate() !== day) {
63
+ return undefined;
64
+ }
65
+ if (end === 'from') {
66
+ return start;
67
+ }
68
+ const nextUnit = dayText !== undefined
69
+ ? Date.UTC(year, month - 1, day + 1)
70
+ : monthText !== undefined
71
+ ? Date.UTC(year, month, 1)
72
+ : Date.UTC(year + 1, 0, 1);
73
+ return new Date(nextUnit - 1000);
74
+ };
75
+ /**
76
+ * Split a range into one per calendar year, each clipped to it.
77
+ *
78
+ * @returns Them, oldest first; empty when the range is inverted.
79
+ */
80
+ const toYearRanges = ({ from, to }) => {
81
+ const ranges = [];
82
+ for (let year = from.getUTCFullYear(); year <= to.getUTCFullYear(); year += 1) {
83
+ const yearRange = getGitHubYearRange(year);
84
+ const start = from > yearRange.from ? from : yearRange.from;
85
+ const end = to < yearRange.to ? to : yearRange.to;
86
+ if (start <= end) {
87
+ ranges.push({ from: start, to: end });
88
+ }
89
+ }
90
+ return ranges;
91
+ };
92
+ /**
93
+ * Whole years as a card writes them.
94
+ *
95
+ * @returns e.g. `2024` or `2020–2024`.
96
+ */
97
+ const formatYears = (first, last) => first === last ? `${first}` : `${first}–${last}`;
98
+ /**
99
+ * A range as a card writes it, at the coarsest granularity that stays true.
100
+ *
101
+ * @returns e.g. `2024`, `2020–2024` or `2024-03-15 – 2024-06-30`.
102
+ */
103
+ const formatRange = ({ from, to }) => {
104
+ const firstYear = from.getUTCFullYear();
105
+ const lastYear = to.getUTCFullYear();
106
+ const wholeYears = from.getTime() === getGitHubYearRange(firstYear).from.getTime() &&
107
+ to.getTime() === getGitHubYearRange(lastYear).to.getTime();
108
+ if (!wholeYears) {
109
+ return `${from.toISOString().slice(0, 10)} – ${to.toISOString().slice(0, 10)}`;
110
+ }
111
+ return formatYears(firstYear, lastYear);
112
+ };
113
+ /**
114
+ * The ranges a walk asks GitHub for: one per calendar year the account contributed in.
115
+ * Ordered here, which is what makes a walk's ties chronological.
116
+ *
117
+ * @returns Them, oldest first.
118
+ */
119
+ const toContributionRanges = (contributionYears, range) => {
120
+ const contributed = new Set(contributionYears);
121
+ return toYearRanges(range).filter((year) => contributed.has(year.from.getUTCFullYear()));
122
+ };
123
+ export { formatRange, formatYears, getWidestRange, getGitHubYearRange, parseRangeDate, toContributionRanges, toGitHubDateTime, toRange, toYearRanges, };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolves a GitHub emoji shortcode to its unicode character.
3
+ *
4
+ * @returns The emoji, or `undefined` when GitHub has no such shortcode.
5
+ */
6
+ declare const getEmoji: (name: string) => string | undefined;
7
+ export { getEmoji };
8
+ //# sourceMappingURL=emojiMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emojiMap.d.ts","sourceRoot":"","sources":["../../src/common/emojiMap.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,QAAA,MAAM,QAAQ,SAAU,MAAM,KAAG,MAAM,GAAG,SAA2B,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import emojiMapJson from './emojiMap.json' with { type: 'json' };
2
+ // The generated JSON types has literal keys; index it as a plain lookup table.
3
+ const emojiMap = emojiMapJson;
4
+ /**
5
+ * Resolves a GitHub emoji shortcode to its unicode character.
6
+ *
7
+ * @returns The emoji, or `undefined` when GitHub has no such shortcode.
8
+ */
9
+ const getEmoji = (name) => emojiMap[name];
10
+ export { getEmoji };