@stats-organization/github-readme-stats-core 2.1.4 → 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 (182) 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 +28 -26
  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 +32 -36
  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 +18 -33
  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 +32 -44
  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 +28 -26
  16. package/build/calculateRank.d.ts +12 -11
  17. package/build/calculateRank.d.ts.map +1 -1
  18. package/build/calculateRank.js +18 -18
  19. package/build/cards/common-options.d.ts +13 -0
  20. package/build/cards/common-options.d.ts.map +1 -0
  21. package/build/cards/common-options.js +1 -0
  22. package/build/cards/gist.d.ts +11 -16
  23. package/build/cards/gist.d.ts.map +1 -1
  24. package/build/cards/gist.js +26 -31
  25. package/build/cards/repo.d.ts +19 -16
  26. package/build/cards/repo.d.ts.map +1 -1
  27. package/build/cards/repo.js +79 -72
  28. package/build/cards/stats.d.ts +29 -44
  29. package/build/cards/stats.d.ts.map +1 -1
  30. package/build/cards/stats.js +118 -173
  31. package/build/cards/top-languages.d.ts +81 -77
  32. package/build/cards/top-languages.d.ts.map +1 -1
  33. package/build/cards/top-languages.js +186 -184
  34. package/build/cards/wakatime.d.ts +21 -11
  35. package/build/cards/wakatime.d.ts.map +1 -1
  36. package/build/cards/wakatime.js +92 -109
  37. package/build/common/Card.d.ts +41 -14
  38. package/build/common/Card.d.ts.map +1 -1
  39. package/build/common/Card.js +92 -31
  40. package/build/common/I18n.d.ts +4 -2
  41. package/build/common/I18n.d.ts.map +1 -1
  42. package/build/common/color.d.ts +91 -15
  43. package/build/common/color.d.ts.map +1 -1
  44. package/build/common/color.js +163 -17
  45. package/build/common/config.d.ts +2 -1
  46. package/build/common/config.d.ts.map +1 -1
  47. package/build/common/config.js +16 -26
  48. package/build/common/constants.d.ts +2 -1
  49. package/build/common/constants.d.ts.map +1 -1
  50. package/build/common/date.d.ts +37 -0
  51. package/build/common/date.d.ts.map +1 -0
  52. package/build/common/date.js +31 -0
  53. package/build/common/html.js +1 -1
  54. package/build/common/http.d.ts +37 -5
  55. package/build/common/http.d.ts.map +1 -1
  56. package/build/common/http.js +29 -6
  57. package/build/common/icons.d.ts +1 -0
  58. package/build/common/icons.d.ts.map +1 -1
  59. package/build/common/icons.js +1 -0
  60. package/build/common/languageColors.d.ts +11 -0
  61. package/build/common/languageColors.d.ts.map +1 -0
  62. package/build/common/languageColors.js +15 -0
  63. package/build/common/languageColors.json +10 -1
  64. package/build/common/ops.d.ts +27 -33
  65. package/build/common/ops.d.ts.map +1 -1
  66. package/build/common/ops.js +31 -48
  67. package/build/common/render.d.ts +154 -113
  68. package/build/common/render.d.ts.map +1 -1
  69. package/build/common/render.js +209 -92
  70. package/build/common/retryer.d.ts +15 -6
  71. package/build/common/retryer.d.ts.map +1 -1
  72. package/build/common/retryer.js +2 -0
  73. package/build/fetchers/gist.d.ts +6 -21
  74. package/build/fetchers/gist.d.ts.map +1 -1
  75. package/build/fetchers/gist.js +28 -64
  76. package/build/fetchers/repo.d.ts +12 -11
  77. package/build/fetchers/repo.d.ts.map +1 -1
  78. package/build/fetchers/repo.js +27 -68
  79. package/build/fetchers/stats.d.ts +24 -17
  80. package/build/fetchers/stats.d.ts.map +1 -1
  81. package/build/fetchers/stats.js +302 -184
  82. package/build/fetchers/top-languages.d.ts +10 -15
  83. package/build/fetchers/top-languages.d.ts.map +1 -1
  84. package/build/fetchers/top-languages.js +52 -103
  85. package/build/fetchers/types.d.ts +130 -0
  86. package/build/fetchers/types.d.ts.map +1 -0
  87. package/build/fetchers/types.js +1 -0
  88. package/build/fetchers/wakatime.d.ts +9 -5
  89. package/build/fetchers/wakatime.d.ts.map +1 -1
  90. package/build/fetchers/wakatime.js +8 -4
  91. package/build/graphql/contributionsDocument.d.ts +18 -0
  92. package/build/graphql/contributionsDocument.d.ts.map +1 -0
  93. package/build/graphql/contributionsDocument.js +30 -0
  94. package/build/graphql/generated/common.d.ts +42 -0
  95. package/build/graphql/generated/common.d.ts.map +1 -0
  96. package/build/graphql/generated/common.js +2 -0
  97. package/build/graphql/generated/gist.d.ts +44 -0
  98. package/build/graphql/generated/gist.d.ts.map +1 -0
  99. package/build/graphql/generated/gist.js +27 -0
  100. package/build/graphql/generated/repo.d.ts +67 -0
  101. package/build/graphql/generated/repo.d.ts.map +1 -0
  102. package/build/graphql/generated/repo.js +30 -0
  103. package/build/graphql/generated/stats.d.ts +150 -0
  104. package/build/graphql/generated/stats.d.ts.map +1 -0
  105. package/build/graphql/generated/stats.js +95 -0
  106. package/build/graphql/generated/top-languages.d.ts +54 -0
  107. package/build/graphql/generated/top-languages.d.ts.map +1 -0
  108. package/build/graphql/generated/top-languages.js +27 -0
  109. package/build/graphql/graphqlDocument.d.ts +22 -0
  110. package/build/graphql/graphqlDocument.d.ts.map +1 -0
  111. package/build/graphql/graphqlDocument.js +8 -0
  112. package/build/graphql/reposContributedToDocument.d.ts +27 -0
  113. package/build/graphql/reposContributedToDocument.d.ts.map +1 -0
  114. package/build/graphql/reposContributedToDocument.js +59 -0
  115. package/build/index.d.ts +3 -1
  116. package/build/index.d.ts.map +1 -1
  117. package/build/index.js +2 -1
  118. package/build/themes/index.d.ts +32 -0
  119. package/build/themes/index.d.ts.map +1 -1
  120. package/build/themes/index.js +28 -0
  121. package/build/translations.d.ts +17 -0
  122. package/build/translations.d.ts.map +1 -1
  123. package/build/translations.js +17 -0
  124. package/package.json +14 -8
  125. package/src/_emoji-name-map.d.ts +10 -0
  126. package/src/_github-username-regex.d.ts +4 -0
  127. package/src/api/gist.js +31 -31
  128. package/src/api/index.js +40 -42
  129. package/src/api/pin.js +20 -38
  130. package/src/api/top-langs.js +36 -49
  131. package/src/api/wakatime.js +31 -31
  132. package/src/{calculateRank.js → calculateRank.ts} +29 -19
  133. package/src/cards/common-options.ts +13 -0
  134. package/src/cards/{gist.js → gist.ts} +37 -37
  135. package/src/cards/{repo.js → repo.ts} +107 -79
  136. package/src/cards/{stats.js → stats.ts} +173 -210
  137. package/src/cards/{top-languages.js → top-languages.ts} +325 -243
  138. package/src/cards/{wakatime.js → wakatime.ts} +158 -127
  139. package/src/common/Card.ts +123 -43
  140. package/src/common/I18n.ts +6 -2
  141. package/src/common/color.ts +240 -28
  142. package/src/common/config.ts +22 -29
  143. package/src/common/constants.ts +3 -1
  144. package/src/common/date.ts +45 -0
  145. package/src/common/html.ts +1 -1
  146. package/src/common/http.ts +71 -0
  147. package/src/common/icons.ts +1 -0
  148. package/src/common/languageColors.json +10 -1
  149. package/src/common/languageColors.ts +19 -0
  150. package/src/common/ops.ts +158 -0
  151. package/src/common/render.ts +652 -0
  152. package/src/common/retryer.ts +21 -12
  153. package/src/fetchers/gist.ts +79 -0
  154. package/src/fetchers/repo.ts +114 -0
  155. package/src/fetchers/stats.ts +743 -0
  156. package/src/fetchers/top-languages.ts +135 -0
  157. package/src/fetchers/{types.d.ts → types.ts} +28 -20
  158. package/src/fetchers/{wakatime.js → wakatime.ts} +19 -5
  159. package/src/graphql/contributionsDocument.ts +44 -0
  160. package/src/graphql/generated/common.ts +26 -0
  161. package/src/graphql/generated/gist.ts +59 -0
  162. package/src/graphql/generated/repo.ts +90 -0
  163. package/src/graphql/generated/stats.ts +194 -0
  164. package/src/graphql/generated/top-languages.ts +75 -0
  165. package/src/graphql/graphqlDocument.ts +25 -0
  166. package/src/graphql/queries/gist.graphql +25 -0
  167. package/src/graphql/queries/repo.graphql +28 -0
  168. package/src/graphql/queries/stats.graphql +120 -0
  169. package/src/graphql/queries/top-languages.graphql +34 -0
  170. package/src/graphql/reposContributedToDocument.ts +86 -0
  171. package/src/index.ts +3 -1
  172. package/src/themes/index.ts +33 -0
  173. package/src/translations.ts +17 -0
  174. package/src/cards/types.d.ts +0 -78
  175. package/src/common/http.js +0 -19
  176. package/src/common/ops.js +0 -170
  177. package/src/common/render.js +0 -440
  178. package/src/fetchers/gist.js +0 -112
  179. package/src/fetchers/repo.js +0 -161
  180. package/src/fetchers/stats.js +0 -474
  181. package/src/fetchers/top-languages.js +0 -175
  182. package/src/themes/README.md +0 -229
@@ -1,16 +1,26 @@
1
- export type WakaTimeLang = any;
2
- export type WakaTimeData = any;
3
- export type WakaTimeOptions = any;
4
- /**
5
- * @typedef {import('../fetchers/types').WakaTimeData} WakaTimeData
6
- * @typedef {import('./types').WakaTimeOptions} WakaTimeOptions
7
- */
1
+ import type { WakaTimeData } from "../fetchers/types.js";
2
+ import type { CommonOptions } from "./common-options.js";
3
+ type WakaTimeLayout = "compact" | "normal";
4
+ type DisplayFormat = "time" | "percent";
5
+ interface WakaTimeOptions extends CommonOptions {
6
+ hide_title: boolean;
7
+ hide: Array<string>;
8
+ card_width: number;
9
+ line_height: number | string;
10
+ hide_progress: boolean;
11
+ custom_title: string;
12
+ layout: WakaTimeLayout;
13
+ langs_count: number;
14
+ display_format: DisplayFormat;
15
+ disable_animations: boolean;
16
+ }
8
17
  /**
9
18
  * Renders WakaTime card.
10
19
  *
11
- * @param {Partial<WakaTimeData>} stats WakaTime stats.
12
- * @param {Partial<WakaTimeOptions>} options Card options.
13
- * @returns {string} WakaTime card SVG.
20
+ * @param stats WakaTime stats.
21
+ * @param options Card options.
22
+ * @returns WakaTime card SVG.
14
23
  */
15
- export function renderWakatimeCard(stats?: Partial<WakaTimeData>, options?: Partial<WakaTimeOptions>): string;
24
+ declare const renderWakatimeCard: (stats?: Partial<WakaTimeData>, options?: Partial<WakaTimeOptions>) => string;
25
+ export { renderWakatimeCard };
16
26
  //# sourceMappingURL=wakatime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/cards/wakatime.js"],"names":[],"mappings":";;;AA6NA;;;GAGG;AAEH;;;;;;GAMG;AACH,2CAJW,OAAO,CAAC,YAAY,CAAC,YACrB,OAAO,CAAC,eAAe,CAAC,GACtB,MAAM,CA2OlB"}
1
+ {"version":3,"file":"wakatime.d.ts","sourceRoot":"","sources":["../../src/cards/wakatime.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,sBAAsB,CAAC;AAGvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,KAAK,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC3C,KAAK,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAExC,UAAU,eAAgB,SAAQ,aAAa;IAC7C,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,aAAa,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAoPD;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,GACtB,QAAO,OAAO,CAAC,YAAY,CAAM,EACjC,UAAS,OAAO,CAAC,eAAe,CAAgB,KAC/C,MAgNF,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { Card } from "../common/Card.js";
2
2
  import { I18n } from "../common/I18n.js";
3
- import { getCardColors } from "../common/color.js";
4
- import languageColors from "../common/languageColors.json" with { type: "json" };
3
+ import { getLightDarkColors, isPrefixedHexColor } from "../common/color.js";
4
+ import { encodeHTML } from "../common/html.js";
5
+ import { getLanguageColor } from "../common/languageColors.js";
5
6
  import { clampValue, lowercaseTrim } from "../common/ops.js";
6
7
  import { createProgressNode, flexLayout } from "../common/render.js";
7
8
  import { wakatimeCardLocales } from "../translations.js";
@@ -16,51 +17,52 @@ const TOTAL_TEXT_WIDTH = 275;
16
17
  /**
17
18
  * Creates the no coding activity SVG node.
18
19
  *
19
- * @param {object} props The function properties.
20
- * @param {string} props.color No coding activity text color.
21
- * @param {string} props.text No coding activity translated text.
22
- * @returns {string} No coding activity SVG node string.
20
+ * @param props The function properties.
21
+ * @param props.text No coding activity translated text.
22
+ * @returns No coding activity SVG node string.
23
23
  */
24
- const noCodingActivityNode = ({ color, text }) => {
24
+ const noCodingActivityNode = ({ text }) => {
25
25
  return `
26
- <text x="25" y="11" class="stat bold" fill="${color}">${text}</text>
26
+ <text x="25" y="11" class="stat bold">${encodeHTML(text)}</text>
27
27
  `;
28
28
  };
29
- /**
30
- * @typedef {import('../fetchers/types').WakaTimeLang} WakaTimeLang
31
- */
32
29
  /**
33
30
  * Format language value.
34
31
  *
35
- * @param {Object} args The function arguments.
36
- * @param {WakaTimeLang} args.lang The language object.
37
- * @param {"time" | "percent"} args.display_format The display format of the language node.
38
- * @returns {string} The formatted language value.
32
+ * @param args The function arguments.
33
+ * @param args.lang The language object.
34
+ * @param args.display_format The display format of the language node.
35
+ * @returns The formatted language value.
39
36
  */
40
- const formatLanguageValue = ({ display_format, lang }) => {
37
+ const formatLanguageValue = ({ display_format, lang, }) => {
41
38
  return display_format === "percent"
42
- ? `${lang.percent.toFixed(2).toString()} %`
39
+ ? `${lang.percent.toFixed(2)} %`
43
40
  : lang.text;
44
41
  };
45
42
  /**
46
43
  * Create compact WakaTime layout.
47
44
  *
48
- * @param {Object} args The function arguments.
49
- * @param {WakaTimeLang} args.lang The languages array.
50
- * @param {number} args.x The x position of the language node.
51
- * @param {number} args.y The y position of the language node.
52
- * @param {"time" | "percent"} args.display_format The display format of the language node.
53
- * @returns {string} The compact layout language SVG node.
45
+ * @param args The function arguments.
46
+ * @param args.lang The languages array.
47
+ * @param args.x The x position of the language node.
48
+ * @param args.y The y position of the language node.
49
+ * @param args.display_format The display format of the language node.
50
+ * @returns The compact layout language SVG node.
54
51
  */
55
- const createCompactLangNode = ({ lang, x, y, display_format }) => {
56
- // @ts-ignore
57
- const color = languageColors[lang.name] || "#858585";
52
+ const createCompactLangNode = ({ lang, x, y, display_format, }) => {
53
+ if (!Number.isFinite(x)) {
54
+ throw new Error(`Invalid x: "${x}"`);
55
+ }
56
+ if (!Number.isFinite(y)) {
57
+ throw new Error(`Invalid y: "${y}"`);
58
+ }
59
+ const color = getLanguageColor(lang.name);
58
60
  const value = formatLanguageValue({ display_format, lang });
59
61
  return `
60
62
  <g transform="translate(${x}, ${y})">
61
63
  <circle cx="5" cy="6" r="5" fill="${color}" />
62
64
  <text data-testid="lang-name" x="15" y="10" class='lang-name'>
63
- ${lang.name} - ${value}
65
+ ${encodeHTML(lang.name)} - ${encodeHTML(value)}
64
66
  </text>
65
67
  </g>
66
68
  `;
@@ -68,14 +70,14 @@ const createCompactLangNode = ({ lang, x, y, display_format }) => {
68
70
  /**
69
71
  * Create WakaTime language text node item.
70
72
  *
71
- * @param {Object} args The function arguments.
72
- * @param {WakaTimeLang[]} args.langs The language objects.
73
- * @param {number} args.y The y position of the language node.
74
- * @param {"time" | "percent"} args.display_format The display format of the language node.
75
- * @param {number} args.card_width Width in px of the card.
76
- * @returns {string[]} The language text node items.
73
+ * @param args The function arguments.
74
+ * @param args.langs The language objects.
75
+ * @param args.y The y position of the language node.
76
+ * @param args.display_format The display format of the language node.
77
+ * @param args.card_width Width in px of the card.
78
+ * @returns The language text node items.
77
79
  */
78
- const createLanguageTextNode = ({ langs, y, display_format, card_width }) => {
80
+ const createLanguageTextNode = ({ langs, y, display_format, card_width, }) => {
79
81
  const LEFT_X = 25;
80
82
  const RIGHT_X_BASE = 230;
81
83
  const rightOffset = (card_width - DEFAULT_CARD_WIDTH) / 2;
@@ -93,19 +95,23 @@ const createLanguageTextNode = ({ langs, y, display_format, card_width }) => {
93
95
  /**
94
96
  * Create WakaTime text item.
95
97
  *
96
- * @param {Object} args The function arguments.
97
- * @param {string} args.id The id of the text node item.
98
- * @param {string} args.label The label of the text node item.
99
- * @param {string} args.value The value of the text node item.
100
- * @param {number} args.index The index of the text node item.
101
- * @param {number} args.percent Percentage of the text node item.
102
- * @param {boolean=} args.hideProgress Whether to hide the progress bar.
103
- * @param {string} args.progressBarColor The color of the progress bar.
104
- * @param {string} args.progressBarBackgroundColor The color of the progress bar background.
105
- * @param {number} args.progressBarWidth The width of the progress bar.
106
- * @returns {string} The text SVG node.
98
+ * @param args The function arguments.
99
+ * @param args.id The id of the text node item.
100
+ * @param args.label The label of the text node item.
101
+ * @param args.value The value of the text node item.
102
+ * @param args.index The index of the text node item.
103
+ * @param args.percent Percentage of the text node item.
104
+ * @param args.hideProgress Whether to hide the progress bar.
105
+ * @param args.progressBarWidth The width of the progress bar.
106
+ * @returns The text SVG node.
107
107
  */
108
- const createTextNode = ({ id, label, value, index, percent, hideProgress, progressBarColor, progressBarBackgroundColor, progressBarWidth, }) => {
108
+ const createTextNode = ({ id, label, value, index, percent, hideProgress, progressBarWidth, }) => {
109
+ if (!Number.isFinite(index)) {
110
+ throw new Error(`Invalid index: "${index}"`);
111
+ }
112
+ if (!Number.isFinite(progressBarWidth)) {
113
+ throw new Error(`Invalid progressBarWidth: "${progressBarWidth}"`);
114
+ }
109
115
  const staggerDelay = (index + 3) * 150;
110
116
  const cardProgress = hideProgress
111
117
  ? null
@@ -113,22 +119,18 @@ const createTextNode = ({ id, label, value, index, percent, hideProgress, progre
113
119
  x: 110,
114
120
  y: 4,
115
121
  progress: percent,
116
- color: progressBarColor,
117
122
  width: progressBarWidth,
118
- // @ts-ignore
119
- name: label,
120
- progressBarBackgroundColor,
121
123
  delay: staggerDelay + 300,
122
124
  });
123
125
  return `
124
126
  <g class="stagger" style="animation-delay: ${staggerDelay}ms" transform="translate(25, 0)">
125
- <text class="stat bold" y="12.5" data-testid="${id}">${label}:</text>
127
+ <text class="stat bold" y="12.5" data-testid="${encodeHTML(id)}">${encodeHTML(label)}:</text>
126
128
  <text
127
129
  class="stat"
128
130
  x="${hideProgress ? HIDDEN_PROGRESSBAR_PADDING : PROGRESSBAR_PADDING + progressBarWidth}"
129
131
  y="12.5"
130
- >${value}</text>
131
- ${cardProgress}
132
+ >${encodeHTML(value)}</text>
133
+ ${String(cardProgress)}
132
134
  </g>
133
135
  `;
134
136
  };
@@ -136,8 +138,7 @@ const createTextNode = ({ id, label, value, index, percent, hideProgress, progre
136
138
  * Recalculating percentages so that, compact layout's progress bar does not break when
137
139
  * hiding languages.
138
140
  *
139
- * @param {WakaTimeLang[]} languages The languages array.
140
- * @returns {void} The recalculated languages array.
141
+ * @param languages The languages array.
141
142
  */
142
143
  const recalculatePercentages = (languages) => {
143
144
  const totalSum = languages.reduce((totalSum, language) => totalSum + language.percent, 0);
@@ -149,14 +150,14 @@ const recalculatePercentages = (languages) => {
149
150
  /**
150
151
  * Retrieves CSS styles for a card.
151
152
  *
152
- * @param {Object} colors The colors to use for the card.
153
- * @param {string} colors.titleColor The title color.
154
- * @param {string} colors.textColor The text color.
155
- * @returns {string} Card CSS styles.
153
+ * @param colors The colors to use for the card.
154
+ * @param colors.textColor The text color.
155
+ * @returns Card CSS styles.
156
156
  */
157
- const getStyles = ({
158
- // eslint-disable-next-line no-unused-vars
159
- titleColor, textColor, }) => {
157
+ const getStyles = ({ textColor }) => {
158
+ if (!isPrefixedHexColor(textColor)) {
159
+ throw new Error(`Invalid text color: "${textColor}"`);
160
+ }
160
161
  return `
161
162
  .stat {
162
163
  font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${textColor};
@@ -176,31 +177,27 @@ titleColor, textColor, }) => {
176
177
  /**
177
178
  * Normalize incoming width (string or number) and clamp to minimum.
178
179
  *
179
- * @param {Object} args The function arguments.
180
- * @param {WakaTimeOptions["layout"] | undefined} args.layout The incoming layout value.
181
- * @param {number|undefined} args.value The incoming width value.
182
- * @returns {number} The normalized width value.
180
+ * @param args The function arguments.
181
+ * @param args.layout The incoming layout value.
182
+ * @param args.value The incoming width value.
183
+ * @returns The normalized width value.
183
184
  */
184
- const normalizeCardWidth = ({ value, layout }) => {
185
- if (value === undefined || value === null || isNaN(value)) {
185
+ const normalizeCardWidth = ({ value, layout, }) => {
186
+ if (value === undefined || isNaN(value)) {
186
187
  return DEFAULT_CARD_WIDTH;
187
188
  }
188
189
  return Math.max(layout === "compact" ? COMPACT_LAYOUT_MIN_WIDTH : MIN_CARD_WIDTH, value);
189
190
  };
190
- /**
191
- * @typedef {import('../fetchers/types').WakaTimeData} WakaTimeData
192
- * @typedef {import('./types').WakaTimeOptions} WakaTimeOptions
193
- */
194
191
  /**
195
192
  * Renders WakaTime card.
196
193
  *
197
- * @param {Partial<WakaTimeData>} stats WakaTime stats.
198
- * @param {Partial<WakaTimeOptions>} options Card options.
199
- * @returns {string} WakaTime card SVG.
194
+ * @param stats WakaTime stats.
195
+ * @param options Card options.
196
+ * @returns WakaTime card SVG.
200
197
  */
201
198
  const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
202
199
  let { languages = [] } = stats;
203
- const { hide_title = false, hide_border = false, card_width, hide, line_height = DEFAULT_LINE_HEIGHT, title_color, icon_color, text_color, bg_color, theme = "default", hide_progress, custom_title, locale, layout, langs_count = languages.length, border_radius, border_color, display_format = "time", disable_animations, } = options;
200
+ const { hide_title = false, hide_border = false, card_width, hide, line_height = DEFAULT_LINE_HEIGHT, hide_progress, custom_title, locale, layout, langs_count = languages.length, border_radius, display_format = "time", disable_animations, } = options;
204
201
  const normalizedWidth = normalizeCardWidth({ value: card_width, layout });
205
202
  const shouldHideLangs = Array.isArray(hide) && hide.length > 0;
206
203
  if (shouldHideLangs) {
@@ -217,25 +214,14 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
217
214
  });
218
215
  const lheight = parseInt(String(line_height), 10);
219
216
  const langsCount = clampValue(langs_count, 1, langs_count);
220
- // returns theme based colors with proper overrides and defaults
221
- const { titleColor, textColor, iconColor, bgColor, borderColor } = getCardColors({
222
- title_color,
223
- icon_color,
224
- text_color,
225
- bg_color,
226
- border_color,
227
- theme,
228
- });
217
+ const { lightColors, darkColors } = getLightDarkColors(options);
218
+ const { titleColor, textColor } = lightColors;
229
219
  const filteredLanguages = languages
230
220
  .filter((language) => language.hours || language.minutes)
231
221
  .slice(0, langsCount);
232
222
  // Calculate the card height depending on how many items there are
233
223
  // but if rank circle is visible clamp the minimum height to `150`
234
224
  let height = Math.max(45 + (filteredLanguages.length + 1) * lheight, 150);
235
- const cssStyles = getStyles({
236
- titleColor,
237
- textColor,
238
- });
239
225
  let finalLayout;
240
226
  // RENDER COMPACT LAYOUT
241
227
  if (layout === "compact") {
@@ -249,8 +235,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
249
235
  .map((language) => {
250
236
  const progress = ((width - COMPACT_LAYOUT_PROGRESSBAR_PADDING) * language.percent) /
251
237
  100;
252
- // @ts-ignore
253
- const languageColor = languageColors[language.name] || "#858585";
238
+ const languageColor = getLanguageColor(language.name);
254
239
  const output = `
255
240
  <rect
256
241
  mask="url(#rect-mask)"
@@ -279,8 +264,6 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
279
264
  card_width: normalizedWidth,
280
265
  }).join("")
281
266
  : noCodingActivityNode({
282
- // @ts-ignore
283
- color: textColor,
284
267
  text: stats.is_coding_activity_visible
285
268
  ? stats.is_other_usage_visible
286
269
  ? i18n.t("wakatimecard.nocodingactivity")
@@ -299,18 +282,12 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
299
282
  value: formatLanguageValue({ display_format, lang: language }),
300
283
  index,
301
284
  percent: language.percent,
302
- // @ts-ignore
303
- progressBarColor: titleColor,
304
- // @ts-ignore
305
- progressBarBackgroundColor: textColor === titleColor ? bgColor : textColor,
306
285
  hideProgress: hide_progress,
307
286
  progressBarWidth: normalizedWidth - TOTAL_TEXT_WIDTH,
308
287
  });
309
288
  })
310
289
  : [
311
290
  noCodingActivityNode({
312
- // @ts-ignore
313
- color: textColor,
314
291
  text: stats.is_coding_activity_visible
315
292
  ? stats.is_other_usage_visible
316
293
  ? i18n.t("wakatimecard.nocodingactivity")
@@ -338,21 +315,16 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
338
315
  width: normalizedWidth,
339
316
  height,
340
317
  border_radius,
341
- colors: {
342
- titleColor,
343
- textColor,
344
- iconColor,
345
- bgColor,
346
- borderColor,
347
- },
318
+ colors: { light: lightColors, dark: darkColors },
348
319
  });
349
320
  if (disable_animations) {
350
321
  card.disableAnimations();
351
322
  }
352
323
  card.setHideBorder(hide_border);
353
324
  card.setHideTitle(hide_title);
354
- card.setCSS(`
355
- ${cssStyles}
325
+ card.setCSS({
326
+ light: `
327
+ ${getStyles({ textColor })}
356
328
  @keyframes slideInAnimation {
357
329
  from {
358
330
  width: 0;
@@ -375,8 +347,19 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
375
347
  }
376
348
  .lang-progress{
377
349
  animation: growWidthAnimation 0.6s ease-in-out forwards;
350
+ fill: ${titleColor};
378
351
  }
379
- `);
352
+ .progress-background { fill: ${textColor === titleColor ? "#fff0" /* transparent */ : textColor}; }
353
+ `,
354
+ dark: darkColors
355
+ ? `
356
+ ${getStyles({ textColor: darkColors.textColor })}
357
+ .lang-name { fill: ${darkColors.textColor} }
358
+ .lang-progress { fill: ${darkColors.titleColor}; }
359
+ .progress-background { fill: ${darkColors.textColor === darkColors.titleColor ? "#fff0" /* transparent */ : darkColors.textColor}; }
360
+ `
361
+ : null,
362
+ });
380
363
  return card.render(`
381
364
  <svg x="0" y="0" width="100%">
382
365
  ${finalLayout}
@@ -1,14 +1,14 @@
1
1
  interface CardColors {
2
2
  /** Card title color. */
3
- titleColor?: string;
3
+ titleColor: string;
4
4
  /** Card text color. */
5
- textColor?: string;
5
+ textColor: string;
6
6
  /** Card icon color. */
7
- iconColor?: string;
7
+ iconColor: string;
8
8
  /** Card background color. */
9
- bgColor?: string | Array<string>;
9
+ bgColor: string | Array<string>;
10
10
  /** Card border color. */
11
- borderColor?: string;
11
+ borderColor: string;
12
12
  }
13
13
  declare class Card {
14
14
  width: number;
@@ -16,9 +16,13 @@ declare class Card {
16
16
  hideBorder: boolean;
17
17
  hideTitle: boolean;
18
18
  border_radius: number;
19
- colors: CardColors;
19
+ colors: {
20
+ light: CardColors;
21
+ dark: CardColors | null;
22
+ };
20
23
  title: string;
21
24
  css: string;
25
+ darkCss: string;
22
26
  paddingX: number;
23
27
  paddingY: number;
24
28
  titlePrefixIcon: string | undefined;
@@ -28,21 +32,28 @@ declare class Card {
28
32
  /**
29
33
  * Creates a new card instance.
30
34
  *
35
+ * The caller must ensure that the passed `titlePrefixIcon` is properly sanitized!
36
+ *
31
37
  * @param props Card arguments.
32
38
  * @param props.width Card width.
33
39
  * @param props.height Card height.
34
40
  * @param props.border_radius Card border radius.
35
- * @param props.colors Card colors arguments.
41
+ * @param props.colors Card colors for light and dark mode.
42
+ * @param props.colors.light Card colors for light mode.
43
+ * @param props.colors.dark Card colors for dark mode, or `null` when no dark-mode override is needed.
36
44
  * @param props.customTitle Card custom title.
37
45
  * @param props.defaultTitle Card default title.
38
- * @param props.titlePrefixIcon Card title prefix icon.
46
+ * @param props.titlePrefixIcon Sanitized card title prefix icon.
39
47
  */
40
48
  constructor({ width, height, border_radius, colors, customTitle, defaultTitle, titlePrefixIcon, }: {
41
49
  width?: number;
42
50
  height?: number;
43
- border_radius?: number;
44
- colors?: CardColors;
45
- customTitle?: string;
51
+ border_radius?: number | undefined;
52
+ colors?: {
53
+ light: CardColors;
54
+ dark: CardColors | null;
55
+ };
56
+ customTitle?: string | undefined;
46
57
  defaultTitle?: string;
47
58
  titlePrefixIcon?: string;
48
59
  });
@@ -57,9 +68,18 @@ declare class Card {
57
68
  desc: string;
58
69
  }): void;
59
70
  /**
60
- * @param value The CSS to add to the card.
71
+ * Sets the card CSS for light and dark mode.
72
+ *
73
+ * The caller must ensure that the passed CSS strings are properly sanitized!
74
+ *
75
+ * @param props The props object.
76
+ * @param props.light CSS applied unconditionally (light/default mode).
77
+ * @param props.dark CSS placed inside a `@media (prefers-color-scheme: dark)` block. Pass `null` when not needed.
61
78
  */
62
- setCSS(value: string): void;
79
+ setCSS({ light, dark }: {
80
+ light: string;
81
+ dark?: string | null;
82
+ }): void;
63
83
  /**
64
84
  * @param value Whether to hide the border or not.
65
85
  */
@@ -87,7 +107,14 @@ declare class Card {
87
107
  */
88
108
  getAnimations: () => string;
89
109
  /**
90
- * @param body The inner body of the card.
110
+ * Builds the @media (prefers-color-scheme: dark) CSS block for the card.
111
+ * Returns an empty string when no dark colors are set.
112
+ */
113
+ private renderDarkMediaBlock;
114
+ /**
115
+ * The caller must ensure that the passed `body` string is properly sanitized!
116
+ *
117
+ * @param body The sanitized inner body of the card.
91
118
  * @returns The rendered card.
92
119
  */
93
120
  render(body: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/common/Card.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,cAAM,IAAI;IACR,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;;;OAWG;gBACS,EACV,KAAW,EACX,MAAY,EACZ,aAAmB,EACnB,MAAW,EACX,WAAW,EACX,YAAiB,EACjB,eAAe,GAChB,EAAE;QACD,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B;IAyBD,iBAAiB,IAAI,IAAI;IAIzB;;;;OAIG;IACH,qBAAqB,CAAC,EACpB,KAAK,EACL,IAAI,GACL,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI;IAKR;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAInC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAOlC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,WAAW,IAAI,MAAM;IAoCrB;;OAEG;IACH,cAAc,IAAI,MAAM;IA0BxB;;;;OAIG;IACH,aAAa,QAAO,MAAM,CAoBxB;IAEF;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAgE7B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/common/Card.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAClB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,cAAM,IAAI;IACR,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;;;;;;;OAeG;gBACS,EACV,KAAW,EACX,MAAY,EACZ,aAAmB,EACnB,MAAiD,EACjD,WAAW,EACX,YAAiB,EACjB,eAAe,GAChB,EAAE;QACD,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAEhB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACnC,MAAM,CAAC,EAAE;YAAE,KAAK,EAAE,UAAU,CAAC;YAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;SAAE,CAAC;QACxD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACjC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B;IAuBD,iBAAiB,IAAI,IAAI;IAIzB;;;;OAIG;IACH,qBAAqB,CAAC,EACpB,KAAK,EACL,IAAI,GACL,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI;IAKR;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAKtE;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAInC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAUlC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,WAAW,IAAI,MAAM;IAoCrB;;OAEG;IACH,cAAc,IAAI,MAAM;IA4CxB;;;;OAIG;IACH,aAAa,QAAO,MAAM,CAoBxB;IAEF;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAuF7B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,eAAe,IAAI,CAAC"}