forked from mirrored/github-readme-stats
refactor: move operations into separate module (#4582)
Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
co-authored by
Alexandr
parent
6d1a5e51bc
commit
e158f0d27f
+2
-1
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import { renderError, parseBoolean } from "../src/common/utils.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { isLocaleAvailable } from "../src/translations.js";
|
||||
import { renderGistCard } from "../src/cards/gist.js";
|
||||
import { fetchGist } from "../src/fetchers/gist.js";
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
MissingParamError,
|
||||
retrieveSecondaryMessage,
|
||||
} from "../src/common/error.js";
|
||||
import { parseBoolean } from "../src/common/ops.js";
|
||||
|
||||
// @ts-ignore
|
||||
export default async (req, res) => {
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@ import {
|
||||
MissingParamError,
|
||||
retrieveSecondaryMessage,
|
||||
} from "../src/common/error.js";
|
||||
import { parseArray, parseBoolean, renderError } from "../src/common/utils.js";
|
||||
import { parseArray, parseBoolean } from "../src/common/ops.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { fetchStats } from "../src/fetchers/stats.js";
|
||||
import { isLocaleAvailable } from "../src/translations.js";
|
||||
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@ import {
|
||||
MissingParamError,
|
||||
retrieveSecondaryMessage,
|
||||
} from "../src/common/error.js";
|
||||
import { parseBoolean, renderError } from "../src/common/utils.js";
|
||||
import { parseBoolean } from "../src/common/ops.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { fetchRepo } from "../src/fetchers/repo.js";
|
||||
import { isLocaleAvailable } from "../src/translations.js";
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import { request } from "../../src/common/http.js";
|
||||
import { logger } from "../../src/common/log.js";
|
||||
import { dateDiff } from "../../src/common/utils.js";
|
||||
import { dateDiff } from "../../src/common/ops.js";
|
||||
|
||||
export const RATE_LIMIT_SECONDS = 60 * 5; // 1 request per 5 minutes
|
||||
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@ import {
|
||||
MissingParamError,
|
||||
retrieveSecondaryMessage,
|
||||
} from "../src/common/error.js";
|
||||
import { parseArray, parseBoolean, renderError } from "../src/common/utils.js";
|
||||
import { parseArray, parseBoolean } from "../src/common/ops.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { fetchTopLanguages } from "../src/fetchers/top-languages.js";
|
||||
import { isLocaleAvailable } from "../src/translations.js";
|
||||
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import { renderWakatimeCard } from "../src/cards/wakatime.js";
|
||||
import { parseArray, parseBoolean, renderError } from "../src/common/utils.js";
|
||||
import { renderError } from "../src/common/utils.js";
|
||||
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
|
||||
import { isLocaleAvailable } from "../src/translations.js";
|
||||
import {
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
MissingParamError,
|
||||
retrieveSecondaryMessage,
|
||||
} from "../src/common/error.js";
|
||||
import { parseArray, parseBoolean } from "../src/common/ops.js";
|
||||
|
||||
// @ts-ignore
|
||||
export default async (req, res) => {
|
||||
|
||||
+1
-1
@@ -1,7 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import {
|
||||
parseEmojis,
|
||||
encodeHTML,
|
||||
measureText,
|
||||
flexLayout,
|
||||
@@ -12,6 +11,7 @@ import Card from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
|
||||
import { icons } from "../common/icons.js";
|
||||
import { parseEmojis } from "../common/ops.js";
|
||||
|
||||
/** Import language colors.
|
||||
*
|
||||
|
||||
+1
-2
@@ -5,14 +5,13 @@ import { getCardColors } from "../common/color.js";
|
||||
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import { icons } from "../common/icons.js";
|
||||
import { clampValue, parseEmojis } from "../common/ops.js";
|
||||
import {
|
||||
encodeHTML,
|
||||
flexLayout,
|
||||
measureText,
|
||||
parseEmojis,
|
||||
iconWithLabel,
|
||||
createLanguageNode,
|
||||
clampValue,
|
||||
} from "../common/utils.js";
|
||||
import { repoCardLocales } from "../translations.js";
|
||||
|
||||
|
||||
+2
-1
@@ -6,7 +6,8 @@ import { CustomError } from "../common/error.js";
|
||||
import { kFormatter } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import { icons, rankIcon } from "../common/icons.js";
|
||||
import { clampValue, flexLayout, measureText } from "../common/utils.js";
|
||||
import { clampValue } from "../common/ops.js";
|
||||
import { flexLayout, measureText } from "../common/utils.js";
|
||||
import { statCardLocales, wakatimeCardLocales } from "../translations.js";
|
||||
|
||||
const CARD_MIN_WIDTH = 287;
|
||||
|
||||
@@ -5,13 +5,8 @@ import { getCardColors } from "../common/color.js";
|
||||
import { createProgressNode } from "../common/createProgressNode.js";
|
||||
import { formatBytes } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import {
|
||||
chunkArray,
|
||||
clampValue,
|
||||
flexLayout,
|
||||
lowercaseTrim,
|
||||
measureText,
|
||||
} from "../common/utils.js";
|
||||
import { chunkArray, clampValue, lowercaseTrim } from "../common/ops.js";
|
||||
import { flexLayout, measureText } from "../common/utils.js";
|
||||
import { langCardLocales } from "../translations.js";
|
||||
|
||||
const DEFAULT_CARD_WIDTH = 300;
|
||||
|
||||
@@ -4,7 +4,8 @@ import { Card } from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { createProgressNode } from "../common/createProgressNode.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import { clampValue, flexLayout, lowercaseTrim } from "../common/utils.js";
|
||||
import { clampValue, lowercaseTrim } from "../common/ops.js";
|
||||
import { flexLayout } from "../common/utils.js";
|
||||
import { wakatimeCardLocales } from "../translations.js";
|
||||
|
||||
/** Import language colors.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import { clampValue } from "./utils.js";
|
||||
import { clampValue } from "./ops.js";
|
||||
|
||||
const MIN = 60;
|
||||
const HOUR = 60 * MIN;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
import { clampValue } from "./utils.js";
|
||||
import { clampValue } from "./ops.js";
|
||||
|
||||
/**
|
||||
* Create a node to indicate progress in percentage along a horizontal line.
|
||||
|
||||
@@ -10,12 +10,6 @@ export {
|
||||
ERROR_CARD_LENGTH,
|
||||
renderError,
|
||||
encodeHTML,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
flexLayout,
|
||||
measureText,
|
||||
lowercaseTrim,
|
||||
chunkArray,
|
||||
parseEmojis,
|
||||
} from "./utils.js";
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
// @ts-check
|
||||
|
||||
import toEmoji from "emoji-name-map";
|
||||
|
||||
/**
|
||||
* Returns boolean if value is either "true" or "false" else the value as it is.
|
||||
*
|
||||
* @param {string | boolean} value The value to parse.
|
||||
* @returns {boolean | undefined } The parsed value.
|
||||
*/
|
||||
const parseBoolean = (value) => {
|
||||
if (typeof value === "boolean") {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
if (value.toLowerCase() === "true") {
|
||||
return true;
|
||||
} else if (value.toLowerCase() === "false") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse string to array of strings.
|
||||
*
|
||||
* @param {string} str The string to parse.
|
||||
* @returns {string[]} The array of strings.
|
||||
*/
|
||||
const parseArray = (str) => {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
return str.split(",");
|
||||
};
|
||||
|
||||
/**
|
||||
* Clamp the given number between the given range.
|
||||
*
|
||||
* @param {number} number The number to clamp.
|
||||
* @param {number} min The minimum value.
|
||||
* @param {number} max The maximum value.
|
||||
* @returns {number} The clamped number.
|
||||
*/
|
||||
const clampValue = (number, min, max) => {
|
||||
// @ts-ignore
|
||||
if (Number.isNaN(parseInt(number, 10))) {
|
||||
return min;
|
||||
}
|
||||
return Math.max(min, Math.min(number, max));
|
||||
};
|
||||
|
||||
/**
|
||||
* Lowercase and trim string.
|
||||
*
|
||||
* @param {string} name String to lowercase and trim.
|
||||
* @returns {string} Lowercased and trimmed string.
|
||||
*/
|
||||
const lowercaseTrim = (name) => name.toLowerCase().trim();
|
||||
|
||||
/**
|
||||
* Split array of languages in two columns.
|
||||
*
|
||||
* @template T Language object.
|
||||
* @param {Array<T>} arr Array of languages.
|
||||
* @param {number} perChunk Number of languages per column.
|
||||
* @returns {Array<T>} Array of languages split in two columns.
|
||||
*/
|
||||
const chunkArray = (arr, perChunk) => {
|
||||
return arr.reduce((resultArray, item, index) => {
|
||||
const chunkIndex = Math.floor(index / perChunk);
|
||||
|
||||
if (!resultArray[chunkIndex]) {
|
||||
// @ts-ignore
|
||||
resultArray[chunkIndex] = []; // start a new chunk
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
resultArray[chunkIndex].push(item);
|
||||
|
||||
return resultArray;
|
||||
}, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse emoji from string.
|
||||
*
|
||||
* @param {string} str String to parse emoji from.
|
||||
* @returns {string} String with emoji parsed.
|
||||
*/
|
||||
const parseEmojis = (str) => {
|
||||
if (!str) {
|
||||
throw new Error("[parseEmoji]: str argument not provided");
|
||||
}
|
||||
return str.replace(/:\w+:/gm, (emoji) => {
|
||||
return toEmoji.get(emoji) || "";
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get diff in minutes between two dates.
|
||||
*
|
||||
* @param {Date} d1 First date.
|
||||
* @param {Date} d2 Second date.
|
||||
* @returns {number} Number of minutes between the two dates.
|
||||
*/
|
||||
const dateDiff = (d1, d2) => {
|
||||
const date1 = new Date(d1);
|
||||
const date2 = new Date(d2);
|
||||
const diff = date1.getTime() - date2.getTime();
|
||||
return Math.round(diff / (1000 * 60));
|
||||
};
|
||||
|
||||
export {
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
lowercaseTrim,
|
||||
chunkArray,
|
||||
parseEmojis,
|
||||
dateDiff,
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
import toEmoji from "emoji-name-map";
|
||||
import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js";
|
||||
import { getCardColors } from "./color.js";
|
||||
|
||||
@@ -74,56 +73,6 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
|
||||
return flexLayout({ items: [iconSvg, text], gap: 20 }).join("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns boolean if value is either "true" or "false" else the value as it is.
|
||||
*
|
||||
* @param {string | boolean} value The value to parse.
|
||||
* @returns {boolean | undefined } The parsed value.
|
||||
*/
|
||||
const parseBoolean = (value) => {
|
||||
if (typeof value === "boolean") {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
if (value.toLowerCase() === "true") {
|
||||
return true;
|
||||
} else if (value.toLowerCase() === "false") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse string to array of strings.
|
||||
*
|
||||
* @param {string} str The string to parse.
|
||||
* @returns {string[]} The array of strings.
|
||||
*/
|
||||
const parseArray = (str) => {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
return str.split(",");
|
||||
};
|
||||
|
||||
/**
|
||||
* Clamp the given number between the given range.
|
||||
*
|
||||
* @param {number} number The number to clamp.
|
||||
* @param {number} min The minimum value.
|
||||
* @param {number} max The maximum value.
|
||||
* @returns {number} The clamped number.
|
||||
*/
|
||||
const clampValue = (number, min, max) => {
|
||||
// @ts-ignore
|
||||
if (Number.isNaN(parseInt(number, 10))) {
|
||||
return min;
|
||||
}
|
||||
return Math.max(min, Math.min(number, max));
|
||||
};
|
||||
|
||||
// Script parameters.
|
||||
const ERROR_CARD_LENGTH = 576.5;
|
||||
|
||||
@@ -253,80 +202,12 @@ const measureText = (str, fontSize = 10) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Lowercase and trim string.
|
||||
*
|
||||
* @param {string} name String to lowercase and trim.
|
||||
* @returns {string} Lowercased and trimmed string.
|
||||
*/
|
||||
const lowercaseTrim = (name) => name.toLowerCase().trim();
|
||||
|
||||
/**
|
||||
* Split array of languages in two columns.
|
||||
*
|
||||
* @template T Language object.
|
||||
* @param {Array<T>} arr Array of languages.
|
||||
* @param {number} perChunk Number of languages per column.
|
||||
* @returns {Array<T>} Array of languages split in two columns.
|
||||
*/
|
||||
const chunkArray = (arr, perChunk) => {
|
||||
return arr.reduce((resultArray, item, index) => {
|
||||
const chunkIndex = Math.floor(index / perChunk);
|
||||
|
||||
if (!resultArray[chunkIndex]) {
|
||||
// @ts-ignore
|
||||
resultArray[chunkIndex] = []; // start a new chunk
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
resultArray[chunkIndex].push(item);
|
||||
|
||||
return resultArray;
|
||||
}, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse emoji from string.
|
||||
*
|
||||
* @param {string} str String to parse emoji from.
|
||||
* @returns {string} String with emoji parsed.
|
||||
*/
|
||||
const parseEmojis = (str) => {
|
||||
if (!str) {
|
||||
throw new Error("[parseEmoji]: str argument not provided");
|
||||
}
|
||||
return str.replace(/:\w+:/gm, (emoji) => {
|
||||
return toEmoji.get(emoji) || "";
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get diff in minutes between two dates.
|
||||
*
|
||||
* @param {Date} d1 First date.
|
||||
* @param {Date} d2 Second date.
|
||||
* @returns {number} Number of minutes between the two dates.
|
||||
*/
|
||||
const dateDiff = (d1, d2) => {
|
||||
const date1 = new Date(d1);
|
||||
const date2 = new Date(d2);
|
||||
const diff = date1.getTime() - date2.getTime();
|
||||
return Math.round(diff / (1000 * 60));
|
||||
};
|
||||
|
||||
export {
|
||||
ERROR_CARD_LENGTH,
|
||||
renderError,
|
||||
createLanguageNode,
|
||||
iconWithLabel,
|
||||
encodeHTML,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
flexLayout,
|
||||
measureText,
|
||||
lowercaseTrim,
|
||||
chunkArray,
|
||||
parseEmojis,
|
||||
dateDiff,
|
||||
};
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import { encodeHTML, parseBoolean, renderError } from "../src/common/utils.js";
|
||||
import { encodeHTML, renderError } from "../src/common/utils.js";
|
||||
import { parseBoolean } from "../src/common/ops.js";
|
||||
|
||||
describe("Test utils.js", () => {
|
||||
it("should test parseBoolean", () => {
|
||||
|
||||
Reference in New Issue
Block a user