refactor: add eslint-plugin-import-x (#65)

- related to #29
This commit is contained in:
Marco Pasqualetti
2026-02-09 09:15:46 +01:00
committed by GitHub
parent 8bad081e79
commit 3fb7b37d75
103 changed files with 394 additions and 190 deletions
+8 -4
View File
@@ -97,15 +97,19 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Dependencies
uses: ./.github/actions/install-dependencies
# needed to resolve .vercel folder from apps/frontend/src/components/Card/SVG.js
# Heads up!
#
# 1. Execution of this script is needed to resolve `.vercel` folder from `apps/frontend/src/components/Card/SVG.js`
# 2. This scripts removes `apps/backend/node_modules` breaking ESLints module resolution.
# Dependency installation must occur after running ./vercel-preparation.sh.
- name: Run vercel-preparation.sh
run: |
chmod +x ./vercel-preparation.sh
./vercel-preparation.sh
- name: Install Dependencies
uses: ./.github/actions/install-dependencies
- name: Format
run: pnpm run format:check
+2 -1
View File
@@ -3,7 +3,8 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.tabSize": 2
"editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"cSpell.words": ["Wakatime"]
}
@@ -1,16 +1,17 @@
import { default as api } from "./api-renamed/index.js";
/* eslint-disable import-x/no-unresolved */
import { default as authenticate } from "./api-renamed/authenticate.js";
import { default as deleteUser } from "./api-renamed/delete-user.js";
import { default as downgrade } from "./api-renamed/downgrade.js";
import { default as gist } from "./api-renamed/gist.js";
import { default as api } from "./api-renamed/index.js";
import { default as pin } from "./api-renamed/pin.js";
import { default as topLangs } from "./api-renamed/top-langs.js";
import { default as wakatime } from "./api-renamed/wakatime.js";
import { default as wakatimeProxy } from "./api-renamed/wakatime-proxy.js";
import { default as repeatRecent } from "./api-renamed/repeat-recent.js";
import { default as patInfo } from "./api-renamed/status/pat-info.js";
import { default as statusUp } from "./api-renamed/status/up.js";
import { default as authenticate } from "./api-renamed/authenticate.js";
import { default as deleteUser } from "./api-renamed/delete-user.js";
import { default as topLangs } from "./api-renamed/top-langs.js";
import { default as userAccess } from "./api-renamed/user-access.js";
import { default as downgrade } from "./api-renamed/downgrade.js";
import { default as wakatimeProxy } from "./api-renamed/wakatime-proxy.js";
import { default as wakatime } from "./api-renamed/wakatime.js";
export default async (req, res) => {
// remaining code expects express.js-like request and response objects
+1 -1
View File
@@ -1,5 +1,5 @@
import { logger } from "../src/common/log.js";
import { deleteUser } from "../src/common/database.js";
import { logger } from "../src/common/log.js";
/**
* @param {any} req The request.
+2 -1
View File
@@ -1,5 +1,6 @@
import { getUserAccessByKey, deleteUser } from "../src/common/database.js";
import axios from "axios";
import { deleteUser, getUserAccessByKey } from "../src/common/database.js";
import { logger } from "../src/common/log.js";
export default async (req, res) => {
+5 -5
View File
@@ -1,22 +1,22 @@
// @ts-check
import { renderError } from "../src/common/render.js";
import { isLocaleAvailable } from "../src/translations.js";
import { renderGistCard } from "../src/cards/gist.js";
import { fetchGist } from "../src/fetchers/gist.js";
import { storeRequest } from "../src/common/database.js";
import { guardAccess } from "../src/common/access.js";
import {
CACHE_TTL,
resolveCacheSeconds,
setCacheHeaders,
setErrorCacheHeaders,
} from "../src/common/cache.js";
import { guardAccess } from "../src/common/access.js";
import { storeRequest } from "../src/common/database.js";
import {
MissingParamError,
retrieveSecondaryMessage,
} from "../src/common/error.js";
import { parseBoolean } from "../src/common/ops.js";
import { renderError } from "../src/common/render.js";
import { fetchGist } from "../src/fetchers/gist.js";
import { isLocaleAvailable } from "../src/translations.js";
// @ts-ignore
export default async (req, res) => {
+1 -1
View File
@@ -8,6 +8,7 @@ import {
setCacheHeaders,
setErrorCacheHeaders,
} from "../src/common/cache.js";
import { storeRequest } from "../src/common/database.js";
import {
MissingParamError,
retrieveSecondaryMessage,
@@ -16,7 +17,6 @@ import { parseArray, parseBoolean } from "../src/common/ops.js";
import { renderError } from "../src/common/render.js";
import { fetchStats } from "../src/fetchers/stats.js";
import { isLocaleAvailable } from "../src/translations.js";
import { storeRequest } from "../src/common/database.js";
// @ts-ignore
export default async (req, res) => {
+2 -3
View File
@@ -8,16 +8,15 @@ import {
setCacheHeaders,
setErrorCacheHeaders,
} from "../src/common/cache.js";
import { storeRequest } from "../src/common/database.js";
import {
MissingParamError,
retrieveSecondaryMessage,
} from "../src/common/error.js";
import { parseBoolean } from "../src/common/ops.js";
import { parseArray } from "../src/common/ops.js";
import { parseArray, parseBoolean } from "../src/common/ops.js";
import { renderError } from "../src/common/render.js";
import { fetchRepo } from "../src/fetchers/repo.js";
import { isLocaleAvailable } from "../src/translations.js";
import { storeRequest } from "../src/common/database.js";
// @ts-ignore
export default async (req, res) => {
+1 -1
View File
@@ -8,8 +8,8 @@
*/
import { request } from "../../src/common/http.js";
import retryer from "../../src/common/retryer.js";
import { logger } from "../../src/common/log.js";
import { default as retryer } from "../../src/common/retryer.js";
export const RATE_LIMIT_SECONDS = 60 * 3; // 1 request per 3 minutes
+1 -1
View File
@@ -8,6 +8,7 @@ import {
setCacheHeaders,
setErrorCacheHeaders,
} from "../src/common/cache.js";
import { storeRequest } from "../src/common/database.js";
import {
MissingParamError,
retrieveSecondaryMessage,
@@ -16,7 +17,6 @@ import { parseArray, parseBoolean } from "../src/common/ops.js";
import { renderError } from "../src/common/render.js";
import { fetchTopLanguages } from "../src/fetchers/top-languages.js";
import { isLocaleAvailable } from "../src/translations.js";
import { storeRequest } from "../src/common/database.js";
// @ts-ignore
export default async (req, res) => {
+1 -1
View File
@@ -1,5 +1,5 @@
import { logger } from "../src/common/log.js";
import { getUserAccessByKey } from "../src/common/database.js";
import { logger } from "../src/common/log.js";
/**
* @param {any} req The request.
+1 -1
View File
@@ -1,5 +1,5 @@
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
import { logger } from "../src/common/log.js";
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
/**
* @param {any} req The request.
+5 -5
View File
@@ -1,22 +1,22 @@
// @ts-check
import { renderWakatimeCard } from "../src/cards/wakatime.js";
import { renderError } from "../src/common/render.js";
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
import { isLocaleAvailable } from "../src/translations.js";
import { storeRequest } from "../src/common/database.js";
import { guardAccess } from "../src/common/access.js";
import {
CACHE_TTL,
resolveCacheSeconds,
setCacheHeaders,
setErrorCacheHeaders,
} from "../src/common/cache.js";
import { guardAccess } from "../src/common/access.js";
import { storeRequest } from "../src/common/database.js";
import {
MissingParamError,
retrieveSecondaryMessage,
} from "../src/common/error.js";
import { parseArray, parseBoolean } from "../src/common/ops.js";
import { renderError } from "../src/common/render.js";
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
import { isLocaleAvailable } from "../src/translations.js";
// @ts-ignore
export default async (req, res) => {
+3 -2
View File
@@ -1,10 +1,11 @@
import "dotenv/config";
import express from "express";
import gistCard from "./api-renamed/gist.js";
import statsCard from "./api-renamed/index.js";
import repoCard from "./api-renamed/pin.js";
import langCard from "./api-renamed/top-langs.js";
import wakatimeCard from "./api-renamed/wakatime.js";
import gistCard from "./api-renamed/gist.js";
import express from "express";
const app = express();
const router = express.Router();
@@ -1,14 +1,16 @@
/**
* @file Script that can be used to close stale theme PRs that have a `invalid` label.
*/
import * as dotenv from "dotenv";
dotenv.config();
import { debug, setFailed } from "@actions/core";
import github from "@actions/github";
import * as github from "@actions/github";
// eslint-disable-next-line import-x/no-unresolved
import { RequestError } from "@octokit/request-error";
import * as dotenv from "dotenv";
import { getGithubToken, getRepoInfo } from "./helpers.js";
dotenv.config();
const CLOSING_COMMENT = `
\rThis theme PR has been automatically closed due to inactivity. Please reopen it if you want to continue working on it.\
\rThank you for your contributions.
+3 -2
View File
@@ -1,6 +1,7 @@
import axios from "axios";
import fs from "fs";
import jsYaml from "js-yaml";
import axios from "axios";
import { default as jsYaml } from "js-yaml";
const LANGS_FILEPATH = "./src/common/languageColors.json";
@@ -1,4 +1,5 @@
import fs from "fs";
import { themes } from "../themes/index.js";
const TARGET_FILE = "./themes/README.md";
+9 -6
View File
@@ -1,21 +1,24 @@
/**
* @file This script is used to preview the theme on theme PRs.
*/
import * as dotenv from "dotenv";
dotenv.config();
import { info } from "console";
import { inspect } from "util";
import { debug, setFailed } from "@actions/core";
import github from "@actions/github";
import { default as github } from "@actions/github";
import ColorContrastChecker from "color-contrast-checker";
import { info } from "console";
import * as dotenv from "dotenv";
import Hjson from "hjson";
import snakeCase from "lodash.snakecase";
import parse from "parse-diff";
import { inspect } from "util";
import { isValidHexColor, isValidGradient } from "../src/common/color.js";
import { isValidGradient, isValidHexColor } from "../src/common/color.js";
import { themes } from "../themes/index.js";
import { getGithubToken, getRepoInfo } from "./helpers.js";
dotenv.config();
const COMMENTER = "github-actions[bot]";
const COMMENT_TITLE = "Automated Theme Preview";
+7 -7
View File
@@ -1,18 +1,18 @@
// @ts-check
import {
measureText,
flexLayout,
iconWithLabel,
createLanguageNode,
} from "../common/render.js";
import Card from "../common/Card.js";
import { default as Card } from "../common/Card.js";
import { getCardColors } from "../common/color.js";
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
import { encodeHTML } from "../common/html.js";
import { icons } from "../common/icons.js";
import languageColors from "../common/languageColors.json" with { type: "json" };
import { parseEmojis } from "../common/ops.js";
import {
createLanguageNode,
flexLayout,
iconWithLabel,
measureText,
} from "../common/render.js";
const ICON_SIZE = 16;
const CARD_DEFAULT_WIDTH = 400;
+6 -6
View File
@@ -1,20 +1,20 @@
// @ts-check
import { Card } from "../common/Card.js";
import { I18n } from "../common/I18n.js";
import { getCardColors } from "../common/color.js";
import { kFormatter, wrapTextMultiline } from "../common/fmt.js";
import { encodeHTML } from "../common/html.js";
import { I18n } from "../common/I18n.js";
import { icons } from "../common/icons.js";
import { clampValue, parseEmojis } from "../common/ops.js";
import { buildSearchFilter } from "../common/ops.js";
import { buildSearchFilter, clampValue, parseEmojis } from "../common/ops.js";
import {
flexLayout,
measureText,
iconWithLabel,
createLanguageNode,
flexLayout,
iconWithLabel,
measureText,
} from "../common/render.js";
import { repoCardLocales } from "../translations.js";
import { createTextNode } from "./stats.js";
const ICON_SIZE = 16;
+2 -3
View File
@@ -1,13 +1,12 @@
// @ts-check
import { Card } from "../common/Card.js";
import { I18n } from "../common/I18n.js";
import { getCardColors } from "../common/color.js";
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 } from "../common/ops.js";
import { buildSearchFilter } from "../common/ops.js";
import { buildSearchFilter, clampValue } from "../common/ops.js";
import { flexLayout, measureText } from "../common/render.js";
import { statCardLocales, wakatimeCardLocales } from "../translations.js";
+1 -1
View File
@@ -1,9 +1,9 @@
// @ts-check
import { Card } from "../common/Card.js";
import { I18n } from "../common/I18n.js";
import { getCardColors } from "../common/color.js";
import { formatBytes } from "../common/fmt.js";
import { I18n } from "../common/I18n.js";
import { chunkArray, clampValue, lowercaseTrim } from "../common/ops.js";
import {
createProgressNode,
+2 -2
View File
@@ -1,12 +1,12 @@
// @ts-check
import { Card } from "../common/Card.js";
import { getCardColors } from "../common/color.js";
import { I18n } from "../common/I18n.js";
import { getCardColors } from "../common/color.js";
import languageColors from "../common/languageColors.json" with { type: "json" };
import { clampValue, lowercaseTrim } from "../common/ops.js";
import { createProgressNode, flexLayout } from "../common/render.js";
import { wakatimeCardLocales } from "../translations.js";
import languageColors from "../common/languageColors.json" with { type: "json" };
const DEFAULT_CARD_WIDTH = 495;
const MIN_CARD_WIDTH = 250;
+2 -2
View File
@@ -1,8 +1,8 @@
// @ts-check
import { renderError } from "./render.js";
import { blacklist } from "./blacklist.js";
import { whitelist, gistWhitelist } from "./envs.js";
import { gistWhitelist, whitelist } from "./envs.js";
import { renderError } from "./render.js";
const NOT_WHITELISTED_USERNAME_MESSAGE = "This username is not whitelisted";
const NOT_WHITELISTED_GIST_MESSAGE = "This gist ID is not whitelisted";
+1
View File
@@ -1,4 +1,5 @@
import pkg from "pg";
// eslint-disable-next-line import-x/no-named-as-default-member
const { Pool } = pkg;
export const pool = process.env.POSTGRES_URL
+1
View File
@@ -1,6 +1,7 @@
// @ts-check
import wrap from "word-wrap";
import { encodeHTML } from "./html.js";
/**
+1
View File
@@ -1,6 +1,7 @@
// @ts-check
import toEmoji from "emoji-name-map";
import { CustomError } from "./error.js";
const OWNER_AFFILIATIONS = ["OWNER", "COLLABORATOR", "ORGANIZATION_MEMBER"];
+1 -1
View File
@@ -1,7 +1,7 @@
// @ts-check
import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js";
import { getCardColors } from "./color.js";
import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js";
import { encodeHTML } from "./html.js";
import { clampValue } from "./ops.js";
+1 -1
View File
@@ -1,8 +1,8 @@
// @ts-check
import { getUserAccessByName } from "./database.js";
import { CustomError } from "./error.js";
import { logger } from "./log.js";
import { getUserAccessByName } from "./database.js";
/**
* Returns a random integer from 0 (inclusive) to `max` (exclusive).
+1 -1
View File
@@ -1,8 +1,8 @@
// @ts-check
import { retryer } from "../common/retryer.js";
import { MissingParamError } from "../common/error.js";
import { request } from "../common/http.js";
import { retryer } from "../common/retryer.js";
const QUERY = `
query gistInfo($gistName: String!) {
+1
View File
@@ -3,6 +3,7 @@
import { MissingParamError } from "../common/error.js";
import { request } from "../common/http.js";
import { retryer } from "../common/retryer.js";
import { fetchRepoUserStats } from "./stats.js";
/**
+4 -3
View File
@@ -3,14 +3,15 @@
import axios from "axios";
import * as dotenv from "dotenv";
import githubUsernameRegex from "github-username-regex";
import { calculateRank } from "../calculateRank.js";
import { retryer } from "../common/retryer.js";
import { buildSearchFilter, parseOwnerAffiliations } from "../common/ops.js";
import { logger } from "../common/log.js";
import { excludeRepositories } from "../common/envs.js";
import { CustomError, MissingParamError } from "../common/error.js";
import { wrapTextMultiline } from "../common/fmt.js";
import { request } from "../common/http.js";
import { logger } from "../common/log.js";
import { buildSearchFilter, parseOwnerAffiliations } from "../common/ops.js";
import { retryer } from "../common/retryer.js";
dotenv.config();
+3 -3
View File
@@ -1,12 +1,12 @@
// @ts-check
import { retryer } from "../common/retryer.js";
import { parseOwnerAffiliations } from "../common/ops.js";
import { logger } from "../common/log.js";
import { excludeRepositories } from "../common/envs.js";
import { CustomError, MissingParamError } from "../common/error.js";
import { wrapTextMultiline } from "../common/fmt.js";
import { request } from "../common/http.js";
import { logger } from "../common/log.js";
import { parseOwnerAffiliations } from "../common/ops.js";
import { retryer } from "../common/retryer.js";
/**
* Top languages fetcher object.
+1
View File
@@ -1,6 +1,7 @@
// @ts-check
import axios from "axios";
import { CustomError, MissingParamError } from "../common/error.js";
/**
+2 -1
View File
@@ -1,8 +1,9 @@
import axios from "axios";
import {
pool,
deleteOldRequests,
getRecentRequests,
pool,
} from "./common/database.js";
/**
+1
View File
@@ -1,4 +1,5 @@
import axios from "axios";
import { storeUser } from "./common/database.js";
/**
+2 -1
View File
@@ -10,11 +10,12 @@ import {
} from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import api from "../api-renamed/index.js";
import { calculateRank } from "../src/calculateRank.js";
import { renderStatsCard } from "../src/cards/stats.js";
import { renderError } from "../src/common/render.js";
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
import { renderError } from "../src/common/render.js";
/**
* @type {import("../src/fetchers/stats").StatsData}
+4 -2
View File
@@ -1,7 +1,9 @@
import api from "../../api-renamed/index.js";
import { it, jest } from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { it, jest } from "@jest/globals";
import api from "../../api-renamed/index.js";
import { runAndLogStats } from "./utils.js";
const stats = {
@@ -1,5 +1,7 @@
import { calculateRank } from "../../src/calculateRank.js";
import { it } from "@jest/globals";
import { calculateRank } from "../../src/calculateRank.js";
import { runAndLogStats } from "./utils.js";
it("calculateRank", async () => {
+4 -2
View File
@@ -1,7 +1,9 @@
import gist from "../../api-renamed/gist.js";
import { it, jest } from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { it, jest } from "@jest/globals";
import gist from "../../api-renamed/gist.js";
import { runAndLogStats } from "./utils.js";
const gist_data = {
+4 -2
View File
@@ -1,7 +1,9 @@
import pin from "../../api-renamed/pin.js";
import { it, jest } from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { it, jest } from "@jest/globals";
import pin from "../../api-renamed/pin.js";
import { runAndLogStats } from "./utils.js";
const data_repo = {
+2
View File
@@ -1,6 +1,8 @@
import { describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import { calculateRank } from "../src/calculateRank.js";
import { approxNumber } from "./bench/utils.js";
describe("Test calculateRank", () => {
+2 -1
View File
@@ -2,9 +2,10 @@ import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom";
import { cssToObject } from "@uppercod/css-to-object";
import { Card } from "../src/common/Card.js";
import { icons } from "../src/common/icons.js";
import { getCardColors } from "../src/common/color.js";
import { icons } from "../src/common/icons.js";
describe("Card", () => {
it("should hide border", () => {
+2 -1
View File
@@ -1,6 +1,7 @@
import { getCardColors } from "../src/common/color";
import { describe, expect, it } from "@jest/globals";
import { getCardColors } from "../src/common/color";
describe("Test color.js", () => {
it("getCardColors: should return expected values", () => {
let colors = getCardColors({
+4 -2
View File
@@ -1,17 +1,19 @@
/**
* @file Contains end-to-end tests for the Vercel preview instance.
*/
import dotenv from "dotenv";
dotenv.config();
import { beforeAll, describe, expect, test } from "@jest/globals";
import axios from "axios";
import * as dotenv from "dotenv";
import { renderGistCard } from "../../src/cards/gist.js";
import { renderRepoCard } from "../../src/cards/repo.js";
import { renderStatsCard } from "../../src/cards/stats.js";
import { renderTopLanguages } from "../../src/cards/top-languages.js";
import { renderWakatimeCard } from "../../src/cards/wakatime.js";
dotenv.config();
const REPO = "curly-fiesta";
const USER = "catelinemnemosyne";
const STATS_CARD_USER = "e2eninja";
+1
View File
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { fetchGist } from "../src/fetchers/gist.js";
const gist_data = {
+1
View File
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { fetchRepo } from "../src/fetchers/repo.js";
const data_repo = {
+1
View File
@@ -9,6 +9,7 @@ import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { calculateRank } from "../src/calculateRank.js";
import { fetchStats } from "../src/fetchers/stats.js";
@@ -2,7 +2,9 @@ import { afterEach, describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { fetchTopLanguages } from "../src/fetchers/top-languages.js";
import { approxNumber } from "./bench/utils.js";
const mock = new MockAdapter(axios);
+1
View File
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
const mock = new MockAdapter(axios);
+1
View File
@@ -1,4 +1,5 @@
import { describe, expect, it } from "@jest/globals";
import { flexLayout } from "../src/common/render.js";
describe("flexLayout", () => {
+1
View File
@@ -1,4 +1,5 @@
import { describe, expect, it } from "@jest/globals";
import {
formatBytes,
kFormatter,
+2 -1
View File
@@ -4,10 +4,11 @@ import { afterEach, describe, expect, it, jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import gist from "../api-renamed/gist.js";
import { renderGistCard } from "../src/cards/gist.js";
import { renderError } from "../src/common/render.js";
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
import { renderError } from "../src/common/render.js";
const gist_data = {
data: {
+1
View File
@@ -1,4 +1,5 @@
import { describe, expect, it } from "@jest/globals";
import { encodeHTML } from "../src/common/html.js";
describe("Test html.js", () => {
+1
View File
@@ -1,4 +1,5 @@
import { describe, expect, it } from "@jest/globals";
import { I18n } from "../src/common/I18n.js";
import { statCardLocales } from "../src/translations.js";
+6 -5
View File
@@ -1,12 +1,13 @@
import { describe, expect, it } from "@jest/globals";
import {
parseBoolean,
parseArray,
clampValue,
lowercaseTrim,
chunkArray,
parseEmojis,
clampValue,
dateDiff,
lowercaseTrim,
parseArray,
parseBoolean,
parseEmojis,
} from "../src/common/ops.js";
describe("Test ops.js", () => {
+4 -3
View File
@@ -2,9 +2,6 @@
* @file Tests for the status/pat-info cloud function.
*/
import dotenv from "dotenv";
dotenv.config();
import {
afterEach,
beforeAll,
@@ -15,8 +12,12 @@ import {
} from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { dotenv } from "dotenv";
import patInfo, { RATE_LIMIT_SECONDS } from "../api-renamed/status/pat-info.js";
dotenv.config();
const mock = new MockAdapter(axios);
const successData = {
+2 -1
View File
@@ -4,10 +4,11 @@ import { afterEach, describe, expect, it, jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import pin from "../api-renamed/pin.js";
import { renderRepoCard } from "../src/cards/repo.js";
import { renderError } from "../src/common/render.js";
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
import { renderError } from "../src/common/render.js";
const data_repo = {
repository: {
+1
View File
@@ -2,6 +2,7 @@
import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom/jest-globals";
import { renderError } from "../src/common/render.js";
@@ -2,6 +2,7 @@ import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom";
import { cssToObject } from "@uppercod/css-to-object";
import { renderGistCard } from "../src/cards/gist.js";
import { themes } from "../themes/index.js";
@@ -2,6 +2,7 @@ import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom";
import { cssToObject } from "@uppercod/css-to-object";
import { renderRepoCard } from "../src/cards/repo.js";
import { themes } from "../themes/index.js";
@@ -6,6 +6,7 @@ import {
} from "@testing-library/dom";
import "@testing-library/jest-dom";
import { cssToObject } from "@uppercod/css-to-object";
import { renderStatsCard } from "../src/cards/stats.js";
import { CustomError } from "../src/common/error.js";
import { themes } from "../themes/index.js";
@@ -2,6 +2,7 @@ import { describe, expect, it } from "@jest/globals";
import { queryAllByTestId, queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom";
import { cssToObject } from "@uppercod/css-to-object";
import {
MIN_CARD_WIDTH,
calculateCompactLayoutHeight,
@@ -20,8 +21,8 @@ import {
renderTopLanguages,
trimTopLanguages,
} from "../src/cards/top-languages.js";
import { themes } from "../themes/index.js";
import { approxNumber } from "./bench/utils.js";
const langs = {
@@ -1,9 +1,12 @@
import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom";
import { renderWakatimeCard } from "../src/cards/wakatime.js";
import { wakaTimeData } from "./fetchWakatime.test.js";
import "@testing-library/jest-dom";
describe("Test Render WakaTime Card", () => {
it("should render correctly", () => {
const card = renderWakatimeCard(wakaTimeData.data);
+2 -1
View File
@@ -1,9 +1,10 @@
// @ts-check
import { describe, expect, it, jest } from "@jest/globals";
import "@testing-library/jest-dom";
import { retryer } from "../src/common/retryer.js";
import { logger } from "../src/common/log.js";
import { retryer } from "../src/common/retryer.js";
const fetcher = jest.fn((variables, token) => {
logger.log(variables, token);
+1 -1
View File
@@ -1,6 +1,6 @@
//https://stackoverflow.com/a/68468204/1643179
import { TextEncoder, TextDecoder } from "util";
import { TextDecoder, TextEncoder } from "util";
Object.assign(global, { TextDecoder, TextEncoder });
process.env.PAT_1 = "dummyPAT1";
+1
View File
@@ -5,6 +5,7 @@
import { afterEach, describe, expect, it, jest } from "@jest/globals";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import up, { RATE_LIMIT_SECONDS } from "../api-renamed/status/up.js";
const mock = new MockAdapter(axios);
+2 -1
View File
@@ -4,10 +4,11 @@ import { afterEach, describe, expect, it, jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import topLangs from "../api-renamed/top-langs.js";
import { renderTopLanguages } from "../src/cards/top-languages.js";
import { renderError } from "../src/common/render.js";
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
import { renderError } from "../src/common/render.js";
const data_langs = {
data: {
+1
View File
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, jest } from "@jest/globals";
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import wakatime from "../api-renamed/wakatime.js";
import { renderWakatimeCard } from "../src/cards/wakatime.js";
import { CACHE_TTL, DURATIONS } from "../src/common/cache.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { test, expect } from "@playwright/test";
import { expect, test } from "@playwright/test";
test("load initial page correctly", async ({ page }) => {
await page.goto("");
+1 -1
View File
@@ -39,6 +39,6 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
+1 -1
View File
@@ -1,7 +1,7 @@
import axios, { getAdapter } from "axios";
import { setupCache } from "axios-cache-interceptor";
import { HOST } from "./constants";
import { HOST } from "./constants";
import additionalUserStars from "./mockData/additional_user_stars.json" with { type: "json" };
import commentedIssues from "./mockData/commented_issues.json" with { type: "json" };
import commentedPrs from "./mockData/commented_prs.json" with { type: "json" };
+1 -1
View File
@@ -1,5 +1,5 @@
import { clsx } from "clsx";
import type { JSX } from "react";
import clsx from "clsx";
import { CardImage } from "./CardImage";
@@ -1,4 +1,4 @@
import clsx from "clsx";
import { clsx } from "clsx";
import { HOST } from "../../constants";
@@ -1,13 +1,13 @@
import axios from "axios";
import { useEffect, useRef, useState } from "react";
import type { JSX } from "react";
import axios from "axios";
import Skeleton from "react-loading-skeleton";
import "react-loading-skeleton/dist/skeleton.css";
import { createMockRequest, createMockResponse } from "../../mock-http.js";
import { setShouldMock } from "../../axios-override.js";
// @ts-expect-error will be solved by npm package
import { default as router } from "../../backend/.vercel/output/functions/api.func/router.js";
import { setShouldMock } from "../../axios-override.js";
import { createMockRequest, createMockResponse } from "../../mock-http.js";
import {
useIsAuthenticated,
useUserToken,
@@ -1,4 +1,4 @@
import clsx from "clsx";
import { clsx } from "clsx";
import type { HTMLProps, JSX, ReactNode } from "react";
interface ButtonProps extends HTMLProps<HTMLButtonElement> {
@@ -1,4 +1,4 @@
import clsx from "clsx";
import { clsx } from "clsx";
import type { JSX } from "react";
export interface SelectOption {
@@ -1,7 +1,9 @@
import { Section } from "./Section";
import { Checkbox } from "../Generic/Checkbox";
import type { JSX } from "react";
import { Checkbox } from "../Generic/Checkbox";
import { Section } from "./Section";
interface CheckboxSectionProps {
title: string;
question: string;
@@ -1,9 +1,10 @@
import type { JSX } from "react";
import { Section } from "./Section";
import { Select } from "../Generic/Select";
import type { SelectOption } from "../Generic/Select";
import { Section } from "./Section";
export const DEFAULT_OPTION: SelectOption = {
id: 1,
label: "Normal",
@@ -1,6 +1,5 @@
import clsx from "clsx";
import { clsx } from "clsx";
import type { JSX, MouseEventHandler } from "react";
import {
FaArrowLeft as LeftArrowIcon,
FaArrowRight as RightArrowIcon,
@@ -1,5 +1,4 @@
import type { JSX, ReactNode } from "react";
import { HiOutlineLightningBolt as LightningIcon } from "react-icons/hi";
interface SectionProps {
@@ -1,6 +1,6 @@
import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react";
import type { ClipboardEventHandler, JSX, ReactNode } from "react";
import clsx from "clsx";
import { Section } from "./Section";
@@ -1,9 +1,10 @@
import type { JSX } from "react";
import { Section } from "./Section";
import { Select } from "../Generic/Select";
import type { SelectOption } from "../Generic/Select";
import { Section } from "./Section";
export const DEFAULT_OPTION: SelectOption = {
id: 1,
label: "Normal",
@@ -1,13 +1,14 @@
import "./axios-override";
import ReactDOM from "react-dom/client";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import { AppTrends } from "./pages/App/AppTrends";
import { store } from "./redux/store";
import "./index.css";
const root = ReactDOM.createRoot(document.getElementById("root"));
const root = createRoot(document.getElementById("root") as HTMLElement);
root.render(
<Provider store={store}>
+10 -9
View File
@@ -1,24 +1,25 @@
import { useEffect, useRef, useState } from "react";
import { useDispatch } from "react-redux";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { ToastContainer, toast } from "react-toastify";
import {
logout as _logout,
setUserAccess as _setUserAccess,
} from "../../redux/slices/user";
import { clearAxiosCache } from "../../axios-override";
import { HomeScreen } from "../Home/Home";
import { getUserMetadata } from "../../api/user";
import { clearAxiosCache } from "../../axios-override";
import type { StageIndex } from "../../models/Stage";
import {
useIsAuthenticated,
useUserKey,
useUserToken,
} from "../../redux/selectors/userSelectors";
import type { StageIndex } from "../../models/Stage";
import {
logout as _logout,
setUserAccess as _setUserAccess,
} from "../../redux/slices/user";
import { HomeScreen } from "../Home/Home";
import { Header } from "./Header";
import "react-toastify/dist/ReactToastify.css";
const toMessage = (
input: string | ErrorEvent | PromiseRejectionEvent,
): string => {
+1 -1
View File
@@ -1,7 +1,7 @@
import type { JSX } from "react";
import { FaGithub as GithubIcon } from "react-icons/fa";
import appIcon from "../../assets/appLogo64.png";
import { FaGithub as GithubIcon } from "react-icons/fa";
import { ProgressBar } from "../../components/Home/Progress";
import { STAGE_LABELS } from "../../models/Stage";
import type { StageIndex } from "../../models/Stage";
+15 -15
View File
@@ -1,30 +1,30 @@
import axios from "axios";
import { useEffect, useMemo, useRef, useState } from "react";
import type { JSX } from "react";
import { useDispatch } from "react-redux";
import BounceLoader from "react-spinners/BounceLoader";
import axios from "axios";
import { v4 as uuidv4 } from "uuid";
import { authenticate } from "../../api/user";
import { login } from "../../redux/slices/user";
import {
HOST,
DEMO_USER,
DEMO_WAKATIME_USER,
DEMO_REPO,
DEMO_GIST,
} from "../../constants";
import { CardType } from "../../models/CardType";
import { DEFAULT_OPTION as STATS_DEFAULT_RANK } from "../../components/Home/StatsRankSection";
import { DEFAULT_OPTION as LANGUAGES_DEFAULT_LAYOUT } from "../../components/Home/LanguagesLayoutSection";
import { DEFAULT_OPTION as STATS_DEFAULT_RANK } from "../../components/Home/StatsRankSection";
import { DEFAULT_OPTION as WAKATIME_DEFAULT_LAYOUT } from "../../components/Home/WakatimeLayoutSection";
import {
useUserId,
useIsAuthenticated,
usePrivateAccess,
} from "../../redux/selectors/userSelectors";
DEMO_GIST,
DEMO_REPO,
DEMO_USER,
DEMO_WAKATIME_USER,
HOST,
} from "../../constants";
import { CardType } from "../../models/CardType";
import { STAGE_LABELS } from "../../models/Stage";
import type { StageIndex } from "../../models/Stage";
import {
useIsAuthenticated,
usePrivateAccess,
useUserId,
} from "../../redux/selectors/userSelectors";
import { login } from "../../redux/slices/user";
import { CustomizeStage } from "./stages/Customize";
import { DisplayStage } from "./stages/Display";
@@ -1,13 +1,12 @@
import type React from "react";
import type { JSX } from "react";
import type { JSX, default as React } from "react";
import { CardType } from "../../../models/CardType";
import { CardImage } from "../../../components/Card/CardImage";
import type { SelectOption } from "../../../components/Generic/Select";
import { CheckboxSection } from "../../../components/Home/CheckboxSection";
import { TextSection } from "../../../components/Home/TextSection";
import { LanguagesLayoutSection } from "../../../components/Home/LanguagesLayoutSection";
import { NumericSection } from "../../../components/Home/NumericSection";
import { StatsRankSection } from "../../../components/Home/StatsRankSection";
import { LanguagesLayoutSection } from "../../../components/Home/LanguagesLayoutSection";
import { TextSection } from "../../../components/Home/TextSection";
import { WakatimeLayoutSection } from "../../../components/Home/WakatimeLayoutSection";
import {
DEMO_GIST,
@@ -15,9 +14,9 @@ import {
DEMO_USER,
DEMO_WAKATIME_USER,
} from "../../../constants";
import { useIsAuthenticated } from "../../../redux/selectors/userSelectors";
import type { SelectOption } from "../../../components/Generic/Select";
import { CardType } from "../../../models/CardType";
import type { StageIndex } from "../../../models/Stage";
import { useIsAuthenticated } from "../../../redux/selectors/userSelectors";
type Updater<T> = React.Dispatch<React.SetStateAction<T>>;
@@ -1,12 +1,13 @@
import { clsx } from "clsx";
import { saveSvgAsPng } from "save-svg-as-png";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { Button } from "../../../components/Generic/Button";
import { CardImage } from "../../../components/Card/CardImage";
import { HOST } from "../../../constants";
import type { JSX } from "react";
import { toast } from "react-toastify";
import { saveSvgAsPng } from "save-svg-as-png";
import { CardImage } from "../../../components/Card/CardImage";
import { Button } from "../../../components/Generic/Button";
import { HOST } from "../../../constants";
import "react-toastify/dist/ReactToastify.css";
interface DisplayStageProps {
filename: string;
@@ -2,8 +2,8 @@ import type { JSX } from "react";
import { useIsAuthenticated } from "../../../../redux/selectors/userSelectors";
import { LoginOptions } from "./LoginOptions";
import { LoginAccountManagement } from "./LoginAccountManagement";
import { LoginOptions } from "./LoginOptions";
interface LoginStageProps {
onContinueAsGuest: () => void;
@@ -1,4 +1,5 @@
import { useEffect, useRef, type JSX, type RefObject } from "react";
import { useEffect, useRef } from "react";
import type { JSX, RefObject } from "react";
import { createPortal } from "react-dom";
import { Button } from "../../../../components/Generic/Button";
@@ -1,22 +1,23 @@
import { useCallback, useState, type JSX } from "react";
import { useDispatch } from "react-redux";
import { useCallback, useState } from "react";
import type { JSX } from "react";
import { FaGithub as GithubIcon } from "react-icons/fa";
import { useDispatch } from "react-redux";
import { deleteAccount } from "../../../../api/user";
import { Button } from "../../../../components/Generic/Button";
import {
CLIENT_ID,
GITHUB_PRIVATE_AUTH_URL,
HOST,
} from "../../../../constants";
import {
usePrivateAccess,
useUserId,
useUserKey,
} from "../../../../redux/selectors/userSelectors";
import { deleteAccount } from "../../../../api/user";
import { Button } from "../../../../components/Generic/Button";
import {
CLIENT_ID,
HOST,
GITHUB_PRIVATE_AUTH_URL,
} from "../../../../constants";
import { LoginAccountDeleteModal } from "./LoginAccountDeleteModal";
import { logout } from "../../../../redux/slices/user";
import { LoginAccountDeleteModal } from "./LoginAccountDeleteModal";
import { LoginBox } from "./LoginBox";
export function LoginAccountManagement(): JSX.Element {
@@ -1,5 +1,5 @@
import { clsx } from "clsx";
import type { JSX, ReactNode } from "react";
import clsx from "clsx";
import { LoginBoxDemoCards } from "./LoginBoxDemoCards";
@@ -2,10 +2,10 @@ import type { JSX } from "react";
import { CardImage } from "../../../../components/Card/CardImage";
import {
DEMO_GIST,
DEMO_REPO,
DEMO_USER,
DEMO_WAKATIME_USER,
DEMO_GIST,
} from "../../../../constants";
const cards: Array<{ demoImageSrc: string }> = [
@@ -3,8 +3,8 @@ import { FaGithub as GithubIcon } from "react-icons/fa";
import { Button } from "../../../../components/Generic/Button";
import {
GITHUB_PUBLIC_AUTH_URL,
GITHUB_PRIVATE_AUTH_URL,
GITHUB_PUBLIC_AUTH_URL,
} from "../../../../constants";
import { LoginBox } from "./LoginBox";
@@ -1,5 +1,7 @@
import { useMemo } from "react";
import type { JSX } from "react";
import { Card } from "../../../components/Card/Card";
import { useUserId } from "../../../redux/selectors/userSelectors";
import {
DEMO_GIST,
DEMO_REPO,
@@ -7,7 +9,7 @@ import {
DEMO_WAKATIME_USER,
} from "../../../constants";
import { CardType } from "../../../models/CardType";
import { useMemo, type JSX } from "react";
import { useUserId } from "../../../redux/selectors/userSelectors";
interface SelectCardStageProps {
selectedCardType: CardType;
@@ -1,8 +1,8 @@
import type { JSX } from "react";
import { Card } from "../../../components/Card/Card";
// @ts-expect-error this will be provided by the npm package
import { themes } from "../../../backend/themes/index";
import { Card } from "../../../components/Card/Card";
// to be removed once npm package has been created
type ThemeData = Record<
+1
View File
@@ -1,4 +1,5 @@
import axios from "axios";
import { HOST } from "./constants";
// See https://github.com/stats-organization/github-stats-extended/pull/27#discussion_r2712184285
+1 -2
View File
@@ -1,9 +1,8 @@
import path from "node:path";
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";
import { nodePolyfills } from "vite-plugin-node-polyfills";
import react from "@vitejs/plugin-react-swc";
import StringReplace from "vite-plugin-string-replace";
// https://vitejs.dev/config/
+32 -5
View File
@@ -1,19 +1,46 @@
import { fileURLToPath } from "node:url";
import { defineConfig } from "eslint/config";
import globals from "globals";
import { includeIgnoreFile } from "@eslint/compat";
import js from "@eslint/js";
import jsdoc from "eslint-plugin-jsdoc";
import { defineConfig } from "eslint/config";
import { importX } from "eslint-plugin-import-x";
import { default as jsdoc } from "eslint-plugin-jsdoc";
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import { includeIgnoreFile } from "@eslint/compat";
import tseslint from "typescript-eslint";
import globals from "globals";
import { default as tseslint } from "typescript-eslint";
const gitignorePath = fileURLToPath(new URL(".gitignore", import.meta.url));
export default defineConfig(
includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"),
js.configs.recommended,
{
extends: [importX.flatConfigs.recommended, importX.flatConfigs.typescript],
rules: {
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
"import-x/order": [
"error",
{
groups: [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
],
alphabetize: {
order: "asc",
caseInsensitive: false,
},
named: { enabled: true, export: false },
"newlines-between": "always",
},
],
},
},
{
linterOptions: {
reportUnusedDisableDirectives: "error",

Some files were not shown because too many files have changed in this diff Show More