@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,4 @@
1
- import { isPrefixedHexColor, isValidGradient } from "./color.js";
1
+ import { getCardColors, isPrefixedHexColor, isValidGradient } from "./color.js";
2
2
  import { encodeHTML } from "./html.js";
3
3
  import { flexLayout } from "./render.js";
4
4
  class Card {
@@ -10,6 +10,7 @@ class Card {
10
10
  colors;
11
11
  title;
12
12
  css;
13
+ darkCss;
13
14
  paddingX;
14
15
  paddingY;
15
16
  titlePrefixIcon;
@@ -25,21 +26,23 @@ class Card {
25
26
  * @param props.width Card width.
26
27
  * @param props.height Card height.
27
28
  * @param props.border_radius Card border radius.
28
- * @param props.colors Card colors arguments.
29
+ * @param props.colors Card colors for light and dark mode.
30
+ * @param props.colors.light Card colors for light mode.
31
+ * @param props.colors.dark Card colors for dark mode, or `null` when no dark-mode override is needed.
29
32
  * @param props.customTitle Card custom title.
30
33
  * @param props.defaultTitle Card default title.
31
34
  * @param props.titlePrefixIcon Sanitized card title prefix icon.
32
35
  */
33
- constructor({ width = 100, height = 100, border_radius = 4.5, colors = {}, customTitle, defaultTitle = "", titlePrefixIcon, }) {
36
+ constructor({ width = 100, height = 100, border_radius = 4.5, colors = { light: getCardColors({}), dark: null }, customTitle, defaultTitle = "", titlePrefixIcon, }) {
34
37
  this.width = width;
35
38
  this.height = height;
36
39
  this.hideBorder = false;
37
40
  this.hideTitle = false;
38
41
  this.border_radius = parseFloat(String(border_radius));
39
- // returns theme based colors with proper overrides and defaults
40
42
  this.colors = colors;
41
43
  this.title = customTitle === undefined ? defaultTitle : customTitle;
42
44
  this.css = "";
45
+ this.darkCss = "";
43
46
  this.paddingX = 25;
44
47
  this.paddingY = 35;
45
48
  this.titlePrefixIcon = titlePrefixIcon;
@@ -60,12 +63,17 @@ class Card {
60
63
  this.a11yDesc = desc;
61
64
  }
62
65
  /**
63
- * The caller must ensure that the passed `css` string is properly sanitized!
66
+ * Sets the card CSS for light and dark mode.
64
67
  *
65
- * @param value The sanitized CSS to add to the card.
68
+ * The caller must ensure that the passed CSS strings are properly sanitized!
69
+ *
70
+ * @param props The props object.
71
+ * @param props.light CSS applied unconditionally (light/default mode).
72
+ * @param props.dark CSS placed inside a `@media (prefers-color-scheme: dark)` block. Pass `null` when not needed.
66
73
  */
67
- setCSS(value) {
68
- this.css = value;
74
+ setCSS({ light, dark }) {
75
+ this.css = light;
76
+ this.darkCss = dark ?? "";
69
77
  }
70
78
  /**
71
79
  * @param value Whether to hide the border or not.
@@ -132,27 +140,35 @@ class Card {
132
140
  * @returns The rendered card gradient.
133
141
  */
134
142
  renderGradient() {
135
- if (typeof this.colors.bgColor !== "object") {
136
- return "";
137
- }
138
- if (!isValidGradient(this.colors.bgColor)) {
139
- throw new Error(`Invalid gradient: ${this.colors.bgColor.join(",")}`);
140
- }
141
- const gradients = this.colors.bgColor.slice(1);
142
- return `
143
- <defs>
143
+ const buildGradientDef = (id, bgColor) => {
144
+ const gradients = bgColor.slice(1);
145
+ return `
144
146
  <linearGradient
145
- id="gradient"
146
- gradientTransform="rotate(${String(this.colors.bgColor[0])})"
147
+ id="${id}"
148
+ gradientTransform="rotate(${String(bgColor[0])})"
147
149
  gradientUnits="userSpaceOnUse"
148
150
  >
149
151
  ${gradients
150
- .map((grad, index) => {
151
- const offset = (index * 100) / (gradients.length - 1);
152
- return `<stop offset="${offset}%" stop-color="#${grad}" />`;
153
- })
154
- .join(",")}
155
- </linearGradient>
152
+ .map((grad, index) => {
153
+ const offset = (index * 100) / (gradients.length - 1);
154
+ return `<stop offset="${offset}%" stop-color="#${grad}" />`;
155
+ })
156
+ .join(",")}
157
+ </linearGradient>`;
158
+ };
159
+ if (typeof this.colors.light.bgColor === "object" &&
160
+ !isValidGradient(this.colors.light.bgColor)) {
161
+ throw new Error(`Invalid gradient: ${this.colors.light.bgColor.join(",")}`);
162
+ }
163
+ if (this.colors.dark &&
164
+ typeof this.colors.dark.bgColor === "object" &&
165
+ !isValidGradient(this.colors.dark.bgColor)) {
166
+ throw new Error(`Invalid dark gradient: ${this.colors.dark.bgColor.join(",")}`);
167
+ }
168
+ return `
169
+ <defs>
170
+ ${typeof this.colors.light.bgColor === "object" ? buildGradientDef("gradient", this.colors.light.bgColor) : ""}
171
+ ${this.colors.dark && typeof this.colors.dark.bgColor === "object" ? buildGradientDef("gradient-dark", this.colors.dark.bgColor) : ""}
156
172
  </defs>
157
173
  `;
158
174
  }
@@ -182,6 +198,24 @@ class Card {
182
198
  }
183
199
  `;
184
200
  };
201
+ /**
202
+ * Builds the @media (prefers-color-scheme: dark) CSS block for the card.
203
+ * Returns an empty string when no dark colors are set.
204
+ */
205
+ renderDarkMediaBlock() {
206
+ if (!this.colors.dark) {
207
+ return "";
208
+ }
209
+ const bgFill = typeof this.colors.dark.bgColor === "object"
210
+ ? "url(#gradient-dark)"
211
+ : this.colors.dark.bgColor;
212
+ return `
213
+ @media (prefers-color-scheme: dark) {
214
+ .header { fill: ${this.colors.dark.titleColor}; }
215
+ .card-bg { fill: ${bgFill}; stroke: ${this.colors.dark.borderColor}; }
216
+ ${this.darkCss}
217
+ }`;
218
+ }
185
219
  /**
186
220
  * The caller must ensure that the passed `body` string is properly sanitized!
187
221
  *
@@ -192,19 +226,16 @@ class Card {
192
226
  if (!Number.isFinite(this.border_radius)) {
193
227
  throw new Error(`Invalid border radius: "${this.border_radius}"`);
194
228
  }
195
- if (this.colors.titleColor !== undefined &&
196
- !isPrefixedHexColor(this.colors.titleColor)) {
197
- throw new Error(`Invalid title color: "${this.colors.titleColor}"`);
229
+ if (!isPrefixedHexColor(this.colors.light.titleColor)) {
230
+ throw new Error(`Invalid title color: "${this.colors.light.titleColor}"`);
198
231
  }
199
- if (this.colors.borderColor !== undefined &&
200
- !isPrefixedHexColor(this.colors.borderColor)) {
201
- throw new Error(`Invalid border color: "${this.colors.borderColor}"`);
232
+ if (!isPrefixedHexColor(this.colors.light.borderColor)) {
233
+ throw new Error(`Invalid border color: "${this.colors.light.borderColor}"`);
202
234
  }
203
- if (this.colors.bgColor !== undefined &&
204
- !(typeof this.colors.bgColor === "object"
205
- ? isValidGradient(this.colors.bgColor)
206
- : isPrefixedHexColor(this.colors.bgColor))) {
207
- throw new Error(`Invalid background color: ${String(this.colors.bgColor)}`);
235
+ if (!(typeof this.colors.light.bgColor === "object"
236
+ ? isValidGradient(this.colors.light.bgColor)
237
+ : isPrefixedHexColor(this.colors.light.bgColor))) {
238
+ throw new Error(`Invalid background color: ${String(this.colors.light.bgColor)}`);
208
239
  }
209
240
  return `
210
241
  <svg
@@ -221,7 +252,7 @@ class Card {
221
252
  <style>
222
253
  .header {
223
254
  font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif;
224
- fill: ${String(this.colors.titleColor)};
255
+ fill: ${this.colors.light.titleColor};
225
256
  animation: fadeInAnimation 0.8s ease-in-out forwards;
226
257
  }
227
258
  @supports(-moz-appearance: auto) {
@@ -229,6 +260,7 @@ class Card {
229
260
  .header { font-size: 15.5px; }
230
261
  }
231
262
  ${this.css}
263
+ ${this.renderDarkMediaBlock()}
232
264
 
233
265
  ${this.getAnimations()}
234
266
  ${this.animations
@@ -240,15 +272,16 @@ class Card {
240
272
 
241
273
  <rect
242
274
  data-testid="card-bg"
275
+ class="card-bg"
243
276
  x="0.5"
244
277
  y="0.5"
245
278
  rx="${this.border_radius}"
246
279
  height="99%"
247
- stroke="${String(this.colors.borderColor)}"
280
+ stroke="${this.colors.light.borderColor}"
248
281
  width="${this.width - 1}"
249
- fill="${typeof this.colors.bgColor === "object"
282
+ fill="${typeof this.colors.light.bgColor === "object"
250
283
  ? "url(#gradient)"
251
- : String(this.colors.bgColor)}"
284
+ : this.colors.light.bgColor}"
252
285
  stroke-opacity="${this.hideBorder ? 0 : 1}"
253
286
  />
254
287
 
@@ -1,7 +1,9 @@
1
+ /** A map of translation keys to per-locale strings. */
2
+ type TranslationsMap = Record<string, Record<string, string>>;
1
3
  /**
2
4
  * I18n translation class.
3
5
  */
4
- declare class I18n<Translations extends Record<string, Record<string, string>>> {
6
+ declare class I18n<Translations extends TranslationsMap = TranslationsMap> {
5
7
  locale: string;
6
8
  translations: Translations;
7
9
  /**
@@ -10,7 +12,7 @@ declare class I18n<Translations extends Record<string, Record<string, string>>>
10
12
  * @param props.translations Translations.
11
13
  */
12
14
  constructor({ locale, translations, }: {
13
- locale?: string;
15
+ locale?: string | undefined;
14
16
  translations: Translations;
15
17
  });
16
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"I18n.d.ts","sourceRoot":"","sources":["../../src/common/I18n.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,cAAM,IAAI,CAAC,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAE3B;;;;OAIG;gBACS,EACV,MAAM,EACN,YAAY,GACb,EAAE;QACD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,YAAY,CAAC;KAC5B;IAKD;;;;;OAKG;IACH,CAAC,CAAC,GAAG,EAAE,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM;CAe5C;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"I18n.d.ts","sourceRoot":"","sources":["../../src/common/I18n.ts"],"names":[],"mappings":"AAEA,uDAAuD;AACvD,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D;;GAEG;AACH,cAAM,IAAI,CAAC,YAAY,SAAS,eAAe,GAAG,eAAe;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAE3B;;;;OAIG;gBACS,EACV,MAAM,EACN,YAAY,GACb,EAAE;QAED,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,YAAY,EAAE,YAAY,CAAC;KAC5B;IAKD;;;;;OAKG;IACH,CAAC,CAAC,GAAG,EAAE,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM;CAe5C;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
@@ -32,14 +32,6 @@ declare const isValidGradient: (parts: Array<string>) => boolean;
32
32
  * @return The first key where the associated input value is not valid. null if all inputs are valid.
33
33
  */
34
34
  declare const findInvalidColor: (colors: Record<string, string | null | undefined>) => string | null;
35
- /**
36
- * Retrieves a gradient if color has more than one valid hex codes else a single color.
37
- *
38
- * @param color The color to parse.
39
- * @param fallbackColor The fallback color.
40
- * @returns The gradient or color.
41
- */
42
- declare const fallbackColor: (color: string | undefined, fallbackColor: string | Array<string>) => string | Array<string>;
43
35
  /**
44
36
  * Object containing card colors.
45
37
  */
@@ -50,7 +42,24 @@ interface CardColors {
50
42
  bgColor: string | Array<string>;
51
43
  borderColor: string;
52
44
  ringColor: string;
45
+ progBarBgColor: string;
53
46
  }
47
+ /**
48
+ * Every color param a card accepts, before any `_light` / `_dark` suffix.
49
+ *
50
+ * Single source of truth: the param types and {@link COLOR_PARAM_KEYS} are all
51
+ * derived from this, so adding a param here is enough.
52
+ */
53
+ declare const BASE_COLOR_KEYS: readonly ["title_color", "icon_color", "text_color", "bg_color", "border_color", "ring_color", "prog_bar_bg_color", "theme"];
54
+ declare const THEME_VARIANTS: readonly ["light", "dark"];
55
+ type BaseColorKey = (typeof BASE_COLOR_KEYS)[number];
56
+ type ThemeVariant = (typeof THEME_VARIANTS)[number];
57
+ /**
58
+ * Object with all input color params. Not every field is consumed by every card
59
+ * (e.g. `prog_bar_bg_color` is only used by the top-languages card's `normal`
60
+ * layout).
61
+ */
62
+ type ColorInput = Partial<Record<BaseColorKey, string | undefined>>;
54
63
  /**
55
64
  * Returns theme based colors with proper overrides and defaults.
56
65
  *
@@ -61,17 +70,50 @@ interface CardColors {
61
70
  * @param props.bg_color Card background color.
62
71
  * @param props.border_color Card border color.
63
72
  * @param props.ring_color Card ring color.
73
+ * @param props.prog_bar_bg_color Progress bar background color.
64
74
  * @param props.theme Card theme.
65
75
  * @returns Card colors.
66
76
  */
67
- declare const getCardColors: ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, theme, }: {
68
- title_color?: string | undefined;
69
- text_color?: string | undefined;
70
- icon_color?: string | undefined;
71
- bg_color?: string | undefined;
72
- border_color?: string | undefined;
73
- ring_color?: string | undefined;
74
- theme?: string | undefined;
75
- }) => CardColors;
76
- export { fallbackColor, getCardColors, findInvalidColor, isValidGradient, isBareHexColor, isPrefixedHexColor, };
77
+ declare const getCardColors: ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, prog_bar_bg_color, theme, }: ColorInput) => CardColors;
78
+ type LightDarkColorParams = Partial<Record<`${BaseColorKey}_${ThemeVariant}`, string | undefined>>;
79
+ /**
80
+ * Returns resolved colors for both light and dark mode given all input params.
81
+ *
82
+ * Each mode resolves independently, then runs the normal `getCardColors` precedence
83
+ * (explicit color -> theme color -> default theme):
84
+ * light: `theme_light ?? theme`, with `*_light` params overriding general ones
85
+ * dark: `theme_dark ?? theme`, with `*_dark` params overriding general ones
86
+ *
87
+ * Anything a mode does not override falls back to the general params,
88
+ * so a partial override such as `bg_color_dark` alone keeps every other color from the base theme.
89
+ *
90
+ * When no `_light` / `_dark` param is provided at all, `darkColors` is `null` and the caller emits no dark-mode block.
91
+ *
92
+ * @param params Raw query params, containing both general and `_light`/`_dark` suffixed colors and themes.
93
+ * @returns `{ lightColors, darkColors }`, resolved colors for both light and dark mode
94
+ */
95
+ declare const getLightDarkColors: (params: ColorInput & LightDarkColorParams) => {
96
+ lightColors: CardColors;
97
+ darkColors: CardColors | null;
98
+ };
99
+ type ColorParams = ColorInput & LightDarkColorParams;
100
+ declare const COLOR_PARAM_KEYS: ReadonlyArray<keyof ColorParams>;
101
+ /**
102
+ * Picks all color-related parameters from a query object.
103
+ *
104
+ * @param query Raw query parameters.
105
+ * @returns All color-related parameters.
106
+ */
107
+ declare const pickColorParams: (query: Record<string, string | undefined>) => ColorParams;
108
+ /**
109
+ * Finds the first color param holding an invalid color.
110
+ *
111
+ * Theme params are skipped: they name a theme, and an unknown name falls back
112
+ * to the default rather than being an error.
113
+ *
114
+ * @param params Color params, as returned by {@link pickColorParams}.
115
+ * @returns The first invalid param name, or null if all are valid.
116
+ */
117
+ declare const findInvalidColorParam: (params: ColorParams) => string | null;
118
+ export { getCardColors, getLightDarkColors, findInvalidColor, findInvalidColorParam, pickColorParams, isValidGradient, isBareHexColor, isPrefixedHexColor, BASE_COLOR_KEYS, THEME_VARIANTS, COLOR_PARAM_KEYS, };
77
119
  //# sourceMappingURL=color.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/common/color.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,OAExC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAM5C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,eAAe,GAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAG,OAS/C,CAAC;AAeF;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,GACpB,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,KAChD,MAAM,GAAG,IAOX,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,aAAa,GACjB,OAAO,MAAM,GAAG,SAAS,EACzB,eAAe,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KACpC,MAAM,GAAG,KAAK,CAAC,MAAM,CAWvB,CAAC;AAEF;;GAEG;AACH,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,aAAa,GAAI,qFAQpB;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,KAAG,UAuDH,CAAC;AAEF,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,kBAAkB,GACnB,CAAC"}
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/common/color.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,QAAA,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,OAExC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAM5C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,eAAe,GAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAG,OAS/C,CAAC;AAeF;;;;;GAKG;AACH,QAAA,MAAM,gBAAgB,GACpB,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,KAChD,MAAM,GAAG,IAOX,CAAC;AAyBF;;GAEG;AACH,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,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,UAkEf,CAAC;AAEF,KAAK,oBAAoB,GAAG,OAAO,CACjC,MAAM,CAAC,GAAG,YAAY,IAAI,YAAY,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,CAC9D,CAAC;AAkBF;;;;;;;;;;;;;;;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;;;;;GAKG;AACH,QAAA,MAAM,eAAe,GACnB,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KACxC,WAGA,CAAC;AAQJ;;;;;;;;GAQG;AACH,QAAA,MAAM,qBAAqB,GAAI,QAAQ,WAAW,KAAG,MAAM,GAAG,IAO3D,CAAC;AAEJ,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAIlB,eAAe,EACf,cAAc,EACd,gBAAgB,GACjB,CAAC"}
@@ -84,6 +84,23 @@ const fallbackColor = (color, fallbackColor) => {
84
84
  }
85
85
  return fallbackColor;
86
86
  };
87
+ /**
88
+ * Every color param a card accepts, before any `_light` / `_dark` suffix.
89
+ *
90
+ * Single source of truth: the param types and {@link COLOR_PARAM_KEYS} are all
91
+ * derived from this, so adding a param here is enough.
92
+ */
93
+ const BASE_COLOR_KEYS = [
94
+ "title_color",
95
+ "icon_color",
96
+ "text_color",
97
+ "bg_color",
98
+ "border_color",
99
+ "ring_color",
100
+ "prog_bar_bg_color",
101
+ "theme",
102
+ ];
103
+ const THEME_VARIANTS = ["light", "dark"];
87
104
  /**
88
105
  * Returns theme based colors with proper overrides and defaults.
89
106
  *
@@ -94,10 +111,11 @@ const fallbackColor = (color, fallbackColor) => {
94
111
  * @param props.bg_color Card background color.
95
112
  * @param props.border_color Card border color.
96
113
  * @param props.ring_color Card ring color.
114
+ * @param props.prog_bar_bg_color Progress bar background color.
97
115
  * @param props.theme Card theme.
98
116
  * @returns Card colors.
99
117
  */
100
- const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, theme, }) => {
118
+ const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_color, ring_color, prog_bar_bg_color, theme, }) => {
101
119
  const defaultTheme = themes.default;
102
120
  const isThemeProvided = theme !== undefined && theme in themes;
103
121
  const selectedTheme = isThemeProvided
@@ -111,19 +129,98 @@ const getCardColors = ({ title_color, text_color, icon_color, bg_color, border_c
111
129
  const titleColor = fallbackColor(title_color || selectedTheme.title_color, "#" + defaultTheme.title_color);
112
130
  // get the color provided by the user else the theme color
113
131
  // finally if both colors are invalid we use the titleColor
114
- // NOTE: no built-in theme defines `ring_color`, so it falls back to the title color.
115
- const ringColor = fallbackColor(ring_color, titleColor);
116
132
  const iconColor = fallbackColor(icon_color || selectedTheme.icon_color, "#" + defaultTheme.icon_color);
117
133
  const textColor = fallbackColor(text_color || selectedTheme.text_color, "#" + defaultTheme.text_color);
118
134
  const bgColor = fallbackColor(bg_color || selectedTheme.bg_color, "#" + defaultTheme.bg_color);
119
135
  const borderColor = fallbackColor(border_color || defaultBorderColor, "#" + defaultBorderColor);
136
+ // No theme defines `ring_color`, so it falls back to the title color.
137
+ const ringColor = fallbackColor(ring_color, titleColor);
138
+ // No theme defines `prog_bar_bg_color`, so it falls back to "#ddd".
139
+ const progBarBgColor = fallbackColor(prog_bar_bg_color, "#ddd");
120
140
  if (typeof titleColor !== "string" ||
121
141
  typeof textColor !== "string" ||
122
142
  typeof ringColor !== "string" ||
143
+ typeof progBarBgColor !== "string" ||
123
144
  typeof iconColor !== "string" ||
124
145
  typeof borderColor !== "string") {
125
146
  throw new Error("Unexpected behavior, all colors except background should be string.");
126
147
  }
127
- return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor };
148
+ return {
149
+ titleColor,
150
+ iconColor,
151
+ textColor,
152
+ bgColor,
153
+ borderColor,
154
+ ringColor,
155
+ progBarBgColor,
156
+ };
128
157
  };
129
- export { fallbackColor, getCardColors, findInvalidColor, isValidGradient, isBareHexColor, isPrefixedHexColor, };
158
+ /**
159
+ * Returns the light- or dark-mode-specific color params, given a set of
160
+ * raw query params. Also removes the "_light" or "_dark" suffixes.
161
+ *
162
+ * @param params Raw query params with optional `_light` / `_dark` suffixes.
163
+ * @param suffix `"_light"` or `"_dark"`.
164
+ * @returns ColorInput with the suffix stripped, ready for `getCardColors`.
165
+ */
166
+ const extractLightDarkColors = (params, suffix) => Object.fromEntries(BASE_COLOR_KEYS.map((key) => [key, params[`${key}${suffix}`]]));
167
+ /**
168
+ * Returns resolved colors for both light and dark mode given all input params.
169
+ *
170
+ * Each mode resolves independently, then runs the normal `getCardColors` precedence
171
+ * (explicit color -> theme color -> default theme):
172
+ * light: `theme_light ?? theme`, with `*_light` params overriding general ones
173
+ * dark: `theme_dark ?? theme`, with `*_dark` params overriding general ones
174
+ *
175
+ * Anything a mode does not override falls back to the general params,
176
+ * so a partial override such as `bg_color_dark` alone keeps every other color from the base theme.
177
+ *
178
+ * When no `_light` / `_dark` param is provided at all, `darkColors` is `null` and the caller emits no dark-mode block.
179
+ *
180
+ * @param params Raw query params, containing both general and `_light`/`_dark` suffixed colors and themes.
181
+ * @returns `{ lightColors, darkColors }`, resolved colors for both light and dark mode
182
+ */
183
+ const getLightDarkColors = (params) => {
184
+ const lightOverrides = extractLightDarkColors(params, "_light");
185
+ const darkOverrides = extractLightDarkColors(params, "_dark");
186
+ const hasModeOverrides = Object.values(lightOverrides).some((v) => v !== undefined) ||
187
+ Object.values(darkOverrides).some((v) => v !== undefined);
188
+ if (!hasModeOverrides) {
189
+ return { lightColors: getCardColors(params), darkColors: null };
190
+ }
191
+ const defined = (obj) => Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
192
+ return {
193
+ lightColors: getCardColors({ ...params, ...defined(lightOverrides) }),
194
+ darkColors: getCardColors({ ...params, ...defined(darkOverrides) }),
195
+ };
196
+ };
197
+ const COLOR_PARAM_KEYS = [
198
+ ...BASE_COLOR_KEYS,
199
+ ...THEME_VARIANTS.flatMap((variant) => BASE_COLOR_KEYS.map((key) => `${key}_${variant}`)),
200
+ ];
201
+ /**
202
+ * Picks all color-related parameters from a query object.
203
+ *
204
+ * @param query Raw query parameters.
205
+ * @returns All color-related parameters.
206
+ */
207
+ const pickColorParams = (query) => Object.fromEntries(COLOR_PARAM_KEYS.filter((k) => k in query).map((k) => [k, query[k]]));
208
+ /** Params naming a theme rather than holding a color value. */
209
+ const THEME_PARAM_KEYS = [
210
+ "theme",
211
+ ...THEME_VARIANTS.map((variant) => `theme_${variant}`),
212
+ ];
213
+ /**
214
+ * Finds the first color param holding an invalid color.
215
+ *
216
+ * Theme params are skipped: they name a theme, and an unknown name falls back
217
+ * to the default rather than being an error.
218
+ *
219
+ * @param params Color params, as returned by {@link pickColorParams}.
220
+ * @returns The first invalid param name, or null if all are valid.
221
+ */
222
+ const findInvalidColorParam = (params) => findInvalidColor(Object.fromEntries(Object.entries(params).filter(([key]) => !THEME_PARAM_KEYS.includes(key))));
223
+ export { getCardColors, getLightDarkColors, findInvalidColor, findInvalidColorParam, pickColorParams, isValidGradient, isBareHexColor, isPrefixedHexColor,
224
+ // Not re-exported from the package index: internal,
225
+ // exposed so tests can pin the accepted param list.
226
+ BASE_COLOR_KEYS, THEME_VARIANTS, COLOR_PARAM_KEYS, };
@@ -7,7 +7,8 @@ interface Config {
7
7
  whitelist: Array<string> | undefined;
8
8
  gistWhitelist: Array<string> | undefined;
9
9
  excludeRepositories: Array<string>;
10
- fetchMultiPageStars: string | undefined;
10
+ /** Max pages of starred repos to fetch; `Infinity` means every page, `1` only the first. */
11
+ fetchMultiPageStars: number;
11
12
  pats: Array<PersonalAccessToken>;
12
13
  }
13
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/common/config.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,MAAM;IACd,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACrC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,IAAI,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;CAClC;AAkDD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAK,GAAqB,KAAG,IAY9D,CAAC;AAIF,eAAO,MAAM,SAAS,QAAO,MAAuB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/common/config.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,MAAM;IACd,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACrC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,4FAA4F;IAC5F,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;CAClC;AA4CD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAK,GAAqB,KAAG,IAU9D,CAAC;AAIF,eAAO,MAAM,SAAS,QAAO,MAAuB,CAAC"}
@@ -2,11 +2,17 @@
2
2
  * @param value Comma-separated string.
3
3
  * @returns Parsed string values.
4
4
  */
5
- const parseCsv = (value) => {
6
- if (!value) {
7
- return undefined;
5
+ const parseCsv = (value) => value ? value.split(",") : undefined;
6
+ /**
7
+ * @param value Raw `FETCH_MULTI_PAGE_STARS` value.
8
+ * @returns Page limit: `"true"` means every page, a positive number caps the pages, anything else means one.
9
+ */
10
+ const parseFetchMultiPageStars = (value) => {
11
+ if (value === "true") {
12
+ return Infinity;
8
13
  }
9
- return value.split(",");
14
+ const limit = Number(value);
15
+ return limit > 0 ? limit : 1;
10
16
  };
11
17
  /**
12
18
  * @param env Environment variables to inspect.
@@ -27,34 +33,18 @@ const getDefaultEnv = () => {
27
33
  const processEnv = globalThis.process?.env;
28
34
  return processEnv ?? {};
29
35
  };
30
- /**
31
- * @param config (Partial) config values to normalize.
32
- * @returns Normalized config object with defaults applied.
33
- */
34
- const normalizeConfig = (config = {}) => {
35
- return {
36
- whitelist: config.whitelist,
37
- gistWhitelist: config.gistWhitelist,
38
- excludeRepositories: config.excludeRepositories ?? [],
39
- fetchMultiPageStars: config.fetchMultiPageStars,
40
- pats: config.pats ?? [],
41
- };
42
- };
43
36
  let currentConfig;
44
37
  /**
45
38
  * @param env Environment variables used to build the runtime config.
46
39
  */
47
40
  export const loadConfigFromEnv = (env = getDefaultEnv()) => {
48
- const whitelist = parseCsv(env["WHITELIST"]);
49
- const gistWhitelist = parseCsv(env["GIST_WHITELIST"]);
50
- const excludeRepositories = parseCsv(env["EXCLUDE_REPO"]) ?? [];
51
- currentConfig = normalizeConfig({
52
- whitelist,
53
- gistWhitelist,
54
- excludeRepositories,
55
- fetchMultiPageStars: env["FETCH_MULTI_PAGE_STARS"],
41
+ currentConfig = {
42
+ whitelist: parseCsv(env["WHITELIST"]),
43
+ gistWhitelist: parseCsv(env["GIST_WHITELIST"]),
44
+ excludeRepositories: parseCsv(env["EXCLUDE_REPO"]) ?? [],
45
+ fetchMultiPageStars: parseFetchMultiPageStars(env["FETCH_MULTI_PAGE_STARS"]),
56
46
  pats: parsePATsFromEnv(env),
57
- });
47
+ };
58
48
  };
59
49
  loadConfigFromEnv();
60
50
  export const getConfig = () => currentConfig;
@@ -1,6 +1,7 @@
1
+ import type { RepositoryAffiliation } from "../graphql/generated/common.js";
1
2
  /**
2
3
  * Valid owner affiliations for GitHub API queries.
3
4
  */
4
- declare const OWNER_AFFILIATIONS: Array<string>;
5
+ declare const OWNER_AFFILIATIONS: Array<RepositoryAffiliation>;
5
6
  export { OWNER_AFFILIATIONS };
6
7
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAIrC,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;;GAEG;AACH,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,qBAAqB,CAIpD,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** A span between two dates, as GitHub's range arguments take it. */
2
+ interface GitHubDateRange {
3
+ /** Start of the range, inclusive. */
4
+ from: Date;
5
+ /** End of the range, inclusive. */
6
+ to: Date;
7
+ }
8
+ /**
9
+ * Format a date as a GitHub `DateTime` scalar.
10
+ * Seconds precision, no milliseconds.
11
+ *
12
+ * @param date Date to format.
13
+ * @returns e.g. `2024-01-01T00:00:00Z`.
14
+ */
15
+ declare const toGitHubDateTime: (date: Date) => string;
16
+ /**
17
+ * The full UTC span of a calendar year, both ends inclusive.
18
+ *
19
+ * The end matters to callers that would otherwise leave a range open:
20
+ * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
21
+ * which pulls the next 1st of January into the year.
22
+ *
23
+ * @param year Four-digit year.
24
+ * @returns The range covering it.
25
+ */
26
+ declare const getGitHubYearRange: (year: number) => GitHubDateRange;
27
+ /**
28
+ * Get diff in minutes between two dates.
29
+ *
30
+ * @param d1 First date.
31
+ * @param d2 Second date.
32
+ * @returns Number of minutes between the two dates.
33
+ */
34
+ declare const dateDiff: (d1: Date, d2: Date) => number;
35
+ export { dateDiff, getGitHubYearRange, toGitHubDateTime };
36
+ export type { GitHubDateRange };
37
+ //# sourceMappingURL=date.d.ts.map
@@ -0,0 +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,MACA,CAAC;AAExC;;;;;;;;;GASG;AACH,QAAA,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,eAGzC,CAAC;AAEH;;;;;;GAMG;AACH,QAAA,MAAM,QAAQ,GAAI,IAAI,IAAI,EAAE,IAAI,IAAI,KAAG,MACkB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Format a date as a GitHub `DateTime` scalar.
3
+ * Seconds precision, no milliseconds.
4
+ *
5
+ * @param date Date to format.
6
+ * @returns e.g. `2024-01-01T00:00:00Z`.
7
+ */
8
+ const toGitHubDateTime = (date) => `${date.toISOString().slice(0, 19)}Z`;
9
+ /**
10
+ * The full UTC span of a calendar year, both ends inclusive.
11
+ *
12
+ * The end matters to callers that would otherwise leave a range open:
13
+ * GitHub's `contributionsCollection` defaults `to` to one year after `from`,
14
+ * which pulls the next 1st of January into the year.
15
+ *
16
+ * @param year Four-digit year.
17
+ * @returns The range covering it.
18
+ */
19
+ const getGitHubYearRange = (year) => ({
20
+ from: new Date(Date.UTC(year, 0, 1)),
21
+ to: new Date(Date.UTC(year, 11, 31, 23, 59, 59)),
22
+ });
23
+ /**
24
+ * Get diff in minutes between two dates.
25
+ *
26
+ * @param d1 First date.
27
+ * @param d2 Second date.
28
+ * @returns Number of minutes between the two dates.
29
+ */
30
+ const dateDiff = (d1, d2) => Math.round((d1.getTime() - d2.getTime()) / (1000 * 60));
31
+ export { dateDiff, getGitHubYearRange, toGitHubDateTime };