Skip to content

Commit 02ebd32

Browse files
authored
refactor: jsdoc in utils & minor changes (anuraghazra#1377)
* refactor: jsdoc in utils & minor changes * chore: jsdoc Card class * chore: jsdoc for getStyles
1 parent d0ab2ff commit 02ebd32

File tree

7 files changed

+143
-41
lines changed

7 files changed

+143
-41
lines changed

api/index.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ module.exports = async (req, res) => {
3434
border_radius,
3535
border_color,
3636
} = req.query;
37-
let stats;
38-
3937
res.setHeader("Content-Type", "image/svg+xml");
4038

4139
if (blacklist.includes(username)) {
@@ -47,7 +45,7 @@ module.exports = async (req, res) => {
4745
}
4846

4947
try {
50-
stats = await fetchStats(
48+
const stats = await fetchStats(
5149
username,
5250
parseBoolean(count_private),
5351
parseBoolean(include_all_commits),

api/pin.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ module.exports = async (req, res) => {
2727
border_color,
2828
} = req.query;
2929

30-
let repoData;
31-
3230
res.setHeader("Content-Type", "image/svg+xml");
3331

3432
if (blacklist.includes(username)) {
@@ -40,7 +38,7 @@ module.exports = async (req, res) => {
4038
}
4139

4240
try {
43-
repoData = await fetchRepo(username, repo);
41+
const repoData = await fetchRepo(username, repo);
4442

4543
let cacheSeconds = clampValue(
4644
parseInt(cache_seconds || CONSTANTS.TWO_HOURS, 10),

api/top-langs.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ module.exports = async (req, res) => {
3131
border_radius,
3232
border_color,
3333
} = req.query;
34-
let topLangs;
35-
3634
res.setHeader("Content-Type", "image/svg+xml");
3735

3836
if (blacklist.includes(username)) {
@@ -44,7 +42,7 @@ module.exports = async (req, res) => {
4442
}
4543

4644
try {
47-
topLangs = await fetchTopLanguages(
45+
const topLangs = await fetchTopLanguages(
4846
username,
4947
parseArray(exclude_repo),
5048
parseArray(hide),

src/cards/repo-card.js

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,14 @@ const renderRepoCard = (repo, options = {}) => {
110110
});
111111

112112
// returns theme based colors with proper overrides and defaults
113-
const { titleColor, textColor, iconColor, bgColor, borderColor } =
114-
getCardColors({
115-
title_color,
116-
icon_color,
117-
text_color,
118-
bg_color,
119-
border_color,
120-
theme,
121-
});
113+
const colors = getCardColors({
114+
title_color,
115+
icon_color,
116+
text_color,
117+
bg_color,
118+
border_color,
119+
theme,
120+
});
122121

123122
const svgLanguage = primaryLanguage
124123
? createLanguageNode(langName, langColor)
@@ -145,32 +144,26 @@ const renderRepoCard = (repo, options = {}) => {
145144
width: 400,
146145
height,
147146
border_radius,
148-
colors: {
149-
titleColor,
150-
textColor,
151-
iconColor,
152-
bgColor,
153-
borderColor,
154-
},
147+
colors,
155148
});
156149

157150
card.disableAnimations();
158151
card.setHideBorder(hide_border);
159152
card.setHideTitle(false);
160153
card.setCSS(`
161-
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
162-
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
163-
.icon { fill: ${iconColor} }
154+
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} }
155+
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} }
156+
.icon { fill: ${colors.iconColor} }
164157
.badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
165158
.badge rect { opacity: 0.2 }
166159
`);
167160

168161
return card.render(`
169162
${
170163
isTemplate
171-
? getBadgeSVG(i18n.t("repocard.template"), textColor)
164+
? getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
172165
: isArchived
173-
? getBadgeSVG(i18n.t("repocard.archived"), textColor)
166+
? getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
174167
: ""
175168
}
176169

src/common/Card.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ const { getAnimations } = require("../getStyles");
22
const { flexLayout, encodeHTML } = require("../common/utils");
33

44
class Card {
5+
/**
6+
* @param {object} args
7+
* @param {number?=} args.width
8+
* @param {number?=} args.height
9+
* @param {number?=} args.border_radius
10+
* @param {string?=} args.customTitle
11+
* @param {string?=} args.defaultTitle
12+
* @param {string?=} args.titlePrefixIcon
13+
* @param {ReturnType<import('../common/utils').getCardColors>?=} args.colors
14+
*/
515
constructor({
616
width = 100,
717
height = 100,
@@ -38,21 +48,33 @@ class Card {
3848
this.animations = false;
3949
}
4050

51+
/**
52+
* @param {string} value
53+
*/
4154
setCSS(value) {
4255
this.css = value;
4356
}
4457

58+
/**
59+
* @param {boolean} value
60+
*/
4561
setHideBorder(value) {
4662
this.hideBorder = value;
4763
}
4864

65+
/**
66+
* @param {boolean} value
67+
*/
4968
setHideTitle(value) {
5069
this.hideTitle = value;
5170
if (value) {
5271
this.height -= 30;
5372
}
5473
}
5574

75+
/**
76+
* @param {string} text
77+
*/
5678
setTitle(text) {
5779
this.title = text;
5880
}
@@ -114,6 +136,9 @@ class Card {
114136
: "";
115137
}
116138

139+
/**
140+
* @param {string} body
141+
*/
117142
render(body) {
118143
return `
119144
<svg

src/common/utils.js

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
// @ts-check
12
const axios = require("axios");
23
const wrap = require("word-wrap");
34
const themes = require("../../themes");
45
const toEmoji = require("emoji-name-map");
56

7+
/**
8+
* @param {string} message
9+
* @param {string} secondaryMessage
10+
* @returns {string}
11+
*/
612
const renderError = (message, secondaryMessage = "") => {
713
return `
814
<svg width="495" height="120" viewBox="0 0 495 120" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -21,7 +27,11 @@ const renderError = (message, secondaryMessage = "") => {
2127
`;
2228
};
2329

24-
// https://stackoverflow.com/a/48073476/10629172
30+
/**
31+
* @see https://stackoverflow.com/a/48073476/10629172
32+
* @param {string} str
33+
* @returns {string}
34+
*/
2535
function encodeHTML(str) {
2636
return str
2737
.replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => {
@@ -30,18 +40,29 @@ function encodeHTML(str) {
3040
.replace(/\u0008/gim, "");
3141
}
3242

43+
/**
44+
* @param {number} num
45+
*/
3346
function kFormatter(num) {
3447
return Math.abs(num) > 999
35-
? Math.sign(num) * (Math.abs(num) / 1000).toFixed(1) + "k"
48+
? Math.sign(num) * parseFloat((Math.abs(num) / 1000).toFixed(1)) + "k"
3649
: Math.sign(num) * Math.abs(num);
3750
}
3851

52+
/**
53+
* @param {string} hexColor
54+
* @returns {boolean}
55+
*/
3956
function isValidHexColor(hexColor) {
4057
return new RegExp(
4158
/^([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{4})$/,
4259
).test(hexColor);
4360
}
4461

62+
/**
63+
* @param {string} value
64+
* @returns {boolean | string}
65+
*/
4566
function parseBoolean(value) {
4667
if (value === "true") {
4768
return true;
@@ -52,19 +73,37 @@ function parseBoolean(value) {
5273
}
5374
}
5475

76+
/**
77+
* @param {string} str
78+
*/
5579
function parseArray(str) {
5680
if (!str) return [];
5781
return str.split(",");
5882
}
5983

84+
/**
85+
* @param {number} number
86+
* @param {number} min
87+
* @param {number} max
88+
*/
6089
function clampValue(number, min, max) {
90+
// @ts-ignore
91+
if (Number.isNaN(parseInt(number))) return min;
6192
return Math.max(min, Math.min(number, max));
6293
}
6394

95+
/**
96+
* @param {string[]} colors
97+
*/
6498
function isValidGradient(colors) {
6599
return isValidHexColor(colors[1]) && isValidHexColor(colors[2]);
66100
}
67101

102+
/**
103+
* @param {string} color
104+
* @param {string} fallbackColor
105+
* @returns {string | string[]}
106+
*/
68107
function fallbackColor(color, fallbackColor) {
69108
let colors = color.split(",");
70109
let gradient = null;
@@ -79,7 +118,12 @@ function fallbackColor(color, fallbackColor) {
79118
);
80119
}
81120

121+
/**
122+
* @param {import('axios').AxiosRequestConfig['data']} data
123+
* @param {import('axios').AxiosRequestConfig['headers']} headers
124+
*/
82125
function request(data, headers) {
126+
// @ts-ignore
83127
return axios({
84128
url: "https://api.github.com/graphql",
85129
method: "post",
@@ -92,8 +136,8 @@ function request(data, headers) {
92136
* @param {object} props
93137
* @param {string[]} props.items
94138
* @param {number} props.gap
95-
* @param {number[]} props.sizes
96-
* @param {"column" | "row"} props.direction
139+
* @param {number[]?=} props.sizes
140+
* @param {"column" | "row"?=} props.direction
97141
*
98142
* @returns {string[]}
99143
*
@@ -115,14 +159,27 @@ function flexLayout({ items, gap, direction, sizes = [] }) {
115159
});
116160
}
117161

118-
// returns theme based colors with proper overrides and defaults
162+
/**
163+
* @typedef {object} CardColors
164+
* @prop {string} title_color
165+
* @prop {string} text_color
166+
* @prop {string} icon_color
167+
* @prop {string} bg_color
168+
* @prop {string} border_color
169+
* @prop {keyof typeof import('../../themes')?=} fallbackTheme
170+
* @prop {keyof typeof import('../../themes')?=} theme
171+
*/
172+
/**
173+
* returns theme based colors with proper overrides and defaults
174+
* @param {CardColors} options
175+
*/
119176
function getCardColors({
120177
title_color,
121178
text_color,
122179
icon_color,
123180
bg_color,
124-
theme,
125181
border_color,
182+
theme,
126183
fallbackTheme = "default",
127184
}) {
128185
const defaultTheme = themes[fallbackTheme];
@@ -157,6 +214,12 @@ function getCardColors({
157214
return { titleColor, iconColor, textColor, bgColor, borderColor };
158215
}
159216

217+
/**
218+
* @param {string} text
219+
* @param {number} width
220+
* @param {number} maxLines
221+
* @returns {string[]}
222+
*/
160223
function wrapTextMultiline(text, width = 60, maxLines = 3) {
161224
const wrapped = wrap(encodeHTML(text), { width })
162225
.split("\n") // Split wrapped lines to get an array of lines
@@ -193,6 +256,10 @@ const SECONDARY_ERROR_MESSAGES = {
193256
};
194257

195258
class CustomError extends Error {
259+
/**
260+
* @param {string} message
261+
* @param {string} type
262+
*/
196263
constructor(message, type) {
197264
super(message);
198265
this.type = type;
@@ -203,7 +270,12 @@ class CustomError extends Error {
203270
static USER_NOT_FOUND = "USER_NOT_FOUND";
204271
}
205272

206-
// https://stackoverflow.com/a/48172630/10629172
273+
/**
274+
* @see https://stackoverflow.com/a/48172630/10629172
275+
* @param {string} str
276+
* @param {number} fontSize
277+
* @returns
278+
*/
207279
function measureText(str, fontSize = 10) {
208280
// prettier-ignore
209281
const widths = [
@@ -237,6 +309,8 @@ function measureText(str, fontSize = 10) {
237309
.reduce((cur, acc) => acc + cur) * fontSize
238310
);
239311
}
312+
313+
/** @param {string} name */
240314
const lowercaseTrim = (name) => name.toLowerCase().trim();
241315

242316
/**

0 commit comments

Comments
 (0)