From 12f206eeca09b5fd9116efb505eba81d62779781 Mon Sep 17 00:00:00 2001 From: Miodec Date: Thu, 27 Nov 2025 00:05:41 +0100 Subject: [PATCH 1/2] fix: ts issues (how did this get past ci?) --- frontend/src/ts/pages/profile-search.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/src/ts/pages/profile-search.ts b/frontend/src/ts/pages/profile-search.ts index 7fea826ba13d..ceac50af37a3 100644 --- a/frontend/src/ts/pages/profile-search.ts +++ b/frontend/src/ts/pages/profile-search.ts @@ -1,10 +1,7 @@ import Page from "./page"; import * as Skeleton from "../utils/skeleton"; import Ape from "../ape"; -import { - ValidatedHtmlInputElement, - validateWithIndicator, -} from "../elements/input-validation"; +import { ValidatedHtmlInputElement } from "../elements/input-validation"; import { UserNameSchema, UserProfile } from "@monkeytype/schemas/users"; import { remoteValidation } from "../utils/remote-validation"; import * as NavigationEvent from "../observables/navigation-event"; @@ -31,7 +28,7 @@ export const page = new Page({ Skeleton.append("pageProfileSearch", "main"); if (nameInputEl === null) { - nameInputEl = validateWithIndicator( + nameInputEl = new ValidatedHtmlInputElement( document.querySelector( ".page.pageProfileSearch input" ) as HTMLInputElement, From f910c8a56797459ef45dfa80e857efe35e7ae9d3 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 27 Nov 2025 00:20:09 +0100 Subject: [PATCH 2/2] chore: prettier upgrade (@miodec) (#7159) --- .github/workflows/pretty-check.yml | 2 +- .github/workflows/pretty-fix.yml | 2 +- .prettierrc | 1 + backend/__migration__/testActivity.ts | 15 +- .../__integration__/dal/blocklist.spec.ts | 62 ++-- .../__integration__/dal/config.spec.ts | 2 +- .../__integration__/dal/connections.spec.ts | 40 +-- .../dal/leaderboards.isolated.spec.ts | 36 +-- .../__integration__/dal/preset.spec.ts | 32 +- .../__integration__/dal/result.spec.ts | 2 +- .../__integration__/dal/user.spec.ts | 122 ++++---- .../__tests__/__integration__/global-setup.ts | 4 +- .../services/weekly-xp-leaderboard.spec.ts | 15 +- .../utils/daily-leaderboards.spec.ts | 38 +-- backend/__tests__/__testData__/auth.ts | 2 +- backend/__tests__/__testData__/connections.ts | 4 +- .../__tests__/__testData__/monkey-error.ts | 2 +- backend/__tests__/__testData__/rate-limit.ts | 2 +- backend/__tests__/__testData__/users.ts | 8 +- .../__tests__/api/controllers/admin.spec.ts | 42 +-- .../__tests__/api/controllers/ape-key.spec.ts | 28 +- .../api/controllers/configuration.spec.ts | 2 +- .../api/controllers/connections.spec.ts | 16 +- backend/__tests__/api/controllers/dev.spec.ts | 2 +- .../api/controllers/leaderboard.spec.ts | 80 ++--- .../__tests__/api/controllers/public.spec.ts | 2 +- .../__tests__/api/controllers/quotes.spec.ts | 16 +- .../__tests__/api/controllers/result.spec.ts | 26 +- .../__tests__/api/controllers/user.spec.ts | 156 +++++----- .../api/controllers/webhooks.spec.ts | 6 +- backend/__tests__/middlewares/auth.spec.ts | 98 +++--- .../middlewares/configuration.spec.ts | 46 +-- .../__tests__/middlewares/permission.spec.ts | 54 ++-- backend/__tests__/setup-common-mocks.ts | 2 +- backend/__tests__/utils/misc.spec.ts | 12 +- backend/__tests__/utils/pb.spec.ts | 8 +- backend/__tests__/utils/result.spec.ts | 4 +- backend/__tests__/utils/validation.spec.ts | 2 +- backend/private/index.html | 2 +- backend/private/script.js | 12 +- backend/scripts/openapi.ts | 16 +- backend/src/anticheat/index.ts | 4 +- backend/src/api/controllers/admin.ts | 22 +- backend/src/api/controllers/ape-key.ts | 10 +- backend/src/api/controllers/config.ts | 6 +- backend/src/api/controllers/configuration.ts | 8 +- backend/src/api/controllers/connections.ts | 10 +- backend/src/api/controllers/dev.ts | 24 +- backend/src/api/controllers/leaderboard.ts | 58 ++-- backend/src/api/controllers/preset.ts | 8 +- backend/src/api/controllers/public.ts | 4 +- backend/src/api/controllers/quote.ts | 22 +- backend/src/api/controllers/result.ts | 70 ++--- backend/src/api/controllers/user.ts | 170 +++++------ backend/src/api/controllers/webhooks.ts | 2 +- backend/src/api/routes/docs.ts | 2 +- backend/src/api/routes/index.ts | 14 +- backend/src/api/routes/swagger.ts | 6 +- backend/src/api/ts-rest-adapter.ts | 8 +- backend/src/api/types.ts | 2 +- backend/src/constants/base-configuration.ts | 16 +- backend/src/constants/monkey-status-codes.ts | 2 +- backend/src/dal/ape-keys.ts | 14 +- backend/src/dal/blocklist.ts | 22 +- backend/src/dal/config.ts | 6 +- backend/src/dal/connections.ts | 18 +- backend/src/dal/leaderboards.ts | 24 +- backend/src/dal/logs.ts | 8 +- backend/src/dal/new-quotes.ts | 20 +- backend/src/dal/preset.ts | 10 +- backend/src/dal/public.ts | 10 +- backend/src/dal/quote-ratings.ts | 12 +- backend/src/dal/report.ts | 6 +- backend/src/dal/result.ts | 14 +- backend/src/dal/user.ts | 168 +++++------ backend/src/init/configuration.ts | 18 +- backend/src/init/db.ts | 4 +- backend/src/init/email-client.ts | 13 +- backend/src/init/firebase-admin.ts | 8 +- backend/src/init/redis.ts | 14 +- backend/src/jobs/delete-old-logs.ts | 2 +- backend/src/jobs/log-queue-sizes.ts | 2 +- backend/src/jobs/update-leaderboards.ts | 8 +- backend/src/middlewares/auth.ts | 40 +-- backend/src/middlewares/compatibilityCheck.ts | 2 +- backend/src/middlewares/configuration.ts | 16 +- backend/src/middlewares/context.ts | 2 +- backend/src/middlewares/error.ts | 8 +- backend/src/middlewares/permission.ts | 34 +-- backend/src/middlewares/rate-limit.ts | 22 +- backend/src/middlewares/utility.ts | 8 +- backend/src/queues/email-queue.ts | 6 +- backend/src/queues/george-queue.ts | 8 +- backend/src/queues/later-queue.ts | 8 +- backend/src/queues/monkey-queue.ts | 2 +- backend/src/server.ts | 4 +- backend/src/services/weekly-xp-leaderboard.ts | 40 +-- backend/src/utils/auth.ts | 8 +- backend/src/utils/captcha.ts | 2 +- backend/src/utils/daily-leaderboards.ts | 37 +-- backend/src/utils/discord.ts | 6 +- backend/src/utils/error.ts | 2 +- backend/src/utils/misc.ts | 22 +- backend/src/utils/pb.ts | 14 +- backend/src/utils/prometheus.ts | 18 +- backend/src/utils/result.ts | 2 +- backend/src/workers/email-worker.ts | 2 +- backend/src/workers/later-worker.ts | 26 +- frontend/__tests__/commandline/util.spec.ts | 14 +- .../controllers/preset-controller.spec.ts | 14 +- .../elements/test-activity-calendar.spec.ts | 50 ++-- .../input/helpers/fail-or-finish.spec.ts | 7 +- .../input/helpers/validation.spec.ts | 22 +- .../__tests__/root/config-metadata.spec.ts | 22 +- frontend/__tests__/root/config.spec.ts | 60 ++-- .../__tests__/test/british-english.spec.ts | 8 +- frontend/__tests__/test/funbox.spec.ts | 2 +- .../test/funbox/funbox-validation.spec.ts | 6 +- .../__tests__/test/layout-emulator.spec.ts | 4 +- frontend/__tests__/utils/colors.spec.ts | 2 +- frontend/__tests__/utils/config.spec.ts | 6 +- .../__tests__/utils/date-and-time.spec.ts | 4 +- frontend/__tests__/utils/format.spec.ts | 18 +- frontend/__tests__/utils/generate.spec.ts | 2 +- frontend/__tests__/utils/ip-addresses.spec.ts | 24 +- .../__tests__/utils/key-converter.spec.ts | 8 +- .../utils/local-storage-with-schema.spec.ts | 14 +- frontend/__tests__/utils/sanitize.spec.ts | 24 +- frontend/__tests__/utils/strings.spec.ts | 20 +- frontend/__tests__/utils/tag-builder.spec.ts | 10 +- frontend/__tests__/utils/url-handler.spec.ts | 24 +- frontend/scripts/check-assets.ts | 60 ++-- frontend/scripts/fill-colors.js | 12 +- frontend/scripts/fix-quote-lengths.cjs | 4 +- frontend/src/404.html | 2 +- frontend/src/email-handler.html | 28 +- frontend/src/index.html | 2 +- frontend/src/privacy-policy.html | 2 +- frontend/src/security-policy.html | 2 +- frontend/src/styles/buttons.scss | 14 +- frontend/src/styles/core.scss | 14 +- frontend/src/styles/inputs.scss | 16 +- frontend/src/styles/nav.scss | 8 +- frontend/src/styles/test.scss | 20 +- frontend/src/terms-of-service.html | 2 +- .../src/ts/ape/adapters/ts-rest-adapter.ts | 4 +- frontend/src/ts/auth.ts | 28 +- .../ts/commandline/commandline-metadata.ts | 8 +- frontend/src/ts/commandline/commandline.ts | 32 +- frontend/src/ts/commandline/lists.ts | 28 +- .../ts/commandline/lists/custom-background.ts | 4 +- .../src/ts/commandline/lists/font-family.ts | 6 +- .../src/ts/commandline/lists/min-burst.ts | 4 +- .../ts/commandline/lists/quote-favorites.ts | 8 +- .../src/ts/commandline/lists/result-screen.ts | 2 +- frontend/src/ts/commandline/lists/themes.ts | 6 +- frontend/src/ts/commandline/util.ts | 22 +- frontend/src/ts/config-metadata.ts | 14 +- frontend/src/ts/config-validation.ts | 4 +- frontend/src/ts/config.ts | 158 +++++----- frontend/src/ts/constants/languages.ts | 4 +- frontend/src/ts/constants/themes.ts | 2 +- .../ts/controllers/analytics-controller.ts | 2 +- .../src/ts/controllers/badge-controller.ts | 2 +- .../src/ts/controllers/captcha-controller.ts | 4 +- .../ts/controllers/challenge-controller.ts | 22 +- .../src/ts/controllers/chart-controller.ts | 54 ++-- .../src/ts/controllers/page-controller.ts | 12 +- .../src/ts/controllers/quotes-controller.ts | 8 +- .../src/ts/controllers/route-controller.ts | 12 +- .../src/ts/controllers/sound-controller.ts | 6 +- .../src/ts/controllers/theme-controller.ts | 32 +- .../ts/controllers/user-flag-controller.ts | 2 +- frontend/src/ts/db.ts | 81 ++--- frontend/src/ts/elements/account-button.ts | 10 +- .../account-settings/ape-key-table.ts | 6 +- .../account-settings/blocked-user-table.ts | 12 +- frontend/src/ts/elements/account/pb-tables.ts | 2 +- .../src/ts/elements/account/result-filters.ts | 76 ++--- frontend/src/ts/elements/alerts.ts | 16 +- .../src/ts/elements/composition-display.ts | 2 +- .../ts/elements/custom-background-filter.ts | 44 +-- frontend/src/ts/elements/input-indicator.ts | 8 +- frontend/src/ts/elements/input-validation.ts | 10 +- frontend/src/ts/elements/keymap.ts | 12 +- frontend/src/ts/elements/last-10-average.ts | 2 +- frontend/src/ts/elements/merch-banner.ts | 2 +- frontend/src/ts/elements/modes-notice.ts | 86 +++--- frontend/src/ts/elements/monkey-power.ts | 14 +- frontend/src/ts/elements/no-css.ts | 4 +- frontend/src/ts/elements/notifications.ts | 32 +- frontend/src/ts/elements/profile.ts | 46 +-- frontend/src/ts/elements/psa.ts | 18 +- frontend/src/ts/elements/result-batches.ts | 10 +- .../src/ts/elements/result-word-highlight.ts | 14 +- .../settings/custom-background-picker.ts | 2 +- .../elements/settings/custom-font-picker.ts | 4 +- .../ts/elements/settings/fps-limit-section.ts | 6 +- .../ts/elements/settings/settings-group.ts | 16 +- .../src/ts/elements/settings/theme-picker.ts | 48 +-- .../src/ts/elements/test-activity-calendar.ts | 10 +- frontend/src/ts/elements/test-activity.ts | 12 +- frontend/src/ts/elements/test-init-failed.ts | 2 +- frontend/src/ts/elements/xp-bar.ts | 30 +- frontend/src/ts/event-handlers/account.ts | 4 +- frontend/src/ts/event-handlers/footer.ts | 4 +- frontend/src/ts/event-handlers/global.ts | 2 +- .../src/ts/event-handlers/leaderboards.ts | 2 +- frontend/src/ts/event-handlers/settings.ts | 10 +- frontend/src/ts/event-handlers/test.ts | 8 +- frontend/src/ts/firebase.ts | 24 +- .../src/ts/input/handlers/before-delete.ts | 2 +- frontend/src/ts/input/handlers/insert-text.ts | 12 +- frontend/src/ts/input/handlers/keydown.ts | 14 +- frontend/src/ts/input/helpers/input-type.ts | 2 +- .../src/ts/input/helpers/word-navigation.ts | 4 +- frontend/src/ts/modals/cookies.ts | 2 +- frontend/src/ts/modals/custom-generator.ts | 4 +- .../src/ts/modals/custom-test-duration.ts | 7 +- frontend/src/ts/modals/custom-text.ts | 54 ++-- frontend/src/ts/modals/custom-word-amount.ts | 9 +- frontend/src/ts/modals/dev-options.ts | 8 +- frontend/src/ts/modals/edit-preset.ts | 50 ++-- frontend/src/ts/modals/edit-profile.ts | 12 +- frontend/src/ts/modals/edit-result-tags.ts | 8 +- frontend/src/ts/modals/edit-tag.ts | 2 +- frontend/src/ts/modals/forgot-password.ts | 6 +- frontend/src/ts/modals/google-sign-up.ts | 10 +- .../src/ts/modals/last-signed-out-result.ts | 4 +- frontend/src/ts/modals/mini-result-chart.ts | 4 +- frontend/src/ts/modals/mobile-test-config.ts | 4 +- frontend/src/ts/modals/pb-tables.ts | 2 +- frontend/src/ts/modals/practise-words.ts | 8 +- frontend/src/ts/modals/quote-approve.ts | 28 +- frontend/src/ts/modals/quote-rate.ts | 14 +- frontend/src/ts/modals/quote-report.ts | 8 +- frontend/src/ts/modals/quote-search.ts | 30 +- frontend/src/ts/modals/quote-submit.ts | 8 +- frontend/src/ts/modals/register-captcha.ts | 4 +- frontend/src/ts/modals/save-custom-text.ts | 6 +- frontend/src/ts/modals/saved-texts.ts | 6 +- frontend/src/ts/modals/share-custom-theme.ts | 6 +- frontend/src/ts/modals/share-test-settings.ts | 6 +- frontend/src/ts/modals/simple-modals.ts | 42 +-- frontend/src/ts/modals/streak-hour-offset.ts | 6 +- frontend/src/ts/modals/support.ts | 2 +- frontend/src/ts/modals/user-report.ts | 8 +- frontend/src/ts/modals/version-history.ts | 6 +- frontend/src/ts/modals/word-filter.ts | 12 +- frontend/src/ts/observables/config-event.ts | 4 +- .../ts/observables/google-sign-up-event.ts | 4 +- frontend/src/ts/observables/keymap-event.ts | 2 +- .../src/ts/observables/notification-event.ts | 4 +- frontend/src/ts/pages/about.ts | 36 +-- frontend/src/ts/pages/account-settings.ts | 12 +- frontend/src/ts/pages/account.ts | 66 ++-- frontend/src/ts/pages/friends.ts | 54 ++-- frontend/src/ts/pages/leaderboards.ts | 150 +++++----- frontend/src/ts/pages/loading.ts | 2 +- frontend/src/ts/pages/login.ts | 16 +- frontend/src/ts/pages/page.ts | 2 +- frontend/src/ts/pages/profile-search.ts | 6 +- frontend/src/ts/pages/profile.ts | 8 +- frontend/src/ts/pages/settings.ts | 282 +++++++++--------- frontend/src/ts/popups/video-ad-popup.ts | 4 +- frontend/src/ts/ready.ts | 2 +- frontend/src/ts/sentry.ts | 2 +- frontend/src/ts/states/connection.ts | 4 +- frontend/src/ts/states/custom-text-name.ts | 2 +- frontend/src/ts/states/glarses-mode.ts | 2 +- frontend/src/ts/states/version.ts | 4 +- frontend/src/ts/test/british-english.ts | 6 +- frontend/src/ts/test/caret.ts | 2 +- frontend/src/ts/test/custom-text.ts | 6 +- frontend/src/ts/test/english-punctuation.ts | 8 +- .../src/ts/test/funbox/funbox-functions.ts | 52 ++-- frontend/src/ts/test/funbox/funbox-memory.ts | 2 +- .../src/ts/test/funbox/funbox-validation.ts | 30 +- frontend/src/ts/test/funbox/funbox.ts | 30 +- .../test/funbox/layoutfluid-funbox-timer.ts | 2 +- frontend/src/ts/test/funbox/list.ts | 18 +- .../src/ts/test/funbox/memory-funbox-timer.ts | 2 +- frontend/src/ts/test/layout-emulator.ts | 10 +- frontend/src/ts/test/lazy-mode.ts | 10 +- frontend/src/ts/test/live-acc.ts | 2 +- frontend/src/ts/test/live-burst.ts | 2 +- frontend/src/ts/test/live-speed.ts | 2 +- frontend/src/ts/test/monkey.ts | 4 +- frontend/src/ts/test/out-of-focus.ts | 2 +- frontend/src/ts/test/pace-caret.ts | 23 +- frontend/src/ts/test/pb-crown.ts | 2 +- frontend/src/ts/test/practise-words.ts | 6 +- frontend/src/ts/test/replay.ts | 44 +-- frontend/src/ts/test/result.ts | 106 +++---- frontend/src/ts/test/test-config.ts | 22 +- frontend/src/ts/test/test-input.ts | 10 +- frontend/src/ts/test/test-logic.ts | 93 +++--- frontend/src/ts/test/test-screenshot.ts | 12 +- frontend/src/ts/test/test-stats.ts | 32 +- frontend/src/ts/test/test-timer.ts | 6 +- frontend/src/ts/test/test-ui.ts | 84 +++--- frontend/src/ts/test/timer-progress.ts | 6 +- frontend/src/ts/test/wikipedia.ts | 10 +- frontend/src/ts/test/words-generator.ts | 38 +-- frontend/src/ts/ui.ts | 6 +- frontend/src/ts/utils/animated-modal.ts | 26 +- frontend/src/ts/utils/arrays.ts | 6 +- frontend/src/ts/utils/async-modules.ts | 2 +- frontend/src/ts/utils/caret.ts | 20 +- frontend/src/ts/utils/colors.ts | 4 +- frontend/src/ts/utils/config.ts | 8 +- frontend/src/ts/utils/date-and-time.ts | 2 +- .../src/ts/utils/debounced-animation-frame.ts | 2 +- frontend/src/ts/utils/debug.ts | 10 +- frontend/src/ts/utils/discord-avatar.ts | 4 +- frontend/src/ts/utils/format.ts | 12 +- frontend/src/ts/utils/ip-addresses.ts | 4 +- frontend/src/ts/utils/json-data.ts | 16 +- frontend/src/ts/utils/key-converter.ts | 2 +- .../src/ts/utils/local-storage-with-schema.ts | 12 +- frontend/src/ts/utils/logger.ts | 8 +- frontend/src/ts/utils/misc.ts | 36 +-- frontend/src/ts/utils/numbers.ts | 6 +- frontend/src/ts/utils/quick-restart.ts | 2 +- frontend/src/ts/utils/remote-validation.ts | 4 +- frontend/src/ts/utils/results.ts | 6 +- frontend/src/ts/utils/sanitize.ts | 6 +- frontend/src/ts/utils/search-service.ts | 12 +- frontend/src/ts/utils/simple-modal.ts | 16 +- frontend/src/ts/utils/sorted-table.ts | 4 +- frontend/src/ts/utils/strings.ts | 10 +- frontend/src/ts/utils/typing-speed-units.ts | 2 +- frontend/src/ts/utils/url-handler.ts | 6 +- frontend/static/funbox/crt.css | 63 ++-- frontend/static/themes/chaos_theory.css | 51 ++-- frontend/static/themes/dmg.css | 12 +- frontend/static/themes/dots.css | 39 ++- frontend/static/themes/lavender.css | 6 +- frontend/static/themes/moonlight.css | 6 +- frontend/static/themes/phantom.css | 24 +- frontend/static/themes/rainbow_trail.css | 32 +- frontend/static/themes/snes.css | 48 ++- frontend/static/themes/taro.css | 6 +- frontend/static/themes/terrazzo.css | 24 +- frontend/vite-plugins/env-config.ts | 2 +- frontend/vite-plugins/font-preview.ts | 8 +- frontend/vite-plugins/fontawesome-subset.ts | 21 +- frontend/vite-plugins/language-hashes.ts | 4 +- frontend/vite-plugins/minify-json.ts | 4 +- frontend/vite.config.prod.js | 6 +- monkeytype.code-workspace | 34 +-- package.json | 2 +- .../__test__/validation/validation.spec.ts | 2 +- packages/contracts/src/admin.ts | 6 +- packages/contracts/src/ape-keys.ts | 4 +- packages/contracts/src/configs.ts | 2 +- packages/contracts/src/configuration.ts | 2 +- packages/contracts/src/connections.ts | 6 +- packages/contracts/src/dev.ts | 6 +- packages/contracts/src/leaderboards.ts | 18 +- packages/contracts/src/presets.ts | 4 +- packages/contracts/src/psas.ts | 2 +- packages/contracts/src/public.ts | 2 +- packages/contracts/src/quotes.ts | 4 +- .../src/require-configuration/index.ts | 10 +- packages/contracts/src/results.ts | 10 +- packages/contracts/src/users.ts | 24 +- packages/contracts/src/util/api.ts | 8 +- packages/contracts/src/webhooks.ts | 2 +- packages/funbox/__test__/validation.spec.ts | 14 +- packages/funbox/src/list.ts | 4 +- packages/funbox/src/validation.ts | 50 ++-- packages/oxlint-config/index.jsonc | 30 +- packages/release/src/buildChangelog.js | 18 +- packages/release/src/index.js | 24 +- packages/schemas/src/challenges.ts | 2 +- packages/schemas/src/configs.ts | 4 +- packages/schemas/src/configuration.ts | 2 +- packages/schemas/src/fonts.ts | 4 +- packages/schemas/src/languages.ts | 2 +- packages/schemas/src/layouts.ts | 2 +- packages/schemas/src/presets.ts | 4 +- packages/schemas/src/public.ts | 2 +- packages/schemas/src/shared.ts | 6 +- packages/schemas/src/themes.ts | 2 +- packages/schemas/src/users.ts | 32 +- packages/schemas/src/util.ts | 4 +- packages/schemas/src/validation/validation.ts | 6 +- packages/tsup-config/src/index.ts | 2 +- packages/util/__test__/date-and-time.spec.ts | 2 +- packages/util/__test__/json.spec.ts | 12 +- packages/util/__test__/numbers.spec.ts | 8 +- packages/util/__test__/predicates.spec.ts | 2 +- packages/util/__test__/strings.spec.ts | 2 +- packages/util/__test__/trycatch.spec.ts | 2 +- packages/util/src/date-and-time.ts | 4 +- packages/util/src/json.ts | 10 +- packages/util/src/numbers.ts | 6 +- packages/util/src/predicates.ts | 2 +- packages/util/src/trycatch.ts | 2 +- pnpm-lock.yaml | 57 +--- vitest.config.ts | 2 +- 402 files changed, 3481 insertions(+), 3337 deletions(-) diff --git a/.github/workflows/pretty-check.yml b/.github/workflows/pretty-check.yml index 6d76cf6660c7..ccb397ca6f4e 100644 --- a/.github/workflows/pretty-check.yml +++ b/.github/workflows/pretty-check.yml @@ -36,7 +36,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Install prettier - run: pnpm add -g prettier@2.8.8 + run: pnpm add -g prettier@3.6.2 - name: Get changed files id: get-changed-files diff --git a/.github/workflows/pretty-fix.yml b/.github/workflows/pretty-fix.yml index 23c7eea0a855..8b38263da8b0 100644 --- a/.github/workflows/pretty-fix.yml +++ b/.github/workflows/pretty-fix.yml @@ -34,7 +34,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Install prettier - run: pnpm add -g prettier@2.8.8 + run: pnpm add -g prettier@3.6.2 - name: Get changed files id: get-changed-files diff --git a/.prettierrc b/.prettierrc index 61dfe52984b9..dcdadfa35cf4 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,6 +2,7 @@ "tabWidth": 2, "useTabs": false, "htmlWhitespaceSensitivity": "ignore", + "trailingComma": "all", "endOfLine": "lf", "overrides": [ { diff --git a/backend/__migration__/testActivity.ts b/backend/__migration__/testActivity.ts index 211d64d6362d..36dca374ae28 100644 --- a/backend/__migration__/testActivity.ts +++ b/backend/__migration__/testActivity.ts @@ -27,10 +27,9 @@ if (require.main === module) { async function main(): Promise { try { console.log( - `Connecting to database ${process.env["DB_NAME"]} on ${process.env["DB_URI"]}...` + `Connecting to database ${process.env["DB_NAME"]} on ${process.env["DB_URI"]}...`, ); - //@ts-ignore if (!readlineSync.keyInYN("Ready to start migration?")) { appRunning = false; } @@ -222,7 +221,7 @@ async function migrateUsers(uids: string[]): Promise { }, }, ], - { allowDiskUse: true } + { allowDiskUse: true }, ) .toArray(); } @@ -232,7 +231,7 @@ async function handleUsersWithNoResults(uids: string[]): Promise { { $and: [{ uid: { $in: uids } }, filter], }, - { $set: { testActivity: {} } } + { $set: { testActivity: {} } }, ); } @@ -240,11 +239,11 @@ function updateProgress( all: number, current: number, start: number, - previousBatchSizeTime: number + previousBatchSizeTime: number, ): void { const percentage = (current / all) * 100; const timeLeft = Math.round( - (((new Date().valueOf() - start) / percentage) * (100 - percentage)) / 1000 + (((new Date().valueOf() - start) / percentage) * (100 - percentage)) / 1000, ); process.stdout.clearLine?.(0); @@ -253,7 +252,7 @@ function updateProgress( `Previous batch took ${Math.round(previousBatchSizeTime)}ms (~${ previousBatchSizeTime / batchSize }ms per user) ${Math.round( - percentage - )}% done, estimated time left ${timeLeft} seconds.` + percentage, + )}% done, estimated time left ${timeLeft} seconds.`, ); } diff --git a/backend/__tests__/__integration__/dal/blocklist.spec.ts b/backend/__tests__/__integration__/dal/blocklist.spec.ts index 2a3fa38df2b3..1253d7aa0098 100644 --- a/backend/__tests__/__integration__/dal/blocklist.spec.ts +++ b/backend/__tests__/__integration__/dal/blocklist.spec.ts @@ -36,7 +36,7 @@ describe("BlocklistDal", () => { await expect( BlacklistDal.getCollection().findOne({ emailHash: BlacklistDal.hash(email), - }) + }), ).resolves.toMatchObject({ emailHash: BlacklistDal.hash(email), timestamp: now, @@ -45,7 +45,7 @@ describe("BlocklistDal", () => { await expect( BlacklistDal.getCollection().findOne({ usernameHash: BlacklistDal.hash(name), - }) + }), ).resolves.toMatchObject({ usernameHash: BlacklistDal.hash(name), timestamp: now, @@ -67,7 +67,7 @@ describe("BlocklistDal", () => { await expect( BlacklistDal.getCollection().findOne({ discordIdHash: BlacklistDal.hash(discordId), - }) + }), ).resolves.toMatchObject({ discordIdHash: BlacklistDal.hash(discordId), timestamp: now, @@ -92,21 +92,21 @@ describe("BlocklistDal", () => { .find({ usernameHash: BlacklistDal.hash(name), }) - .toArray() + .toArray(), ).resolves.toHaveLength(1); await expect( BlacklistDal.getCollection() .find({ emailHash: BlacklistDal.hash(email), }) - .toArray() + .toArray(), ).resolves.toHaveLength(1); await expect( BlacklistDal.getCollection() .find({ emailHash: BlacklistDal.hash(email2), }) - .toArray() + .toArray(), ).resolves.toHaveLength(1); }); it("adds user should not create duplicate email", async () => { @@ -128,7 +128,7 @@ describe("BlocklistDal", () => { .find({ emailHash: BlacklistDal.hash(email), }) - .toArray() + .toArray(), ).resolves.toHaveLength(1); }); it("adds user should not create duplicate discordId", async () => { @@ -153,7 +153,7 @@ describe("BlocklistDal", () => { .find({ discordIdHash: BlacklistDal.hash(discordId), }) - .toArray() + .toArray(), ).resolves.toHaveLength(1); }); }); @@ -170,33 +170,33 @@ describe("BlocklistDal", () => { //by name await expect(BlacklistDal.contains({ name })).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ name: name.toUpperCase() }) + BlacklistDal.contains({ name: name.toUpperCase() }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ name, email: "unknown", discordId: "unknown" }) + BlacklistDal.contains({ name, email: "unknown", discordId: "unknown" }), ).resolves.toBeTruthy(); //by email await expect(BlacklistDal.contains({ email })).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ email: email.toUpperCase() }) + BlacklistDal.contains({ email: email.toUpperCase() }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ name: "unknown", email, discordId: "unknown" }) + BlacklistDal.contains({ name: "unknown", email, discordId: "unknown" }), ).resolves.toBeTruthy(); //by discordId await expect(BlacklistDal.contains({ discordId })).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ discordId: discordId.toUpperCase() }) + BlacklistDal.contains({ discordId: discordId.toUpperCase() }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ name: "unknown", email: "unknown", discordId }) + BlacklistDal.contains({ name: "unknown", email: "unknown", discordId }), ).resolves.toBeTruthy(); //by name and email and discordId await expect( - BlacklistDal.contains({ name, email, discordId }) + BlacklistDal.contains({ name, email, discordId }), ).resolves.toBeTruthy(); }); it("does not contain user", async () => { @@ -206,20 +206,20 @@ describe("BlocklistDal", () => { //WHEN / THEN await expect( - BlacklistDal.contains({ name: "unknown" }) + BlacklistDal.contains({ name: "unknown" }), ).resolves.toBeFalsy(); await expect( - BlacklistDal.contains({ email: "unknown" }) + BlacklistDal.contains({ email: "unknown" }), ).resolves.toBeFalsy(); await expect( - BlacklistDal.contains({ discordId: "unknown" }) + BlacklistDal.contains({ discordId: "unknown" }), ).resolves.toBeFalsy(); await expect( BlacklistDal.contains({ name: "unknown", email: "unknown", discordId: "unknown", - }) + }), ).resolves.toBeFalsy(); await expect(BlacklistDal.contains({})).resolves.toBeFalsy(); @@ -243,10 +243,10 @@ describe("BlocklistDal", () => { //decoy still exists await expect( - BlacklistDal.contains({ name: "test" }) + BlacklistDal.contains({ name: "test" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ email: "test@example.com" }) + BlacklistDal.contains({ email: "test@example.com" }), ).resolves.toBeTruthy(); }); it("removes existing email", async () => { @@ -265,10 +265,10 @@ describe("BlocklistDal", () => { //decoy still exists await expect( - BlacklistDal.contains({ name: "test" }) + BlacklistDal.contains({ name: "test" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ email: "test@example.com" }) + BlacklistDal.contains({ email: "test@example.com" }), ).resolves.toBeTruthy(); }); it("removes existing discordId", async () => { @@ -293,13 +293,13 @@ describe("BlocklistDal", () => { //decoy still exists await expect( - BlacklistDal.contains({ name: "test" }) + BlacklistDal.contains({ name: "test" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ email: "test@example.com" }) + BlacklistDal.contains({ email: "test@example.com" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ discordId: "testDiscordId" }) + BlacklistDal.contains({ discordId: "testDiscordId" }), ).resolves.toBeTruthy(); }); it("removes existing username,email and discordId", async () => { @@ -324,13 +324,13 @@ describe("BlocklistDal", () => { //decoy still exists await expect( - BlacklistDal.contains({ name: "test" }) + BlacklistDal.contains({ name: "test" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ email: "test@example.com" }) + BlacklistDal.contains({ email: "test@example.com" }), ).resolves.toBeTruthy(); await expect( - BlacklistDal.contains({ discordId: "testDiscordId" }) + BlacklistDal.contains({ discordId: "testDiscordId" }), ).resolves.toBeTruthy(); }); @@ -355,8 +355,8 @@ describe("BlocklistDal", () => { it("hashes case insensitive", () => { ["test", "TEST", "tESt"].forEach((value) => expect(BlacklistDal.hash(value)).toEqual( - "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" - ) + "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", + ), ); }); }); diff --git a/backend/__tests__/__integration__/dal/config.spec.ts b/backend/__tests__/__integration__/dal/config.spec.ts index bab22b49f96c..e42c253d5e03 100644 --- a/backend/__tests__/__integration__/dal/config.spec.ts +++ b/backend/__tests__/__integration__/dal/config.spec.ts @@ -29,7 +29,7 @@ describe("ConfigDal", () => { //THEN const savedConfig = (await ConfigDal.getConfig( - uid + uid, )) as ConfigDal.DBConfig; expect(savedConfig.config.ads).toBe("off"); diff --git a/backend/__tests__/__integration__/dal/connections.spec.ts b/backend/__tests__/__integration__/dal/connections.spec.ts index b7b9af47c325..193c27861978 100644 --- a/backend/__tests__/__integration__/dal/connections.spec.ts +++ b/backend/__tests__/__integration__/dal/connections.spec.ts @@ -33,7 +33,7 @@ describe("ConnectionsDal", () => { await ConnectionsDal.getConnections({ initiatorUid: uid, receiverUid: uid, - }) + }), ).toStrictEqual([initOne, initTwo, friendOne]); }); @@ -71,7 +71,7 @@ describe("ConnectionsDal", () => { initiatorUid: uid, receiverUid: uid, status: ["accepted", "blocked"], - }) + }), ).toStrictEqual([initAccepted, initBlocked, friendAccepted]); }); }); @@ -98,7 +98,7 @@ describe("ConnectionsDal", () => { createConnection({ initiatorUid: first.receiverUid, receiverUid: uid, - }) + }), ).rejects.toThrow("Connection request already sent"); }); @@ -111,7 +111,7 @@ describe("ConnectionsDal", () => { const created = await ConnectionsDal.create( { uid, name: "Bob" }, { uid: receiverUid, name: "Kevin" }, - 2 + 2, ); //THEN @@ -135,7 +135,7 @@ describe("ConnectionsDal", () => { //WHEN / THEM await expect(createConnection({ initiatorUid }, 2)).rejects.toThrow( - "Maximum number of connections reached\nStack: create connection request" + "Maximum number of connections reached\nStack: create connection request", ); }); @@ -152,7 +152,7 @@ describe("ConnectionsDal", () => { createConnection({ initiatorUid: first.receiverUid, receiverUid: uid, - }) + }), ).rejects.toThrow("Connection blocked"); }); }); @@ -181,19 +181,19 @@ describe("ConnectionsDal", () => { await ConnectionsDal.updateStatus( uid, first._id.toHexString(), - "accepted" + "accepted", ); //THEN expect(await ConnectionsDal.getConnections({ receiverUid: uid })).toEqual( - [{ ...first, status: "accepted", lastModified: now }, second] + [{ ...first, status: "accepted", lastModified: now }, second], ); //can update twice to the same status await ConnectionsDal.updateStatus( uid, first._id.toHexString(), - "accepted" + "accepted", ); }); it("should fail if uid does not match the reeceiverUid", async () => { @@ -205,7 +205,7 @@ describe("ConnectionsDal", () => { //WHEN / THEN await expect( - ConnectionsDal.updateStatus(uid, first._id.toHexString(), "accepted") + ConnectionsDal.updateStatus(uid, first._id.toHexString(), "accepted"), ).rejects.toThrow("No permission or connection not found"); }); }); @@ -226,7 +226,7 @@ describe("ConnectionsDal", () => { //THEN expect( - await ConnectionsDal.getConnections({ initiatorUid: uid }) + await ConnectionsDal.getConnections({ initiatorUid: uid }), ).toStrictEqual([second]); }); @@ -248,7 +248,7 @@ describe("ConnectionsDal", () => { expect( await ConnectionsDal.getConnections({ initiatorUid: second.initiatorUid, - }) + }), ).toStrictEqual([second]); }); @@ -261,7 +261,7 @@ describe("ConnectionsDal", () => { //WHEN / THEN await expect( - ConnectionsDal.deleteById("Bob", first._id.toHexString()) + ConnectionsDal.deleteById("Bob", first._id.toHexString()), ).rejects.toThrow("No permission or connection not found"); }); @@ -275,7 +275,7 @@ describe("ConnectionsDal", () => { //WHEN / THEN await expect( - ConnectionsDal.deleteById(uid, myRequestWasBlocked._id.toHexString()) + ConnectionsDal.deleteById(uid, myRequestWasBlocked._id.toHexString()), ).rejects.toThrow("No permission or connection not found"); }); it("allow receiver to delete blocked", async () => { @@ -291,7 +291,7 @@ describe("ConnectionsDal", () => { //THEN expect(await ConnectionsDal.getConnections({ receiverUid: uid })).toEqual( - [] + [], ); }); }); @@ -313,13 +313,13 @@ describe("ConnectionsDal", () => { await ConnectionsDal.getConnections({ initiatorUid: uid, receiverUid: uid, - }) + }), ).toEqual([]); expect( await ConnectionsDal.getConnections({ initiatorUid: decoy.initiatorUid, - }) + }), ).toEqual([decoy]); }); }); @@ -349,7 +349,7 @@ describe("ConnectionsDal", () => { await ConnectionsDal.getConnections({ initiatorUid: uid, receiverUid: uid, - }) + }), ).toEqual([ { ...initOne, initiatorName: "King Bob" }, { ...initTwo, initiatorName: "King Bob" }, @@ -359,7 +359,7 @@ describe("ConnectionsDal", () => { expect( await ConnectionsDal.getConnections({ initiatorUid: decoy.initiatorUid, - }) + }), ).toEqual([decoy]); }); }); @@ -472,7 +472,7 @@ describe("ConnectionsDal", () => { connectionId: "$connectionMeta._id", }, }, - ] + ], ); //THEN diff --git a/backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts b/backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts index cfa3a4750120..09c8b1852f81 100644 --- a/backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts +++ b/backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts @@ -38,7 +38,7 @@ describe("LeaderboardsDal", () => { //THEN expect(results).toHaveLength(1); expect( - (results as LeaderboardsDal.DBLeaderboardEntry[])[0] + (results as LeaderboardsDal.DBLeaderboardEntry[])[0], ).toHaveProperty("uid", applicableUser.uid); }); @@ -56,7 +56,7 @@ describe("LeaderboardsDal", () => { "15", "english", 0, - 50 + 50, )) as DBLeaderboardEntry[]; //THEN @@ -84,7 +84,7 @@ describe("LeaderboardsDal", () => { "60", "english", 0, - 50 + 50, )) as LeaderboardsDal.DBLeaderboardEntry[]; //THEN @@ -111,7 +111,7 @@ describe("LeaderboardsDal", () => { "60", "english", 0, - 50 + 50, )) as DBLeaderboardEntry[]; //THEN @@ -135,7 +135,7 @@ describe("LeaderboardsDal", () => { "15", "english", 0, - 50 + 50, )) as DBLeaderboardEntry[]; //THEN @@ -198,7 +198,7 @@ describe("LeaderboardsDal", () => { "15", "english", 0, - 50 + 50, )) as DBLeaderboardEntry[]; //THEN @@ -237,7 +237,7 @@ describe("LeaderboardsDal", () => { "english", 0, 50, - true + true, )) as DBLeaderboardEntry[]; //THEN @@ -270,7 +270,7 @@ describe("LeaderboardsDal", () => { "english", 0, 50, - false + false, )) as DBLeaderboardEntry[]; //THEN @@ -295,7 +295,7 @@ describe("LeaderboardsDal", () => { "english", 1, 2, - true + true, )) as LeaderboardsDal.DBLeaderboardEntry[]; //THEN @@ -334,7 +334,7 @@ describe("LeaderboardsDal", () => { 0, 50, false, - uid + uid, )) as LeaderboardsDal.DBLeaderboardEntry[]; //THEN @@ -373,7 +373,7 @@ describe("LeaderboardsDal", () => { 1, 2, false, - uid + uid, )) as LeaderboardsDal.DBLeaderboardEntry[]; //THEN @@ -395,7 +395,7 @@ describe("LeaderboardsDal", () => { 1, 2, false, - uid + uid, )) as LeaderboardsDal.DBLeaderboardEntry[]; //THEN expect(results).toEqual([]); @@ -421,7 +421,7 @@ describe("LeaderboardsDal", () => { rank: 3, name: me.name, uid: me.uid, - }) + }), ); }); it("should get for friends only", async () => { @@ -450,7 +450,7 @@ describe("LeaderboardsDal", () => { expect(await LeaderboardsDal.getCount("time", "60", "english", me.uid)) // .toEqual(3); expect( - await LeaderboardsDal.getRank("time", "60", "english", me.uid, true) + await LeaderboardsDal.getRank("time", "60", "english", me.uid, true), ) // .toEqual( expect.objectContaining({ @@ -459,7 +459,7 @@ describe("LeaderboardsDal", () => { friendsRank: 2, name: me.name, uid: me.uid, - }) + }), ); }); }); @@ -467,7 +467,7 @@ describe("LeaderboardsDal", () => { function expectedLbEntry( time: string, - { rank, user, badgeId, isPremium, friendsRank }: ExpectedLbEntry + { rank, user, badgeId, isPremium, friendsRank }: ExpectedLbEntry, ) { // @ts-expect-error const lbBest: PersonalBest = @@ -493,7 +493,7 @@ function expectedLbEntry( async function createUser( lbPersonalBests?: LbPersonalBests, - userProperties?: Partial + userProperties?: Partial, ): Promise { const uid = new ObjectId().toHexString(); await UserDal.addUser("User " + uid, uid + "@example.com", uid); @@ -510,7 +510,7 @@ async function createUser( ...userProperties, lbPersonalBests, }, - } + }, ); return await UserDal.getUser(uid, "test"); diff --git a/backend/__tests__/__integration__/dal/preset.spec.ts b/backend/__tests__/__integration__/dal/preset.spec.ts index 74ecedce8354..56ead180dca4 100644 --- a/backend/__tests__/__integration__/dal/preset.spec.ts +++ b/backend/__tests__/__integration__/dal/preset.spec.ts @@ -53,7 +53,7 @@ describe("PresetDal", () => { showAverage: "off", }, }), - ]) + ]), ); }); }); @@ -68,7 +68,7 @@ describe("PresetDal", () => { //WHEN / THEN await expect(() => - PresetDal.addPreset(uid, { name: "max", config: {} }) + PresetDal.addPreset(uid, { name: "max", config: {} }), ).rejects.toThrowError("Too many presets"); }); it("should add preset", async () => { @@ -98,7 +98,7 @@ describe("PresetDal", () => { name: "new", config: { ads: "sellout" }, }), - ]) + ]), ); }); }); @@ -162,7 +162,7 @@ describe("PresetDal", () => { name: "second", config: { ads: "result" }, }), - ]) + ]), ); expect(await PresetDal.getPresets(decoyUid)).toEqual( expect.arrayContaining([ @@ -172,7 +172,7 @@ describe("PresetDal", () => { name: "unknown", config: { ads: "result" }, }), - ]) + ]), ); }); @@ -199,7 +199,7 @@ describe("PresetDal", () => { name: "newName", config: { ads: "sellout" }, }), - ]) + ]), ); }); it("should edit with name only - partial preset", async () => { @@ -237,7 +237,7 @@ describe("PresetDal", () => { showAverage: "off", }, }), - ]) + ]), ); }); it("should not edit present not matching uid", async () => { @@ -269,7 +269,7 @@ describe("PresetDal", () => { name: "first", config: { ads: "sellout" }, }), - ]) + ]), ); }); it("should edit when partial is edited to full", async () => { @@ -305,7 +305,7 @@ describe("PresetDal", () => { config: { ads: "off" }, settingGroups: null, }), - ]) + ]), ); }); it("should edit when full is edited to partial", async () => { @@ -348,7 +348,7 @@ describe("PresetDal", () => { showAverage: "off", }, }), - ]) + ]), ); }); }); @@ -357,7 +357,7 @@ describe("PresetDal", () => { it("should fail if preset is unknown", async () => { const uid = new ObjectId().toHexString(); await expect(() => - PresetDal.removePreset(uid, new ObjectId().toHexString()) + PresetDal.removePreset(uid, new ObjectId().toHexString()), ).rejects.toThrowError("Preset not found"); }); it("should remove", async () => { @@ -394,7 +394,7 @@ describe("PresetDal", () => { name: "second", config: { ads: "result" }, }), - ]) + ]), ); expect(await PresetDal.getPresets(decoyUid)).toEqual( expect.arrayContaining([ @@ -404,7 +404,7 @@ describe("PresetDal", () => { name: "unknown", config: { ads: "result" }, }), - ]) + ]), ); }); it("should not remove present not matching uid", async () => { @@ -420,7 +420,7 @@ describe("PresetDal", () => { //WHEN await expect(() => - PresetDal.removePreset(decoyUid, first) + PresetDal.removePreset(decoyUid, first), ).rejects.toThrowError("Preset not found"); //THEN @@ -434,7 +434,7 @@ describe("PresetDal", () => { name: "first", config: { ads: "sellout" }, }), - ]) + ]), ); }); }); @@ -475,7 +475,7 @@ describe("PresetDal", () => { name: "unknown", config: { ads: "result" }, }), - ]) + ]), ); }); }); diff --git a/backend/__tests__/__integration__/dal/result.spec.ts b/backend/__tests__/__integration__/dal/result.spec.ts index c3bf95760fd8..f466cf528eb9 100644 --- a/backend/__tests__/__integration__/dal/result.spec.ts +++ b/backend/__tests__/__integration__/dal/result.spec.ts @@ -11,7 +11,7 @@ const timestamp = Date.now() - 60000; async function createDummyData( uid: string, count: number, - modify?: Partial + modify?: Partial, ): Promise { const dummyUser: UserDal.DBUser = { _id: new ObjectId(), diff --git a/backend/__tests__/__integration__/dal/user.spec.ts b/backend/__tests__/__integration__/dal/user.spec.ts index 5bc19e779195..ba0ecdd469a3 100644 --- a/backend/__tests__/__integration__/dal/user.spec.ts +++ b/backend/__tests__/__integration__/dal/user.spec.ts @@ -122,7 +122,7 @@ describe("UserDal", () => { // then // should error because user already exists await expect( - UserDAL.addUser(newUser.name, newUser.email, newUser.uid) + UserDAL.addUser(newUser.name, newUser.email, newUser.uid), ).rejects.toThrow("User document already exists"); }); @@ -168,7 +168,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.updateName(user1.uid, user2.name, user1.name) + UserDAL.updateName(user1.uid, user2.name, user1.name), ).rejects.toThrow("Username already taken"); }); @@ -186,7 +186,7 @@ describe("UserDal", () => { expect(updatedUser1.name).toBe(name1.toUpperCase()); await expect( - UserDAL.updateName(user2.uid, name1, user2.name) + UserDAL.updateName(user2.uid, name1, user2.name), ).rejects.toThrow("Username already taken"); }); @@ -219,7 +219,7 @@ describe("UserDal", () => { custom: {}, }, }, - } + }, ); const { personalBests } = @@ -298,9 +298,9 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.addResultFilterPreset("non existing uid", mockResultFilter, 5) + UserDAL.addResultFilterPreset("non existing uid", mockResultFilter, 5), ).rejects.toThrow( - "Maximum number of custom filters reached\nStack: add result filter preset" + "Maximum number of custom filters reached\nStack: add result filter preset", ); }); @@ -312,9 +312,9 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.addResultFilterPreset(uid, mockResultFilter, 1) + UserDAL.addResultFilterPreset(uid, mockResultFilter, 1), ).rejects.toThrow( - "Maximum number of custom filters reached\nStack: add result filter preset" + "Maximum number of custom filters reached\nStack: add result filter preset", ); }); @@ -324,9 +324,9 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.addResultFilterPreset(uid, mockResultFilter, 0) + UserDAL.addResultFilterPreset(uid, mockResultFilter, 0), ).rejects.toThrow( - "Maximum number of custom filters reached\nStack: add result filter preset" + "Maximum number of custom filters reached\nStack: add result filter preset", ); }); @@ -340,7 +340,7 @@ describe("UserDal", () => { const result = await UserDAL.addResultFilterPreset( uid, { ...mockResultFilter }, - 2 + 2, ); // then @@ -357,8 +357,8 @@ describe("UserDal", () => { await expect( UserDAL.removeResultFilterPreset( "non existing uid", - new ObjectId().toHexString() - ) + new ObjectId().toHexString(), + ), ).rejects.toThrow("Custom filter not found\nStack: remove result filter"); }); @@ -370,7 +370,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.removeResultFilterPreset(uid, new ObjectId().toHexString()) + UserDAL.removeResultFilterPreset(uid, new ObjectId().toHexString()), ).rejects.toThrow("Custom filter not found\nStack: remove result filter"); }); it("should remove filter", async () => { @@ -394,7 +394,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.addTag("non existing uid", "tagName") + UserDAL.addTag("non existing uid", "tagName"), ).rejects.toThrow("Maximum number of tags reached\nStack: add tag"); }); @@ -410,7 +410,7 @@ describe("UserDal", () => { // when, then await expect(UserDAL.addTag(uid, "new")).rejects.toThrow( - "Maximum number of tags reached\nStack: add tag" + "Maximum number of tags reached\nStack: add tag", ); }); @@ -442,7 +442,7 @@ describe("UserDal", () => { expect.arrayContaining([ expect.objectContaining({ name: "first", personalBests: emptyPb }), expect.objectContaining({ name: "newTag", personalBests: emptyPb }), - ]) + ]), ); }); }); @@ -454,8 +454,8 @@ describe("UserDal", () => { UserDAL.editTag( "non existing uid", new ObjectId().toHexString(), - "newName" - ) + "newName", + ), ).rejects.toThrow("Tag not found\nStack: edit tag"); }); @@ -472,7 +472,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.editTag(uid, new ObjectId().toHexString(), "newName") + UserDAL.editTag(uid, new ObjectId().toHexString(), "newName"), ).rejects.toThrow("Tag not found\nStack: edit tag"); }); @@ -502,7 +502,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.removeTag("non existing uid", new ObjectId().toHexString()) + UserDAL.removeTag("non existing uid", new ObjectId().toHexString()), ).rejects.toThrow("Tag not found\nStack: remove tag"); }); @@ -519,7 +519,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.removeTag(uid, new ObjectId().toHexString()) + UserDAL.removeTag(uid, new ObjectId().toHexString()), ).rejects.toThrow("Tag not found\nStack: remove tag"); }); it("should remove tag", async () => { @@ -556,7 +556,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.removeTagPb("non existing uid", new ObjectId().toHexString()) + UserDAL.removeTagPb("non existing uid", new ObjectId().toHexString()), ).rejects.toThrow("Tag not found\nStack: remove tag pb"); }); @@ -573,7 +573,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.removeTagPb(uid, new ObjectId().toHexString()) + UserDAL.removeTagPb(uid, new ObjectId().toHexString()), ).rejects.toThrow("Tag not found\nStack: remove tag pb"); }); it("should remove tag pb", async () => { @@ -637,7 +637,7 @@ describe("UserDal", () => { }, { badges: [], - } + }, ); const user = await UserDAL.getUser(uid, "test add result filters"); @@ -663,7 +663,7 @@ describe("UserDal", () => { selected: true, }, ], - } + }, ); const updatedUser = await UserDAL.getUser(uid, "test add result filters"); @@ -698,12 +698,12 @@ describe("UserDal", () => { id: 1, }, ], - } + }, ); const updatedUser2 = await UserDAL.getUser( uid, - "test add result filters" + "test add result filters", ); expect(updatedUser2.profileDetails).toStrictEqual({ bio: "test bio 2", @@ -767,7 +767,7 @@ describe("UserDal", () => { }, { badges: [], - } + }, ); await UserDAL.incrementBananas(uid, 100); @@ -813,7 +813,7 @@ describe("UserDal", () => { { enabled: true, maxMail: 100, - } + }, ); const inbox = await UserDAL.getInbox(uid); @@ -841,7 +841,7 @@ describe("UserDal", () => { subject: "Hello 1!", } as any, ], - config + config, ); await UserDAL.addToInbox( @@ -851,7 +851,7 @@ describe("UserDal", () => { subject: "Hello 2!", } as any, ], - config + config, ); const inbox = await UserDAL.getInbox(uid); @@ -889,7 +889,7 @@ describe("UserDal", () => { { enabled: true, maxMail: 100, - } + }, ); const inbox = await UserDAL.getInbox(user1); @@ -912,7 +912,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect(UserDAL.updateStreak("non existing uid", 0)).rejects.toThrow( - "User not found\nStack: calculate streak" + "User not found\nStack: calculate streak", ); }); @@ -1125,7 +1125,7 @@ describe("UserDal", () => { describe("getPartialUser", () => { it("should throw for unknown user", async () => { await expect(async () => - UserDAL.getPartialUser("1234", "stack", []) + UserDAL.getPartialUser("1234", "stack", []), ).rejects.toThrowError("User not found\nStack: stack"); }); @@ -1160,7 +1160,7 @@ describe("UserDal", () => { describe("updateEmail", () => { it("throws for nonexisting user", async () => { await expect(async () => - UserDAL.updateEmail("unknown", "test@example.com") + UserDAL.updateEmail("unknown", "test@example.com"), ).rejects.toThrowError("User not found\nStack: update email"); }); it("should update", async () => { @@ -1178,7 +1178,7 @@ describe("UserDal", () => { describe("resetPb", () => { it("throws for nonexisting user", async () => { await expect(async () => UserDAL.resetPb("unknown")).rejects.toThrowError( - "User not found\nStack: reset pb" + "User not found\nStack: reset pb", ); }); it("should reset", async () => { @@ -1204,7 +1204,7 @@ describe("UserDal", () => { describe("linkDiscord", () => { it("throws for nonexisting user", async () => { await expect(async () => - UserDAL.linkDiscord("unknown", "", "") + UserDAL.linkDiscord("unknown", "", ""), ).rejects.toThrowError("User not found\nStack: link discord"); }); it("should update", async () => { @@ -1240,7 +1240,7 @@ describe("UserDal", () => { describe("unlinkDiscord", () => { it("throws for nonexisting user", async () => { await expect(async () => - UserDAL.unlinkDiscord("unknown") + UserDAL.unlinkDiscord("unknown"), ).rejects.toThrowError("User not found\nStack: unlink discord"); }); it("should update", async () => { @@ -1309,7 +1309,7 @@ describe("UserDal", () => { await UserDAL.updateInbox( user.uid, [rewardOne.id, rewardTwo.id, rewardThree.id], - [] + [], ); //THEN @@ -1423,7 +1423,7 @@ describe("UserDal", () => { await UserDAL.updateInbox( user.uid, [rewardOne.id, rewardTwo.id, rewardThree.id, rewardOne.id], - [] + [], ); //THEN @@ -1466,7 +1466,7 @@ describe("UserDal", () => { await UserDAL.updateInbox( user.uid, [rewardOne.id, rewardTwo.id], - [rewardOne.id, rewardTwo.id] + [rewardOne.id, rewardTwo.id], ); //THEN @@ -1518,8 +1518,8 @@ describe("UserDal", () => { UserDAL.updateInbox( user.uid, [rewardOne.id, rewardTwo.id, rewardThree.id], - [] - ) + [], + ), ); await Promise.all(calls); @@ -1545,7 +1545,7 @@ describe("UserDal", () => { // when, then await expect(UserDAL.isDiscordIdAvailable(discordId)).resolves.toBe( - false + false, ); }); }); @@ -1558,8 +1558,8 @@ describe("UserDal", () => { "time", "15", "english", - 4711 - ) + 4711, + ), ).rejects.toThrow("User not found\nStack: update lb memory"); }); @@ -1728,9 +1728,9 @@ describe("UserDal", () => { UserDAL.addTheme("non existing uid", { name: "new", colors: [] as any, - }) + }), ).rejects.toThrow( - "Maximum number of custom themes reached\nStack: add theme" + "Maximum number of custom themes reached\nStack: add theme", ); }); @@ -1746,9 +1746,9 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.addTheme(uid, { name: "new", colors: [] as any }) + UserDAL.addTheme(uid, { name: "new", colors: [] as any }), ).rejects.toThrow( - "Maximum number of custom themes reached\nStack: add theme" + "Maximum number of custom themes reached\nStack: add theme", ); }); @@ -1782,7 +1782,7 @@ describe("UserDal", () => { name: "newTheme", colors: newTheme.colors, }), - ]) + ]), ); }); }); @@ -1794,7 +1794,7 @@ describe("UserDal", () => { UserDAL.editTheme("non existing uid", new ObjectId().toHexString(), { name: "newName", colors: [] as any, - }) + }), ).rejects.toThrow("Custom theme not found\nStack: edit theme"); }); @@ -1814,7 +1814,7 @@ describe("UserDal", () => { UserDAL.editTheme(uid, new ObjectId().toHexString(), { name: "newName", colors: [] as any, - }) + }), ).rejects.toThrow("Custom theme not found\nStack: edit theme"); }); @@ -1846,7 +1846,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.removeTheme("non existing uid", new ObjectId().toHexString()) + UserDAL.removeTheme("non existing uid", new ObjectId().toHexString()), ).rejects.toThrow("Custom theme not found\nStack: remove theme"); }); @@ -1863,7 +1863,7 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.removeTheme(uid, new ObjectId().toHexString()) + UserDAL.removeTheme(uid, new ObjectId().toHexString()), ).rejects.toThrow("Custom theme not found\nStack: remove theme"); }); it("should remove theme", async () => { @@ -1901,9 +1901,9 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.addFavoriteQuote("non existing uid", "english", "1", 5) + UserDAL.addFavoriteQuote("non existing uid", "english", "1", 5), ).rejects.toThrow( - "Maximum number of favorite quotes reached\nStack: add favorite quote" + "Maximum number of favorite quotes reached\nStack: add favorite quote", ); }); @@ -1919,9 +1919,9 @@ describe("UserDal", () => { // when, then await expect( - UserDAL.addFavoriteQuote(uid, "polish", "6", 5) + UserDAL.addFavoriteQuote(uid, "polish", "6", 5), ).rejects.toThrow( - "Maximum number of favorite quotes reached\nStack: add favorite quote" + "Maximum number of favorite quotes reached\nStack: add favorite quote", ); }); @@ -1972,7 +1972,7 @@ describe("UserDal", () => { it("should return error if uid not found", async () => { // when, then await expect( - UserDAL.removeFavoriteQuote("non existing uid", "english", "0") + UserDAL.removeFavoriteQuote("non existing uid", "english", "0"), ).rejects.toThrow("User not found\nStack: remove favorite quote"); }); diff --git a/backend/__tests__/__integration__/global-setup.ts b/backend/__tests__/__integration__/global-setup.ts index 75a4f2865c07..2aac2acd51a8 100644 --- a/backend/__tests__/__integration__/global-setup.ts +++ b/backend/__tests__/__integration__/global-setup.ts @@ -14,7 +14,7 @@ export async function setup(): Promise { startedMongoContainer = await mongoContainer.start(); const mongoUrl = `mongodb://${startedMongoContainer?.getHost()}:${startedMongoContainer?.getMappedPort( - 27017 + 27017, )}`; process.env["TEST_DB_URL"] = mongoUrl; @@ -26,7 +26,7 @@ export async function setup(): Promise { startedRedisContainer = await redisContainer.start(); const redisUrl = `redis://${startedRedisContainer.getHost()}:${startedRedisContainer.getMappedPort( - 6379 + 6379, )}`; process.env["REDIS_URI"] = redisUrl; } diff --git a/backend/__tests__/__integration__/services/weekly-xp-leaderboard.spec.ts b/backend/__tests__/__integration__/services/weekly-xp-leaderboard.spec.ts index 970f38143ca9..43cc77213a26 100644 --- a/backend/__tests__/__integration__/services/weekly-xp-leaderboard.spec.ts +++ b/backend/__tests__/__integration__/services/weekly-xp-leaderboard.spec.ts @@ -22,7 +22,7 @@ describe("Weekly XP Leaderboards", () => { describe("get", () => { it("should get if enabled", () => { expect(WeeklyXpLeaderboard.get(leaderboardsConfig)).toBeInstanceOf( - WeeklyXpLeaderboard.WeeklyXpLeaderboard + WeeklyXpLeaderboard.WeeklyXpLeaderboard, ); }); it("should return null if disabled", () => { @@ -203,7 +203,10 @@ describe("Weekly XP Leaderboards", () => { it("should return null for unknown user", async () => { expect(await lb.getRank("decoy", leaderboardsConfig)).toBeNull(); expect( - await lb.getRank("decoy", leaderboardsConfig, ["unknown", "unknown2"]) + await lb.getRank("decoy", leaderboardsConfig, [ + "unknown", + "unknown2", + ]), ).toBeNull(); }); @@ -217,11 +220,11 @@ describe("Weekly XP Leaderboards", () => { //WHEN / THEN expect( - await lb.getRank(user2.uid, leaderboardsConfig, friends) + await lb.getRank(user2.uid, leaderboardsConfig, friends), ).toEqual({ rank: 2, friendsRank: 1, totalXp: 60, ...user2 }); expect( - await lb.getRank(user1.uid, leaderboardsConfig, friends) + await lb.getRank(user1.uid, leaderboardsConfig, friends), ).toEqual({ rank: 3, friendsRank: 2, totalXp: 50, ...user1 }); }); }); @@ -234,7 +237,7 @@ describe("Weekly XP Leaderboards", () => { //WHEN await WeeklyXpLeaderboard.purgeUserFromXpLeaderboards( cheater.uid, - leaderboardsConfig + leaderboardsConfig, ); //THEN expect(await lb.getRank(cheater.uid, leaderboardsConfig)).toBeNull(); @@ -246,7 +249,7 @@ describe("Weekly XP Leaderboards", () => { async function givenResult( xpGained: number, - entry?: Partial + entry?: Partial, ): Promise { const uid = new ObjectId().toHexString(); const result: RedisXpLeaderboardEntry = { diff --git a/backend/__tests__/__integration__/utils/daily-leaderboards.spec.ts b/backend/__tests__/__integration__/utils/daily-leaderboards.spec.ts index 8cd725566248..ece13c8d305a 100644 --- a/backend/__tests__/__integration__/utils/daily-leaderboards.spec.ts +++ b/backend/__tests__/__integration__/utils/daily-leaderboards.spec.ts @@ -88,10 +88,10 @@ describe("Daily Leaderboards", () => { language, mode, mode2 as any, - dailyLeaderboardsConfig + dailyLeaderboardsConfig, ); expect(!!result).toBe(expected); - } + }, ); }); describe("DailyLeaderboard class", () => { @@ -100,7 +100,7 @@ describe("Daily Leaderboards", () => { "english", "time", "60", - dailyLeaderboardsConfig + dailyLeaderboardsConfig, )!; describe("addResult", () => { it("adds best result for user", async () => { @@ -117,7 +117,7 @@ describe("Daily Leaderboards", () => { 0, 5, dailyLeaderboardsConfig, - true + true, ); //THEN expect(results).toEqual({ @@ -138,10 +138,10 @@ describe("Daily Leaderboards", () => { await Promise.all( new Array(maxResults - 1) .fill(0) - .map(() => givenResult({ wpm: 20 + Math.random() * 100 })) + .map(() => givenResult({ wpm: 20 + Math.random() * 100 })), ); expect( - await lb.getResults(0, 5, dailyLeaderboardsConfig, true) + await lb.getResults(0, 5, dailyLeaderboardsConfig, true), ).toEqual(expect.objectContaining({ count: maxResults })); expect(await lb.getRank(bob.uid, dailyLeaderboardsConfig)).toEqual({ @@ -155,7 +155,7 @@ describe("Daily Leaderboards", () => { //THEN //max count is still the same, but bob is no longer on the leaderboard expect( - await lb.getResults(0, 5, dailyLeaderboardsConfig, true) + await lb.getResults(0, 5, dailyLeaderboardsConfig, true), ).toEqual(expect.objectContaining({ count: maxResults })); expect(await lb.getRank(bob.uid, dailyLeaderboardsConfig)).toBeNull(); }); @@ -172,7 +172,7 @@ describe("Daily Leaderboards", () => { 0, 5, dailyLeaderboardsConfig, - true + true, ); //THEN expect(results).toEqual({ @@ -198,7 +198,7 @@ describe("Daily Leaderboards", () => { 1, 2, dailyLeaderboardsConfig, - true + true, ); //THEN expect(results).toEqual({ @@ -222,7 +222,7 @@ describe("Daily Leaderboards", () => { 0, 5, dailyLeaderboardsConfig, - false + false, ); //THEN expect(results).toEqual({ @@ -250,7 +250,7 @@ describe("Daily Leaderboards", () => { 5, dailyLeaderboardsConfig, true, - [user2.uid, user4.uid, new ObjectId().toHexString()] + [user2.uid, user4.uid, new ObjectId().toHexString()], ); //THEN expect(results).toEqual({ @@ -278,7 +278,7 @@ describe("Daily Leaderboards", () => { 2, dailyLeaderboardsConfig, true, - [user1.uid, user2.uid, user4.uid, new ObjectId().toHexString()] + [user1.uid, user2.uid, user4.uid, new ObjectId().toHexString()], ); //THEN @@ -298,7 +298,7 @@ describe("Daily Leaderboards", () => { 5, dailyLeaderboardsConfig, true, - [] + [], ); //THEN expect(results).toEqual({ @@ -332,7 +332,7 @@ describe("Daily Leaderboards", () => { await lb.getRank("decoy", dailyLeaderboardsConfig, [ "unknown", "unknown2", - ]) + ]), ).toBeNull(); }); @@ -345,11 +345,11 @@ describe("Daily Leaderboards", () => { //WHEN / THEN expect( - await lb.getRank(user2.uid, dailyLeaderboardsConfig, friends) + await lb.getRank(user2.uid, dailyLeaderboardsConfig, friends), ).toEqual({ rank: 2, friendsRank: 1, ...user2 }); expect( - await lb.getRank(user1.uid, dailyLeaderboardsConfig, friends) + await lb.getRank(user1.uid, dailyLeaderboardsConfig, friends), ).toEqual({ rank: 3, friendsRank: 2, ...user1 }); }); }); @@ -363,7 +363,7 @@ describe("Daily Leaderboards", () => { //WHEN await DailyLeaderboards.purgeUserFromDailyLeaderboards( cheater.uid, - dailyLeaderboardsConfig + dailyLeaderboardsConfig, ); //THEN expect(await lb.getRank(cheater.uid, dailyLeaderboardsConfig)).toBeNull(); @@ -375,12 +375,12 @@ describe("Daily Leaderboards", () => { { rank: 1, ...user1 }, { rank: 2, ...user2 }, ], - } + }, ); }); async function givenResult( - entry?: Partial + entry?: Partial, ): Promise { const uid = new ObjectId().toHexString(); const result = { diff --git a/backend/__tests__/__testData__/auth.ts b/backend/__tests__/__testData__/auth.ts index 4d6003535380..e185d8b0061c 100644 --- a/backend/__tests__/__testData__/auth.ts +++ b/backend/__tests__/__testData__/auth.ts @@ -10,7 +10,7 @@ import * as AuthUtils from "../../src/utils/auth"; export async function mockAuthenticateWithApeKey( uid: string, - config: Configuration + config: Configuration, ): Promise { if (!config.apeKeys.acceptKeys) throw Error("config.apeKeys.acceptedKeys needs to be set to true"); diff --git a/backend/__tests__/__testData__/connections.ts b/backend/__tests__/__testData__/connections.ts index 38a18f614270..a927ad4985a2 100644 --- a/backend/__tests__/__testData__/connections.ts +++ b/backend/__tests__/__testData__/connections.ts @@ -3,7 +3,7 @@ import * as ConnectionsDal from "../../src/dal/connections"; export async function createConnection( data: Partial, - maxPerUser = 25 + maxPerUser = 25, ): Promise { const result = await ConnectionsDal.create( { @@ -14,7 +14,7 @@ export async function createConnection( uid: data.receiverUid ?? new ObjectId().toHexString(), name: data.receiverName ?? "user" + new ObjectId().toHexString(), }, - maxPerUser + maxPerUser, ); await ConnectionsDal.__testing .getCollection() diff --git a/backend/__tests__/__testData__/monkey-error.ts b/backend/__tests__/__testData__/monkey-error.ts index 3c9245be9ebf..774c06fa4f47 100644 --- a/backend/__tests__/__testData__/monkey-error.ts +++ b/backend/__tests__/__testData__/monkey-error.ts @@ -6,7 +6,7 @@ export function enableMonkeyErrorExpects(): void { expect.extend({ toMatchMonkeyError( received: MonkeyError, - expected: MonkeyError + expected: MonkeyError, ): MatcherResult { return { pass: diff --git a/backend/__tests__/__testData__/rate-limit.ts b/backend/__tests__/__testData__/rate-limit.ts index bd5461fb4b2a..ba157d41a69a 100644 --- a/backend/__tests__/__testData__/rate-limit.ts +++ b/backend/__tests__/__testData__/rate-limit.ts @@ -7,7 +7,7 @@ export function enableRateLimitExpects(): void { expect.extend({ toBeRateLimited: async ( received: SuperTest, - expected: ExpectedRateLimit + expected: ExpectedRateLimit, ): Promise => { const now = Date.now(); const { headers } = await received.expect(200); diff --git a/backend/__tests__/__testData__/users.ts b/backend/__tests__/__testData__/users.ts index 9b6faa31c4f3..e7f1f4b66c27 100644 --- a/backend/__tests__/__testData__/users.ts +++ b/backend/__tests__/__testData__/users.ts @@ -4,7 +4,7 @@ import { ObjectId } from "mongodb"; import { PersonalBest } from "@monkeytype/schemas/shared"; export async function createUser( - user?: Partial + user?: Partial, ): Promise { const uid = new ObjectId().toHexString(); await UserDAL.addUser("user" + uid, uid + "@example.com", uid); @@ -13,14 +13,14 @@ export async function createUser( } export async function createUserWithoutMigration( - user?: Partial + user?: Partial, ): Promise { const uid = new ObjectId().toHexString(); await UserDAL.addUser("user" + uid, uid + "@example.com", uid); await DB.collection("users").updateOne({ uid }, { $set: { ...user } }); await DB.collection("users").updateOne( { uid }, - { $unset: { testActivity: "" } } + { $unset: { testActivity: "" } }, ); return await UserDAL.getUser(uid, "test"); @@ -29,7 +29,7 @@ export async function createUserWithoutMigration( export function pb( wpm: number, acc: number = 90, - timestamp: number = 1 + timestamp: number = 1, ): PersonalBest { return { acc, diff --git a/backend/__tests__/api/controllers/admin.spec.ts b/backend/__tests__/api/controllers/admin.spec.ts index b1b04c3dd39b..8d6a7ca8ff76 100644 --- a/backend/__tests__/api/controllers/admin.spec.ts +++ b/backend/__tests__/api/controllers/admin.spec.ts @@ -46,17 +46,17 @@ describe("AdminController", () => { }); it("should fail if user is no admin", async () => { await expectFailForNonAdmin( - mockApp.get("/admin").set("Authorization", `Bearer ${uid}`) + mockApp.get("/admin").set("Authorization", `Bearer ${uid}`), ); }); it("should fail if admin endpoints are disabled", async () => { await expectFailForDisabledEndpoint( - mockApp.get("/admin").set("Authorization", `Bearer ${uid}`) + mockApp.get("/admin").set("Authorization", `Bearer ${uid}`), ); }); it("should be rate limited", async () => { await expect( - mockApp.get("/admin").set("Authorization", `Bearer ${uid}`) + mockApp.get("/admin").set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); @@ -68,7 +68,7 @@ describe("AdminController", () => { beforeEach(() => { [userBannedMock, georgeBannedMock, getUserMock].forEach((it) => - it.mockClear() + it.mockClear(), ); userBannedMock.mockResolvedValue(); }); @@ -165,7 +165,7 @@ describe("AdminController", () => { mockApp .post("/admin/toggleBan") .send({ uid: new ObjectId().toHexString() }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if admin endpoints are disabled", async () => { @@ -174,7 +174,7 @@ describe("AdminController", () => { mockApp .post("/admin/toggleBan") .send({ uid: new ObjectId().toHexString() }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should be rate limited", async () => { @@ -190,7 +190,7 @@ describe("AdminController", () => { mockApp .post("/admin/toggleBan") .send({ uid: victimUid }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); @@ -258,7 +258,7 @@ describe("AdminController", () => { mockApp .post("/admin/clearStreakHourOffset") .send({ uid: new ObjectId().toHexString() }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if admin endpoints are disabled", async () => { @@ -267,7 +267,7 @@ describe("AdminController", () => { mockApp .post("/admin/clearStreakHourOffset") .send({ uid: new ObjectId().toHexString() }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should be rate limited", async () => { @@ -279,7 +279,7 @@ describe("AdminController", () => { mockApp .post("/admin/clearStreakHourOffset") .send({ uid: victimUid }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); @@ -291,7 +291,7 @@ describe("AdminController", () => { beforeEach(() => { [getReportsMock, deleteReportsMock, addToInboxMock].forEach((it) => - it.mockClear() + it.mockClear(), ); deleteReportsMock.mockResolvedValue(); }); @@ -374,7 +374,7 @@ describe("AdminController", () => { mockApp .post("/admin/report/accept") .send({ reports: [] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if admin endpoints are disabled", async () => { @@ -383,7 +383,7 @@ describe("AdminController", () => { mockApp .post("/admin/report/accept") .send({ reports: [] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should be rate limited", async () => { @@ -395,7 +395,7 @@ describe("AdminController", () => { mockApp .post("/admin/report/accept") .send({ reports: [{ reportId: "1" }] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); @@ -492,7 +492,7 @@ describe("AdminController", () => { mockApp .post("/admin/report/reject") .send({ reports: [] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if admin endpoints are disabled", async () => { @@ -501,7 +501,7 @@ describe("AdminController", () => { mockApp .post("/admin/report/reject") .send({ reports: [] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should be rate limited", async () => { @@ -513,14 +513,14 @@ describe("AdminController", () => { mockApp .post("/admin/report/reject") .send({ reports: [{ reportId: "1" }] }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); describe("send forgot password email", () => { const sendForgotPasswordEmailMock = vi.spyOn( AuthUtil, - "sendForgotPasswordEmail" + "sendForgotPasswordEmail", ); beforeEach(() => { @@ -544,7 +544,7 @@ describe("AdminController", () => { }); expect(sendForgotPasswordEmailMock).toHaveBeenCalledWith( - "meowdec@example.com" + "meowdec@example.com", ); }); it("should be rate limited", async () => { @@ -553,7 +553,7 @@ describe("AdminController", () => { mockApp .post("/admin/sendForgotPasswordEmail") .send({ email: "meowdec@example.com" }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 1, windowMs: 5000 }); }); }); @@ -574,6 +574,6 @@ async function enableAdminEndpoints(enabled: boolean): Promise { mockConfig.admin = { ...mockConfig.admin, endpointsEnabled: enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/ape-key.spec.ts b/backend/__tests__/api/controllers/ape-key.spec.ts index 330ae4832576..3a89ef56588f 100644 --- a/backend/__tests__/api/controllers/ape-key.spec.ts +++ b/backend/__tests__/api/controllers/ape-key.spec.ts @@ -65,12 +65,12 @@ describe("ApeKeyController", () => { }); it("should fail if apeKeys endpoints are disabled", async () => { await expectFailForDisabledEndpoint( - mockApp.get("/ape-keys").set("Authorization", `Bearer ${uid}`) + mockApp.get("/ape-keys").set("Authorization", `Bearer ${uid}`), ); }); it("should fail if user has no apeKey permissions", async () => { await expectFailForNoPermissions( - mockApp.get("/ape-keys").set("Authorization", `Bearer ${uid}`) + mockApp.get("/ape-keys").set("Authorization", `Bearer ${uid}`), ); }); }); @@ -122,7 +122,7 @@ describe("ApeKeyController", () => { name: "test", uid: uid, useCount: 0, - }) + }), ); }); it("should fail without mandatory properties", async () => { @@ -167,7 +167,7 @@ describe("ApeKeyController", () => { //THEN expect(body.message).toEqual( - "Maximum number of ApeKeys have been generated" + "Maximum number of ApeKeys have been generated", ); }); it("should fail if apeKeys endpoints are disabled", async () => { @@ -175,7 +175,7 @@ describe("ApeKeyController", () => { mockApp .post("/ape-keys") .send({ name: "test", enabled: false }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if user has no apeKey permissions", async () => { @@ -183,7 +183,7 @@ describe("ApeKeyController", () => { mockApp .post("/ape-keys") .send({ name: "test", enabled: false }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); }); @@ -228,7 +228,7 @@ describe("ApeKeyController", () => { uid, apeKeyId, "new", - undefined + undefined, ); }); it("should fail with missing path", async () => { @@ -261,7 +261,7 @@ describe("ApeKeyController", () => { mockApp .patch(`/ape-keys/${apeKeyId}`) .send({ name: "test", enabled: false }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); it("should fail if user has no apeKey permissions", async () => { @@ -269,7 +269,7 @@ describe("ApeKeyController", () => { mockApp .patch(`/ape-keys/${apeKeyId}`) .send({ name: "test", enabled: false }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); }); @@ -308,7 +308,7 @@ describe("ApeKeyController", () => { await expectFailForDisabledEndpoint( mockApp .delete(`/ape-keys/${apeKeyId}`) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); @@ -316,7 +316,7 @@ describe("ApeKeyController", () => { await expectFailForNoPermissions( mockApp .delete(`/ape-keys/${apeKeyId}`) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); }); @@ -324,7 +324,7 @@ describe("ApeKeyController", () => { getUserMock.mockResolvedValue(user(uid, { canManageApeKeys: false })); const { body } = await call.expect(403); expect(body.message).toEqual( - "You have lost access to ape keys, please contact support" + "You have lost access to ape keys, please contact support", ); } async function expectFailForDisabledEndpoint(call: SuperTest): Promise { @@ -336,7 +336,7 @@ describe("ApeKeyController", () => { function apeKeyDb( uid: string, - data?: Partial + data?: Partial, ): ApeKeyDal.DBApeKey { return { _id: new ObjectId(), @@ -361,7 +361,7 @@ async function enableApeKeysEndpoints(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/configuration.spec.ts b/backend/__tests__/api/controllers/configuration.spec.ts index c0422137c448..3b6e8fdead4d 100644 --- a/backend/__tests__/api/controllers/configuration.spec.ts +++ b/backend/__tests__/api/controllers/configuration.spec.ts @@ -100,7 +100,7 @@ describe("Configuration Controller", () => { describe("updateConfiguration", () => { const patchConfigurationMock = vi.spyOn( Configuration, - "patchConfiguration" + "patchConfiguration", ); beforeEach(() => { patchConfigurationMock.mockClear(); diff --git a/backend/__tests__/api/controllers/connections.spec.ts b/backend/__tests__/api/controllers/connections.spec.ts index 4f0514bfc8ca..adda54965357 100644 --- a/backend/__tests__/api/controllers/connections.spec.ts +++ b/backend/__tests__/api/controllers/connections.spec.ts @@ -150,7 +150,7 @@ describe("ConnectionsController", () => { it("should fail if connections endpoints are disabled", async () => { await expectFailForDisabledEndpoint( - mockApp.get("/connections").set("Authorization", `Bearer ${uid}`) + mockApp.get("/connections").set("Authorization", `Bearer ${uid}`), ); }); it("should fail without authentication", async () => { @@ -177,7 +177,7 @@ describe("ConnectionsController", () => { beforeEach(() => { [getUserByNameMock, getPartialUserMock, createUserMock].forEach((it) => - it.mockClear() + it.mockClear(), ); }); @@ -220,12 +220,12 @@ describe("ConnectionsController", () => { expect(getUserByNameMock).toHaveBeenCalledWith( "Kevin", - "create connection" + "create connection", ); expect(getPartialUserMock).toHaveBeenCalledWith( uid, "create connection", - ["uid", "name"] + ["uid", "name"], ); expect(createUserMock).toHaveBeenCalledWith(me, myFriend, 100); }); @@ -282,7 +282,7 @@ describe("ConnectionsController", () => { mockApp .post("/connections") .send({ receiverName: "1" }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); @@ -310,7 +310,7 @@ describe("ConnectionsController", () => { }); it("should fail if connections endpoints are disabled", async () => { await expectFailForDisabledEndpoint( - mockApp.delete("/connections/1").set("Authorization", `Bearer ${uid}`) + mockApp.delete("/connections/1").set("Authorization", `Bearer ${uid}`), ); }); @@ -368,7 +368,7 @@ describe("ConnectionsController", () => { mockApp .patch("/connections/1") .send({ status: "accepted" }) - .set("Authorization", `Bearer ${uid}`) + .set("Authorization", `Bearer ${uid}`), ); }); @@ -386,7 +386,7 @@ async function enableConnectionsEndpoints(enabled: boolean): Promise { mockConfig.connections = { ...mockConfig.connections, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/dev.spec.ts b/backend/__tests__/api/controllers/dev.spec.ts index ec6bf84d78f7..2ca26f93bb29 100644 --- a/backend/__tests__/api/controllers/dev.spec.ts +++ b/backend/__tests__/api/controllers/dev.spec.ts @@ -23,7 +23,7 @@ describe("DevController", () => { .expect(503); //THEN expect(body.message).toEqual( - "Development endpoints are only available in DEV mode." + "Development endpoints are only available in DEV mode.", ); }); it("should fail without mandatory properties", async () => { diff --git a/backend/__tests__/api/controllers/leaderboard.spec.ts b/backend/__tests__/api/controllers/leaderboard.spec.ts index 3c1477cb59b1..ea22fe70a113 100644 --- a/backend/__tests__/api/controllers/leaderboard.spec.ts +++ b/backend/__tests__/api/controllers/leaderboard.spec.ts @@ -95,14 +95,14 @@ describe("Loaderboard Controller", () => { 0, 50, false, - undefined + undefined, ); expect(getLeaderboardCountMock).toHaveBeenCalledWith( "time", "60", "english", - undefined + undefined, ); }); @@ -143,7 +143,7 @@ describe("Loaderboard Controller", () => { page, pageSize, false, - undefined + undefined, ); }); @@ -176,13 +176,13 @@ describe("Loaderboard Controller", () => { 0, 50, false, - uid + uid, ); expect(getLeaderboardCountMock).toHaveBeenCalledWith( "time", "60", "english", - uid + uid, ); }); @@ -205,7 +205,7 @@ describe("Loaderboard Controller", () => { .get("/leaderboards") .query({ language, mode, mode2 }) .expect(expectStatus); - } + }, ); }); @@ -275,7 +275,7 @@ describe("Loaderboard Controller", () => { .expect(503); expect(body.message).toEqual( - "Leaderboard is currently updating. Please try again in a few seconds." + "Leaderboard is currently updating. Please try again in a few seconds.", ); }); }); @@ -329,7 +329,7 @@ describe("Loaderboard Controller", () => { "60", "english", uid, - false + false, ); }); it("should get for english time 60 friends only", async () => { @@ -355,7 +355,7 @@ describe("Loaderboard Controller", () => { "60", "english", uid, - true + true, ); }); it("should get with ape key", async () => { @@ -458,7 +458,7 @@ describe("Loaderboard Controller", () => { .expect(503); expect(body.message).toEqual( - "Leaderboard is currently updating. Please try again in a few seconds." + "Leaderboard is currently updating. Please try again in a few seconds.", ); }); }); @@ -466,14 +466,14 @@ describe("Loaderboard Controller", () => { describe("get daily leaderboard", () => { const getDailyLeaderboardMock = vi.spyOn( DailyLeaderboards, - "getDailyLeaderboard" + "getDailyLeaderboard", ); const getFriendsUidsMock = vi.spyOn(ConnectionsDal, "getFriendsUids"); const getResultMock = vi.fn(); beforeEach(async () => { [getDailyLeaderboardMock, getFriendsUidsMock, getResultMock].forEach( - (it) => it.mockClear() + (it) => it.mockClear(), ); vi.useFakeTimers(); vi.setSystemTime(1722606812000); @@ -551,7 +551,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - -1 + -1, ); expect(getResultMock).toHaveBeenCalledWith( @@ -559,7 +559,7 @@ describe("Loaderboard Controller", () => { 50, lbConf, premiumEnabled, - undefined + undefined, ); }); @@ -594,7 +594,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - 1722470400000 + 1722470400000, ); }); it("should get for english time 60 with page and pageSize", async () => { @@ -634,7 +634,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - -1 + -1, ); expect(getResultMock).toHaveBeenCalledWith( @@ -642,7 +642,7 @@ describe("Loaderboard Controller", () => { pageSize, lbConf, premiumEnabled, - undefined + undefined, ); }); @@ -676,7 +676,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - -1 + -1, ); expect(getResultMock).toHaveBeenCalledWith( @@ -684,7 +684,7 @@ describe("Loaderboard Controller", () => { 50, lbConf, premiumEnabled, - friends + friends, ); }); @@ -711,7 +711,7 @@ describe("Loaderboard Controller", () => { const { body } = await mockApp.get("/leaderboards/daily").expect(503); expect(body.message).toEqual( - "Daily leaderboards are not available at this time." + "Daily leaderboards are not available at this time.", ); }); @@ -797,7 +797,7 @@ describe("Loaderboard Controller", () => { .expect(404); expect(body.message).toEqual( - "There is no daily leaderboard for this mode" + "There is no daily leaderboard for this mode", ); }); }); @@ -805,14 +805,14 @@ describe("Loaderboard Controller", () => { describe("get daily leaderboard rank", () => { const getDailyLeaderboardMock = vi.spyOn( DailyLeaderboards, - "getDailyLeaderboard" + "getDailyLeaderboard", ); const getRankMock = vi.fn(); const getFriendsUidsMock = vi.spyOn(ConnectionsDal, "getFriendsUids"); beforeEach(async () => { [getDailyLeaderboardMock, getRankMock, getFriendsUidsMock].forEach((it) => - it.mockClear() + it.mockClear(), ); getDailyLeaderboardMock.mockReturnValue({ @@ -874,7 +874,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - -1 + -1, ); expect(getRankMock).toHaveBeenCalledWith(uid, lbConf, undefined); @@ -907,7 +907,7 @@ describe("Loaderboard Controller", () => { "time", "60", lbConf, - -1 + -1, ); expect(getRankMock).toHaveBeenCalledWith(uid, lbConf, friends); @@ -923,7 +923,7 @@ describe("Loaderboard Controller", () => { .expect(503); expect(body.message).toEqual( - "Daily leaderboards are not available at this time." + "Daily leaderboards are not available at this time.", ); }); @@ -1019,7 +1019,7 @@ describe("Loaderboard Controller", () => { .expect(404); expect(body.message).toEqual( - "There is no daily leaderboard for this mode" + "There is no daily leaderboard for this mode", ); }); }); @@ -1031,7 +1031,7 @@ describe("Loaderboard Controller", () => { beforeEach(async () => { [getXpWeeklyLeaderboardMock, getResultMock, getFriendsUidsMock].forEach( - (it) => it.mockClear() + (it) => it.mockClear(), ); vi.useFakeTimers(); vi.setSystemTime(1722606812000); @@ -1100,7 +1100,7 @@ describe("Loaderboard Controller", () => { 50, lbConf, false, - undefined + undefined, ); }); @@ -1128,7 +1128,7 @@ describe("Loaderboard Controller", () => { expect(getXpWeeklyLeaderboardMock).toHaveBeenCalledWith( lbConf, - 1721606400000 + 1721606400000, ); }); @@ -1164,7 +1164,7 @@ describe("Loaderboard Controller", () => { pageSize, lbConf, false, - undefined + undefined, ); }); @@ -1200,7 +1200,7 @@ describe("Loaderboard Controller", () => { pageSize, lbConf, false, - friends + friends, ); }); @@ -1210,7 +1210,7 @@ describe("Loaderboard Controller", () => { const { body } = await mockApp.get("/leaderboards/xp/weekly").expect(503); expect(body.message).toEqual( - "Weekly XP leaderboards are not available at this time." + "Weekly XP leaderboards are not available at this time.", ); }); @@ -1260,7 +1260,7 @@ describe("Loaderboard Controller", () => { beforeEach(async () => { [getXpWeeklyLeaderboardMock, getRankMock, getFriendsUidsMock].forEach( - (it) => it.mockClear() + (it) => it.mockClear(), ); await weeklyLeaderboardEnabled(true); @@ -1330,7 +1330,7 @@ describe("Loaderboard Controller", () => { expect(getXpWeeklyLeaderboardMock).toHaveBeenCalledWith( lbConf, - 1721606400000 + 1721606400000, ); expect(getRankMock).toHaveBeenCalledWith(uid, lbConf, undefined); @@ -1371,7 +1371,7 @@ describe("Loaderboard Controller", () => { .expect(503); expect(body.message).toEqual( - "Weekly XP leaderboards are not available at this time." + "Weekly XP leaderboards are not available at this time.", ); }); @@ -1425,7 +1425,7 @@ async function acceptApeKeys(enabled: boolean): Promise { mockConfig.apeKeys = { ...mockConfig.apeKeys, acceptKeys: enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -1437,7 +1437,7 @@ async function dailyLeaderboardEnabled(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } async function weeklyLeaderboardEnabled(enabled: boolean): Promise { @@ -1448,7 +1448,7 @@ async function weeklyLeaderboardEnabled(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } async function enableConnectionsFeature(enabled: boolean): Promise { @@ -1456,6 +1456,6 @@ async function enableConnectionsFeature(enabled: boolean): Promise { mockConfig.connections = { ...mockConfig.connections, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/public.spec.ts b/backend/__tests__/api/controllers/public.spec.ts index bbe556fc99fe..c3501ec99872 100644 --- a/backend/__tests__/api/controllers/public.spec.ts +++ b/backend/__tests__/api/controllers/public.spec.ts @@ -31,7 +31,7 @@ describe("PublicController", () => { expect(getSpeedHistogramMock).toHaveBeenCalledWith( "english", "time", - "60" + "60", ); }); diff --git a/backend/__tests__/api/controllers/quotes.spec.ts b/backend/__tests__/api/controllers/quotes.spec.ts index 1f9d6c0ebff0..4275d2299672 100644 --- a/backend/__tests__/api/controllers/quotes.spec.ts +++ b/backend/__tests__/api/controllers/quotes.spec.ts @@ -192,7 +192,7 @@ describe("QuotesController", () => { newQuote.text, newQuote.source, newQuote.language, - uid + uid, ); expect(verifyCaptchaMock).toHaveBeenCalledWith(newQuote.captcha); @@ -212,7 +212,7 @@ describe("QuotesController", () => { //THEN expect(body.message).toEqual( - "Quote submission is disabled temporarily. The queue is quite long and we need some time to catch up." + "Quote submission is disabled temporarily. The queue is quite long and we need some time to catch up.", ); }); it("should fail without mandatory properties", async () => { @@ -315,7 +315,7 @@ describe("QuotesController", () => { quoteId, "editedText", "editedSource", - "Bob" + "Bob", ); }); it("should approve with optional parameters as null", async () => { @@ -343,7 +343,7 @@ describe("QuotesController", () => { quoteId, undefined, undefined, - "Bob" + "Bob", ); }); it("should approve without optional parameters", async () => { @@ -371,7 +371,7 @@ describe("QuotesController", () => { quoteId, undefined, undefined, - "Bob" + "Bob", ); }); it("should fail without mandatory properties", async () => { @@ -794,7 +794,7 @@ describe("QuotesController", () => { comment: "I don't like this.", }), 10, //configuration maxReport - 20 //configuration contentReportLimit + 20, //configuration contentReportLimit ); }); @@ -877,7 +877,7 @@ async function enableQuotes(enabled: boolean): Promise { mockConfig.quotes = { ...mockConfig.quotes, submissionsEnabled: enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -891,6 +891,6 @@ async function enableQuoteReporting(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/result.spec.ts b/backend/__tests__/api/controllers/result.spec.ts index 2a2a493d15cc..e5fee5001c8a 100644 --- a/backend/__tests__/api/controllers/result.spec.ts +++ b/backend/__tests__/api/controllers/result.spec.ts @@ -126,7 +126,7 @@ describe("result controller test", () => { expect(body.message).toEqual( `Max results limit of ${ (await configuration).results.limits.regularUser - } exceeded.` + } exceeded.`, ); }); it("should get with higher max limit for premium user", async () => { @@ -199,7 +199,7 @@ describe("result controller test", () => { expect(body.message).toEqual( `Max results limit of ${ (await configuration).results.limits.premiumUser - } exceeded.` + } exceeded.`, ); }); it("should get results within regular limits for premium users even if premium is globally disabled", async () => { @@ -274,7 +274,7 @@ describe("result controller test", () => { }); it("should be rate limited", async () => { await expect( - mockApp.get("/results").set("Authorization", `Bearer ${uid}`) + mockApp.get("/results").set("Authorization", `Bearer ${uid}`), ).toBeRateLimited({ max: 60, windowMs: 60 * 60 * 1000 }); }); it("should be rate limited for ape keys", async () => { @@ -284,7 +284,7 @@ describe("result controller test", () => { //WHEN await expect( - mockApp.get("/results").set("Authorization", `ApeKey ${apeKey}`) + mockApp.get("/results").set("Authorization", `ApeKey ${apeKey}`), ).toBeRateLimited({ max: 30, windowMs: 24 * 60 * 60 * 1000 }); }); }); @@ -340,7 +340,7 @@ describe("result controller test", () => { await expect( mockApp .get(`/results/id/${result._id}`) - .set("Authorization", `ApeKey ${apeKey}`) + .set("Authorization", `ApeKey ${apeKey}`), ).toBeRateLimited({ max: 60, windowMs: 60 * 60 * 1000 }); }); }); @@ -394,7 +394,7 @@ describe("result controller test", () => { //WHEN await expect( - mockApp.get("/results/last").set("Authorization", `ApeKey ${apeKey}`) + mockApp.get("/results/last").set("Authorization", `ApeKey ${apeKey}`), ).toBeRateLimited({ max: 30, windowMs: 60 * 1000 }); //should use defaultApeRateLimit }); }); @@ -672,18 +672,18 @@ describe("result controller test", () => { testDuration: 15.1, uid: uid, wpm: 80, - }) + }), ); expect(publicUpdateStatsMock).toHaveBeenCalledWith( 4, - 15.1 + 2 - 5 //duration + incompleteTestSeconds-afk + 15.1 + 2 - 5, //duration + incompleteTestSeconds-afk ); expect(userIncrementXpMock).toHaveBeenCalledWith(uid, 0); expect(userUpdateTypingStatsMock).toHaveBeenCalledWith( uid, 4, - 15.1 + 2 - 5 //duration + incompleteTestSeconds-afk + 15.1 + 2 - 5, //duration + incompleteTestSeconds-afk ); }); it("should fail if result saving is disabled", async () => { @@ -826,7 +826,7 @@ async function enablePremiumFeatures(enabled: boolean): Promise { mockConfig.users.premium = { ...mockConfig.users.premium, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } function givenDbResult(uid: string, customize?: Partial): DBResult { @@ -869,7 +869,7 @@ async function acceptApeKeys(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -878,7 +878,7 @@ async function enableResultsSaving(enabled: boolean): Promise { mockConfig.results = { ...mockConfig.results, savingEnabled: enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } async function enableUsersXpGain(enabled: boolean): Promise { @@ -886,6 +886,6 @@ async function enableUsersXpGain(enabled: boolean): Promise { mockConfig.users.xp = { ...mockConfig.users.xp, enabled, funboxBonus: 1 }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/user.spec.ts b/backend/__tests__/api/controllers/user.spec.ts index e2f8eb9639d7..374a2b509357 100644 --- a/backend/__tests__/api/controllers/user.spec.ts +++ b/backend/__tests__/api/controllers/user.spec.ts @@ -330,11 +330,11 @@ describe("user controller test", () => { expect(getPartialUserMock).toHaveBeenCalledWith( uid, "request verification email", - ["uid", "name", "email"] + ["uid", "name", "email"], ); expect(adminGenerateVerificationLinkMock).toHaveBeenCalledWith( "newuser@mail.com", - { url: "http://localhost:3000" } + { url: "http://localhost:3000" }, ); }); it("should fail with missing firebase user", async () => { @@ -349,7 +349,7 @@ describe("user controller test", () => { //THEN expect(body.message).toContain( - "Auth user not found, even though the token got decoded" + "Auth user not found, even though the token got decoded", ); }); it("should fail with already verified email", async () => { @@ -379,7 +379,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Authenticated email does not match the email found in the database. This might happen if you recently changed your email. Please refresh and try again." + "Authenticated email does not match the email found in the database. This might happen if you recently changed your email. Please refresh and try again.", ); }); @@ -427,7 +427,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( "Auth user not found when the user was found in the database. Contact support with this error message and your email\n" + - 'Stack: {"decodedTokenEmail":"newuser@mail.com","userInfoEmail":"newuser@mail.com"}' + 'Stack: {"decodedTokenEmail":"newuser@mail.com","userInfoEmail":"newuser@mail.com"}', ); }); it("should fail with unknown error", async () => { @@ -446,14 +446,14 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Failed to generate an email verification link: Internal server error" + "Failed to generate an email verification link: Internal server error", ); }); }); describe("sendForgotPasswordEmail", () => { const sendForgotPasswordEmailMock = vi.spyOn( AuthUtils, - "sendForgotPasswordEmail" + "sendForgotPasswordEmail", ); const verifyCaptchaMock = vi.spyOn(Captcha, "verify"); @@ -478,7 +478,7 @@ describe("user controller test", () => { }); expect(sendForgotPasswordEmailMock).toHaveBeenCalledWith( - "bob@example.com" + "bob@example.com", ); }); it("should fail without mandatory properties", async () => { @@ -627,11 +627,11 @@ describe("user controller test", () => { const deleteAllResultMock = vi.spyOn(ResultDal, "deleteAll"); const purgeUserFromDailyLeaderboardsMock = vi.spyOn( DailyLeaderboards, - "purgeUserFromDailyLeaderboards" + "purgeUserFromDailyLeaderboards", ); const purgeUserFromXpLeaderboardsMock = vi.spyOn( WeeklyXpLeaderboard, - "purgeUserFromXpLeaderboards" + "purgeUserFromXpLeaderboards", ); const blocklistAddMock = vi.spyOn(BlocklistDal, "add"); const connectionsDeletebyUidMock = vi.spyOn(ConnectionsDal, "deleteByUid"); @@ -700,11 +700,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(logsDeleteUserMock).toHaveBeenCalledWith(uid); }); @@ -736,11 +736,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(logsDeleteUserMock).toHaveBeenCalledWith(uid); }); @@ -767,11 +767,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(logsDeleteUserMock).toHaveBeenCalledWith(uid); }); @@ -797,11 +797,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).not.toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).not.toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).not.toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(logsDeleteUserMock).not.toHaveBeenCalled(); }); @@ -838,11 +838,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(logsDeleteUserMock).toHaveBeenCalledWith(uid); }); @@ -879,11 +879,11 @@ describe("user controller test", () => { expect(connectionsDeletebyUidMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).dailyLeaderboards + (await configuration).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); }); }); @@ -896,11 +896,11 @@ describe("user controller test", () => { const deleteConfigMock = vi.spyOn(ConfigDal, "deleteConfig"); const purgeUserFromDailyLeaderboardsMock = vi.spyOn( DailyLeaderboards, - "purgeUserFromDailyLeaderboards" + "purgeUserFromDailyLeaderboards", ); const purgeUserFromXpLeaderboardsMock = vi.spyOn( WeeklyXpLeaderboard, - "purgeUserFromXpLeaderboards" + "purgeUserFromXpLeaderboards", ); const unlinkDiscordMock = vi.spyOn(GeorgeQueue, "unlinkDiscord"); @@ -951,11 +951,11 @@ describe("user controller test", () => { } expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await Configuration.getLiveConfiguration()).dailyLeaderboards + (await Configuration.getLiveConfiguration()).dailyLeaderboards, ); expect(purgeUserFromXpLeaderboardsMock).toHaveBeenCalledWith( uid, - (await configuration).leaderboards.weeklyXp + (await configuration).leaderboards.weeklyXp, ); expect(unlinkDiscordMock).not.toHaveBeenCalled(); /*TODO @@ -1035,7 +1035,7 @@ describe("user controller test", () => { expect(addImportantLogMock).toHaveBeenCalledWith( "user_name_updated", "changed name from Bob to newName", - uid + uid, ); expect(connectionsUpdateNameMock).toHaveBeenCalledWith(uid, "newName"); }); @@ -1087,7 +1087,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "You can change your name once every 30 days" + "You can change your name once every 30 days", ); expect(updateNameMock).not.toHaveBeenCalled(); }); @@ -1161,7 +1161,7 @@ describe("user controller test", () => { const clearPbMock = vi.spyOn(UserDal, "clearPb"); const purgeUserFromDailyLeaderboardsMock = vi.spyOn( DailyLeaderboards, - "purgeUserFromDailyLeaderboards" + "purgeUserFromDailyLeaderboards", ); const addImportantLogMock = vi.spyOn(LogDal, "addImportantLog"); @@ -1190,12 +1190,12 @@ describe("user controller test", () => { expect(clearPbMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await Configuration.getLiveConfiguration()).dailyLeaderboards + (await Configuration.getLiveConfiguration()).dailyLeaderboards, ); expect(addImportantLogMock).toHaveBeenCalledWith( "user_cleared_pbs", "", - uid + uid, ); }); }); @@ -1203,7 +1203,7 @@ describe("user controller test", () => { const optOutOfLeaderboardsMock = vi.spyOn(UserDal, "optOutOfLeaderboards"); const purgeUserFromDailyLeaderboardsMock = vi.spyOn( DailyLeaderboards, - "purgeUserFromDailyLeaderboards" + "purgeUserFromDailyLeaderboards", ); const addImportantLogMock = vi.spyOn(LogDal, "addImportantLog"); @@ -1232,12 +1232,12 @@ describe("user controller test", () => { expect(optOutOfLeaderboardsMock).toHaveBeenCalledWith(uid); expect(purgeUserFromDailyLeaderboardsMock).toHaveBeenCalledWith( uid, - (await Configuration.getLiveConfiguration()).dailyLeaderboards + (await Configuration.getLiveConfiguration()).dailyLeaderboards, ); expect(addImportantLogMock).toHaveBeenCalledWith( "user_opted_out_of_leaderboards", "", - uid + uid, ); }); // it("should fail with unknown properties", async () => { @@ -1260,7 +1260,7 @@ describe("user controller test", () => { beforeEach(() => { [authUpdateEmailMock, userUpdateEmailMock, addImportantLogMock].forEach( - (it) => it.mockClear().mockResolvedValue(null as never) + (it) => it.mockClear().mockResolvedValue(null as never), ); }); it("should update users email", async () => { @@ -1282,16 +1282,16 @@ describe("user controller test", () => { expect(authUpdateEmailMock).toHaveBeenCalledWith( uid, - newEmail.toLowerCase() + newEmail.toLowerCase(), ); expect(userUpdateEmailMock).toHaveBeenCalledWith( uid, - newEmail.toLowerCase() + newEmail.toLowerCase(), ); expect(addImportantLogMock).toHaveBeenCalledWith( "user_email_updated", "changed email from previousemail@example.com to newemail@example.com", - uid + uid, ); }); it("should fail for duplicate email", async () => { @@ -1318,7 +1318,7 @@ describe("user controller test", () => { .expect(409); expect(body.message).toEqual( - "The email address is already in use by another account" + "The email address is already in use by another account", ); expect(userUpdateEmailMock).not.toHaveBeenCalled(); @@ -1402,7 +1402,7 @@ describe("user controller test", () => { .expect(404); expect(body.message).toEqual( - "User not found in the auth system\nStack: update email" + "User not found in the auth system\nStack: update email", ); expect(userUpdateEmailMock).not.toHaveBeenCalled(); @@ -1576,7 +1576,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Discord integration is not available at this time" + "Discord integration is not available at this time", ); }); }); @@ -1585,7 +1585,7 @@ describe("user controller test", () => { const isDiscordIdAvailableMock = vi.spyOn(UserDal, "isDiscordIdAvailable"); const isStateValidForUserMock = vi.spyOn( DiscordUtils, - "iStateValidForUser" + "iStateValidForUser", ); const getDiscordUserMock = vi.spyOn(DiscordUtils, "getDiscordUser"); const blocklistContainsMock = vi.spyOn(BlocklistDal, "contains"); @@ -1643,16 +1643,16 @@ describe("user controller test", () => { }); expect(isStateValidForUserMock).toHaveBeenCalledWith( "statestatestatestate", - uid + uid, ); expect(getUserMock).toHaveBeenCalledWith( uid, "link discord", - expect.any(Array) + expect.any(Array), ); expect(getDiscordUserMock).toHaveBeenCalledWith( "tokenType", - "accessToken" + "accessToken", ); expect(isDiscordIdAvailableMock).toHaveBeenCalledWith("discordUserId"); expect(blocklistContainsMock).toHaveBeenCalledWith({ @@ -1661,17 +1661,17 @@ describe("user controller test", () => { expect(userLinkDiscordMock).toHaveBeenCalledWith( uid, "discordUserId", - "discordUserAvatar" + "discordUserAvatar", ); expect(georgeLinkDiscordMock).toHaveBeenCalledWith( "discordUserId", uid, - false + false, ); expect(addImportantLogMock).toHaveBeenCalledWith( "user_discord_link", "linked to discordUserId", - uid + uid, ); }); @@ -1701,7 +1701,7 @@ describe("user controller test", () => { expect(userLinkDiscordMock).toHaveBeenCalledWith( uid, "existingDiscordId", - "discordUserAvatar" + "discordUserAvatar", ); expect(isDiscordIdAvailableMock).not.toHaveBeenCalled(); expect(blocklistContainsMock).not.toHaveBeenCalled(); @@ -1761,7 +1761,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Could not get Discord account info\nStack: discord id is undefined" + "Could not get Discord account info\nStack: discord id is undefined", ); //THEN @@ -1784,7 +1784,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "This Discord account is linked to a different account" + "This Discord account is linked to a different account", ); //THEN @@ -1893,7 +1893,7 @@ describe("user controller test", () => { expect(addImportantLogMock).toHaveBeenCalledWith( "user_discord_unlinked", "discordId", - uid + uid, ); }); it("should fail for banned user", async () => { @@ -1925,7 +1925,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "User does not have a linked Discord account" + "User does not have a linked Discord account", ); expect(userUnlinkDiscordMock).not.toHaveBeenCalled(); expect(georgeUnlinkDiscordMock).not.toHaveBeenCalled(); @@ -1993,7 +1993,7 @@ describe("user controller test", () => { const addResultFilterPresetMock = vi.spyOn( UserDal, - "addResultFilterPreset" + "addResultFilterPreset", ); beforeEach(async () => { @@ -2020,7 +2020,7 @@ describe("user controller test", () => { uid, validPreset, (await Configuration.getLiveConfiguration()).results.filterPresets - .maxPresetsPerUser + .maxPresetsPerUser, ); }); it("should fail without mandatory properties", async () => { @@ -2077,14 +2077,14 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Result filter presets are not available at this time." + "Result filter presets are not available at this time.", ); }); }); describe("remove result filter preset", () => { const removeResultFilterPresetMock = vi.spyOn( UserDal, - "removeResultFilterPreset" + "removeResultFilterPreset", ); beforeEach(() => { @@ -2118,7 +2118,7 @@ describe("user controller test", () => { //THEN expect(body.message).toEqual( - "Result filter presets are not available at this time." + "Result filter presets are not available at this time.", ); }); }); @@ -2365,7 +2365,7 @@ describe("user controller test", () => { "time", "60", "english", - 7 + 7, ); }); @@ -2830,7 +2830,7 @@ describe("user controller test", () => { uid, "english", "7", - (await Configuration.getLiveConfiguration()).quotes.maxFavorites + (await Configuration.getLiveConfiguration()).quotes.maxFavorites, ); }); it("should fail without mandatory properties", async () => { @@ -3053,7 +3053,7 @@ describe("user controller test", () => { expect.objectContaining({ lastDay: 1712102400000, testsByDays: expect.arrayContaining([]), - }) + }), ); }); it("should not get testActivity if disabled", async () => { @@ -3220,7 +3220,7 @@ describe("user controller test", () => { }, { badges: [{ id: 4 }, { id: 2, selected: true }, { id: 3 }], - } + }, ); }); it("should update with empty strings", async () => { @@ -3264,7 +3264,7 @@ describe("user controller test", () => { }, { badges: [{ id: 4 }, { id: 2 }, { id: 3 }], - } + }, ); }); it("should fail with unknown properties", async () => { @@ -3308,7 +3308,7 @@ describe("user controller test", () => { keyboard: "string with many spaces", socialProfiles: {}, }, - expect.objectContaining({}) + expect.objectContaining({}), ); }); it("should fail with profanity", async () => { @@ -3492,7 +3492,7 @@ describe("user controller test", () => { expect(updateInboxMock).toHaveBeenCalledWith( uid, [mailIdOne, mailIdTwo], - [mailIdOne] + [mailIdOne], ); }); it("should update without body", async () => { @@ -3593,7 +3593,7 @@ describe("user controller test", () => { (await Configuration.getLiveConfiguration()).quotes.reporting .maxReports, (await Configuration.getLiveConfiguration()).quotes.reporting - .contentReportLimit + .contentReportLimit, ); expect(verifyCaptchaMock).toHaveBeenCalledWith("captcha"); }); @@ -3746,7 +3746,7 @@ describe("user controller test", () => { expect(addImportantLogMock).toHaveBeenCalledWith( "user_streak_hour_offset_set", { hourOffset: -2 }, - uid + uid, ); }); it("should fail if offset already set", async () => { @@ -3824,7 +3824,7 @@ describe("user controller test", () => { expect(addImportantLogMock).toHaveBeenCalledWith( "user_tokens_revoked", "", - uid + uid, ); }); }); @@ -3946,7 +3946,7 @@ describe("user controller test", () => { it("should fail if friends endpoints are disabled", async () => { await expectFailForDisabledEndpoint( - mockApp.get("/users/friends").set("Authorization", `Bearer ${uid}`) + mockApp.get("/users/friends").set("Authorization", `Bearer ${uid}`), ); }); @@ -3969,7 +3969,7 @@ async function enablePremiumFeatures(enabled: boolean): Promise { mockConfig.users.premium = { ...mockConfig.users.premium, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -3978,7 +3978,7 @@ async function enableSignup(signUp: boolean): Promise { mockConfig.users = { ...mockConfig.users, signUp }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -3990,7 +3990,7 @@ async function enableDiscordIntegration(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -4002,7 +4002,7 @@ async function enableResultFilterPresets(enabled: boolean): Promise { }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -4011,7 +4011,7 @@ async function acceptApeKeys(acceptKeys: boolean): Promise { mockConfig.apeKeys = { ...mockConfig.apeKeys, acceptKeys }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -4020,7 +4020,7 @@ async function enableProfiles(enabled: boolean): Promise { mockConfig.users.profiles = { ...mockConfig.users.profiles, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } async function enableInbox(enabled: boolean): Promise { @@ -4028,7 +4028,7 @@ async function enableInbox(enabled: boolean): Promise { mockConfig.users.inbox = { ...mockConfig.users.inbox, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -4037,7 +4037,7 @@ async function enableReporting(enabled: boolean): Promise { mockConfig.quotes.reporting = { ...mockConfig.quotes.reporting, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } @@ -4046,7 +4046,7 @@ async function enableConnectionsEndpoints(enabled: boolean): Promise { mockConfig.connections = { ...mockConfig.connections, enabled }; vi.spyOn(Configuration, "getCachedConfiguration").mockResolvedValue( - mockConfig + mockConfig, ); } diff --git a/backend/__tests__/api/controllers/webhooks.spec.ts b/backend/__tests__/api/controllers/webhooks.spec.ts index 72cdd41d2653..06bb055f9423 100644 --- a/backend/__tests__/api/controllers/webhooks.spec.ts +++ b/backend/__tests__/api/controllers/webhooks.spec.ts @@ -9,7 +9,7 @@ describe("WebhooksController", () => { describe("githubRelease", () => { const georgeSendReleaseAnnouncementMock = vi.spyOn( GeorgeQueue, - "sendReleaseAnnouncement" + "sendReleaseAnnouncement", ); const timingSafeEqualMock = vi.spyOn(crypto, "timingSafeEqual"); @@ -37,9 +37,9 @@ describe("WebhooksController", () => { expect(georgeSendReleaseAnnouncementMock).toHaveBeenCalledWith("1"); expect(timingSafeEqualMock).toHaveBeenCalledWith( Buffer.from( - "sha256=ff0f3080539e9df19153f6b5b5780f66e558d61038e6cf5ecf4efdc7266a7751" + "sha256=ff0f3080539e9df19153f6b5b5780f66e558d61038e6cf5ecf4efdc7266a7751", ), - Buffer.from("the-signature") + Buffer.from("the-signature"), ); }); it("should ignore non-published actions", async () => { diff --git a/backend/__tests__/middlewares/auth.spec.ts b/backend/__tests__/middlewares/auth.spec.ts index 12605b4d4ddb..fc679171af55 100644 --- a/backend/__tests__/middlewares/auth.spec.ts +++ b/backend/__tests__/middlewares/auth.spec.ts @@ -91,7 +91,7 @@ describe("middlewares/auth", () => { beforeEach(() => { timingSafeEqualMock.mockClear().mockReturnValue(true); [prometheusIncrementAuthMock, prometheusRecordAuthTimeMock].forEach( - (it) => it.mockClear() + (it) => it.mockClear(), ); }); @@ -100,18 +100,18 @@ describe("middlewares/auth", () => { Date.now = vi.fn(() => 60001); const expectedError = new MonkeyError( 401, - "Unauthorized\nStack: This endpoint requires a fresh token" + "Unauthorized\nStack: This endpoint requires a fresh token", ); //WHEN await expect(() => - authenticate({}, { requireFreshToken: true }) + authenticate({}, { requireFreshToken: true }), ).rejects.toMatchMonkeyError(expectedError); //THEN expect(nextFunction).toHaveBeenLastCalledWith( - expect.toMatchMonkeyError(expectedError) + expect.toMatchMonkeyError(expectedError), ); expect(prometheusIncrementAuthMock).not.toHaveBeenCalled(); expect(prometheusRecordAuthTimeMock).toHaveBeenCalledOnce(); @@ -137,7 +137,7 @@ describe("middlewares/auth", () => { //WHEN const result = await authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: true } + { acceptApeKeys: true }, ); //THEN @@ -152,8 +152,8 @@ describe("middlewares/auth", () => { await expect(() => authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: false } - ) + { acceptApeKeys: false }, + ), ).rejects.toThrowError("This endpoint does not accept ApeKeys"); //THEN @@ -168,8 +168,8 @@ describe("middlewares/auth", () => { await expect(() => authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: false } - ) + { acceptApeKeys: false }, + ), ).rejects.toThrowError("ApeKeys are not being accepted at this time"); //THEN @@ -203,7 +203,7 @@ describe("middlewares/auth", () => { //WHEN const result = await authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { isPublic: true } + { isPublic: true }, ); //THEN @@ -247,14 +247,14 @@ describe("middlewares/auth", () => { //WHEN / THEN await expect(() => - authenticate({ headers: { authorization: "Uid 123" } }) + authenticate({ headers: { authorization: "Uid 123" } }), ).rejects.toMatchMonkeyError( - new MonkeyError(401, "Baerer type uid is not supported") + new MonkeyError(401, "Baerer type uid is not supported"), ); }); it("should fail without authentication", async () => { await expect(() => authenticate({ headers: {} })).rejects.toThrowError( - "Unauthorized\nStack: endpoint: /api/v1 no authorization header found" + "Unauthorized\nStack: endpoint: /api/v1 no authorization header found", ); //THEH @@ -263,14 +263,14 @@ describe("middlewares/auth", () => { "None", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should fail with empty authentication", async () => { await expect(() => - authenticate({ headers: { authorization: "" } }) + authenticate({ headers: { authorization: "" } }), ).rejects.toThrowError( - "Unauthorized\nStack: endpoint: /api/v1 no authorization header found" + "Unauthorized\nStack: endpoint: /api/v1 no authorization header found", ); //THEH @@ -279,14 +279,14 @@ describe("middlewares/auth", () => { "", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should fail with missing authentication token", async () => { await expect(() => - authenticate({ headers: { authorization: "Bearer" } }) + authenticate({ headers: { authorization: "Bearer" } }), ).rejects.toThrowError( - "Missing authentication token\nStack: authenticateWithAuthHeader" + "Missing authentication token\nStack: authenticateWithAuthHeader", ); //THEH @@ -295,14 +295,14 @@ describe("middlewares/auth", () => { "Bearer", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should fail with unknown authentication scheme", async () => { await expect(() => - authenticate({ headers: { authorization: "unknown format" } }) + authenticate({ headers: { authorization: "unknown format" } }), ).rejects.toThrowError( - 'Unknown authentication scheme\nStack: The authentication scheme "unknown" is not implemented' + 'Unknown authentication scheme\nStack: The authentication scheme "unknown" is not implemented', ); //THEH @@ -311,24 +311,24 @@ describe("middlewares/auth", () => { "unknown", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should record country if provided", async () => { const prometheusRecordRequestCountryMock = vi.spyOn( Prometheus, - "recordRequestCountry" + "recordRequestCountry", ); await authenticate( { headers: { "cf-ipcountry": "gb" } }, - { isPublic: true } + { isPublic: true }, ); //THEN expect(prometheusRecordRequestCountryMock).toHaveBeenCalledWith( "gb", - expect.anything() + expect.anything(), ); }); it("should allow the request with authentation on dev public endpoint", async () => { @@ -346,7 +346,7 @@ describe("middlewares/auth", () => { //WHEN const result = await authenticate( { headers: {} }, - { isPublicOnDev: true } + { isPublicOnDev: true }, ); //THEN @@ -363,7 +363,7 @@ describe("middlewares/auth", () => { //WHEN const result = await authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: true, isPublicOnDev: true } + { acceptApeKeys: true, isPublicOnDev: true }, ); //THEN @@ -385,7 +385,7 @@ describe("middlewares/auth", () => { //WHEN const result = await authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: true, isPublicOnDev: true } + { acceptApeKeys: true, isPublicOnDev: true }, ); //THEN @@ -416,7 +416,7 @@ describe("middlewares/auth", () => { //THEN await expect(() => - authenticate({ headers: {} }, { isPublicOnDev: true }) + authenticate({ headers: {} }, { isPublicOnDev: true }), ).rejects.toThrowError("Unauthorized"); }); it("should allow with apeKey on dev public endpoint in production", async () => { @@ -424,7 +424,7 @@ describe("middlewares/auth", () => { isDevModeMock.mockReturnValue(false); const result = await authenticate( { headers: { authorization: "ApeKey aWQua2V5" } }, - { acceptApeKeys: true, isPublicOnDev: true } + { acceptApeKeys: true, isPublicOnDev: true }, ); //THEN @@ -445,7 +445,7 @@ describe("middlewares/auth", () => { headers: { "x-hub-signature-256": "the-signature" }, body: { action: "published", release: { id: 1 } }, }, - { isGithubWebhook: true } + { isGithubWebhook: true }, ); //THEN @@ -459,9 +459,9 @@ describe("middlewares/auth", () => { expect(prometheusRecordAuthTimeMock).toHaveBeenCalledOnce(); expect(timingSafeEqualMock).toHaveBeenCalledWith( Buffer.from( - "sha256=ff0f3080539e9df19153f6b5b5780f66e558d61038e6cf5ecf4efdc7266a7751" + "sha256=ff0f3080539e9df19153f6b5b5780f66e558d61038e6cf5ecf4efdc7266a7751", ), - Buffer.from("the-signature") + Buffer.from("the-signature"), ); }); it("should fail githubwebhook with mismatched signature", async () => { @@ -474,8 +474,8 @@ describe("middlewares/auth", () => { headers: { "x-hub-signature-256": "the-signature" }, body: { action: "published", release: { id: 1 } }, }, - { isGithubWebhook: true } - ) + { isGithubWebhook: true }, + ), ).rejects.toThrowError("Github webhook signature invalid"); //THEH @@ -484,7 +484,7 @@ describe("middlewares/auth", () => { "None", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should fail without header when endpoint is using githubwebhook", async () => { @@ -495,8 +495,8 @@ describe("middlewares/auth", () => { headers: {}, body: { action: "published", release: { id: 1 } }, }, - { isGithubWebhook: true } - ) + { isGithubWebhook: true }, + ), ).rejects.toThrowError("Missing Github signature header"); //THEH @@ -505,7 +505,7 @@ describe("middlewares/auth", () => { "None", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should fail with missing GITHUB_WEBHOOK_SECRET when endpoint is using githubwebhook", async () => { @@ -516,8 +516,8 @@ describe("middlewares/auth", () => { headers: { "x-hub-signature-256": "the-signature" }, body: { action: "published", release: { id: 1 } }, }, - { isGithubWebhook: true } - ) + { isGithubWebhook: true }, + ), ).rejects.toThrowError("Missing Github Webhook Secret"); //THEH @@ -526,7 +526,7 @@ describe("middlewares/auth", () => { "None", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); it("should throw 500 if something went wrong when validating the signature when endpoint is using githubwebhook", async () => { @@ -540,10 +540,10 @@ describe("middlewares/auth", () => { headers: { "x-hub-signature-256": "the-signature" }, body: { action: "published", release: { id: 1 } }, }, - { isGithubWebhook: true } - ) + { isGithubWebhook: true }, + ), ).rejects.toThrowError( - "Failed to authenticate Github webhook: could not validate" + "Failed to authenticate Github webhook: could not validate", ); //THEH @@ -552,7 +552,7 @@ describe("middlewares/auth", () => { "None", "failure", expect.anything(), - expect.anything() + expect.anything(), ); }); }); @@ -560,7 +560,7 @@ describe("middlewares/auth", () => { async function authenticate( request: Partial, - authenticationOptions?: RequestAuthenticationOptions + authenticationOptions?: RequestAuthenticationOptions, ): Promise<{ decodedToken: Auth.DecodedToken }> { const mergedRequest = { ...mockRequest, @@ -573,7 +573,7 @@ async function authenticate( await Auth.authenticateTsRestRequest()( mergedRequest, mockResponse as Response, - nextFunction + nextFunction, ); return { decodedToken: mergedRequest.ctx.decodedToken }; diff --git a/backend/__tests__/middlewares/configuration.spec.ts b/backend/__tests__/middlewares/configuration.spec.ts index e0ecc0350f30..0c8e7f01f361 100644 --- a/backend/__tests__/middlewares/configuration.spec.ts +++ b/backend/__tests__/middlewares/configuration.spec.ts @@ -45,7 +45,7 @@ describe("configuration middleware", () => { //GIVEN const req = givenRequest( { path: "users.xp.streak.enabled" }, - { users: { xp: { streak: { enabled: true } as any } as any } as any } + { users: { xp: { streak: { enabled: true } as any } as any } as any }, ); //WHEN @@ -64,15 +64,15 @@ describe("configuration middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(503, "This endpoint is currently unavailable.") - ) + new MonkeyError(503, "This endpoint is currently unavailable."), + ), ); }); it("should fail for disabled configuration and custom message", async () => { //GIVEN const req = givenRequest( { path: "maintenance", invalidMessage: "Feature not enabled." }, - { maintenance: false } + { maintenance: false }, ); //WHEN @@ -80,7 +80,7 @@ describe("configuration middleware", () => { //THEN expect(next).toHaveBeenCalledWith( - expect.toMatchMonkeyError(new MonkeyError(503, "Feature not enabled.")) + expect.toMatchMonkeyError(new MonkeyError(503, "Feature not enabled.")), ); }); it("should fail for invalid path", async () => { @@ -93,15 +93,15 @@ describe("configuration middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(500, 'Invalid configuration path: "invalid.path"') - ) + new MonkeyError(500, 'Invalid configuration path: "invalid.path"'), + ), ); }); it("should fail for undefined value", async () => { //GIVEN const req = givenRequest( { path: "admin.endpointsEnabled" }, - { admin: {} as any } + { admin: {} as any }, ); //WHEN @@ -112,16 +112,16 @@ describe("configuration middleware", () => { expect.toMatchMonkeyError( new MonkeyError( 500, - 'Required configuration doesnt exist: "admin.endpointsEnabled"' - ) - ) + 'Required configuration doesnt exist: "admin.endpointsEnabled"', + ), + ), ); }); it("should fail for null value", async () => { //GIVEN const req = givenRequest( { path: "admin.endpointsEnabled" }, - { admin: { endpointsEnabled: null as any } } + { admin: { endpointsEnabled: null as any } }, ); //WHEN @@ -132,16 +132,16 @@ describe("configuration middleware", () => { expect.toMatchMonkeyError( new MonkeyError( 500, - 'Required configuration doesnt exist: "admin.endpointsEnabled"' - ) - ) + 'Required configuration doesnt exist: "admin.endpointsEnabled"', + ), + ), ); }); it("should fail for non booean value", async () => { //GIVEN const req = givenRequest( { path: "admin.endpointsEnabled" }, - { admin: { endpointsEnabled: "disabled" as any } } + { admin: { endpointsEnabled: "disabled" as any } }, ); //WHEN @@ -152,16 +152,16 @@ describe("configuration middleware", () => { expect.toMatchMonkeyError( new MonkeyError( 500, - 'Required configuration is not a boolean: "admin.endpointsEnabled"' - ) - ) + 'Required configuration is not a boolean: "admin.endpointsEnabled"', + ), + ), ); }); it("should pass for multiple configurations", async () => { //GIVEN const req = givenRequest( [{ path: "maintenance" }, { path: "admin.endpointsEnabled" }], - { maintenance: true, admin: { endpointsEnabled: true } } + { maintenance: true, admin: { endpointsEnabled: true } }, ); //WHEN @@ -177,7 +177,7 @@ describe("configuration middleware", () => { { path: "maintenance", invalidMessage: "maintenance mode" }, { path: "admin.endpointsEnabled", invalidMessage: "admin disabled" }, ], - { maintenance: true, admin: { endpointsEnabled: false } } + { maintenance: true, admin: { endpointsEnabled: false } }, ); //WHEN @@ -185,14 +185,14 @@ describe("configuration middleware", () => { //THEN expect(next).toHaveBeenCalledWith( - expect.toMatchMonkeyError(new MonkeyError(503, "admin disabled")) + expect.toMatchMonkeyError(new MonkeyError(503, "admin disabled")), ); }); }); function givenRequest( requireConfiguration: RequireConfiguration | RequireConfiguration[], - configuration: Partial + configuration: Partial, ): TsRestRequest { return { tsRestRoute: { metadata: { requireConfiguration } }, diff --git a/backend/__tests__/middlewares/permission.spec.ts b/backend/__tests__/middlewares/permission.spec.ts index 7a8ba785d49c..78a17ce2432e 100644 --- a/backend/__tests__/middlewares/permission.spec.ts +++ b/backend/__tests__/middlewares/permission.spec.ts @@ -65,8 +65,8 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); }); it("should pass without authentication if publicOnDev on dev", async () => { @@ -77,7 +77,7 @@ describe("permission middleware", () => { ...requireAdminPermission, authenticationOptions: { isPublicOnDev: true }, }, - { uid } + { uid }, ); //WHEN await handler(req, res, next); @@ -92,7 +92,7 @@ describe("permission middleware", () => { ...requireAdminPermission, authenticationOptions: { isPublicOnDev: true }, }, - { uid } + { uid }, ); //WHEN await handler(req, res, next); @@ -100,8 +100,8 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); }); it("should fail without admin permissions", async () => { @@ -114,8 +114,8 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); expect(isAdminMock).toHaveBeenCalledWith(uid); }); @@ -127,7 +127,7 @@ describe("permission middleware", () => { { requirePermission: ["canReport", "canManageApeKeys"], }, - { uid } + { uid }, ); //WHEN @@ -138,7 +138,7 @@ describe("permission middleware", () => { expect(getPartialUserMock).toHaveBeenCalledWith( uid, "check user permissions", - ["canReport", "canManageApeKeys"] + ["canReport", "canManageApeKeys"], ); }); it("should fail if authentication is missing", async () => { @@ -155,9 +155,9 @@ describe("permission middleware", () => { expect.toMatchMonkeyError( new MonkeyError( 403, - "Failed to check permissions, authentication required." - ) - ) + "Failed to check permissions, authentication required.", + ), + ), ); }); }); @@ -179,7 +179,7 @@ describe("permission middleware", () => { expect(getPartialUserMock).toHaveBeenCalledWith( uid, "check user permissions", - ["quoteMod"] + ["quoteMod"], ); }); it("should pass for specific language", async () => { @@ -195,7 +195,7 @@ describe("permission middleware", () => { expect(getPartialUserMock).toHaveBeenCalledWith( uid, "check user permissions", - ["quoteMod"] + ["quoteMod"], ); }); it("should fail for empty string", async () => { @@ -209,8 +209,8 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); }); it("should fail for missing quoteMod", async () => { @@ -224,8 +224,8 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); }); }); @@ -245,13 +245,13 @@ describe("permission middleware", () => { //THEN expect(next).toHaveBeenCalledWith( expect.toMatchMonkeyError( - new MonkeyError(403, "You don't have permission to do this.") - ) + new MonkeyError(403, "You don't have permission to do this."), + ), ); expect(getPartialUserMock).toHaveBeenCalledWith( uid, "check user permissions", - ["canReport"] + ["canReport"], ); }); it("should pass if user can report", async () => { @@ -295,14 +295,14 @@ describe("permission middleware", () => { expect.toMatchMonkeyError( new MonkeyError( 403, - "You have lost access to ape keys, please contact support" - ) - ) + "You have lost access to ape keys, please contact support", + ), + ), ); expect(getPartialUserMock).toHaveBeenCalledWith( uid, "check user permissions", - ["canManageApeKeys"] + ["canManageApeKeys"], ); }); it("should pass if user can report", async () => { @@ -332,7 +332,7 @@ describe("permission middleware", () => { function givenRequest( metadata: EndpointMetadata, - decodedToken?: Partial + decodedToken?: Partial, ): TsRestRequest { return { tsRestRoute: { metadata }, ctx: { decodedToken } } as any; } diff --git a/backend/__tests__/setup-common-mocks.ts b/backend/__tests__/setup-common-mocks.ts index dc9c54614a2d..9ae3a1d64a12 100644 --- a/backend/__tests__/setup-common-mocks.ts +++ b/backend/__tests__/setup-common-mocks.ts @@ -28,7 +28,7 @@ export function setupCommonMocks() { auth: (): unknown => ({ verifyIdToken: ( _token: string, - _checkRevoked: boolean + _checkRevoked: boolean, ): unknown /* Promise */ => Promise.resolve({ aud: "mockFirebaseProjectId", diff --git a/backend/__tests__/utils/misc.spec.ts b/backend/__tests__/utils/misc.spec.ts index 976402d0318f..89707c7f6404 100644 --- a/backend/__tests__/utils/misc.spec.ts +++ b/backend/__tests__/utils/misc.spec.ts @@ -37,10 +37,10 @@ describe("Misc Utils", () => { ({ pattern, cases, expected }) => { cases.forEach((caseValue, index) => { expect(Misc.matchesAPattern(caseValue, pattern)).toBe( - expected[index] + expected[index], ); }); - } + }, ); }); @@ -90,7 +90,7 @@ describe("Misc Utils", () => { "kogascore with wpm:$wpm, acc:$acc, timestamp:$timestamp = $expectedScore", ({ wpm, acc, timestamp, expectedScore }) => { expect(Misc.kogascore(wpm, acc, timestamp)).toBe(expectedScore); - } + }, ); }); @@ -121,7 +121,7 @@ describe("Misc Utils", () => { "identity with $input = $expected", ({ input, expected }) => { expect(Misc.identity(input)).toBe(expected); - } + }, ); }); @@ -193,7 +193,7 @@ describe("Misc Utils", () => { "flattenObjectDeep with $obj = $expected", ({ obj, expected }) => { expect(Misc.flattenObjectDeep(obj)).toEqual(expected); - } + }, ); }); @@ -386,7 +386,7 @@ describe("Misc Utils", () => { number: 2, }; expect( - Misc.replaceObjectIds([fromDatabase, fromDatabase2]) + Misc.replaceObjectIds([fromDatabase, fromDatabase2]), ).toStrictEqual([ { _id: fromDatabase._id.toHexString(), diff --git a/backend/__tests__/utils/pb.spec.ts b/backend/__tests__/utils/pb.spec.ts index b8400368d465..762c922ea9c4 100644 --- a/backend/__tests__/utils/pb.spec.ts +++ b/backend/__tests__/utils/pb.spec.ts @@ -35,7 +35,7 @@ describe("Pb Utils", () => { ({ funbox, expected }) => { const result = pb.canFunboxGetPb({ funbox } as any); expect(result).toBe(expected); - } + }, ); }); @@ -65,7 +65,7 @@ describe("Pb Utils", () => { const run = pb.checkAndUpdatePb( userPbs, {} as pb.LbPersonalBests, - result + result, ); expect(run.isPb).toBe(true); @@ -117,7 +117,7 @@ describe("Pb Utils", () => { expect.arrayContaining([ expect.objectContaining({ numbers: false, wpm: 100 }), expect.objectContaining({ numbers: true, wpm: 110 }), - ]) + ]), ); }); }); @@ -174,7 +174,7 @@ describe("Pb Utils", () => { const lbPbPb = pb.updateLeaderboardPersonalBests( userPbs, structuredClone(lbPb) as pb.LbPersonalBests, - result15 + result15, ); expect(lbPbPb).toEqual({ diff --git a/backend/__tests__/utils/result.spec.ts b/backend/__tests__/utils/result.spec.ts index 0328512e44d8..6ce6fd3530df 100644 --- a/backend/__tests__/utils/result.spec.ts +++ b/backend/__tests__/utils/result.spec.ts @@ -37,7 +37,7 @@ describe("Result Utils", () => { expect(result.charStats).toEqual(expectedCharStats); expect(result.correctChars).toBeUndefined(); expect(result.incorrectChars).toBeUndefined(); - } + }, ); it("should prioritise charStats when legacy data exists", () => { @@ -86,7 +86,7 @@ describe("Result Utils", () => { expect(result.charStats).toBe(expectedCharStats); expect(result.correctChars).toBe(expectedCorrectChars); expect(result.incorrectChars).toBe(expectedIncorrectChars); - } + }, ); }); diff --git a/backend/__tests__/utils/validation.spec.ts b/backend/__tests__/utils/validation.spec.ts index 116a004e50cc..1cac52222525 100644 --- a/backend/__tests__/utils/validation.spec.ts +++ b/backend/__tests__/utils/validation.spec.ts @@ -48,7 +48,7 @@ describe("Validation", () => { testCases.forEach((testCase) => { expect(Validation.isTestTooShort(testCase.result as any)).toBe( - testCase.expected + testCase.expected, ); }); }); diff --git a/backend/private/index.html b/backend/private/index.html index c4b9ef1cac16..4f68543fe9a2 100644 --- a/backend/private/index.html +++ b/backend/private/index.html @@ -1,4 +1,4 @@ - + diff --git a/backend/private/script.js b/backend/private/script.js index f794bbeef8ee..debc85db5c54 100644 --- a/backend/private/script.js +++ b/backend/private/script.js @@ -141,7 +141,7 @@ const render = (state, schema) => { state, parentState, currentKey = "", - path = "configuration" + path = "configuration", ) => { const parent = document.createElement("div"); parent.classList.add("form-element"); @@ -166,7 +166,7 @@ const render = (state, schema) => { state[key], state, key, - `${path}.${key}` + `${path}.${key}`, ); parent.appendChild(childElement); }); @@ -181,13 +181,13 @@ const render = (state, schema) => { element, state, index, - `${path}[${index}]` + `${path}[${index}]`, ); const decoratedChildElement = arrayFormElementDecorator( childElement, state, - index + index, ); parent.appendChild(decoratedChildElement); }); @@ -287,7 +287,7 @@ window.onload = async () => { exportButton.addEventListener("click", async () => { download( "backend-configuration.json", - JSON.stringify({ configuration: state }) + JSON.stringify({ configuration: state }), ); }); }; @@ -296,7 +296,7 @@ function download(filename, text) { let element = document.createElement("a"); element.setAttribute( "href", - "data:text/plain;charset=utf-8," + encodeURIComponent(text) + "data:text/plain;charset=utf-8," + encodeURIComponent(text), ); element.setAttribute("download", filename); diff --git a/backend/scripts/openapi.ts b/backend/scripts/openapi.ts index 53eaf52eb42c..611db9a1fe4c 100644 --- a/backend/scripts/openapi.ts +++ b/backend/scripts/openapi.ts @@ -162,14 +162,14 @@ export function getOpenApi(): OpenAPIObject { addTags(operation, metadata); return operation; }, - } + }, ); return openApiDocument; } function addAuth( operation: OperationObject, - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): void { const auth = metadata?.authenticationOptions ?? {}; const permissions = getRequiredPermissions(metadata) ?? []; @@ -188,13 +188,13 @@ function addAuth( if (permissions.length !== 0) { operation.description += `**Required permissions:** ${permissions.join( - ", " + ", ", )}\n\n`; } } function getRequiredPermissions( - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): PermissionId[] | undefined { if (metadata === undefined || metadata.requirePermission === undefined) return undefined; @@ -206,7 +206,7 @@ function getRequiredPermissions( function addTags( operation: OperationObject, - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): void { if (metadata === undefined || metadata.openApiTags === undefined) return; operation.tags = Array.isArray(metadata.openApiTags) @@ -216,7 +216,7 @@ function addTags( function addRateLimit( operation: OperationObject, - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): void { if (metadata === undefined || metadata.rateLimit === undefined) return; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment @@ -252,7 +252,7 @@ function getRateLimitDescription(limit: RateLimiterId | RateLimitIds): string { if (limits.apeKeyLimiter !== undefined) { result += ` and up to ${limits.apeKeyLimiter.max} times ${formatWindow( - limits.apeKeyLimiter.window + limits.apeKeyLimiter.window, )} with ApeKeys`; } @@ -275,7 +275,7 @@ function formatWindow(window: Window): string { function addRequiredConfiguration( operation: OperationObject, - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): void { if (metadata === undefined || metadata.requireConfiguration === undefined) return; diff --git a/backend/src/anticheat/index.ts b/backend/src/anticheat/index.ts index 5249ebaa9ce2..96ffb699c2fd 100644 --- a/backend/src/anticheat/index.ts +++ b/backend/src/anticheat/index.ts @@ -14,7 +14,7 @@ export function validateResult( _result: object, _version: string, _uaStringifiedObject: string, - _lbOptOut: boolean + _lbOptOut: boolean, ): boolean { Logger.warning("No anticheat module found, result will not be validated."); return true; @@ -24,7 +24,7 @@ export function validateKeys( _result: CompletedEvent, _keySpacingStats: KeyStats, _keyDurationStats: KeyStats, - _uid: string + _uid: string, ): boolean { Logger.warning("No anticheat module found, key data will not be validated."); return true; diff --git a/backend/src/api/controllers/admin.ts b/backend/src/api/controllers/admin.ts index 02df86c98d50..2840472de572 100644 --- a/backend/src/api/controllers/admin.ts +++ b/backend/src/api/controllers/admin.ts @@ -22,7 +22,7 @@ export async function test(_req: MonkeyRequest): Promise { } export async function toggleBan( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.body; @@ -44,7 +44,7 @@ export async function toggleBan( } export async function clearStreakHourOffset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.body; @@ -55,23 +55,23 @@ export async function clearStreakHourOffset( } export async function acceptReports( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { await handleReports( req.body.reports.map((it) => ({ ...it })), true, - req.ctx.configuration.users.inbox + req.ctx.configuration.users.inbox, ); return new MonkeyResponse("Reports removed and users notified.", null); } export async function rejectReports( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { await handleReports( req.body.reports.map((it) => ({ ...it })), false, - req.ctx.configuration.users.inbox + req.ctx.configuration.users.inbox, ); return new MonkeyResponse("Reports removed and users notified.", null); } @@ -79,7 +79,7 @@ export async function rejectReports( export async function handleReports( reports: { reportId: string; reason?: string }[], accept: boolean, - inboxConfig: Configuration["users"]["inbox"] + inboxConfig: Configuration["users"]["inbox"], ): Promise { const reportIds = reports.map(({ reportId }) => reportId); @@ -88,13 +88,13 @@ export async function handleReports( const existingReportIds = new Set(reportsFromDb.map((report) => report.id)); const missingReportIds = reportIds.filter( - (reportId) => !existingReportIds.has(reportId) + (reportId) => !existingReportIds.has(reportId), ); if (missingReportIds.length > 0) { throw new MonkeyError( 404, - `Reports not found for some IDs ${missingReportIds.join(",")}` + `Reports not found for some IDs ${missingReportIds.join(",")}`, ); } @@ -132,7 +132,7 @@ export async function handleReports( } else { throw new MonkeyError( 500, - "Error handling reports: " + getErrorMessage(e) + "Error handling reports: " + getErrorMessage(e), ); } } @@ -140,7 +140,7 @@ export async function handleReports( } export async function sendForgotPasswordEmail( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { email } = req.body; await authSendForgotPasswordEmail(email); diff --git a/backend/src/api/controllers/ape-key.ts b/backend/src/api/controllers/ape-key.ts index d687f207ac86..a9946ad234c5 100644 --- a/backend/src/api/controllers/ape-key.ts +++ b/backend/src/api/controllers/ape-key.ts @@ -21,20 +21,20 @@ function cleanApeKey(apeKey: ApeKeysDAL.DBApeKey): ApeKey { } export async function getApeKeys( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const apeKeys = await ApeKeysDAL.getApeKeys(uid); const cleanedKeys: Record = Object.fromEntries( - apeKeys.map((item) => [item._id.toHexString(), cleanApeKey(item)]) + apeKeys.map((item) => [item._id.toHexString(), cleanApeKey(item)]), ); return new MonkeyResponse("ApeKeys retrieved", cleanedKeys); } export async function generateApeKey( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { name, enabled } = req.body; const { uid } = req.ctx.decodedToken; @@ -72,7 +72,7 @@ export async function generateApeKey( } export async function editApeKey( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { apeKeyId } = req.params; const { name, enabled } = req.body; @@ -84,7 +84,7 @@ export async function editApeKey( } export async function deleteApeKey( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { apeKeyId } = req.params; const { uid } = req.ctx.decodedToken; diff --git a/backend/src/api/controllers/config.ts b/backend/src/api/controllers/config.ts index 36f6695d4735..aa85cf48e846 100644 --- a/backend/src/api/controllers/config.ts +++ b/backend/src/api/controllers/config.ts @@ -5,7 +5,7 @@ import { GetConfigResponse } from "@monkeytype/contracts/configs"; import { MonkeyRequest } from "../types"; export async function getConfig( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const data = (await ConfigDAL.getConfig(uid))?.config ?? null; @@ -14,7 +14,7 @@ export async function getConfig( } export async function saveConfig( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const config = req.body; const { uid } = req.ctx.decodedToken; @@ -25,7 +25,7 @@ export async function saveConfig( } export async function deleteConfig( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; diff --git a/backend/src/api/controllers/configuration.ts b/backend/src/api/controllers/configuration.ts index 46978d5978c6..9a1dbd528017 100644 --- a/backend/src/api/controllers/configuration.ts +++ b/backend/src/api/controllers/configuration.ts @@ -10,23 +10,23 @@ import MonkeyError from "../../utils/error"; import { MonkeyRequest } from "../types"; export async function getConfiguration( - _req: MonkeyRequest + _req: MonkeyRequest, ): Promise { const currentConfiguration = await Configuration.getLiveConfiguration(); return new MonkeyResponse("Configuration retrieved", currentConfiguration); } export async function getSchema( - _req: MonkeyRequest + _req: MonkeyRequest, ): Promise { return new MonkeyResponse( "Configuration schema retrieved", - CONFIGURATION_FORM_SCHEMA + CONFIGURATION_FORM_SCHEMA, ); } export async function updateConfiguration( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { configuration } = req.body; const success = await Configuration.patchConfiguration(configuration); diff --git a/backend/src/api/controllers/connections.ts b/backend/src/api/controllers/connections.ts index d9ee5ed0fc72..69474061ce96 100644 --- a/backend/src/api/controllers/connections.ts +++ b/backend/src/api/controllers/connections.ts @@ -19,7 +19,7 @@ function convert(db: ConnectionsDal.DBConnection): Connection { return replaceObjectId(omit(db, ["key"])); } export async function getConnections( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { status, type } = req.query; @@ -36,7 +36,7 @@ export async function getConnections( } export async function createConnection( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { receiverName } = req.body; @@ -44,7 +44,7 @@ export async function createConnection( const receiver = await UserDal.getUserByName( receiverName, - "create connection" + "create connection", ); if (uid === receiver.uid) { @@ -62,7 +62,7 @@ export async function createConnection( } export async function deleteConnection( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { id } = req.params; @@ -73,7 +73,7 @@ export async function deleteConnection( } export async function updateConnection( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { id } = req.params; diff --git a/backend/src/api/controllers/dev.ts b/backend/src/api/controllers/dev.ts index 543089ef943e..225cd671bbc2 100644 --- a/backend/src/api/controllers/dev.ts +++ b/backend/src/api/controllers/dev.ts @@ -28,7 +28,7 @@ const CREATE_RESULT_DEFAULT_OPTIONS = { }; export async function createTestData( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { username, createUser } = req.body; const user = await getOrCreateUser(username, "password", createUser); @@ -45,7 +45,7 @@ export async function createTestData( async function getOrCreateUser( username: string, password: string, - createUser = false + createUser = false, ): Promise { const existingUser = await UserDal.findByName(username); @@ -70,7 +70,7 @@ async function getOrCreateUser( async function createTestResults( user: UserDal.DBUser, - configOptions: GenerateDataRequest + configOptions: GenerateDataRequest, ): Promise { const config = { ...CREATE_RESULT_DEFAULT_OPTIONS, @@ -90,11 +90,11 @@ async function createTestResults( for (const day of days) { Logger.success( `User ${user.name} insert ${day.amount} results on ${new Date( - day.timestamp - )}` + day.timestamp, + )}`, ); const results = createArray(day.amount, () => - createResult(user, day.timestamp) + createResult(user, day.timestamp), ); if (results.length > 0) await ResultDal.getResultCollection().insertMany(results); @@ -111,7 +111,7 @@ function random(min: number, max: number): number { function createResult( user: UserDal.DBUser, - timestamp: Date //evil, we modify this value + timestamp: Date, //evil, we modify this value ): DBResult { const mode: Mode = randomValue(["time", "words"]); const mode2: number = @@ -183,7 +183,7 @@ async function updateUser(uid: string): Promise { const timeTyping = stats.reduce((a, c) => (a + c["timeTyping"]) as number, 0); const completedTests = stats.reduce( (a, c) => (a + c["completedTests"]) as number, - 0 + 0, ); //update PBs @@ -207,7 +207,7 @@ async function updateUser(uid: string): Promise { language: Language; mode: "time" | "custom" | "words" | "quote" | "zen"; mode2: `${number}` | "custom" | "zen"; - } + }, ); for (const mode of modes) { @@ -218,7 +218,7 @@ async function updateUser(uid: string): Promise { mode: mode.mode, mode2: mode.mode2, }, - { sort: { wpm: -1, timestamp: 1 } } + { sort: { wpm: -1, timestamp: 1 } }, )) as DBResult; if (personalBests[mode.mode] === undefined) personalBests[mode.mode] = {}; @@ -263,7 +263,7 @@ async function updateUser(uid: string): Promise { personalBests: personalBests, lbPersonalBests: lbPersonalBests, }, - } + }, ); } @@ -391,7 +391,7 @@ async function updateTestActicity(uid: string): Promise { }, }, ], - { allowDiskUse: true } + { allowDiskUse: true }, ) .toArray(); } diff --git a/backend/src/api/controllers/leaderboard.ts b/backend/src/api/controllers/leaderboard.ts index 0e1fe7e414fa..1b9f7134734a 100644 --- a/backend/src/api/controllers/leaderboard.ts +++ b/backend/src/api/controllers/leaderboard.ts @@ -29,7 +29,7 @@ import { MonkeyRequest } from "../types"; import { omit } from "../../utils/misc"; export async function getLeaderboard( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { language, mode, mode2, page, pageSize, friendsOnly } = req.query; const { uid } = req.ctx.decodedToken; @@ -52,13 +52,13 @@ export async function getLeaderboard( page, pageSize, req.ctx.configuration.users.premium.enabled, - friendsOnlyUid + friendsOnlyUid, ); if (leaderboard === false) { throw new MonkeyError( 503, - "Leaderboard is currently updating. Please try again in a few seconds." + "Leaderboard is currently updating. Please try again in a few seconds.", ); } @@ -66,7 +66,7 @@ export async function getLeaderboard( mode, mode2, language, - friendsOnlyUid + friendsOnlyUid, ); const normalizedLeaderboard = leaderboard.map((it) => omit(it, ["_id"])); @@ -78,7 +78,7 @@ export async function getLeaderboard( } export async function getRankFromLeaderboard( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { language, mode, mode2, friendsOnly } = req.query; const { uid } = req.ctx.decodedToken; @@ -89,24 +89,24 @@ export async function getRankFromLeaderboard( mode2, language, uid, - getFriendsOnlyUid(uid, friendsOnly, connectionsConfig) !== undefined + getFriendsOnlyUid(uid, friendsOnly, connectionsConfig) !== undefined, ); if (data === false) { throw new MonkeyError( 503, - "Leaderboard is currently updating. Please try again in a few seconds." + "Leaderboard is currently updating. Please try again in a few seconds.", ); } return new MonkeyResponse( "Rank retrieved", - omit(data as LeaderboardsDAL.DBLeaderboardEntry, ["_id"]) + omit(data as LeaderboardsDAL.DBLeaderboardEntry, ["_id"]), ); } function getDailyLeaderboardWithError( { language, mode, mode2, daysBefore }: DailyLeaderboardQuery, - config: Configuration["dailyLeaderboards"] + config: Configuration["dailyLeaderboards"], ): DailyLeaderboards.DailyLeaderboard { const customTimestamp = daysBefore === undefined @@ -118,7 +118,7 @@ function getDailyLeaderboardWithError( mode, mode2, config, - customTimestamp + customTimestamp, ); if (!dailyLeaderboard) { throw new MonkeyError(404, "There is no daily leaderboard for this mode"); @@ -128,7 +128,7 @@ function getDailyLeaderboardWithError( } export async function getDailyLeaderboard( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { page, pageSize, friendsOnly } = req.query; const { uid } = req.ctx.decodedToken; @@ -137,12 +137,12 @@ export async function getDailyLeaderboard( const friendUids = await getFriendsUids( uid, friendsOnly === true, - connectionsConfig + connectionsConfig, ); const dailyLeaderboard = getDailyLeaderboardWithError( req.query, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ); const results = await dailyLeaderboard.getResults( @@ -150,7 +150,7 @@ export async function getDailyLeaderboard( pageSize, req.ctx.configuration.dailyLeaderboards, req.ctx.configuration.users.premium.enabled, - friendUids + friendUids, ); return new MonkeyResponse("Daily leaderboard retrieved", { @@ -162,7 +162,7 @@ export async function getDailyLeaderboard( } export async function getDailyLeaderboardRank( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { friendsOnly } = req.query; const { uid } = req.ctx.decodedToken; @@ -171,18 +171,18 @@ export async function getDailyLeaderboardRank( const friendUids = await getFriendsUids( uid, friendsOnly === true, - connectionsConfig + connectionsConfig, ); const dailyLeaderboard = getDailyLeaderboardWithError( req.query, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ); const rank = await dailyLeaderboard.getRank( uid, req.ctx.configuration.dailyLeaderboards, - friendUids + friendUids, ); return new MonkeyResponse("Daily leaderboard rank retrieved", rank); @@ -190,7 +190,7 @@ export async function getDailyLeaderboardRank( function getWeeklyXpLeaderboardWithError( config: Configuration["leaderboards"]["weeklyXp"], - weeksBefore?: number + weeksBefore?: number, ): WeeklyXpLeaderboard.WeeklyXpLeaderboard { const customTimestamp = weeksBefore === undefined @@ -206,7 +206,7 @@ function getWeeklyXpLeaderboardWithError( } export async function getWeeklyXpLeaderboard( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { page, pageSize, weeksBefore, friendsOnly } = req.query; @@ -216,19 +216,19 @@ export async function getWeeklyXpLeaderboard( const friendUids = await getFriendsUids( uid, friendsOnly === true, - connectionsConfig + connectionsConfig, ); const weeklyXpLeaderboard = getWeeklyXpLeaderboardWithError( req.ctx.configuration.leaderboards.weeklyXp, - weeksBefore + weeksBefore, ); const results = await weeklyXpLeaderboard.getResults( page, pageSize, req.ctx.configuration.leaderboards.weeklyXp, req.ctx.configuration.users.premium.enabled, - friendUids + friendUids, ); return new MonkeyResponse("Weekly xp leaderboard retrieved", { @@ -239,7 +239,7 @@ export async function getWeeklyXpLeaderboard( } export async function getWeeklyXpLeaderboardRank( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { friendsOnly } = req.query; const { uid } = req.ctx.decodedToken; @@ -248,17 +248,17 @@ export async function getWeeklyXpLeaderboardRank( const friendUids = await getFriendsUids( uid, friendsOnly === true, - connectionsConfig + connectionsConfig, ); const weeklyXpLeaderboard = getWeeklyXpLeaderboardWithError( req.ctx.configuration.leaderboards.weeklyXp, - req.query.weeksBefore + req.query.weeksBefore, ); const rankEntry = await weeklyXpLeaderboard.getRank( uid, req.ctx.configuration.leaderboards.weeklyXp, - friendUids + friendUids, ); return new MonkeyResponse("Weekly xp leaderboard rank retrieved", rankEntry); @@ -267,7 +267,7 @@ export async function getWeeklyXpLeaderboardRank( async function getFriendsUids( uid: string, friendsOnly: boolean, - friendsConfig: Configuration["connections"] + friendsConfig: Configuration["connections"], ): Promise { if (uid !== "" && friendsOnly) { if (!friendsConfig.enabled) { @@ -281,7 +281,7 @@ async function getFriendsUids( function getFriendsOnlyUid( uid: string, friendsOnly: boolean | undefined, - friendsConfig: Configuration["connections"] + friendsConfig: Configuration["connections"], ): string | undefined { if (uid !== "" && friendsOnly === true) { if (!friendsConfig.enabled) { diff --git a/backend/src/api/controllers/preset.ts b/backend/src/api/controllers/preset.ts index a811d2f87a71..a01520b555e8 100644 --- a/backend/src/api/controllers/preset.ts +++ b/backend/src/api/controllers/preset.ts @@ -11,7 +11,7 @@ import { EditPresetRequest } from "@monkeytype/schemas/presets"; import { MonkeyRequest } from "../types"; export async function getPresets( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -26,7 +26,7 @@ export async function getPresets( } export async function addPreset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -36,7 +36,7 @@ export async function addPreset( } export async function editPreset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -46,7 +46,7 @@ export async function editPreset( } export async function removePreset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { presetId } = req.params; const { uid } = req.ctx.decodedToken; diff --git a/backend/src/api/controllers/public.ts b/backend/src/api/controllers/public.ts index 093cffb6dcbb..bbf7c171374d 100644 --- a/backend/src/api/controllers/public.ts +++ b/backend/src/api/controllers/public.ts @@ -8,7 +8,7 @@ import { MonkeyResponse } from "../../utils/monkey-response"; import { MonkeyRequest } from "../types"; export async function getSpeedHistogram( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { language, mode, mode2 } = req.query; const data = await PublicDAL.getSpeedHistogram(language, mode, mode2); @@ -16,7 +16,7 @@ export async function getSpeedHistogram( } export async function getTypingStats( - _req: MonkeyRequest + _req: MonkeyRequest, ): Promise { const data = await PublicDAL.getTypingStats(); return new MonkeyResponse("Public typing stats retrieved", data); diff --git a/backend/src/api/controllers/quote.ts b/backend/src/api/controllers/quote.ts index eeba776b60f6..24b858ae9f16 100644 --- a/backend/src/api/controllers/quote.ts +++ b/backend/src/api/controllers/quote.ts @@ -31,7 +31,7 @@ async function verifyCaptcha(captcha: string): Promise { } export async function getQuotes( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const quoteMod = (await getPartialUser(uid, "get quotes", ["quoteMod"])) @@ -41,22 +41,22 @@ export async function getQuotes( const data = await NewQuotesDAL.get(quoteModLanguage); return new MonkeyResponse( "Quote submissions retrieved", - replaceObjectIds(data) + replaceObjectIds(data), ); } export async function isSubmissionEnabled( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { submissionsEnabled } = req.ctx.configuration.quotes; return new MonkeyResponse( "Quote submission " + (submissionsEnabled ? "enabled" : "disabled"), - { isEnabled: submissionsEnabled } + { isEnabled: submissionsEnabled }, ); } export async function addQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { text, source, language, captcha } = req.body; @@ -68,7 +68,7 @@ export async function addQuote( } export async function approveQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { quoteId, editText, editSource } = req.body; @@ -86,7 +86,7 @@ export async function approveQuote( } export async function refuseQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { quoteId } = req.body; @@ -95,7 +95,7 @@ export async function refuseQuote( } export async function getRating( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { quoteId, language } = req.query; @@ -105,7 +105,7 @@ export async function getRating( } export async function submitRating( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { quoteId, rating, language } = req.body; @@ -122,7 +122,7 @@ export async function submitRating( quoteId, language, newRating, - shouldUpdateRating + shouldUpdateRating, ); if (!userQuoteRatings[language]) { @@ -139,7 +139,7 @@ export async function submitRating( } export async function reportQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { diff --git a/backend/src/api/controllers/result.ts b/backend/src/api/controllers/result.ts index 05cc53536749..a6efd233386e 100644 --- a/backend/src/api/controllers/result.ts +++ b/backend/src/api/controllers/result.ts @@ -71,18 +71,18 @@ try { } catch (e) { if (isDevEnvironment()) { Logger.warning( - "No anticheat module found. Continuing in dev mode, results will not be validated." + "No anticheat module found. Continuing in dev mode, results will not be validated.", ); } else { Logger.error( - "No anticheat module found. To continue in dev mode, add MODE=dev to your .env file in the backend directory" + "No anticheat module found. To continue in dev mode, add MODE=dev to your .env file in the backend directory", ); process.exit(1); } } export async function getResults( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const premiumFeaturesEnabled = req.ctx.configuration.users.premium.enabled; @@ -129,14 +129,14 @@ export async function getResults( onOrAfterTimestamp, isPremium: userHasPremium, }, - uid + uid, ); return new MonkeyResponse("Results retrieved", replaceObjectIds(results)); } export async function getResultById( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { resultId } = req.params; @@ -146,7 +146,7 @@ export async function getResultById( } export async function getLastResult( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const result = await ResultDAL.getLastResult(uid); @@ -162,7 +162,7 @@ export async function deleteAll(req: MonkeyRequest): Promise { } export async function updateTags( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tagIds, resultId } = req.body; @@ -197,7 +197,7 @@ export async function updateTags( } export async function addResult( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -206,7 +206,7 @@ export async function addResult( if (user.needsToChangeName) { throw new MonkeyError( 403, - "Please change your name before submitting a result" + "Please change your name before submitting a result", ); } @@ -234,7 +234,7 @@ export async function addResult( resulthash, result: completedEvent, }, - uid + uid, ); const status = MonkeyStatusCodes.RESULT_HASH_INVALID; throw new MonkeyError(status.code, "Incorrect result hash"); @@ -259,7 +259,7 @@ export async function addResult( keySpacingStats = { average: completedEvent.keySpacing.reduce( - (previous, current) => (current += previous) + (previous, current) => (current += previous), ) / completedEvent.keySpacing.length, sd: stdDev(completedEvent.keySpacing), }; @@ -273,7 +273,7 @@ export async function addResult( keyDurationStats = { average: completedEvent.keyDuration.reduce( - (previous, current) => (current += previous) + (previous, current) => (current += previous), ) / completedEvent.keyDuration.length, sd: stdDev(completedEvent.keyDuration), }; @@ -299,7 +299,7 @@ export async function addResult( ((req.raw.headers["x-client-version"] as string) || req.raw.headers["client-version"]) as string, JSON.stringify(new UAParser(req.raw.headers["user-agent"]).getResult()), - user.lbOptOut === true + user.lbOptOut === true, ) ) { const status = MonkeyStatusCodes.RESULT_DATA_INVALID; @@ -312,7 +312,7 @@ export async function addResult( throw new Error("No anticheat module found"); } Logger.warning( - "No anticheat module found. Continuing in dev mode, results will not be validated." + "No anticheat module found. Continuing in dev mode, results will not be validated.", ); } @@ -329,7 +329,7 @@ export async function addResult( // return res.status(400).json({ message: "Time traveler detected" }); const { data: lastResultTimestamp } = await tryCatch( - ResultDAL.getLastResultTimestamp(uid) + ResultDAL.getLastResultTimestamp(uid), ); //convert result test duration to miliseconds @@ -354,7 +354,7 @@ export async function addResult( testDuration: testDurationMilis, difference: nowNoMilis - earliestPossible, }, - uid + uid, ); const status = MonkeyStatusCodes.RESULT_SPACING_INVALID; throw new MonkeyError(status.code, "Invalid result spacing"); @@ -385,7 +385,7 @@ export async function addResult( const didUserGetBanned = await UserDAL.recordAutoBanEvent( uid, autoBanConfig.maxCount, - autoBanConfig.maxHours + autoBanConfig.maxHours, ); if (didUserGetBanned) { const mail = buildMonkeyMail({ @@ -395,7 +395,7 @@ export async function addResult( await UserDAL.addToInbox( uid, [mail], - req.ctx.configuration.users.inbox + req.ctx.configuration.users.inbox, ); user.banned = true; } @@ -408,7 +408,7 @@ export async function addResult( throw new Error("No anticheat module found"); } Logger.warning( - "No anticheat module found. Continuing in dev mode, results will not be validated." + "No anticheat module found. Continuing in dev mode, results will not be validated.", ); } } @@ -423,7 +423,7 @@ export async function addResult( resulthash, result: completedEvent, }, - uid + uid, ); const status = MonkeyStatusCodes.DUPLICATE_RESULT; throw new MonkeyError(status.code, "Duplicate result"); @@ -486,11 +486,11 @@ export async function addResult( void UserDAL.updateTypingStats( uid, completedEvent.restartCount, - totalDurationTypedSeconds + totalDurationTypedSeconds, ); void PublicDAL.updateStats( completedEvent.restartCount, - totalDurationTypedSeconds + totalDurationTypedSeconds, ); const dailyLeaderboardsConfig = req.ctx.configuration.dailyLeaderboards; @@ -498,7 +498,7 @@ export async function addResult( completedEvent.language, completedEvent.mode, completedEvent.mode2, - dailyLeaderboardsConfig + dailyLeaderboardsConfig, ); let dailyLeaderboardRank = -1; @@ -528,7 +528,7 @@ export async function addResult( incrementDailyLeaderboard( completedEvent.mode, completedEvent.mode2, - completedEvent.language + completedEvent.language, ); dailyLeaderboardRank = await dailyLeaderboard.addResult( { @@ -544,7 +544,7 @@ export async function addResult( badgeId: selectedBadgeId, isPremium, }, - dailyLeaderboardsConfig + dailyLeaderboardsConfig, ); if ( dailyLeaderboardRank >= 1 && @@ -563,7 +563,7 @@ export async function addResult( const streak = await UserDAL.updateStreak(uid, completedEvent.timestamp); const badgeWaitingInInbox = ( user.inbox?.flatMap((i) => - (i.rewards ?? []).map((r) => (r.type === "badge" ? r.item.id : null)) + (i.rewards ?? []).map((r) => (r.type === "badge" ? r.item.id : null)), ) ?? [] ).includes(14); @@ -593,7 +593,7 @@ export async function addResult( req.ctx.configuration.users.xp, lastResultTimestamp, user.xp ?? 0, - streak + streak, ); if (xpGained.xp < 0) { @@ -604,7 +604,7 @@ export async function addResult( xpGained, result: completedEvent, }), - uid + uid, ); } @@ -612,7 +612,7 @@ export async function addResult( let weeklyXpLeaderboardRank = -1; const weeklyXpLeaderboard = WeeklyXpLeaderboard.get( - weeklyXpLeaderboardConfig + weeklyXpLeaderboardConfig, ); if (userEligibleForLeaderboard && xpGained.xp > 0 && weeklyXpLeaderboard) { weeklyXpLeaderboardRank = await weeklyXpLeaderboard.addResult( @@ -629,7 +629,7 @@ export async function addResult( timeTypedSeconds: totalDurationTypedSeconds, }, xpGained: xpGained.xp, - } + }, ); } @@ -654,7 +654,7 @@ export async function addResult( } ${completedEvent.acc}% ${completedEvent.rawWpm} ${ completedEvent.consistency }% (${addedResult.insertedId})`, - uid + uid, ); } @@ -692,7 +692,7 @@ async function calculateXp( xpConfiguration: Configuration["users"]["xp"], lastResultTimestamp: number | null, currentTotalXp: number, - streak: number + streak: number, ): Promise { const { mode, @@ -778,8 +778,8 @@ async function calculateXp( xpConfiguration.streak.maxStreakDays, 0, xpConfiguration.streak.maxStreakMultiplier, - true - ).toFixed(1) + true, + ).toFixed(1), ); if (streakModifier > 0) { @@ -811,7 +811,7 @@ async function calculateXp( const proportionalXp = Math.round(currentTotalXp * 0.05); dailyBonus = Math.max( Math.min(maxDailyBonus, proportionalXp), - minDailyBonus + minDailyBonus, ); breakdown.daily = dailyBonus; } diff --git a/backend/src/api/controllers/user.ts b/backend/src/api/controllers/user.ts index bba8a68d441a..6620abf08547 100644 --- a/backend/src/api/controllers/user.ts +++ b/backend/src/api/controllers/user.ts @@ -99,7 +99,7 @@ async function verifyCaptcha(captcha: string): Promise { if (error) { throw new MonkeyError( 422, - "Request to the Captcha API failed, please try again later" + "Request to the Captcha API failed, please try again later", ); } if (!verified) { @@ -108,7 +108,7 @@ async function verifyCaptcha(captcha: string): Promise { } export async function createNewUser( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { name, captcha } = req.body; const { email, uid } = req.ctx.decodedToken; @@ -142,7 +142,7 @@ export async function createNewUser( } export async function sendVerificationEmail( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { email, uid } = req.ctx.decodedToken; const isVerified = ( @@ -158,7 +158,7 @@ export async function sendVerificationEmail( email, stack: e instanceof Error ? e.stack : JSON.stringify(e), }), - uid + uid, ); }) ).emailVerified; @@ -169,20 +169,20 @@ export async function sendVerificationEmail( const userInfo = await UserDAL.getPartialUser( uid, "request verification email", - ["uid", "name", "email"] + ["uid", "name", "email"], ); if (userInfo.email !== email) { throw new MonkeyError( 400, - "Authenticated email does not match the email found in the database. This might happen if you recently changed your email. Please refresh and try again." + "Authenticated email does not match the email found in the database. This might happen if you recently changed your email. Please refresh and try again.", ); } const { data: link, error } = await tryCatch( FirebaseAdmin() .auth() - .generateEmailVerificationLink(email, { url: getFrontendUrl() }) + .generateEmailVerificationLink(email, { url: getFrontendUrl() }), ); if (error) { @@ -195,7 +195,7 @@ export async function sendVerificationEmail( decodedTokenEmail: email, userInfoEmail: userInfo.email, }), - userInfo.uid + userInfo.uid, ); } else if (error.errorInfo.code === "auth/too-many-requests") { throw new MonkeyError(429, "Too many requests. Please try again later"); @@ -205,14 +205,14 @@ export async function sendVerificationEmail( ) { throw new MonkeyError( 429, - "Too many Firebase requests. Please try again later" + "Too many Firebase requests. Please try again later", ); } else { throw new MonkeyError( 500, "Firebase failed to generate an email verification link: " + error.errorInfo.message, - JSON.stringify(error) + JSON.stringify(error), ); } } else { @@ -220,19 +220,19 @@ export async function sendVerificationEmail( if (message === undefined) { throw new MonkeyError( 500, - "Failed to generate an email verification link. Unknown error occured" + "Failed to generate an email verification link. Unknown error occured", ); } else { if (message.toLowerCase().includes("too_many_attempts")) { throw new MonkeyError( 429, - "Too many requests. Please try again later" + "Too many requests. Please try again later", ); } else { throw new MonkeyError( 500, "Failed to generate an email verification link: " + message, - error.stack + error.stack, ); } } @@ -245,14 +245,14 @@ export async function sendVerificationEmail( } export async function sendForgotPasswordEmail( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { email, captcha } = req.body; await verifyCaptcha(captcha); await authSendForgotPasswordEmail(email); return new MonkeyResponse( "Password reset request received. If the email is valid, you will receive an email shortly.", - null + null, ); } @@ -265,7 +265,7 @@ export async function deleteUser(req: MonkeyRequest): Promise { "name", "email", "discordId", - ]) + ]), ); if (error) { @@ -290,11 +290,11 @@ export async function deleteUser(req: MonkeyRequest): Promise { deleteAllResults(uid), purgeUserFromDailyLeaderboards( uid, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ), purgeUserFromXpLeaderboards( uid, - req.ctx.configuration.leaderboards.weeklyXp + req.ctx.configuration.leaderboards.weeklyXp, ), ConnectionsDal.deleteByUid(uid), ]); @@ -313,7 +313,7 @@ export async function deleteUser(req: MonkeyRequest): Promise { void addImportantLog( "user_deleted", `${userInfo?.email} ${userInfo?.name}`, - uid + uid, ); return new MonkeyResponse("User deleted", null); @@ -340,11 +340,11 @@ export async function resetUser(req: MonkeyRequest): Promise { deleteConfig(uid), purgeUserFromDailyLeaderboards( uid, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ), purgeUserFromXpLeaderboards( uid, - req.ctx.configuration.leaderboards.weeklyXp + req.ctx.configuration.leaderboards.weeklyXp, ), ]; @@ -358,7 +358,7 @@ export async function resetUser(req: MonkeyRequest): Promise { } export async function updateName( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { name } = req.body; @@ -392,7 +392,7 @@ export async function updateName( void addImportantLog( "user_name_updated", `changed name from ${user.name} to ${name}`, - uid + uid, ); return new MonkeyResponse("User's name updated", null); @@ -404,7 +404,7 @@ export async function clearPb(req: MonkeyRequest): Promise { await UserDAL.clearPb(uid); await purgeUserFromDailyLeaderboards( uid, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ); void addImportantLog("user_cleared_pbs", "", uid); @@ -412,18 +412,18 @@ export async function clearPb(req: MonkeyRequest): Promise { } export async function optOutOfLeaderboards( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; await UserDAL.optOutOfLeaderboards(uid); await purgeUserFromDailyLeaderboards( uid, - req.ctx.configuration.dailyLeaderboards + req.ctx.configuration.dailyLeaderboards, ); await purgeUserFromXpLeaderboards( uid, - req.ctx.configuration.leaderboards.weeklyXp + req.ctx.configuration.leaderboards.weeklyXp, ); void addImportantLog("user_opted_out_of_leaderboards", "", uid); @@ -431,7 +431,7 @@ export async function optOutOfLeaderboards( } export async function checkName( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { name } = req.params; const { uid } = req.ctx.decodedToken; @@ -444,7 +444,7 @@ export async function checkName( } export async function updateEmail( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; let { newEmail, previousEmail } = req.body; @@ -460,7 +460,7 @@ export async function updateEmail( if (e.code === "auth/email-already-exists") { throw new MonkeyError( 409, - "The email address is already in use by another account" + "The email address is already in use by another account", ); } else if (e.code === "auth/invalid-email") { throw new MonkeyError(400, "Invalid email address"); @@ -471,7 +471,7 @@ export async function updateEmail( 404, "User not found in the auth system", "update email", - uid + uid, ); } else if (e.code === "auth/invalid-user-token") { throw new MonkeyError(401, "Invalid user token", "update email", uid); @@ -484,14 +484,14 @@ export async function updateEmail( void addImportantLog( "user_email_updated", `changed email from ${previousEmail} to ${newEmail}`, - uid + uid, ); return new MonkeyResponse("Email updated", null); } export async function updatePassword( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { newPassword } = req.body; @@ -536,7 +536,7 @@ export async function getUser(req: MonkeyRequest): Promise { const { uid } = req.ctx.decodedToken; const { data: userInfo, error } = await tryCatch( - UserDAL.getUser(uid, "get user") + UserDAL.getUser(uid, "get user"), ); if (error) { @@ -550,7 +550,7 @@ export async function getUser(req: MonkeyRequest): Promise { 404, "User not found in the database, but found in the auth system. We have deleted the ghost user from the auth system. Please sign up again.", "get user", - uid + uid, ); } catch (e) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access @@ -559,7 +559,7 @@ export async function getUser(req: MonkeyRequest): Promise { 404, "User not found in the database or the auth system. Please sign up again.", "get user", - uid + uid, ); } else { throw e; @@ -607,7 +607,7 @@ export async function getUser(req: MonkeyRequest): Promise { delete relevantUserInfo.tags; const customThemes = (relevantUserInfo.customThemes ?? []).map((it) => - replaceObjectId(it) + replaceObjectId(it), ); delete relevantUserInfo.customThemes; @@ -628,7 +628,7 @@ export async function getUser(req: MonkeyRequest): Promise { } export async function getOauthLink( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -642,7 +642,7 @@ export async function getOauthLink( } export async function linkDiscord( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tokenType, accessToken, state } = req.body; @@ -675,7 +675,7 @@ export async function linkDiscord( throw new MonkeyError( 500, "Could not get Discord account info", - "discord id is undefined" + "discord id is undefined", ); } @@ -683,7 +683,7 @@ export async function linkDiscord( if (!discordIdAvailable) { throw new MonkeyError( 409, - "This Discord account is linked to a different account" + "This Discord account is linked to a different account", ); } @@ -703,7 +703,7 @@ export async function linkDiscord( } export async function unlinkDiscord( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -729,7 +729,7 @@ export async function unlinkDiscord( } export async function addResultFilterPreset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const filter = req.body; @@ -738,16 +738,16 @@ export async function addResultFilterPreset( const createdId = await UserDAL.addResultFilterPreset( uid, filter, - maxPresetsPerUser + maxPresetsPerUser, ); return new MonkeyResponse( "Result filter preset created", - createdId.toHexString() + createdId.toHexString(), ); } export async function removeResultFilterPreset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { presetId } = req.params; @@ -757,7 +757,7 @@ export async function removeResultFilterPreset( } export async function addTag( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tagName } = req.body; @@ -767,7 +767,7 @@ export async function addTag( } export async function clearTagPb( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tagId } = req.params; @@ -777,7 +777,7 @@ export async function clearTagPb( } export async function editTag( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tagId, newName } = req.body; @@ -787,7 +787,7 @@ export async function editTag( } export async function removeTag( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { tagId } = req.params; @@ -804,7 +804,7 @@ export async function getTags(req: MonkeyRequest): Promise { } export async function updateLbMemory( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { mode, language, rank } = req.body; @@ -815,18 +815,18 @@ export async function updateLbMemory( } export async function getCustomThemes( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const customThemes = await UserDAL.getThemes(uid); return new MonkeyResponse( "Custom themes retrieved", - replaceObjectIds(customThemes) + replaceObjectIds(customThemes), ); } export async function addCustomTheme( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { name, colors } = req.body; @@ -836,7 +836,7 @@ export async function addCustomTheme( } export async function removeCustomTheme( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { themeId } = req.body; @@ -845,7 +845,7 @@ export async function removeCustomTheme( } export async function editCustomTheme( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { themeId, theme } = req.body; @@ -855,7 +855,7 @@ export async function editCustomTheme( } export async function getPersonalBests( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { mode, mode2 } = req.query; @@ -872,7 +872,7 @@ export async function getStats(req: MonkeyRequest): Promise { } export async function getFavoriteQuotes( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -882,7 +882,7 @@ export async function getFavoriteQuotes( } export async function addFavoriteQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -892,14 +892,14 @@ export async function addFavoriteQuote( uid, language, quoteId, - req.ctx.configuration.quotes.maxFavorites + req.ctx.configuration.quotes.maxFavorites, ); return new MonkeyResponse("Quote added to favorites", null); } export async function removeFavoriteQuote( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -910,7 +910,7 @@ export async function removeFavoriteQuote( } export async function getProfile( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uidOrName } = req.params; @@ -937,7 +937,7 @@ export async function getProfile( const extractValid = ( src: Record, - validKeys: string[] + validKeys: string[], ): Record => { return validKeys.reduce((obj, key) => { if (src?.[key] !== undefined) { @@ -1009,7 +1009,7 @@ export async function getProfile( } export async function updateProfile( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { @@ -1044,7 +1044,7 @@ export async function updateProfile( Object.entries(socialProfiles ?? {}).map(([key, value]) => [ key, sanitizeString(value), - ]) + ]), ), showActivityOnPublicProfile, }; @@ -1055,7 +1055,7 @@ export async function updateProfile( } export async function getInbox( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -1068,7 +1068,7 @@ export async function getInbox( } export async function updateInbox( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { mailIdsToMarkRead, mailIdsToDelete } = req.body; @@ -1076,14 +1076,14 @@ export async function updateInbox( await UserDAL.updateInbox( uid, mailIdsToMarkRead ?? [], - mailIdsToDelete ?? [] + mailIdsToDelete ?? [], ); return new MonkeyResponse("Inbox updated", null); } export async function reportUser( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { @@ -1111,7 +1111,7 @@ export async function reportUser( } export async function setStreakHourOffset( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const { hourOffset } = req.body; @@ -1135,7 +1135,7 @@ export async function setStreakHourOffset( } export async function revokeAllTokens( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; await AuthUtil.revokeTokensByUid(uid); @@ -1148,26 +1148,26 @@ async function getAllTimeLbs(uid: string): Promise { "time", "15", "english", - uid + uid, ); const allTime15EnglishCount = await LeaderboardsDAL.getCount( "time", "15", - "english" + "english", ); const allTime60English = await LeaderboardsDAL.getRank( "time", "60", "english", - uid + uid, ); const allTime60EnglishCount = await LeaderboardsDAL.getCount( "time", "60", - "english" + "english", ); const english15 = @@ -1199,7 +1199,7 @@ async function getAllTimeLbs(uid: string): Promise { } export function generateCurrentTestActivity( - testActivity: CountByYearAndDay | undefined + testActivity: CountByYearAndDay | undefined, ): TestActivity | undefined { const thisYear = Dates.startOfYear(new UTCDateMini()); const lastYear = Dates.startOfYear(Dates.subYears(thisYear, 1)); @@ -1217,15 +1217,15 @@ export function generateCurrentTestActivity( if (lastYearData.length < Dates.getDaysInYear(lastYear)) { lastYearData.push( ...(new Array(Dates.getDaysInYear(lastYear) - lastYearData.length).fill( - undefined - ) as (number | null)[]) + undefined, + ) as (number | null)[]), ); } //use enough days of the last year to have 372 days in total to always fill the first week of the graph lastYearData = lastYearData.slice(-372 + thisYearData.length); const lastDay = Dates.startOfDay( - Dates.addDays(thisYear, thisYearData.length - 1) + Dates.addDays(thisYear, thisYearData.length - 1), ); return { @@ -1235,7 +1235,7 @@ export function generateCurrentTestActivity( } export async function getTestActivity( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const premiumFeaturesEnabled = req.ctx.configuration.users.premium.enabled; @@ -1255,7 +1255,7 @@ export async function getTestActivity( return new MonkeyResponse( "Test activity data retrieved", - user.testActivity ?? null + user.testActivity ?? null, ); } @@ -1268,7 +1268,7 @@ async function firebaseDeleteUserIgnoreError(uid: string): Promise { } export async function getCurrentTestActivity( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -1278,12 +1278,12 @@ export async function getCurrentTestActivity( const data = generateCurrentTestActivity(user.testActivity); return new MonkeyResponse( "Current test activity data retrieved", - data ?? null + data ?? null, ); } export async function getStreak( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; @@ -1293,7 +1293,7 @@ export async function getStreak( } export async function getFriends( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const { uid } = req.ctx.decodedToken; const premiumEnabled = req.ctx.configuration.users.premium.enabled; diff --git a/backend/src/api/controllers/webhooks.ts b/backend/src/api/controllers/webhooks.ts index 702ff2621a3d..1f3f052ded45 100644 --- a/backend/src/api/controllers/webhooks.ts +++ b/backend/src/api/controllers/webhooks.ts @@ -5,7 +5,7 @@ import MonkeyError from "../../utils/error"; import { MonkeyRequest } from "../types"; export async function githubRelease( - req: MonkeyRequest + req: MonkeyRequest, ): Promise { const action = req.body.action; diff --git a/backend/src/api/routes/docs.ts b/backend/src/api/routes/docs.ts index e39065f8fe84..bd2befb32744 100644 --- a/backend/src/api/routes/docs.ts +++ b/backend/src/api/routes/docs.ts @@ -29,6 +29,6 @@ export default router; function setCsp(res: Response): void { res.setHeader( "Content-Security-Policy", - "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' monkeytype.com cdn.redocly.com data:;object-src 'none';script-src 'self' cdn.redocly.com 'unsafe-inline'; worker-src blob: data;script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' monkeytype.com cdn.redocly.com data:;object-src 'none';script-src 'self' cdn.redocly.com 'unsafe-inline'; worker-src blob: data;script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests", ); } diff --git a/backend/src/api/routes/index.ts b/backend/src/api/routes/index.ts index fec7fbc969a8..61a3ff2f5b98 100644 --- a/backend/src/api/routes/index.ts +++ b/backend/src/api/routes/index.ts @@ -74,8 +74,8 @@ export function addApiRoutes(app: Application): void { .json( new MonkeyResponse( `Unknown request URL (${req.method}: ${req.path})`, - null - ) + null, + ), ); }); } @@ -103,7 +103,7 @@ function applyTsRestApiRoutes(app: IRouter): void { Logger.error( `Unknown validation error for ${req.method} ${ req.path - }: ${JSON.stringify(err)}` + }: ${JSON.stringify(err)}`, ); res .status(500) @@ -143,7 +143,7 @@ function applyDevApiRoutes(app: Application): void { const slowdown = (await getLiveConfiguration()).dev.responseSlowdownMs; if (slowdown > 0) { Logger.info( - `Simulating ${slowdown}ms delay for ${req.method} ${req.path}` + `Simulating ${slowdown}ms delay for ${req.method} ${req.path}`, ); await new Promise((resolve) => setTimeout(resolve, slowdown)); } @@ -159,7 +159,7 @@ function applyApiRoutes(app: Application): void { ( req: ExpressRequestWithContext, res: Response, - next: NextFunction + next: NextFunction, ): void => { if (req.path.startsWith("/configuration")) { next(); @@ -176,7 +176,7 @@ function applyApiRoutes(app: Application): void { } next(); - } + }, ); app.get("/", (_req, res) => { @@ -184,7 +184,7 @@ function applyApiRoutes(app: Application): void { new MonkeyResponse("ok", { uptime: Date.now() - APP_START_TIME, version, - }) + }), ); }); diff --git a/backend/src/api/routes/swagger.ts b/backend/src/api/routes/swagger.ts index 3b2a7f3e7602..cff73fac3c76 100644 --- a/backend/src/api/routes/swagger.ts +++ b/backend/src/api/routes/swagger.ts @@ -10,12 +10,12 @@ function addSwaggerMiddlewares(app: Application): void { const { data: spec, error } = tryCatchSync( () => - JSON.parse(readFileSync(openApiSpec, "utf8")) as Record + JSON.parse(readFileSync(openApiSpec, "utf8")) as Record, ); if (error) { Logger.warning( - `Cannot read openApi specification from ${openApiSpec}. Swagger stats will not fully work.` + `Cannot read openApi specification from ${openApiSpec}. Swagger stats will not fully work.`, ); } @@ -32,7 +32,7 @@ function addSwaggerMiddlewares(app: Application): void { password === process.env["STATS_PASSWORD"] ); }, - }) + }), ); } diff --git a/backend/src/api/ts-rest-adapter.ts b/backend/src/api/ts-rest-adapter.ts index 587fad99c179..0f22d54e18da 100644 --- a/backend/src/api/ts-rest-adapter.ts +++ b/backend/src/api/ts-rest-adapter.ts @@ -12,9 +12,9 @@ export function callController< TResponse, //ignoring as it might be used in the future // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters - TStatus = 200 + TStatus = 200, >( - handler: MonkeyHandler + handler: MonkeyHandler, ): (all: TypeSafeTsRestRequest) => Promise<{ status: TStatus; body: MonkeyResponse; @@ -63,14 +63,14 @@ type WithoutParams = { }; type MonkeyHandler = ( - req: MonkeyRequest + req: MonkeyRequest, ) => Promise>; type TypeSafeTsRestRequest< TRoute extends AppRoute | AppRouter, TQuery, TBody, - TParams + TParams, > = { req: TsRestRequest; } & (TQuery extends undefined ? WithoutQuery : WithQuery) & diff --git a/backend/src/api/types.ts b/backend/src/api/types.ts index ec84f5950567..4c81395f3ba4 100644 --- a/backend/src/api/types.ts +++ b/backend/src/api/types.ts @@ -17,7 +17,7 @@ export type TsRestRequestWithContext = { export type MonkeyRequest< TQuery = undefined, TBody = undefined, - TParams = undefined + TParams = undefined, > = { query: Readonly; body: Readonly; diff --git a/backend/src/constants/base-configuration.ts b/backend/src/constants/base-configuration.ts index 7c135062dedb..60063b733801 100644 --- a/backend/src/constants/base-configuration.ts +++ b/backend/src/constants/base-configuration.ts @@ -139,14 +139,14 @@ type Schema = { [P in keyof T]: T[P] extends unknown[] ? ArraySchema : T[P] extends number - ? NumberSchema - : T[P] extends boolean - ? BooleanSchema - : T[P] extends string - ? StringSchema - : T[P] extends object - ? ObjectSchema - : never; + ? NumberSchema + : T[P] extends boolean + ? BooleanSchema + : T[P] extends string + ? StringSchema + : T[P] extends object + ? ObjectSchema + : never; }; export const CONFIGURATION_FORM_SCHEMA: ObjectSchema = { diff --git a/backend/src/constants/monkey-status-codes.ts b/backend/src/constants/monkey-status-codes.ts index 4d24e8b4d6fb..26b518dce956 100644 --- a/backend/src/constants/monkey-status-codes.ts +++ b/backend/src/constants/monkey-status-codes.ts @@ -70,7 +70,7 @@ const statuses: Statuses = { }; const CUSTOM_STATUS_CODES = new Set( - Object.values(statuses).map((status) => status.code) + Object.values(statuses).map((status) => status.code), ); export function isCustomCode(code: number): boolean { diff --git a/backend/src/dal/ape-keys.ts b/backend/src/dal/ape-keys.ts index 742fd029b4da..94ebde2f25a6 100644 --- a/backend/src/dal/ape-keys.ts +++ b/backend/src/dal/ape-keys.ts @@ -46,7 +46,7 @@ export async function addApeKey(apeKey: DBApeKey): Promise { async function updateApeKey( uid: string, keyId: string, - updates: MatchKeysAndValues + updates: MatchKeysAndValues, ): Promise { const updateResult = await getApeKeysCollection().updateOne( getApeKeyFilter(uid, keyId), @@ -54,10 +54,10 @@ async function updateApeKey( $inc: { useCount: "lastUsedOn" in updates ? 1 : 0 }, $set: Object.fromEntries( Object.entries(updates).filter( - ([_, value]) => value !== null && value !== undefined - ) + ([_, value]) => value !== null && value !== undefined, + ), ), - } + }, ); if (updateResult.modifiedCount === 0) { @@ -69,7 +69,7 @@ export async function editApeKey( uid: string, keyId: string, name?: string, - enabled?: boolean + enabled?: boolean, ): Promise { //check if there is a change if (name === undefined && enabled === undefined) return; @@ -84,7 +84,7 @@ export async function editApeKey( export async function updateLastUsedOn( uid: string, - keyId: string + keyId: string, ): Promise { const apeKeyUpdates = { lastUsedOn: Date.now(), @@ -95,7 +95,7 @@ export async function updateLastUsedOn( export async function deleteApeKey(uid: string, keyId: string): Promise { const deletionResult = await getApeKeysCollection().deleteOne( - getApeKeyFilter(uid, keyId) + getApeKeyFilter(uid, keyId), ); if (deletionResult.deletedCount === 0) { diff --git a/backend/src/dal/blocklist.ts b/backend/src/dal/blocklist.ts index 63827f5ad09d..fe7aadc9f2be 100644 --- a/backend/src/dal/blocklist.ts +++ b/backend/src/dal/blocklist.ts @@ -33,7 +33,7 @@ export async function add(user: BlocklistEntryProperties): Promise { usernameHash, timestamp, }, - { upsert: true } + { upsert: true }, ), getCollection().replaceOne( { emailHash }, @@ -41,8 +41,8 @@ export async function add(user: BlocklistEntryProperties): Promise { emailHash, timestamp, }, - { upsert: true } - ) + { upsert: true }, + ), ); if (user.discordId !== undefined && user.discordId !== "") { @@ -54,15 +54,15 @@ export async function add(user: BlocklistEntryProperties): Promise { discordIdHash, timestamp, }, - { upsert: true } - ) + { upsert: true }, + ), ); } await Promise.all(inserts); } export async function remove( - user: Partial + user: Partial, ): Promise { const filter = getFilter(user); if (filter.length === 0) return; @@ -70,7 +70,7 @@ export async function remove( } export async function contains( - user: Partial + user: Partial, ): Promise { const filter = getFilter(user); if (filter.length === 0) return false; @@ -86,7 +86,7 @@ export function hash(value: string): string { } function getFilter( - user: Partial + user: Partial, ): Partial[] { const filter: Partial[] = []; if (user.email !== undefined) { @@ -107,20 +107,20 @@ export async function createIndicies(): Promise { { unique: true, partialFilterExpression: { usernameHash: { $exists: true } }, - } + }, ); await getCollection().createIndex( { emailHash: 1 }, { unique: true, partialFilterExpression: { emailHash: { $exists: true } }, - } + }, ); await getCollection().createIndex( { discordIdHash: 1 }, { unique: true, partialFilterExpression: { discordIdHash: { $exists: true } }, - } + }, ); } diff --git a/backend/src/dal/config.ts b/backend/src/dal/config.ts index 5b9a2044e811..757ffdeefd93 100644 --- a/backend/src/dal/config.ts +++ b/backend/src/dal/config.ts @@ -33,16 +33,16 @@ const getConfigCollection = (): Collection => export async function saveConfig( uid: string, - config: Partial + config: Partial, ): Promise { const configChanges = Object.fromEntries( - Object.entries(config).map(([key, value]) => [`config.${key}`, value]) + Object.entries(config).map(([key, value]) => [`config.${key}`, value]), ); return await getConfigCollection().updateOne( { uid }, { $set: configChanges, $unset: configLegacyProperties }, - { upsert: true } + { upsert: true }, ); } diff --git a/backend/src/dal/connections.ts b/backend/src/dal/connections.ts index 75b2eeb0ab94..4945943d0a33 100644 --- a/backend/src/dal/connections.ts +++ b/backend/src/dal/connections.ts @@ -43,7 +43,7 @@ export async function getConnections(options: { export async function create( initiator: { uid: string; name: string }, receiver: { uid: string; name: string }, - maxPerUser: number + maxPerUser: number, ): Promise { const count = await getCollection().countDocuments({ initiatorUid: initiator.uid, @@ -53,7 +53,7 @@ export async function create( throw new MonkeyError( 409, "Maximum number of connections reached", - "create connection request" + "create connection request", ); } const key = getKey(initiator.uid, receiver.uid); @@ -77,7 +77,7 @@ export async function create( if (e.name === "MongoServerError" && e.code === 11000) { const existing = await getCollection().findOne( { key }, - { projection: { status: 1 } } + { projection: { status: 1 } }, ); let message = ""; @@ -113,14 +113,14 @@ export async function create( export async function updateStatus( receiverUid: string, id: string, - status: ConnectionStatus + status: ConnectionStatus, ): Promise { const updateResult = await getCollection().updateOne( { _id: new ObjectId(id), receiverUid, }, - { $set: { status, lastModified: Date.now() } } + { $set: { status, lastModified: Date.now() } }, ); if (updateResult.matchedCount === 0) { @@ -201,11 +201,11 @@ export async function getFriendsUids(uid: string): Promise { status: "accepted", $or: [{ initiatorUid: uid }, { receiverUid: uid }], }, - { projection: { initiatorUid: true, receiverUid: true } } + { projection: { initiatorUid: true, receiverUid: true } }, ) .toArray() - ).flatMap((it) => [it.initiatorUid, it.receiverUid]) - ) + ).flatMap((it) => [it.initiatorUid, it.receiverUid]), + ), ); } @@ -232,7 +232,7 @@ export async function aggregateWithAcceptedConnections( */ includeMetaData?: boolean; }, - pipeline: Document[] + pipeline: Document[], ): Promise { const metaData = options.includeMetaData ? { diff --git a/backend/src/dal/leaderboards.ts b/backend/src/dal/leaderboards.ts index 01302bde1ea8..45ebda2346f4 100644 --- a/backend/src/dal/leaderboards.ts +++ b/backend/src/dal/leaderboards.ts @@ -40,7 +40,7 @@ export async function get( page: number, pageSize: number, premiumFeaturesEnabled: boolean = false, - uid?: string + uid?: string, ): Promise { if (page < 0 || pageSize < 0) { throw new MonkeyError(500, "Invalid page or pageSize"); @@ -72,7 +72,7 @@ export async function get( }, }, ...pipeline, - ] + ], ); } else { leaderboard = await getCollection({ language, mode, mode2 }) @@ -100,7 +100,7 @@ export async function getCount( mode: string, mode2: string, language: string, - uid?: string + uid?: string, ): Promise { const key = `${language}_${mode}_${mode2}`; if (uid === undefined && cachedCounts.has(key)) { @@ -121,7 +121,7 @@ export async function getCount( collectionName: getCollectionName({ language, mode, mode2 }), uid, }, - [{ $project: { _id: true } }] + [{ $project: { _id: true } }], ) ).length; } @@ -133,7 +133,7 @@ export async function getRank( mode2: string, language: string, uid: string, - friendsOnly: boolean = false + friendsOnly: boolean = false, ): Promise { try { if (!friendsOnly) { @@ -157,7 +157,7 @@ export async function getRank( }, }, { $match: { uid } }, - ] + ], ); return results[0] ?? null; } @@ -174,7 +174,7 @@ export async function getRank( export async function update( mode: string, mode2: string, - language: string + language: string, ): Promise<{ message: string; rank?: number; @@ -271,7 +271,7 @@ export async function update( }, { $out: lbCollectionName }, ], - { allowDiskUse: true } + { allowDiskUse: true }, ); const start1 = performance.now(); @@ -322,7 +322,7 @@ export async function update( }, }, ], - { allowDiskUse: true } + { allowDiskUse: true }, ); const start3 = performance.now(); await histogram.toArray(); @@ -334,7 +334,7 @@ export async function update( void addLog( `system_lb_update_${language}_${mode}_${mode2}`, - `Aggregate ${timeToRunAggregate}s, loop 0s, insert 0s, index ${timeToRunIndex}s, histogram ${timeToSaveHistogram}` + `Aggregate ${timeToRunAggregate}s, loop 0s, insert 0s, index ${timeToRunIndex}s, histogram ${timeToSaveHistogram}`, ); setLeaderboard(language, mode, mode2, [ @@ -352,7 +352,7 @@ export async function update( async function createIndex( key: string, minTimeTyping: number, - dropIfMismatch = true + dropIfMismatch = true, ): Promise { const index = { [`${key}.wpm`]: -1, @@ -387,7 +387,7 @@ async function createIndex( if (!dropIfMismatch) throw e; if ( (e as Error).message.startsWith( - "An existing index has the same name as the requested index" + "An existing index has the same name as the requested index", ) ) { Logger.warning(`Index ${key} not matching, dropping and recreating...`); diff --git a/backend/src/dal/logs.ts b/backend/src/dal/logs.ts index 8d79b02629c5..9680ab9c761d 100644 --- a/backend/src/dal/logs.ts +++ b/backend/src/dal/logs.ts @@ -19,7 +19,7 @@ async function insertIntoDb( event: string, message: string | Record, uid = "", - important = false + important = false, ): Promise { const dbLog: DbLog = { _id: new ObjectId(), @@ -37,7 +37,7 @@ async function insertIntoDb( Logger.info( `${event}\t${uid}\t${ stringified.length > 100 ? stringified.slice(0, 100) + "..." : stringified - }` + }`, ); await getLogsCollection().insertOne(dbLog); @@ -46,7 +46,7 @@ async function insertIntoDb( export async function addLog( event: string, message: string | Record, - uid = "" + uid = "", ): Promise { await insertIntoDb(event, message, uid); } @@ -54,7 +54,7 @@ export async function addLog( export async function addImportantLog( event: string, message: string | Record, - uid = "" + uid = "", ): Promise { console.log("log", event, message, uid); await insertIntoDb(event, message, uid, true); diff --git a/backend/src/dal/new-quotes.ts b/backend/src/dal/new-quotes.ts index 23ce4831da59..5741deb1b8cd 100644 --- a/backend/src/dal/new-quotes.ts +++ b/backend/src/dal/new-quotes.ts @@ -31,7 +31,7 @@ const QuoteDataSchema = z.object({ const PATH_TO_REPO = "../../../../monkeytype-new-quotes"; const { data: git, error } = tryCatchSync(() => - simpleGit(path.join(__dirname, PATH_TO_REPO)) + simpleGit(path.join(__dirname, PATH_TO_REPO)), ); if (error) { @@ -54,7 +54,7 @@ export async function add( text: string, source: string, language: string, - uid: string + uid: string, ): Promise { if (git === undefined) throw new MonkeyError(500, "Git not available."); const quote = { @@ -78,14 +78,14 @@ export async function add( if (count >= 100) { throw new MonkeyError( 409, - "There are already 100 quotes in the queue for this language." + "There are already 100 quotes in the queue for this language.", ); } //check for duplicate first const fileDir = path.join( __dirname, - `${PATH_TO_REPO}/frontend/static/quotes/${language}.json` + `${PATH_TO_REPO}/frontend/static/quotes/${language}.json`, ); let duplicateId = -1; let similarityScore = -1; @@ -93,7 +93,7 @@ export async function add( const quoteFile = await readFile(fileDir); const quoteFileJSON = parseJsonWithSchema( quoteFile.toString(), - QuoteDataSchema + QuoteDataSchema, ); quoteFileJSON.quotes.every((old) => { if (compareTwoStrings(old.text, quote.text) > 0.9) { @@ -145,7 +145,7 @@ export async function approve( quoteId: string, editQuote: string | undefined, editSource: string | undefined, - name: string + name: string, ): Promise { if (git === null) throw new MonkeyError(500, "Git not available."); //check mod status @@ -155,7 +155,7 @@ export async function approve( if (!targetQuote) { throw new MonkeyError( 404, - "Quote not found. It might have already been reviewed. Please refresh the list." + "Quote not found. It might have already been reviewed. Please refresh the list.", ); } const language = targetQuote.language; @@ -174,14 +174,14 @@ export async function approve( const fileDir = path.join( __dirname, - `${PATH_TO_REPO}/frontend/static/quotes/${language}.json` + `${PATH_TO_REPO}/frontend/static/quotes/${language}.json`, ); await git.pull("upstream", "master"); if (existsSync(fileDir)) { const quoteFile = await readFile(fileDir); const quoteObject = parseJsonWithSchema( quoteFile.toString(), - QuoteDataSchema + QuoteDataSchema, ); quoteObject.quotes.every((old) => { if (compareTwoStrings(old.text, quote.text) > 0.8) { @@ -218,7 +218,7 @@ export async function approve( [601, 9999], ], quotes: [quote], - }) + }), ); message = `Created file ${language}.json and added quote.`; } diff --git a/backend/src/dal/preset.ts b/backend/src/dal/preset.ts index 89b0095b4f38..c4e8ea4904bc 100644 --- a/backend/src/dal/preset.ts +++ b/backend/src/dal/preset.ts @@ -14,7 +14,7 @@ type DBConfigPreset = WithObjectId< function getPresetKeyFilter( uid: string, - keyId: string + keyId: string, ): Filter { return { _id: new ObjectId(keyId), @@ -39,7 +39,7 @@ export async function getPresets(uid: string): Promise { export async function addPreset( uid: string, - preset: Omit + preset: Omit, ): Promise { const presets = await getPresetsCollection().countDocuments({ uid }); @@ -59,7 +59,7 @@ export async function addPreset( export async function editPreset( uid: string, - preset: EditPresetRequest + preset: EditPresetRequest, ): Promise { const update: Partial> = omit(preset, ["_id"]); if ( @@ -77,10 +77,10 @@ export async function editPreset( export async function removePreset( uid: string, - presetId: string + presetId: string, ): Promise { const deleteResult = await getPresetsCollection().deleteOne( - getPresetKeyFilter(uid, presetId) + getPresetKeyFilter(uid, presetId), ); if (deleteResult.deletedCount === 0) { diff --git a/backend/src/dal/public.ts b/backend/src/dal/public.ts index edef961025cf..89f6ffa2ed87 100644 --- a/backend/src/dal/public.ts +++ b/backend/src/dal/public.ts @@ -12,7 +12,7 @@ export type PublicSpeedStatsDB = { export async function updateStats( restartCount: number, - time: number + time: number, ): Promise { await db.collection("public").updateOne( { _id: "stats" }, @@ -23,7 +23,7 @@ export async function updateStats( timeTyping: roundTo2(time), }, }, - { upsert: true } + { upsert: true }, ); return true; } @@ -34,7 +34,7 @@ export async function updateStats( export async function getSpeedHistogram( language: string, mode: string, - mode2: string + mode2: string, ): Promise { const key = `${language}_${mode}_${mode2}` as keyof PublicSpeedStatsDB; @@ -42,7 +42,7 @@ export async function getSpeedHistogram( throw new MonkeyError( 400, "Invalid speed histogram key", - "get speed histogram" + "get speed histogram", ); } @@ -62,7 +62,7 @@ export async function getTypingStats(): Promise { throw new MonkeyError( 404, "Public typing stats not found", - "get typing stats" + "get typing stats", ); } return stats; diff --git a/backend/src/dal/quote-ratings.ts b/backend/src/dal/quote-ratings.ts index 075094d39eba..a189469c9ef1 100644 --- a/backend/src/dal/quote-ratings.ts +++ b/backend/src/dal/quote-ratings.ts @@ -14,19 +14,19 @@ export async function submit( quoteId: number, language: Language, rating: number, - update: boolean + update: boolean, ): Promise { if (update) { await getQuoteRatingCollection().updateOne( { quoteId, language }, { $inc: { totalRating: rating } }, - { upsert: true } + { upsert: true }, ); } else { await getQuoteRatingCollection().updateOne( { quoteId, language }, { $inc: { ratings: 1, totalRating: rating } }, - { upsert: true } + { upsert: true }, ); } @@ -37,18 +37,18 @@ export async function submit( const average = parseFloat( ( Math.round((quoteRating.totalRating / quoteRating.ratings) * 10) / 10 - ).toFixed(1) + ).toFixed(1), ); await getQuoteRatingCollection().updateOne( { quoteId, language }, - { $set: { average } } + { $set: { average } }, ); } export async function get( quoteId: number, - language: Language + language: Language, ): Promise { return await getQuoteRatingCollection().findOne({ quoteId, language }); } diff --git a/backend/src/dal/report.ts b/backend/src/dal/report.ts index 9f3b98332549..550d329fa70a 100644 --- a/backend/src/dal/report.ts +++ b/backend/src/dal/report.ts @@ -30,7 +30,7 @@ export async function deleteReports(reportIds: string[]): Promise { export async function createReport( report: DBReport, maxReports: number, - contentReportLimit: number + contentReportLimit: number, ): Promise { if (report.type === "user" && report.contentId === report.uid) { throw new MonkeyError(400, "You cannot report yourself."); @@ -43,7 +43,7 @@ export async function createReport( if (reportsCount >= maxReports) { throw new MonkeyError( 503, - "Reports are not being accepted at this time due to a large backlog of reports. Please try again later." + "Reports are not being accepted at this time due to a large backlog of reports. Please try again later.", ); } @@ -55,7 +55,7 @@ export async function createReport( if (sameReports.length >= contentReportLimit) { throw new MonkeyError( 409, - "A report limit for this content has been reached." + "A report limit for this content has been reached.", ); } diff --git a/backend/src/dal/result.ts b/backend/src/dal/result.ts index 580b7737e363..a2fc336aadd2 100644 --- a/backend/src/dal/result.ts +++ b/backend/src/dal/result.ts @@ -16,7 +16,7 @@ export const getResultCollection = (): Collection => export async function addResult( uid: string, - result: DBResult + result: DBResult, ): Promise<{ insertedId: ObjectId }> { const { data: user } = await tryCatch(getUser(uid, "add result")); @@ -36,7 +36,7 @@ export async function deleteAll(uid: string): Promise { export async function updateTags( uid: string, resultId: string, - tags: string[] + tags: string[], ): Promise { const result = await getResultCollection().findOne({ _id: new ObjectId(resultId), @@ -54,7 +54,7 @@ export async function updateTags( } return await getResultCollection().updateOne( { _id: new ObjectId(resultId), uid }, - { $set: { tags } } + { $set: { tags } }, ); } @@ -71,7 +71,7 @@ export async function getResult(uid: string, id: string): Promise { export async function getLastResult(uid: string): Promise { const lastResult = await getResultCollection().findOne( { uid }, - { sort: { timestamp: -1 } } + { sort: { timestamp: -1 } }, ); if (lastResult === null) throw new MonkeyError(404, "No last result found"); @@ -84,7 +84,7 @@ export async function getLastResultTimestamp(uid: string): Promise { { projection: { timestamp: 1, _id: 0 }, sort: { timestamp: -1 }, - } + }, ); if (lastResult === null) throw new MonkeyError(404, "No last result found"); @@ -93,7 +93,7 @@ export async function getLastResultTimestamp(uid: string): Promise { export async function getResultByTimestamp( uid: string, - timestamp: number + timestamp: number, ): Promise { const result = await getResultCollection().findOne({ uid, timestamp }); if (result === null) return null; @@ -108,7 +108,7 @@ type GetResultsOpts = { export async function getResults( uid: string, - opts?: GetResultsOpts + opts?: GetResultsOpts, ): Promise { const { onOrAfterTimestamp, offset, limit } = opts ?? {}; diff --git a/backend/src/dal/user.ts b/backend/src/dal/user.ts index 8d100012723f..58725b22085e 100644 --- a/backend/src/dal/user.ts +++ b/backend/src/dal/user.ts @@ -77,7 +77,7 @@ export const getUsersCollection = (): Collection => export async function addUser( name: string, email: string, - uid: string + uid: string, ): Promise { const newUserDocument: Partial = { name, @@ -97,7 +97,7 @@ export async function addUser( const result = await getUsersCollection().updateOne( { uid }, { $setOnInsert: newUserDocument }, - { upsert: true } + { upsert: true }, ); if (result.upsertedCount === 0) { @@ -151,14 +151,14 @@ export async function resetUser(uid: string): Promise { lbOptOut: "", inbox: "", }, - } + }, ); } export async function updateName( uid: string, name: string, - previousName: string + previousName: string, ): Promise { if (name === previousName) { throw new MonkeyError(400, "New name is the same as the old name"); @@ -177,14 +177,14 @@ export async function updateName( $set: { name, lastNameChange: Date.now() }, $unset: { needsToChangeName: "" }, $push: { nameHistory: previousName }, - } + }, ); } export async function flagForNameChange(uid: string): Promise { await getUsersCollection().updateOne( { uid }, - { $set: { needsToChangeName: true } } + { $set: { needsToChangeName: true } }, ); } @@ -204,7 +204,7 @@ export async function clearPb(uid: string): Promise { time: {}, }, }, - } + }, ); } @@ -218,25 +218,25 @@ export async function optOutOfLeaderboards(uid: string): Promise { time: {}, }, }, - } + }, ); } export async function updateQuoteRatings( uid: string, - quoteRatings: UserQuoteRatings + quoteRatings: UserQuoteRatings, ): Promise { await updateUser( { uid }, { $set: { quoteRatings } }, - { stack: "update quote ratings" } + { stack: "update quote ratings" }, ); return true; } export async function updateEmail( uid: string, - email: string + email: string, ): Promise { await updateUser({ uid }, { $set: { email } }, { stack: "update email" }); @@ -260,7 +260,7 @@ export async function getUser(uid: string, stack: string): Promise { export async function getPartialUser( uid: string, stack: string, - fields: K[] + fields: K[], ): Promise> { const projection = new Map(fields.map((it) => [it, 1])); const results = await getUsersCollection().findOne({ uid }, { projection }); @@ -272,7 +272,7 @@ export async function getPartialUser( export async function findByName(name: string): Promise { const found = await getUsersCollection().findOne( { name }, - { collation: { locale: "en", strength: 1 } } + { collation: { locale: "en", strength: 1 } }, ); return found !== null ? found : undefined; @@ -280,7 +280,7 @@ export async function findByName(name: string): Promise { export async function isNameAvailable( name: string, - uid: string + uid: string, ): Promise { const user = await findByName(name); // if the user found by name is the same as the user we are checking for, then the name is available @@ -290,7 +290,7 @@ export async function isNameAvailable( export async function getUserByName( name: string, - stack: string + stack: string, ): Promise { const user = await findByName(name); if (!user) throw new MonkeyError(404, "User not found", stack); @@ -298,11 +298,11 @@ export async function getUserByName( } export async function isDiscordIdAvailable( - discordId: string + discordId: string, ): Promise { const user = await getUsersCollection().findOne( { discordId }, - { projection: { _id: 1 } } + { projection: { _id: 1 } }, ); return user === null; } @@ -310,13 +310,13 @@ export async function isDiscordIdAvailable( export async function addResultFilterPreset( uid: string, resultFilter: ResultFilters, - maxFiltersPerUser: number + maxFiltersPerUser: number, ): Promise { if (maxFiltersPerUser === 0) { throw new MonkeyError( 409, "Maximum number of custom filters reached", - "add result filter preset" + "add result filter preset", ); } @@ -331,7 +331,7 @@ export async function addResultFilterPreset( statusCode: 409, message: "Maximum number of custom filters reached", stack: "add result filter preset", - } + }, ); return _id; @@ -339,7 +339,7 @@ export async function addResultFilterPreset( export async function removeResultFilterPreset( uid: string, - _id: string + _id: string, ): Promise { const presetId = new ObjectId(_id); @@ -350,7 +350,7 @@ export async function removeResultFilterPreset( statusCode: 404, message: "Custom filter not found", stack: "remove result filter preset", - } + }, ); } @@ -374,7 +374,7 @@ export async function addTag(uid: string, name: string): Promise { statusCode: 400, message: "Maximum number of tags reached", stack: "add tag", - } + }, ); return toPush; @@ -389,14 +389,14 @@ export async function getTags(uid: string): Promise { export async function editTag( uid: string, _id: string, - name: string + name: string, ): Promise { const tagId = new ObjectId(_id); await updateUser( { uid, "tags._id": tagId }, { $set: { "tags.$.name": name } }, - { statusCode: 404, message: "Tag not found", stack: "edit tag" } + { statusCode: 404, message: "Tag not found", stack: "edit tag" }, ); } @@ -406,7 +406,7 @@ export async function removeTag(uid: string, _id: string): Promise { await updateUser( { uid, "tags._id": tagId }, { $pull: { tags: { _id: tagId } } }, - { statusCode: 404, message: "Tag not found", stack: "remove tag" } + { statusCode: 404, message: "Tag not found", stack: "remove tag" }, ); } @@ -426,7 +426,7 @@ export async function removeTagPb(uid: string, _id: string): Promise { }, }, }, - { statusCode: 404, message: "Tag not found", stack: "remove tag pb" } + { statusCode: 404, message: "Tag not found", stack: "remove tag pb" }, ); } @@ -435,7 +435,7 @@ export async function updateLbMemory( mode: Mode, mode2: Mode2, language: string, - rank: number + rank: number, ): Promise { const partialUpdate = {}; partialUpdate[`lbMemory.${mode}.${mode2}.${language}`] = rank; @@ -443,14 +443,14 @@ export async function updateLbMemory( await updateUser( { uid }, { $set: partialUpdate }, - { stack: "update lb memory" } + { stack: "update lb memory" }, ); } export async function checkIfPb( uid: string, user: Pick, - result: Result + result: Result, ): Promise { const { mode } = result; @@ -483,13 +483,13 @@ export async function checkIfPb( await getUsersCollection().updateOne( { uid }, - { $set: { personalBests: pb.personalBests } } + { $set: { personalBests: pb.personalBests } }, ); if (pb.lbPersonalBests) { await getUsersCollection().updateOne( { uid }, - { $set: { lbPersonalBests: pb.lbPersonalBests } } + { $set: { lbPersonalBests: pb.lbPersonalBests } }, ); } return true; @@ -498,7 +498,7 @@ export async function checkIfPb( export async function checkIfTagPb( uid: string, user: Pick, - result: Result + result: Result, ): Promise { if (user.tags === undefined || user.tags.length === 0) { return []; @@ -542,7 +542,7 @@ export async function checkIfTagPb( ret.push(tag._id.toHexString()); await getUsersCollection().updateOne( { uid, "tags._id": new ObjectId(tag._id) }, - { $set: { "tags.$.personalBests": tagpb.personalBests } } + { $set: { "tags.$.personalBests": tagpb.personalBests } }, ); } } @@ -564,13 +564,13 @@ export async function resetPb(uid: string): Promise { }, }, }, - { stack: "reset pb" } + { stack: "reset pb" }, ); } export async function updateLastHashes( uid: string, - lastHashes: string[] + lastHashes: string[], ): Promise { await getUsersCollection().updateOne( { uid }, @@ -578,14 +578,14 @@ export async function updateLastHashes( $set: { lastReultHashes: lastHashes, //TODO fix typo }, - } + }, ); } export async function updateTypingStats( uid: string, restartCount: number, - timeTyping: number + timeTyping: number, ): Promise { await getUsersCollection().updateOne( { uid }, @@ -595,14 +595,14 @@ export async function updateTypingStats( completedTests: 1, timeTyping, }, - } + }, ); } export async function linkDiscord( uid: string, discordId: string, - discordAvatar?: string + discordAvatar?: string, ): Promise { const updates: Partial = { discordId }; if (discordAvatar !== undefined && discordAvatar !== null) @@ -615,13 +615,13 @@ export async function unlinkDiscord(uid: string): Promise { await updateUser( { uid }, { $unset: { discordId: "", discordAvatar: "" } }, - { stack: "unlink discord" } + { stack: "unlink discord" }, ); } export async function incrementBananas( uid: string, - wpm: number + wpm: number, ): Promise { //don't throw on missing user await getUsersCollection().updateOne( @@ -655,7 +655,7 @@ export async function incrementBananas( ], }, }, - { $inc: { bananas: 1 } } + { $inc: { bananas: 1 } }, ); } @@ -666,7 +666,7 @@ export async function incrementXp(uid: string, xp: number): Promise { export async function incrementTestActivity( user: DBUser, - timestamp: number + timestamp: number, ): Promise { if (user.testActivity === undefined) { //migration script did not run yet @@ -680,19 +680,19 @@ export async function incrementTestActivity( if (user.testActivity[year] === undefined) { await getUsersCollection().updateOne( { uid: user.uid }, - { $set: { [`testActivity.${date.getFullYear()}`]: [] } } + { $set: { [`testActivity.${date.getFullYear()}`]: [] } }, ); } await getUsersCollection().updateOne( { uid: user.uid }, - { $inc: { [`testActivity.${date.getFullYear()}.${dayOfYear - 1}`]: 1 } } + { $inc: { [`testActivity.${date.getFullYear()}.${dayOfYear - 1}`]: 1 } }, ); } export async function addTheme( uid: string, - { name, colors }: Omit + { name, colors }: Omit, ): Promise<{ _id: ObjectId; name: string }> { const _id = new ObjectId(); @@ -711,7 +711,7 @@ export async function addTheme( statusCode: 409, message: "Maximum number of custom themes reached", stack: "add theme", - } + }, ); return { @@ -729,14 +729,14 @@ export async function removeTheme(uid: string, id: string): Promise { statusCode: 404, message: "Custom theme not found", stack: "remove theme", - } + }, ); } export async function editTheme( uid: string, id: string, - { name, colors }: Omit + { name, colors }: Omit, ): Promise { const themeId = new ObjectId(id); @@ -748,7 +748,7 @@ export async function editTheme( "customThemes.$.colors": colors, }, }, - { statusCode: 404, message: "Custom theme not found", stack: "edit theme" } + { statusCode: 404, message: "Custom theme not found", stack: "edit theme" }, ); } @@ -762,7 +762,7 @@ export async function getThemes(uid: string): Promise { export async function getPersonalBests( uid: string, mode: string, - mode2?: string + mode2?: string, ): Promise { const user = await getPartialUser(uid, "get personal bests", [ "personalBests", @@ -777,7 +777,7 @@ export async function getPersonalBests( } export async function getStats( - uid: string + uid: string, ): Promise> { const user = await getPartialUser(uid, "get stats", [ "startedTests", @@ -789,7 +789,7 @@ export async function getStats( } export async function getFavoriteQuotes( - uid: string + uid: string, ): Promise> { const user = await getPartialUser(uid, "get favorite quotes", [ "favoriteQuotes", @@ -802,7 +802,7 @@ export async function addFavoriteQuote( uid: string, language: string, quoteId: string, - maxQuotes: number + maxQuotes: number, ): Promise { await updateUser( { @@ -831,26 +831,26 @@ export async function addFavoriteQuote( statusCode: 409, message: "Maximum number of favorite quotes reached", stack: "add favorite quote", - } + }, ); } export async function removeFavoriteQuote( uid: string, language: string, - quoteId: string + quoteId: string, ): Promise { await updateUser( { uid }, { $pull: { [`favoriteQuotes.${language}`]: quoteId } }, - { stack: "remove favorite quote" } + { stack: "remove favorite quote" }, ); } export async function recordAutoBanEvent( uid: string, maxCount: number, - maxHours: number + maxHours: number, ): Promise { const user = await getPartialUser(uid, "record auto ban event", [ "banned", @@ -868,7 +868,7 @@ export async function recordAutoBanEvent( //only keep events within the last maxHours const recentAutoBanTimestamps = autoBanTimestamps.filter( - (timestamp) => timestamp >= now - maxHours * SECONDS_PER_HOUR * 1000 + (timestamp) => timestamp >= now - maxHours * SECONDS_PER_HOUR * 1000, ); //push new event @@ -889,7 +889,7 @@ export async function recordAutoBanEvent( void addImportantLog( "user_auto_banned", { autoBanTimestamps, banningUser }, - uid + uid, ); if (banningUser) { @@ -906,17 +906,17 @@ export async function recordAutoBanEvent( export async function updateProfile( uid: string, profileDetailUpdates: Partial, - inventory?: UserInventory + inventory?: UserInventory, ): Promise { let profileUpdates = flattenObjectDeep( Object.fromEntries( Object.entries(profileDetailUpdates).filter( ([_, value]) => value !== undefined && - !(isPlainObject(value) && Object.keys(value).length === 0) - ) + !(isPlainObject(value) && Object.keys(value).length === 0), + ), ), - "profileDetails" + "profileDetails", ); const updates = { @@ -931,12 +931,12 @@ export async function updateProfile( { uid, }, - updates + updates, ); } export async function getInbox( - uid: string + uid: string, ): Promise> { const user = await getPartialUser(uid, "get inbox", ["inbox"]); return user.inbox ?? []; @@ -949,7 +949,7 @@ type AddToInboxBulkEntry = { export async function addToInboxBulk( entries: AddToInboxBulkEntry[], - inboxConfig: Configuration["users"]["inbox"] + inboxConfig: Configuration["users"]["inbox"], ): Promise { const { enabled, maxMail } = inboxConfig; @@ -977,7 +977,7 @@ export async function addToInboxBulk( export async function addToInbox( uid: string, mail: MonkeyMail[], - inboxConfig: Configuration["users"]["inbox"] + inboxConfig: Configuration["users"]["inbox"], ): Promise { const { enabled, maxMail } = inboxConfig; @@ -997,21 +997,21 @@ export async function addToInbox( $slice: maxMail, // Keeps inbox size to maxMail, discarding the oldest }, }, - } + }, ); } export async function updateInbox( uid: string, mailToRead: string[], - mailToDelete: string[] + mailToDelete: string[], ): Promise { const deleteSet = [...new Set(mailToDelete)]; //we don't need to read mails that are going to be deleted because //Rewards will be claimed on unread mails on deletion const readSet = [...new Set(mailToRead)].filter( - (it) => !deleteSet.includes(it) + (it) => !deleteSet.includes(it), ); const update = await getUsersCollection().updateOne({ uid }, [ @@ -1026,14 +1026,14 @@ export async function updateInbox( xp: number, inventory: UserInventory, deletedIds: string[], - readIds: string[] + readIds: string[], ): Pick { const toBeDeleted = inbox.filter((it) => - deletedIds.includes(it.id) + deletedIds.includes(it.id), ); const toBeRead = inbox.filter( - (it) => readIds.includes(it.id) && !it.read + (it) => readIds.includes(it.id) && !it.read, ); //flatMap rewards @@ -1106,7 +1106,7 @@ export async function updateInbox( export async function updateStreak( uid: string, - timestamp: number + timestamp: number, ): Promise { const user = await getPartialUser(uid, "calculate streak", ["streak"]); const streak: UserStreak = { @@ -1141,7 +1141,7 @@ export async function updateStreak( export async function setStreakHourOffset( uid: string, - hourOffset: number + hourOffset: number, ): Promise { await getUsersCollection().updateOne( { uid }, @@ -1150,7 +1150,7 @@ export async function setStreakHourOffset( "streak.hourOffset": hourOffset, "streak.lastResultTimestamp": Date.now(), }, - } + }, ); } @@ -1169,13 +1169,13 @@ export async function clearStreakHourOffset(uid: string): Promise { $unset: { "streak.hourOffset": "", }, - } + }, ); } export async function checkIfUserIsPremium( uid: string, - userInfoOverride?: Pick + userInfoOverride?: Pick, ): Promise { const premiumFeaturesEnabled = (await getCachedConfiguration(true)).users .premium.enabled; @@ -1195,7 +1195,7 @@ export async function checkIfUserIsPremium( export async function logIpAddress( uid: string, ip: string, - userInfoOverride?: Pick + userInfoOverride?: Pick, ): Promise { const user = userInfoOverride ?? (await getPartialUser(uid, "logIpAddress", ["ips"])); @@ -1221,7 +1221,7 @@ export async function logIpAddress( async function updateUser( filter: Filter, update: UpdateFilter, - error: { stack: string; statusCode?: number; message?: string } + error: { stack: string; statusCode?: number; message?: string }, ): Promise { const result = await getUsersCollection().updateOne(filter, update); @@ -1229,7 +1229,7 @@ async function updateUser( throw new MonkeyError( error.statusCode ?? 404, error.message ?? "User not found", - error.stack + error.stack, ); } @@ -1346,6 +1346,6 @@ export async function getFriends(uid: string): Promise { premium: false, }, }, - ] + ], ); } diff --git a/backend/src/init/configuration.ts b/backend/src/init/configuration.ts index d08e393ac60e..63e6eab0f976 100644 --- a/backend/src/init/configuration.ts +++ b/backend/src/init/configuration.ts @@ -19,12 +19,12 @@ import { intersect } from "@monkeytype/util/arrays"; const CONFIG_UPDATE_INTERVAL = 10 * 60 * 1000; // 10 Minutes const SERVER_CONFIG_FILE_PATH = join( __dirname, - "../backend-configuration.json" + "../backend-configuration.json", ); function mergeConfigurations( baseConfiguration: Configuration, - liveConfiguration: PartialConfiguration + liveConfiguration: PartialConfiguration, ): void { if (!isPlainObject(baseConfiguration) || !isPlainObject(liveConfiguration)) { return; @@ -56,7 +56,7 @@ let lastFetchTime = 0; let serverConfigurationUpdated = false; export async function getCachedConfiguration( - attemptCacheUpdate = false + attemptCacheUpdate = false, ): Promise { if ( attemptCacheUpdate && @@ -97,7 +97,7 @@ export async function getLiveConfiguration(): Promise { const errorMessage = getErrorMessage(error) ?? "Unknown error"; void addLog( "fetch_configuration_failure", - `Could not fetch configuration: ${errorMessage}` + `Could not fetch configuration: ${errorMessage}`, ); } @@ -116,13 +116,13 @@ async function pushConfiguration(configuration: Configuration): Promise { const errorMessage = getErrorMessage(error) ?? "Unknown error"; void addLog( "push_configuration_failure", - `Could not push configuration: ${errorMessage}` + `Could not push configuration: ${errorMessage}`, ); } } export async function patchConfiguration( - configurationUpdates: PartialConfiguration + configurationUpdates: PartialConfiguration, ): Promise { try { const currentConfiguration = structuredClone(configuration); @@ -137,7 +137,7 @@ export async function patchConfiguration( const errorMessage = getErrorMessage(error) ?? "Unknown error"; void addLog( "patch_configuration_failure", - `Could not patch configuration: ${errorMessage}` + `Could not patch configuration: ${errorMessage}`, ); return false; @@ -149,14 +149,14 @@ export async function patchConfiguration( export async function updateFromConfigurationFile(): Promise { if (existsSync(SERVER_CONFIG_FILE_PATH)) { Logger.info( - `Reading server configuration from file ${SERVER_CONFIG_FILE_PATH}` + `Reading server configuration from file ${SERVER_CONFIG_FILE_PATH}`, ); const json = readFileSync(SERVER_CONFIG_FILE_PATH, "utf-8"); const data = parseJsonWithSchema( json, z.object({ configuration: PartialConfigurationSchema, - }) + }), ); await patchConfiguration(data.configuration); diff --git a/backend/src/init/db.ts b/backend/src/init/db.ts index 1e93ad0d6f7a..8e6c6d1fc74c 100644 --- a/backend/src/init/db.ts +++ b/backend/src/init/db.ts @@ -51,7 +51,7 @@ export async function connect(): Promise { mongoClient = new MongoClient( DB_URI ?? global.__MONGO_URI__, // Set in tests only - connectionOptions + connectionOptions, ); try { @@ -60,7 +60,7 @@ export async function connect(): Promise { } catch (error) { Logger.error(getErrorMessage(error) ?? "Unknown error"); Logger.error( - "Failed to connect to database. Exiting with exit status code 1." + "Failed to connect to database. Exiting with exit status code 1.", ); process.exit(1); } diff --git a/backend/src/init/email-client.ts b/backend/src/init/email-client.ts index 2fd2b89c55dd..39121cba0fcb 100644 --- a/backend/src/init/email-client.ts +++ b/backend/src/init/email-client.ts @@ -49,7 +49,7 @@ export async function init(): Promise { if (!(EMAIL_HOST ?? "") || !(EMAIL_USER ?? "") || !(EMAIL_PASS ?? "")) { if (isDevEnvironment()) { Logger.warning( - "No email client configuration provided. Running without email." + "No email client configuration provided. Running without email.", ); } else if (process.env["BYPASS_EMAILCLIENT"] === "true") { Logger.warning("BYPASS_EMAILCLIENT is enabled! Running without email."); @@ -76,7 +76,8 @@ export async function init(): Promise { if (!result) { throw new Error( - `Could not verify email client configuration: ` + JSON.stringify(result) + `Could not verify email client configuration: ` + + JSON.stringify(result), ); } @@ -96,7 +97,7 @@ type MailResult = { export async function sendEmail( templateName: EmailType, to: string, - data: EmailTaskContexts[EmailType] + data: EmailTaskContexts[EmailType], ): Promise { if (!isInitialized()) { return { @@ -117,7 +118,7 @@ export async function sendEmail( type Result = { response: string; accepted: string[] }; const { data: result, error } = await tryCatch( - transporter.sendMail(mailOptions) as Promise + transporter.sendMail(mailOptions) as Promise, ); if (error) { @@ -148,7 +149,7 @@ async function getTemplate(name: string): Promise { const template = await fs.promises.readFile( `${EMAIL_TEMPLATES_DIRECTORY}/${name}`, - "utf-8" + "utf-8", ); const html = mjml2html(template).html; @@ -159,7 +160,7 @@ async function getTemplate(name: string): Promise { async function fillTemplate( type: M, - data: EmailTaskContexts[M] + data: EmailTaskContexts[M], ): Promise { const template = await getTemplate(templates[type].templateName); return mustache.render(template, data); diff --git a/backend/src/init/firebase-admin.ts b/backend/src/init/firebase-admin.ts index 79bba2990d56..b9ec54ec8411 100644 --- a/backend/src/init/firebase-admin.ts +++ b/backend/src/init/firebase-admin.ts @@ -7,14 +7,14 @@ import { isDevEnvironment } from "../utils/misc"; const SERVICE_ACCOUNT_PATH = path.join( __dirname, - "../../src/credentials/serviceAccountKey.json" + "../../src/credentials/serviceAccountKey.json", ); export function init(): void { if (!existsSync(SERVICE_ACCOUNT_PATH)) { if (isDevEnvironment()) { Logger.warning( - "Firebase service account key not found! Continuing in dev mode, but authentication will throw errors." + "Firebase service account key not found! Continuing in dev mode, but authentication will throw errors.", ); } else if (process.env["BYPASS_FIREBASE"] === "true") { Logger.warning("BYPASS_FIREBASE is enabled! Running without firebase."); @@ -22,7 +22,7 @@ export function init(): void { throw new MonkeyError( 500, "Firebase service account key not found! Make sure generate a service account key and place it in credentials/serviceAccountKey.json.", - "init() firebase-admin.ts" + "init() firebase-admin.ts", ); } } else { @@ -38,7 +38,7 @@ function get(): typeof admin { throw new MonkeyError( 500, "Firebase app not initialized! Make sure generate a service account key and place it in credentials/serviceAccountKey.json.", - "get() firebase-admin.ts" + "get() firebase-admin.ts", ); } return admin; diff --git a/backend/src/init/redis.ts b/backend/src/init/redis.ts index 3eeeed8e9257..13359aa90104 100644 --- a/backend/src/init/redis.ts +++ b/backend/src/init/redis.ts @@ -16,7 +16,7 @@ export type RedisConnectionWithCustomMethods = Redis & { expirationTime: number, uid: string, score: number, - data: string + data: string, ) => Promise; addResultIncrement: ( keyCount: number, @@ -25,7 +25,7 @@ export type RedisConnectionWithCustomMethods = Redis & { expirationTime: number, uid: string, score: number, - data: string + data: string, ) => Promise; getResults: ( keyCount: number, @@ -34,7 +34,7 @@ export type RedisConnectionWithCustomMethods = Redis & { minRank: number, maxRank: number, withScores: string, - userIds: string + userIds: string, ) => Promise< [string[], string[], string, [string, string | number], string[]] >; //entries, scores(optional), count, min_score(optiona)[uid, score], ranks(optional) @@ -44,12 +44,12 @@ export type RedisConnectionWithCustomMethods = Redis & { resultsKey: string, uid: string, withScores: string, - userIds: string + userIds: string, ) => Promise<[number, string, string, number]>; //rank, score(optional), entry json, friendsRank(optional) purgeResults: ( keyCount: number, uid: string, - namespace: string + namespace: string, ) => Promise; }; @@ -105,11 +105,11 @@ export async function connect(): Promise { if (isDevEnvironment()) { await connection.quit(); Logger.warning( - `Failed to connect to redis. Continuing in dev mode, running without redis.` + `Failed to connect to redis. Continuing in dev mode, running without redis.`, ); } else { Logger.error( - "Failed to connect to redis. Exiting with exit status code 1." + "Failed to connect to redis. Exiting with exit status code 1.", ); process.exit(1); } diff --git a/backend/src/jobs/delete-old-logs.ts b/backend/src/jobs/delete-old-logs.ts index cf28803b276b..2af26c72588e 100644 --- a/backend/src/jobs/delete-old-logs.ts +++ b/backend/src/jobs/delete-old-logs.ts @@ -21,7 +21,7 @@ async function deleteOldLogs(): Promise { void addLog( "system_logs_deleted", `${data.deletedCount} logs deleted older than ${LOG_MAX_AGE_DAYS} day(s)`, - undefined + undefined, ); } diff --git a/backend/src/jobs/log-queue-sizes.ts b/backend/src/jobs/log-queue-sizes.ts index 56b7e892f2d2..294724d4b071 100644 --- a/backend/src/jobs/log-queue-sizes.ts +++ b/backend/src/jobs/log-queue-sizes.ts @@ -24,7 +24,7 @@ async function main(): Promise { setQueueLength(queue.queueName, "active", active); setQueueLength(queue.queueName, "failed", failed); setQueueLength(queue.queueName, "waiting", waitingTotal); - }) + }), ); } diff --git a/backend/src/jobs/update-leaderboards.ts b/backend/src/jobs/update-leaderboards.ts index e6e219c07c49..4f464e9bd62c 100644 --- a/backend/src/jobs/update-leaderboards.ts +++ b/backend/src/jobs/update-leaderboards.ts @@ -8,26 +8,26 @@ const RECENT_AGE_MINUTES = 10; const RECENT_AGE_MILLISECONDS = RECENT_AGE_MINUTES * 60 * 1000; async function getTop10( - leaderboardTime: string + leaderboardTime: string, ): Promise { return (await LeaderboardsDAL.get( "time", leaderboardTime, "english", 0, - 10 + 10, )) as LeaderboardsDAL.DBLeaderboardEntry[]; //can do that because gettop10 will not be called during an update } async function updateLeaderboardAndNotifyChanges( - leaderboardTime: string + leaderboardTime: string, ): Promise { const top10BeforeUpdate = await getTop10(leaderboardTime); const previousRecordsMap = Object.fromEntries( top10BeforeUpdate.map((record) => { return [record.uid, record]; - }) + }), ); await LeaderboardsDAL.update("time", leaderboardTime, "english"); diff --git a/backend/src/middlewares/auth.ts b/backend/src/middlewares/auth.ts index 3c04c981c4b3..f79e08c9b38d 100644 --- a/backend/src/middlewares/auth.ts +++ b/backend/src/middlewares/auth.ts @@ -42,12 +42,12 @@ const DEFAULT_OPTIONS: RequestAuthenticationOptions = { * @returns */ export function authenticateTsRestRequest< - T extends AppRouter | AppRoute + T extends AppRouter | AppRoute, >(): TsRestRequestHandler { return async ( req: TsRestRequestWithContext, _res: Response, - next: NextFunction + next: NextFunction, ): Promise => { const options = { ...DEFAULT_OPTIONS, @@ -74,7 +74,7 @@ export function authenticateTsRestRequest< token = await authenticateWithAuthHeader( authHeader, req.ctx.configuration, - options + options, ); } else if (isPublic === true) { token = { @@ -86,7 +86,7 @@ export function authenticateTsRestRequest< throw new MonkeyError( 401, "Unauthorized", - `endpoint: ${req.baseUrl} no authorization header found` + `endpoint: ${req.baseUrl} no authorization header found`, ); } @@ -103,7 +103,7 @@ export function authenticateTsRestRequest< authType, "failure", Math.round(performance.now() - startTime), - req + req, ); next(error); @@ -113,7 +113,7 @@ export function authenticateTsRestRequest< token.type, "success", Math.round(performance.now() - startTime), - req + req, ); const country = req.headers["cf-ipcountry"] as string; @@ -132,7 +132,7 @@ export function authenticateTsRestRequest< async function authenticateWithAuthHeader( authHeader: string, configuration: Configuration, - options: RequestAuthenticationOptions + options: RequestAuthenticationOptions, ): Promise { const [authScheme, token] = authHeader.split(" "); @@ -140,7 +140,7 @@ async function authenticateWithAuthHeader( throw new MonkeyError( 401, "Missing authentication token", - "authenticateWithAuthHeader" + "authenticateWithAuthHeader", ); } @@ -158,18 +158,18 @@ async function authenticateWithAuthHeader( throw new MonkeyError( 401, "Unknown authentication scheme", - `The authentication scheme "${authScheme}" is not implemented` + `The authentication scheme "${authScheme}" is not implemented`, ); } async function authenticateWithBearerToken( token: string, - options: RequestAuthenticationOptions + options: RequestAuthenticationOptions, ): Promise { try { const decodedToken = await verifyIdToken( token, - (options.requireFreshToken ?? false) || (options.noCache ?? false) + (options.requireFreshToken ?? false) || (options.noCache ?? false), ); if (options.requireFreshToken) { @@ -180,7 +180,7 @@ async function authenticateWithBearerToken( throw new MonkeyError( 401, "Unauthorized", - `This endpoint requires a fresh token` + `This endpoint requires a fresh token`, ); } } @@ -198,7 +198,7 @@ async function authenticateWithBearerToken( throw new MonkeyError( 503, "Firebase returned an internal error when trying to verify the token.", - "authenticateWithBearerToken" + "authenticateWithBearerToken", ); } @@ -209,25 +209,25 @@ async function authenticateWithBearerToken( throw new MonkeyError( 401, "Token expired - please login again", - "authenticateWithBearerToken" + "authenticateWithBearerToken", ); } else if (errorCode?.includes("auth/id-token-revoked")) { throw new MonkeyError( 401, "Token revoked - please login again", - "authenticateWithBearerToken" + "authenticateWithBearerToken", ); } else if (errorCode?.includes("auth/user-not-found")) { throw new MonkeyError( 404, "User not found", - "authenticateWithBearerToken" + "authenticateWithBearerToken", ); } else if (errorCode?.includes("auth/argument-error")) { throw new MonkeyError( 400, "Incorrect Bearer token format", - "authenticateWithBearerToken" + "authenticateWithBearerToken", ); } else { throw error; @@ -238,7 +238,7 @@ async function authenticateWithBearerToken( async function authenticateWithApeKey( key: string, configuration: Configuration, - options: RequestAuthenticationOptions + options: RequestAuthenticationOptions, ): Promise { const isPublic = options.isPublic || (options.isPublicOnDev && isDevEnvironment()); @@ -318,7 +318,7 @@ async function authenticateWithUid(token: string): Promise { export function authenticateGithubWebhook( req: TsRestRequestWithContext, - authHeader: string | string[] | undefined + authHeader: string | string[] | undefined, ): DecodedToken { try { const webhookSecret = process.env["GITHUB_WEBHOOK_SECRET"]; @@ -358,7 +358,7 @@ export function authenticateGithubWebhook( } throw new MonkeyError( 500, - "Failed to authenticate Github webhook: " + (error as Error).message + "Failed to authenticate Github webhook: " + (error as Error).message, ); } } diff --git a/backend/src/middlewares/compatibilityCheck.ts b/backend/src/middlewares/compatibilityCheck.ts index 89c45049fc51..626ddab99536 100644 --- a/backend/src/middlewares/compatibilityCheck.ts +++ b/backend/src/middlewares/compatibilityCheck.ts @@ -13,7 +13,7 @@ import type { Response, NextFunction, Request } from "express"; export async function compatibilityCheckMiddleware( _req: Request, res: Response, - next: NextFunction + next: NextFunction, ): Promise { res.setHeader(COMPATIBILITY_CHECK_HEADER, COMPATIBILITY_CHECK); next(); diff --git a/backend/src/middlewares/configuration.ts b/backend/src/middlewares/configuration.ts index cda2f4147469..2993df3977d7 100644 --- a/backend/src/middlewares/configuration.ts +++ b/backend/src/middlewares/configuration.ts @@ -12,12 +12,12 @@ import { TsRestRequestWithContext } from "../api/types"; import { AppRoute, AppRouter } from "@ts-rest/core"; export function verifyRequiredConfiguration< - T extends AppRouter | AppRoute + T extends AppRouter | AppRoute, >(): TsRestRequestHandler { return async ( req: TsRestRequestWithContext, _res: Response, - next: NextFunction + next: NextFunction, ): Promise => { const requiredConfigurations = getRequireConfigurations(getMetadata(req)); @@ -29,13 +29,13 @@ export function verifyRequiredConfiguration< for (const requireConfiguration of requiredConfigurations) { const value = getValue( req.ctx.configuration, - requireConfiguration.path + requireConfiguration.path, ); if (!value) { throw new MonkeyError( 503, requireConfiguration.invalidMessage ?? - "This endpoint is currently unavailable." + "This endpoint is currently unavailable.", ); } } @@ -50,7 +50,7 @@ export function verifyRequiredConfiguration< function getValue( configuration: Configuration, - path: ConfigurationPath + path: ConfigurationPath, ): boolean { const keys = (path as string).split("."); let result: unknown = configuration; @@ -65,18 +65,18 @@ function getValue( if (result === undefined || result === null) throw new MonkeyError( 500, - `Required configuration doesnt exist: "${path}"` + `Required configuration doesnt exist: "${path}"`, ); if (typeof result !== "boolean") throw new MonkeyError( 500, - `Required configuration is not a boolean: "${path}"` + `Required configuration is not a boolean: "${path}"`, ); return result; } function getRequireConfigurations( - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): RequireConfiguration[] | undefined { if (metadata === undefined || metadata.requireConfiguration === undefined) return undefined; diff --git a/backend/src/middlewares/context.ts b/backend/src/middlewares/context.ts index e8c6d4ed51ce..05d8ea27ada2 100644 --- a/backend/src/middlewares/context.ts +++ b/backend/src/middlewares/context.ts @@ -22,7 +22,7 @@ export type Context = { async function contextMiddleware( req: ExpressRequest, _res: Response, - next: NextFunction + next: NextFunction, ): Promise { const configuration = await getCachedConfiguration(true); diff --git a/backend/src/middlewares/error.ts b/backend/src/middlewares/error.ts index 454105499602..a2af5f982d7e 100644 --- a/backend/src/middlewares/error.ts +++ b/backend/src/middlewares/error.ts @@ -36,7 +36,7 @@ async function errorHandlingMiddleware( error: Error, req: ExpressRequestWithContext, res: Response, - _next: NextFunction + _next: NextFunction, ): Promise { try { const monkeyError = error as MonkeyError; @@ -77,7 +77,7 @@ async function errorHandlingMiddleware( await addLog( "system_error", `${status} ${errorId} ${error.message} ${error.stack}`, - uid + uid, ); await db.collection("errors").insertOne({ _id: errorId, @@ -114,7 +114,7 @@ async function errorHandlingMiddleware( handleErrorResponse( res, 500, - "Something went really wrong, please contact support." + "Something went really wrong, please contact support.", ); } @@ -122,7 +122,7 @@ function handleErrorResponse( res: Response, status: number, message: string, - data?: ErrorData + data?: ErrorData, ): void { res.status(status); if (isCustomCode(status)) { diff --git a/backend/src/middlewares/permission.ts b/backend/src/middlewares/permission.ts index 59787afcd56d..805ce07272a5 100644 --- a/backend/src/middlewares/permission.ts +++ b/backend/src/middlewares/permission.ts @@ -18,7 +18,7 @@ type RequestPermissionCheck = { type: "request"; criteria: ( req: TsRestRequestWithContext, - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ) => Promise; invalidMessage?: string; }; @@ -35,7 +35,7 @@ type PermissionCheck = UserPermissionCheck | RequestPermissionCheck; function buildUserPermission( fields: K[], criteria: (user: Pick) => boolean, - invalidMessage?: string + invalidMessage?: string, ): UserPermissionCheck { return { type: "user", @@ -51,33 +51,33 @@ const permissionChecks: Record = { criteria: async (req, metadata) => await checkIfUserIsAdmin( req.ctx.decodedToken, - metadata?.authenticationOptions + metadata?.authenticationOptions, ), }, quoteMod: buildUserPermission( ["quoteMod"], (user) => user.quoteMod === true || - (typeof user.quoteMod === "string" && (user.quoteMod as string) !== "") + (typeof user.quoteMod === "string" && (user.quoteMod as string) !== ""), ), canReport: buildUserPermission( ["canReport"], - (user) => user.canReport !== false + (user) => user.canReport !== false, ), canManageApeKeys: buildUserPermission( ["canManageApeKeys"], (user) => user.canManageApeKeys ?? true, - "You have lost access to ape keys, please contact support" + "You have lost access to ape keys, please contact support", ), }; export function verifyPermissions< - T extends AppRouter | AppRoute + T extends AppRouter | AppRoute, >(): TsRestRequestHandler { return async ( req: TsRestRequestWithContext, _res: Response, - next: NextFunction + next: NextFunction, ): Promise => { const metadata = getMetadata(req); const requiredPermissionIds = getRequiredPermissionIds(metadata); @@ -103,8 +103,8 @@ export function verifyPermissions< next( new MonkeyError( 403, - check.invalidMessage ?? "You don't have permission to do this." - ) + check.invalidMessage ?? "You don't have permission to do this.", + ), ); return; } @@ -114,15 +114,15 @@ export function verifyPermissions< const userChecks = checks.filter((it) => it.type === "user"); const checkResult = await checkUserPermissions( req.ctx.decodedToken, - userChecks + userChecks, ); if (!checkResult.passed) { next( new MonkeyError( 403, - checkResult.invalidMessage ?? "You don't have permission to do this." - ) + checkResult.invalidMessage ?? "You don't have permission to do this.", + ), ); return; } @@ -134,7 +134,7 @@ export function verifyPermissions< } function getRequiredPermissionIds( - metadata: EndpointMetadata | undefined + metadata: EndpointMetadata | undefined, ): PermissionId[] | undefined { if (metadata === undefined || metadata.requirePermission === undefined) return undefined; @@ -146,7 +146,7 @@ function getRequiredPermissionIds( async function checkIfUserIsAdmin( decodedToken: DecodedToken | undefined, - options: RequestAuthenticationOptions | undefined + options: RequestAuthenticationOptions | undefined, ): Promise { if (decodedToken === undefined) return false; if (options?.isPublicOnDev && isDevEnvironment()) return true; @@ -165,7 +165,7 @@ type CheckResult = async function checkUserPermissions( decodedToken: DecodedToken | undefined, - checks: UserPermissionCheck[] + checks: UserPermissionCheck[], ): Promise { if (checks === undefined || checks.length === 0) { return { @@ -182,7 +182,7 @@ async function checkUserPermissions( const user = (await getPartialUser( decodedToken.uid, "check user permissions", - checks.flatMap((it) => it.fields) + checks.flatMap((it) => it.fields), )) as DBUser; for (const check of checks) { diff --git a/backend/src/middlewares/rate-limit.ts b/backend/src/middlewares/rate-limit.ts index 77e04905bd9a..34a8e3964d8b 100644 --- a/backend/src/middlewares/rate-limit.ts +++ b/backend/src/middlewares/rate-limit.ts @@ -28,12 +28,12 @@ export const customHandler = ( req: ExpressRequestWithContext, _res: Response, _next: NextFunction, - _options: Options + _options: Options, ): void => { if (req.ctx.decodedToken.type === "ApeKey") { throw new MonkeyError( statuses.APE_KEY_RATE_LIMIT_EXCEEDED.code, - statuses.APE_KEY_RATE_LIMIT_EXCEEDED.message + statuses.APE_KEY_RATE_LIMIT_EXCEEDED.message, ); } throw new MonkeyError(429, "Request limit reached, please try again later."); @@ -50,7 +50,7 @@ const getKey = (req: Request, _res: Response): string => { const getKeyWithUid = ( req: ExpressRequestWithContext, - _res: Response + _res: Response, ): string => { const uid = req?.ctx?.decodedToken?.uid; const useUid = uid !== undefined && uid !== ""; @@ -95,12 +95,12 @@ export const requestLimiters: Record = initialiseLimiters(); export function rateLimitRequest< - T extends AppRouter | AppRoute + T extends AppRouter | AppRoute, >(): TsRestRequestHandler { return async ( req: TsRestRequestWithContext, res: Response, - next: NextFunction + next: NextFunction, ): Promise => { const rateLimit = getMetadata(req).rateLimit; if (rateLimit === undefined) { @@ -124,8 +124,8 @@ export function rateLimitRequest< next( new MonkeyError( 500, - `Unknown rateLimiterId '${rateLimiterId}', how did you manage to do this?` - ) + `Unknown rateLimiterId '${rateLimiterId}', how did you manage to do this?`, + ), ); } else { await rateLimiter(req, res, next); @@ -141,7 +141,7 @@ export const rootRateLimiter = rateLimit({ handler: (_req, _res, _next, _options): void => { throw new MonkeyError( 429, - "Maximum API request (root) limit reached. Please try again later." + "Maximum API request (root) limit reached. Please try again later.", ); }, }); @@ -155,7 +155,7 @@ const badAuthRateLimiter = new RateLimiterMemory({ export async function badAuthRateLimiterHandler( req: ExpressRequestWithContext, res: Response, - next: NextFunction + next: NextFunction, ): Promise { const badAuthEnabled = req?.ctx?.configuration?.rateLimiting?.badAuthentication?.enabled; @@ -171,7 +171,7 @@ export async function badAuthRateLimiterHandler( if (rateLimitStatus !== null && rateLimitStatus?.remainingPoints <= 0) { throw new MonkeyError( 429, - "Too many bad authentication attempts, please try again later." + "Too many bad authentication attempts, please try again later.", ); } } catch (error) { @@ -185,7 +185,7 @@ export async function badAuthRateLimiterHandler( export async function incrementBadAuth( req: ExpressRequestWithContext, res: Response, - status: number + status: number, ): Promise { const { enabled, penalty, flaggedStatusCodes } = req?.ctx?.configuration?.rateLimiting?.badAuthentication ?? {}; diff --git a/backend/src/middlewares/utility.ts b/backend/src/middlewares/utility.ts index 26c6577a2eb0..de8faf6fbfcf 100644 --- a/backend/src/middlewares/utility.ts +++ b/backend/src/middlewares/utility.ts @@ -25,14 +25,14 @@ export function onlyAvailableOnDev(): RequestHandler { return ( _req: TsRestRequestWithContext, _res: Response, - next: NextFunction + next: NextFunction, ) => { if (!isDevEnvironment()) { next( new MonkeyError( 503, - "Development endpoints are only available in DEV mode." - ) + "Development endpoints are only available in DEV mode.", + ), ); } else { next(); @@ -55,7 +55,7 @@ export function getMetadata(req: TsRestRequestWithContext): EndpointMetadata { export async function v4RequestBody( req: Request, _res: Response, - next: NextFunction + next: NextFunction, ): Promise { if (req.body === undefined) { req.body = {}; diff --git a/backend/src/queues/email-queue.ts b/backend/src/queues/email-queue.ts index e9a249cc3818..b9252b255a14 100644 --- a/backend/src/queues/email-queue.ts +++ b/backend/src/queues/email-queue.ts @@ -24,7 +24,7 @@ export type EmailTaskContexts = { function buildTask( taskName: EmailType, email: string, - taskContext: EmailTaskContexts[EmailType] + taskContext: EmailTaskContexts[EmailType], ): EmailTask { return { type: taskName, @@ -37,7 +37,7 @@ class EmailQueue extends MonkeyQueue> { async sendVerificationEmail( email: string, name: string, - verificationLink: string + verificationLink: string, ): Promise { const taskName = "verify"; const task = buildTask(taskName, email, { name, verificationLink }); @@ -47,7 +47,7 @@ class EmailQueue extends MonkeyQueue> { async sendForgotPasswordEmail( email: string, name: string, - passwordResetLink: string + passwordResetLink: string, ): Promise { const taskName = "resetPassword"; const task = buildTask(taskName, email, { name, passwordResetLink }); diff --git a/backend/src/queues/george-queue.ts b/backend/src/queues/george-queue.ts index 6d2b31380e39..cc143d08f580 100644 --- a/backend/src/queues/george-queue.ts +++ b/backend/src/queues/george-queue.ts @@ -33,7 +33,7 @@ class GeorgeQueue extends MonkeyQueue { async linkDiscord( discordId: string, uid: string, - lbOptOut: boolean + lbOptOut: boolean, ): Promise { const taskName = "linkDiscord"; const linkDiscordTask = buildGeorgeTask(taskName, [ @@ -52,7 +52,7 @@ class GeorgeQueue extends MonkeyQueue { async awardChallenge( discordId: string, - challengeName: string + challengeName: string, ): Promise { const taskName = "awardChallenge"; const awardChallengeTask = buildGeorgeTask(taskName, [ @@ -70,7 +70,7 @@ class GeorgeQueue extends MonkeyQueue { async announceLeaderboardUpdate( newRecords: Omit[], - leaderboardId: string + leaderboardId: string, ): Promise { const taskName = "announceLeaderboardUpdate"; @@ -97,7 +97,7 @@ class GeorgeQueue extends MonkeyQueue { async announceDailyLeaderboardTopResults( leaderboardId: string, leaderboardTimestamp: number, - topResults: LeaderboardEntry[] + topResults: LeaderboardEntry[], ): Promise { const taskName = "announceDailyLeaderboardTopResults"; diff --git a/backend/src/queues/later-queue.ts b/backend/src/queues/later-queue.ts index 71d3db22b6e4..8cd5194fdef5 100644 --- a/backend/src/queues/later-queue.ts +++ b/backend/src/queues/later-queue.ts @@ -40,7 +40,7 @@ class LaterQueue extends MonkeyQueue> { taskName: string, task: LaterTask, jobId: string, - delay: number + delay: number, ): Promise { await this.add(taskName, task, { delay, @@ -52,13 +52,13 @@ class LaterQueue extends MonkeyQueue> { this.scheduledJobCache.set(jobId, true); Logger.info( - `Scheduled ${task.taskName} for ${new Date(Date.now() + delay)}` + `Scheduled ${task.taskName} for ${new Date(Date.now() + delay)}`, ); } async scheduleForNextWeek( taskName: LaterTaskType, - taskId: string + taskId: string, ): Promise { const currentWeekTimestamp = getCurrentWeekTimestamp(); const jobId = `${taskName}:${currentWeekTimestamp}:${taskId}`; @@ -86,7 +86,7 @@ class LaterQueue extends MonkeyQueue> { async scheduleForTomorrow( taskName: LaterTaskType, taskId: string, - modeRule: ValidModeRule + modeRule: ValidModeRule, ): Promise { const currentDayTimestamp = getCurrentDayTimestamp(); const jobId = `${taskName}:${currentDayTimestamp}:${taskId}`; diff --git a/backend/src/queues/monkey-queue.ts b/backend/src/queues/monkey-queue.ts index 4f134e4db2e1..f11e8de2f1a3 100644 --- a/backend/src/queues/monkey-queue.ts +++ b/backend/src/queues/monkey-queue.ts @@ -51,7 +51,7 @@ export class MonkeyQueue { } async addBulk( - tasks: { name: string; data: T; opts?: BulkJobOptions }[] + tasks: { name: string; data: T; opts?: BulkJobOptions }[], ): Promise { if (this.jobQueue === undefined) { return; diff --git a/backend/src/server.ts b/backend/src/server.ts index 68c7ca3e58a7..fcfc274f5069 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -53,7 +53,7 @@ async function bootServer(port: number): Promise { Logger.success( `Queues initialized: ${queues .map((queue) => queue.queueName) - .join(", ")}` + .join(", ")}`, ); Logger.info("Initializing workers..."); @@ -63,7 +63,7 @@ async function bootServer(port: number): Promise { Logger.success( `Workers initialized: ${workers .map((worker) => worker(connection ?? undefined).name) - .join(", ")}` + .join(", ")}`, ); } diff --git a/backend/src/services/weekly-xp-leaderboard.ts b/backend/src/services/weekly-xp-leaderboard.ts index f6bad83a0584..3aeed4e077e1 100644 --- a/backend/src/services/weekly-xp-leaderboard.ts +++ b/backend/src/services/weekly-xp-leaderboard.ts @@ -53,7 +53,7 @@ export class WeeklyXpLeaderboard { public async addResult( weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"], - opts: AddResultOpts + opts: AddResultOpts, ): Promise { const { entry, xpGained } = opts; @@ -75,12 +75,12 @@ export class WeeklyXpLeaderboard { const weeklyXpLeaderboardExpirationTimeInSeconds = Math.floor( (currentWeekTimestamp + weeklyXpLeaderboardExpirationDurationInMilliseconds) / - 1000 + 1000, ); const currentEntry = await connection.hget( weeklyXpLeaderboardResultsKey, - entry.uid + entry.uid, ); const currentEntryTimeTypedSeconds = @@ -104,12 +104,12 @@ export class WeeklyXpLeaderboard { RedisXpLeaderboardEntrySchema.parse({ ...entry, timeTypedSeconds: totalTimeTypedSeconds, - }) - ) + }), + ), ), LaterQueue.scheduleForNextWeek( "weekly-xp-leaderboard-results", - "weekly-xp" + "weekly-xp", ), ]); @@ -121,7 +121,7 @@ export class WeeklyXpLeaderboard { pageSize: number, weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"], premiumFeaturesEnabled: boolean, - userIds?: string[] + userIds?: string[], ): Promise<{ entries: XpLeaderboardEntry[]; count: number; @@ -153,18 +153,18 @@ export class WeeklyXpLeaderboard { minRank, maxRank, "true", - userIds?.join(",") ?? "" + userIds?.join(",") ?? "", ); if (results === undefined) { throw new Error( - "Redis returned undefined when getting weekly leaderboard results" + "Redis returned undefined when getting weekly leaderboard results", ); } if (scores === undefined) { throw new Error( - "Redis returned undefined when getting weekly leaderboard scores" + "Redis returned undefined when getting weekly leaderboard scores", ); } @@ -173,13 +173,13 @@ export class WeeklyXpLeaderboard { try { const parsed = parseJsonWithSchema( resultJSON, - RedisXpLeaderboardEntrySchema + RedisXpLeaderboardEntrySchema, ); const scoreValue = scores[index]; if (typeof scoreValue !== "string") { throw new Error( - `Invalid score value at index ${index}: ${scoreValue}` + `Invalid score value at index ${index}: ${scoreValue}`, ); } @@ -195,10 +195,10 @@ export class WeeklyXpLeaderboard { throw new Error( `Failed to parse leaderboard entry at index ${index}: ${ error instanceof Error ? error.message : String(error) - }` + }`, ); } - } + }, ); if (!premiumFeaturesEnabled) { @@ -211,7 +211,7 @@ export class WeeklyXpLeaderboard { public async getRank( uid: string, weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"], - userIds?: string[] + userIds?: string[], ): Promise { const connection = RedisClient.getConnection(); if (!connection || !weeklyXpLeaderboardConfig.enabled) { @@ -230,7 +230,7 @@ export class WeeklyXpLeaderboard { weeklyXpLeaderboardResultsKey, uid, "true", - userIds?.join(",") ?? "" + userIds?.join(",") ?? "", ); if (rank === null || result === null) { @@ -248,7 +248,7 @@ export class WeeklyXpLeaderboard { throw new Error( `Failed to parse leaderboard entry: ${ error instanceof Error ? error.message : String(error) - }` + }`, ); } } @@ -256,7 +256,7 @@ export class WeeklyXpLeaderboard { export function get( weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"], - customTimestamp?: number + customTimestamp?: number, ): WeeklyXpLeaderboard | null { const { enabled } = weeklyXpLeaderboardConfig; @@ -269,7 +269,7 @@ export function get( export async function purgeUserFromXpLeaderboards( uid: string, - weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"] + weeklyXpLeaderboardConfig: Configuration["leaderboards"]["weeklyXp"], ): Promise { const connection = RedisClient.getConnection(); if (!connection || !weeklyXpLeaderboardConfig.enabled) { @@ -279,7 +279,7 @@ export async function purgeUserFromXpLeaderboards( await connection.purgeResults( 0, uid, - weeklyXpLeaderboardLeaderboardNamespace + weeklyXpLeaderboardLeaderboardNamespace, ); } diff --git a/backend/src/utils/auth.ts b/backend/src/utils/auth.ts index 616d9aaffd63..8f507398d696 100644 --- a/backend/src/utils/auth.ts +++ b/backend/src/utils/auth.ts @@ -22,7 +22,7 @@ const TOKEN_CACHE_BUFFER = 1000 * 60 * 5; // 5 minutes export async function verifyIdToken( idToken: string, - noCache = false + noCache = false, ): Promise { if (noCache) { return await FirebaseAdmin().auth().verifyIdToken(idToken, true); @@ -54,7 +54,7 @@ export async function verifyIdToken( export async function updateUserEmail( uid: string, - email: string + email: string, ): Promise { await revokeTokensByUid(uid); return await FirebaseAdmin().auth().updateUser(uid, { @@ -65,7 +65,7 @@ export async function updateUserEmail( export async function updateUserPassword( uid: string, - password: string + password: string, ): Promise { await revokeTokensByUid(uid); return await FirebaseAdmin().auth().updateUser(uid, { @@ -93,7 +93,7 @@ export async function sendForgotPasswordEmail(email: string): Promise { const { name } = await UserDAL.getPartialUser( uid, "request forgot password email", - ["name"] + ["name"], ); const link = await FirebaseAdmin() diff --git a/backend/src/utils/captcha.ts b/backend/src/utils/captcha.ts index cf96e7138f57..f9b375141fec 100644 --- a/backend/src/utils/captcha.ts +++ b/backend/src/utils/captcha.ts @@ -24,7 +24,7 @@ export async function verify(captcha: string): Promise { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: `secret=${recaptchaSecret}&response=${captcha}`, - } + }, ); if (!response.ok) { diff --git a/backend/src/utils/daily-leaderboards.ts b/backend/src/utils/daily-leaderboards.ts index bc05e61bf571..e038616e81fb 100644 --- a/backend/src/utils/daily-leaderboards.ts +++ b/backend/src/utils/daily-leaderboards.ts @@ -55,7 +55,7 @@ export class DailyLeaderboard { public async addResult( entry: RedisDailyLeaderboardEntry, - dailyLeaderboardsConfig: Configuration["dailyLeaderboards"] + dailyLeaderboardsConfig: Configuration["dailyLeaderboards"], ): Promise { const connection = RedisClient.getConnection(); if (!connection || !dailyLeaderboardsConfig.enabled) { @@ -71,7 +71,8 @@ export class DailyLeaderboard { leaderboardExpirationTimeInDays * 24 * 60 * 60 * 1000; const leaderboardExpirationTimeInSeconds = Math.floor( - (currentDayTimestamp + leaderboardExpirationDurationInMilliseconds) / 1000 + (currentDayTimestamp + leaderboardExpirationDurationInMilliseconds) / + 1000, ); const resultScore = kogascore(entry.wpm, entry.acc, entry.timestamp); @@ -84,19 +85,19 @@ export class DailyLeaderboard { leaderboardExpirationTimeInSeconds, entry.uid, resultScore, - JSON.stringify(entry) + JSON.stringify(entry), ); if ( isValidModeRule( this.modeRule, - dailyLeaderboardsConfig.scheduleRewardsModeRules + dailyLeaderboardsConfig.scheduleRewardsModeRules, ) ) { await LaterQueue.scheduleForTomorrow( "daily-leaderboard-results", this.leaderboardModeKey, - this.modeRule + this.modeRule, ); } @@ -112,7 +113,7 @@ export class DailyLeaderboard { pageSize: number, dailyLeaderboardsConfig: Configuration["dailyLeaderboards"], premiumFeaturesEnabled: boolean, - userIds?: string[] + userIds?: string[], ): Promise<{ entries: LeaderboardEntry[]; count: number; @@ -146,7 +147,7 @@ export class DailyLeaderboard { minRank, maxRank, "false", - userIds?.join(",") ?? "" + userIds?.join(",") ?? "", ); const minWpm = @@ -156,7 +157,7 @@ export class DailyLeaderboard { if (results === undefined) { throw new Error( - "Redis returned undefined when getting daily leaderboard results" + "Redis returned undefined when getting daily leaderboard results", ); } @@ -165,7 +166,7 @@ export class DailyLeaderboard { try { const parsed = parseJsonWithSchema( resultJSON, - RedisDailyLeaderboardEntrySchema + RedisDailyLeaderboardEntrySchema, ); return { @@ -179,10 +180,10 @@ export class DailyLeaderboard { throw new Error( `Failed to parse leaderboard entry at index ${index}: ${ error instanceof Error ? error.message : String(error) - }` + }`, ); } - } + }, ); if (!premiumFeaturesEnabled) { @@ -195,7 +196,7 @@ export class DailyLeaderboard { public async getRank( uid: string, dailyLeaderboardsConfig: Configuration["dailyLeaderboards"], - userIds?: string[] + userIds?: string[], ): Promise { const connection = RedisClient.getConnection(); if (!connection || !dailyLeaderboardsConfig.enabled) { @@ -214,7 +215,7 @@ export class DailyLeaderboard { leaderboardResultsKey, uid, "false", - userIds?.join(",") ?? "" + userIds?.join(",") ?? "", ); if (rank === null || rank === undefined) { @@ -225,7 +226,7 @@ export class DailyLeaderboard { return { ...parseJsonWithSchema( result ?? "null", - RedisDailyLeaderboardEntrySchema + RedisDailyLeaderboardEntrySchema, ), rank: rank + 1, friendsRank: friendsRank !== undefined ? friendsRank + 1 : undefined, @@ -234,7 +235,7 @@ export class DailyLeaderboard { throw new Error( `Failed to parse leaderboard entry: ${ error instanceof Error ? error.message : String(error) - }` + }`, ); } } @@ -242,7 +243,7 @@ export class DailyLeaderboard { export async function purgeUserFromDailyLeaderboards( uid: string, - configuration: Configuration["dailyLeaderboards"] + configuration: Configuration["dailyLeaderboards"], ): Promise { const connection = RedisClient.getConnection(); if (!connection || !configuration.enabled) { @@ -254,7 +255,7 @@ export async function purgeUserFromDailyLeaderboards( function isValidModeRule( modeRule: ValidModeRule, - modeRules: ValidModeRule[] + modeRules: ValidModeRule[], ): boolean { const { language, mode, mode2 } = modeRule; @@ -271,7 +272,7 @@ export function getDailyLeaderboard( mode: Mode, mode2: Mode2, dailyLeaderboardsConfig: Configuration["dailyLeaderboards"], - customTimestamp = -1 + customTimestamp = -1, ): DailyLeaderboard | null { const { validModeRules, enabled } = dailyLeaderboardsConfig; diff --git a/backend/src/utils/discord.ts b/backend/src/utils/discord.ts index 6ac804f21e21..e290c02d5f75 100644 --- a/backend/src/utils/discord.ts +++ b/backend/src/utils/discord.ts @@ -18,7 +18,7 @@ type DiscordIdAndAvatar = z.infer; export async function getDiscordUser( tokenType: string, - accessToken: string + accessToken: string, ): Promise { const response = await fetch(`${BASE_URL}/users/@me`, { headers: { @@ -28,7 +28,7 @@ export async function getDiscordUser( const parsed = parseJsonWithSchema( await response.text(), - DiscordIdAndAvatarSchema + DiscordIdAndAvatarSchema, ); return parsed; @@ -53,7 +53,7 @@ export async function getOauthLink(uid: string): Promise { export async function iStateValidForUser( state: string, - uid: string + uid: string, ): Promise { const connection = RedisClient.getConnection(); if (!connection) { diff --git a/backend/src/utils/error.ts b/backend/src/utils/error.ts index 85df17f69028..e3a7f75a6bcd 100644 --- a/backend/src/utils/error.ts +++ b/backend/src/utils/error.ts @@ -63,7 +63,7 @@ class MonkeyError extends Error implements MonkeyServerErrorType { if (isDevEnvironment()) { this.message = - stack ?? "" + (stack ?? "") ? String(message) + "\nStack: " + String(stack) : String(message); } else { diff --git a/backend/src/utils/misc.ts b/backend/src/utils/misc.ts index 8a48e0fbd61d..4c11e0d3cf0e 100644 --- a/backend/src/utils/misc.ts +++ b/backend/src/utils/misc.ts @@ -53,10 +53,10 @@ export function buildAgentLog(req: MonkeyRequest): AgentLog { export function padNumbers( numbers: number[], maxLength: number, - fillString: string + fillString: string, ): string[] { return numbers.map((number) => - number.toString().padStart(maxLength, fillString) + number.toString().padStart(maxLength, fillString), ); } @@ -86,7 +86,7 @@ export function kogascore(wpm: number, acc: number, timestamp: number): number { export function flattenObjectDeep( obj: Record, - prefix = "" + prefix = "", ): Record { const result: Record = {}; const keys = Object.keys(obj); @@ -153,7 +153,7 @@ export const MONTH_IN_SECONDS = 1 * 30.4167 * DAY_IN_SECONDS; export const YEAR_IN_SECONDS = 1 * 12 * MONTH_IN_SECONDS; export function formatSeconds( - seconds: number + seconds: number, ): `${number} ${TimeUnit}${"s" | ""}` { let unit: TimeUnit; let secondsInUnit: number; @@ -196,8 +196,8 @@ export function getFrontendUrl(): string { return isDevEnvironment() ? "http://localhost:3000" : process.env["FRONTEND_URL"] !== undefined - ? process.env["FRONTEND_URL"] - : "https://monkeytype.com"; + ? process.env["FRONTEND_URL"] + : "https://monkeytype.com"; } /** @@ -207,13 +207,13 @@ export function getFrontendUrl(): string { */ export function replaceObjectId( - data: T + data: T, ): T & { _id: string }; export function replaceObjectId( - data: T | null + data: T | null, ): (T & { _id: string }) | null; export function replaceObjectId( - data: T | null + data: T | null, ): (T & { _id: string }) | null { if (data === null) { return null; @@ -231,7 +231,7 @@ export function replaceObjectId( * @returns api objects with `id: string` */ export function replaceObjectIds( - data: T[] + data: T[], ): (T & { _id: string })[] { if (data === undefined) return data; return data.map((it) => replaceObjectId(it)); @@ -242,7 +242,7 @@ export type WithObjectId = Omit & { export function omit( obj: T, - keys: K[] + keys: K[], ): Omit { const result = { ...obj }; for (const key of keys) { diff --git a/backend/src/utils/pb.ts b/backend/src/utils/pb.ts index 027ff09d87d1..164296ef5ebd 100644 --- a/backend/src/utils/pb.ts +++ b/backend/src/utils/pb.ts @@ -23,7 +23,7 @@ export function canFunboxGetPb(result: Result): boolean { export function checkAndUpdatePb( userPersonalBests: PersonalBests, lbPersonalBests: LbPersonalBests | undefined, - result: Result + result: Result, ): CheckAndUpdatePbResult { const mode = result.mode; const mode2 = result.mode2; @@ -33,7 +33,7 @@ export function checkAndUpdatePb( userPb[mode][mode2] ??= []; const personalBestMatch = (userPb[mode][mode2] as PersonalBest[]).find((pb) => - matchesPersonalBest(result, pb) + matchesPersonalBest(result, pb), ); let isPb = true; @@ -49,7 +49,7 @@ export function checkAndUpdatePb( const newLbPb = updateLeaderboardPersonalBests( userPb, lbPersonalBests, - result + result, ); if (newLbPb !== null) { lbPersonalBests = newLbPb; @@ -65,7 +65,7 @@ export function checkAndUpdatePb( function matchesPersonalBest( result: Result, - personalBest: PersonalBest + personalBest: PersonalBest, ): boolean { if ( result.difficulty === undefined || @@ -97,7 +97,7 @@ function matchesPersonalBest( function updatePersonalBest( personalBest: PersonalBest, - result: Result + result: Result, ): boolean { if (personalBest.wpm >= result.wpm) { return false; @@ -162,7 +162,7 @@ function buildPersonalBest(result: Result): PersonalBest { export function updateLeaderboardPersonalBests( userPersonalBests: PersonalBests, lbPersonalBests: LbPersonalBests, - result: Result + result: Result, ): LbPersonalBests | null { if (!shouldUpdateLeaderboardPersonalBests(result)) { return null; @@ -183,7 +183,7 @@ export function updateLeaderboardPersonalBests( ) { bestForEveryLanguage[language] = pb; } - } + }, ); Object.entries(bestForEveryLanguage).forEach(([language, pb]) => { const languageDoesNotExist = lbPb[mode][mode2]?.[language] === undefined; diff --git a/backend/src/utils/prometheus.ts b/backend/src/utils/prometheus.ts index 9761e5d2f3ed..6aa239e5501c 100644 --- a/backend/src/utils/prometheus.ts +++ b/backend/src/utils/prometheus.ts @@ -75,7 +75,7 @@ const leaderboardUpdate = new Gauge({ }); export function incrementAuth( - type: "Bearer" | "ApeKey" | "None" | "GithubWebhook" + type: "Bearer" | "ApeKey" | "None" | "GithubWebhook", ): void { auth.inc({ type }); } @@ -84,7 +84,7 @@ export function setLeaderboard( language: string, mode: string, mode2: string, - times: [number, number, number, number] + times: [number, number, number, number], ): void { leaderboardUpdate.set({ language, mode, mode2, step: "aggregate" }, times[0]); leaderboardUpdate.set({ language, mode, mode2, step: "loop" }, times[1]); @@ -138,7 +138,7 @@ export function incrementResult(res: CompletedEvent, isPb?: boolean): void { mode, mode2: m2, }, - res.wpm + res.wpm, ); resultAcc.observe( @@ -146,7 +146,7 @@ export function incrementResult(res: CompletedEvent, isPb?: boolean): void { mode, mode2: m2, }, - res.acc + res.acc, ); resultDuration.observe(res.testDuration); @@ -155,7 +155,7 @@ export function incrementResult(res: CompletedEvent, isPb?: boolean): void { export function incrementDailyLeaderboard( mode: string, mode2: string, - language: string + language: string, ): void { dailyLb.inc({ mode, mode2, language }); } @@ -213,7 +213,7 @@ export function recordAuthTime( type: string, status: "success" | "failure", time: number, - req: Request + req: Request, ): void { // for some reason route is not in the types // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access @@ -257,7 +257,7 @@ const tokenCacheAccess = new Counter({ }); export function recordTokenCacheAccess( - status: "hit" | "miss" | "hit_expired" + status: "hit" | "miss" | "hit_expired", ): void { tokenCacheAccess.inc({ status }); } @@ -309,7 +309,7 @@ const queueLength = new Gauge({ export function setQueueLength( queueName: string, countType: string, - length: number + length: number, ): void { queueLength.set({ queueName, countType }, length); } @@ -339,7 +339,7 @@ const timeToCompleteJobCount = new Counter({ export function recordTimeToCompleteJob( queueName: string, jobName: string, - time: number + time: number, ): void { timeToCompleteJobTotal.inc({ queueName, jobName }, time); timeToCompleteJobCount.inc({ queueName, jobName }); diff --git a/backend/src/utils/result.ts b/backend/src/utils/result.ts index 8b1b1f25186c..2c79813f8b22 100644 --- a/backend/src/utils/result.ts +++ b/backend/src/utils/result.ts @@ -19,7 +19,7 @@ export type DBResult = WithObjectId> & { export function buildDbResult( completedEvent: CompletedEvent, userName: string, - isPb: boolean + isPb: boolean, ): DBResult { const ce = completedEvent; const res: DBResult = { diff --git a/backend/src/workers/email-worker.ts b/backend/src/workers/email-worker.ts index 59a8daccccf2..e7e91d55b45a 100644 --- a/backend/src/workers/email-worker.ts +++ b/backend/src/workers/email-worker.ts @@ -39,7 +39,7 @@ export default (redisConnection?: IORedis.Redis): Worker => { }); worker.on("failed", (job, error) => { Logger.error( - `Job: ${job.data.type} - failed with error "${error.message}"` + `Job: ${job.data.type} - failed with error "${error.message}"`, ); }); return worker; diff --git a/backend/src/workers/later-worker.ts b/backend/src/workers/later-worker.ts index 5b390e3d6513..d1a039910f61 100644 --- a/backend/src/workers/later-worker.ts +++ b/backend/src/workers/later-worker.ts @@ -19,7 +19,7 @@ import { isSafeNumber, mapRange } from "@monkeytype/util/numbers"; import { RewardBracket } from "@monkeytype/schemas/configuration"; async function handleDailyLeaderboardResults( - ctx: LaterTaskContexts["daily-leaderboard-results"] + ctx: LaterTaskContexts["daily-leaderboard-results"], ): Promise { const { yesterdayTimestamp, modeRule } = ctx; const { language, mode, mode2 } = modeRule; @@ -33,7 +33,7 @@ async function handleDailyLeaderboardResults( const maxRankToGet = Math.max( topResultsToAnnounce, - ...xpRewardBrackets.map((bracket) => bracket.maxRank) + ...xpRewardBrackets.map((bracket) => bracket.maxRank), ); const dailyLeaderboard = new DailyLeaderboard(modeRule, yesterdayTimestamp); @@ -42,7 +42,7 @@ async function handleDailyLeaderboardResults( 0, maxRankToGet, dailyLeaderboardsConfig, - false + false, ); if (results === null || results.entries.length === 0) { @@ -87,19 +87,19 @@ async function handleDailyLeaderboardResults( const topResults = results.entries.slice( 0, - dailyLeaderboardsConfig.topResultsToAnnounce + dailyLeaderboardsConfig.topResultsToAnnounce, ); const leaderboardId = `${mode} ${mode2} ${language}`; await GeorgeQueue.announceDailyLeaderboardTopResults( leaderboardId, yesterdayTimestamp, - topResults + topResults, ); } async function handleWeeklyXpLeaderboardResults( - ctx: LaterTaskContexts["weekly-xp-leaderboard-results"] + ctx: LaterTaskContexts["weekly-xp-leaderboard-results"], ): Promise { const { leaderboards: { weeklyXp: weeklyXpConfig }, @@ -115,14 +115,14 @@ async function handleWeeklyXpLeaderboardResults( const weeklyXpLeaderboard = new WeeklyXpLeaderboard(lastWeekTimestamp); const maxRankToGet = Math.max( - ...xpRewardBrackets.map((bracket) => bracket.maxRank) + ...xpRewardBrackets.map((bracket) => bracket.maxRank), ); const allResults = await weeklyXpLeaderboard.getResults( 0, maxRankToGet, weeklyXpConfig, - false + false, ); if (allResults === null || allResults.entries.length === 0) { @@ -147,7 +147,7 @@ async function handleWeeklyXpLeaderboardResults( const rewardMail = buildMonkeyMail({ subject: "Weekly XP Leaderboard placement", body: `Congratulations ${name} on placing ${placementString} with ${xp} xp! Last week, you typed for a total of ${formatSeconds( - timeTypedSeconds + timeTypedSeconds, )}! Keep up the good work :)`, rewards: [ { @@ -188,7 +188,7 @@ async function jobHandler(job: Job>): Promise { function calculateXpReward( xpRewardBrackets: RewardBracket[], - rank: number + rank: number, ): number | undefined { const rewards = xpRewardBrackets .filter((bracket) => rank >= bracket.minRank && rank <= bracket.maxRank) @@ -198,8 +198,8 @@ function calculateXpReward( bracket.minRank, bracket.maxRank, bracket.maxReward, - bracket.minReward - ) + bracket.minReward, + ), ); return rewards.length ? Math.max(...rewards) : undefined; } @@ -211,7 +211,7 @@ export default (redisConnection?: IORedis.Redis): Worker => { }); worker.on("failed", (job, error) => { Logger.error( - `Job: ${job.data.taskName} - failed with error "${error.message}"` + `Job: ${job.data.taskName} - failed with error "${error.message}"`, ); }); return worker; diff --git a/frontend/__tests__/commandline/util.spec.ts b/frontend/__tests__/commandline/util.spec.ts index f3ba297842a8..ac69f9db29b3 100644 --- a/frontend/__tests__/commandline/util.spec.ts +++ b/frontend/__tests__/commandline/util.spec.ts @@ -211,7 +211,7 @@ describe("CommandlineUtils", () => { alias: "alias", input: true, icon: "icon", - }) + }), ); }); @@ -300,7 +300,7 @@ describe("CommandlineUtils", () => { expect(cmd).toEqual( expect.objectContaining({ inputValueConvert: Number, - }) + }), ); }); @@ -318,7 +318,7 @@ describe("CommandlineUtils", () => { expect(cmd).toEqual( expect.objectContaining({ validation: { schema }, - }) + }), ); }); @@ -350,7 +350,7 @@ describe("CommandlineUtils", () => { expect(cmd).toEqual( expect.objectContaining({ validation: { schema }, - }) + }), ); }); @@ -370,7 +370,7 @@ describe("CommandlineUtils", () => { expect(cmd).toEqual( expect.objectContaining({ validation: { isValid }, - }) + }), ); }); @@ -391,7 +391,7 @@ describe("CommandlineUtils", () => { expect.objectContaining({ id: "setMySecondKeyCustom", display: "MySecondKey...", - }) + }), ); }); }); @@ -412,6 +412,6 @@ function buildCommand({ key ?? ("" as any), configMeta ?? ({} as any), cmdMeta as any, - schema ?? z.string() + schema ?? z.string(), ); } diff --git a/frontend/__tests__/controllers/preset-controller.spec.ts b/frontend/__tests__/controllers/preset-controller.spec.ts index df10421fc3e4..bdbca77e1060 100644 --- a/frontend/__tests__/controllers/preset-controller.spec.ts +++ b/frontend/__tests__/controllers/preset-controller.spec.ts @@ -19,11 +19,11 @@ describe("PresetController", () => { const configApplyMock = vi.spyOn(UpdateConfig, "apply"); const configSaveFullConfigMock = vi.spyOn( UpdateConfig, - "saveFullConfigToLocalStorage" + "saveFullConfigToLocalStorage", ); const configGetConfigChangesMock = vi.spyOn( UpdateConfig, - "getConfigChanges" + "getConfigChanges", ); const notificationAddMock = vi.spyOn(Notifications, "add"); const testRestartMock = vi.spyOn(TestLogic, "restart"); @@ -31,7 +31,7 @@ describe("PresetController", () => { const tagControllerSetMock = vi.spyOn(TagController, "set"); const tagControllerSaveActiveMock = vi.spyOn( TagController, - "saveActiveToLocalStorage" + "saveActiveToLocalStorage", ); beforeEach(() => { @@ -82,13 +82,13 @@ describe("PresetController", () => { 1, "tagOne", true, - false + false, ); expect(tagControllerSetMock).toHaveBeenNthCalledWith( 2, "tagTwo", true, - false + false, ); expect(tagControllerSaveActiveMock).toHaveBeenCalled(); }); @@ -143,13 +143,13 @@ describe("PresetController", () => { 1, "tagOne", true, - false + false, ); expect(tagControllerSetMock).toHaveBeenNthCalledWith( 2, "tagTwo", true, - false + false, ); expect(tagControllerSaveActiveMock).toHaveBeenCalled(); }); diff --git a/frontend/__tests__/elements/test-activity-calendar.spec.ts b/frontend/__tests__/elements/test-activity-calendar.spec.ts index db2c51d4cbe0..9a7a13f7df38 100644 --- a/frontend/__tests__/elements/test-activity-calendar.spec.ts +++ b/frontend/__tests__/elements/test-activity-calendar.spec.ts @@ -312,7 +312,7 @@ describe("test-activity-calendar.ts", () => { [], getDate("2023-05-10"), 0, - true + true, ); expect(calendar.getMonths()).toEqual([ @@ -371,7 +371,7 @@ describe("test-activity-calendar.ts", () => { [], getDate("2023-05-10"), 1, - true + true, ); expect(calendar.getMonths()).toEqual([ @@ -430,7 +430,7 @@ describe("test-activity-calendar.ts", () => { [], getDate("2024-05-10"), 0, - true + true, ); expect(calendar.getMonths()).toEqual([ @@ -489,7 +489,7 @@ describe("test-activity-calendar.ts", () => { [], getDate("2024-05-10"), 1, - true + true, ); expect(calendar.getMonths()).toEqual([ @@ -668,7 +668,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-04-10"), - 0 + 0, ); const days = calendar.getDays(); @@ -707,7 +707,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-04-10"), - 1 + 1, ); const days = calendar.getDays(); @@ -748,7 +748,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-12-31"), - 0 + 0, ); //WHEN @@ -780,7 +780,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-12-31"), - 1 + 1, ); //WHEN @@ -812,7 +812,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, new Date("2023-12-31T23:59:59Z"), - 0 + 0, ); //2023-12-31T23:59:59Z //WHEN @@ -849,7 +849,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-04-10"), - 0 + 0, ); //WHEN @@ -875,7 +875,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2024-04-10"), - 0 + 0, ); //WHEN @@ -907,7 +907,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2023-02-10"), - 0 + 0, ); //WHEN @@ -945,7 +945,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new TestActivityCalendar( data, getDate("2023-02-10"), - 0 + 0, ); //WHEN @@ -978,7 +978,7 @@ describe("test-activity-calendar.ts", () => { data, getDate("2024-02-10"), 0, - true + true, ); //WHEN @@ -1007,7 +1007,7 @@ describe("test-activity-calendar.ts", () => { data, getDate("2024-02-10"), 1, - true + true, ); //WHEN @@ -1040,7 +1040,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3], lastDate, - 0 + 0, ); //WHEN @@ -1062,7 +1062,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3], lastDate, - 0 + 0, ); //WHEN @@ -1100,7 +1100,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3], getDate("2024-04-10"), - 0 + 0, ); //WHEN @@ -1125,7 +1125,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( getData("2023-12-20", "2024-12-24"), getDate("2024-12-24"), - 0 + 0, ); //WHEN @@ -1146,12 +1146,12 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3], getDate("2024-04-10"), - 0 + 0, ); //WHEN expect(() => calendar.increment(getDate("2024-04-09"))).toThrowError( - new Error("cannot alter data in the past.") + new Error("cannot alter data in the past."), ); }); }); @@ -1166,7 +1166,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3, 4], lastDate, - 0 + 0, ); //WHEN @@ -1199,7 +1199,7 @@ describe("test-activity-calendar.ts", () => { const calendar = new ModifiableTestActivityCalendar( [1, 2, 3, 4], lastDate, - 0 + 0, ); //THEN @@ -1221,7 +1221,7 @@ function getData(from: string, to: string): number[] { const end = getDate(to); return Dates.eachDayOfInterval({ start, end }).map((it) => - Dates.getDayOfYear(it) + Dates.getDayOfYear(it), ); } @@ -1250,7 +1250,7 @@ expect.extend({ }, toHaveLevel( received: TestActivityDay, - expected: string | number + expected: string | number, ): MatcherResult { return { pass: received.level === expected.toString(), diff --git a/frontend/__tests__/input/helpers/fail-or-finish.spec.ts b/frontend/__tests__/input/helpers/fail-or-finish.spec.ts index 792592c8704e..c45977d7e1b9 100644 --- a/frontend/__tests__/input/helpers/fail-or-finish.spec.ts +++ b/frontend/__tests__/input/helpers/fail-or-finish.spec.ts @@ -12,9 +12,8 @@ import * as Strings from "../../../src/ts/utils/strings"; const { replaceConfig } = __testing; vi.mock("../../../src/ts/utils/misc", async (importOriginal) => { - const actual = await importOriginal< - typeof import("../../../src/ts/utils/misc") - >(); + const actual = + await importOriginal(); return { ...actual, whorf: vi.fn(), @@ -360,6 +359,6 @@ describe("checkIfFinished", () => { }); expect(result).toBe(expected); - } + }, ); }); diff --git a/frontend/__tests__/input/helpers/validation.spec.ts b/frontend/__tests__/input/helpers/validation.spec.ts index 9554f01c6168..08920a5a1465 100644 --- a/frontend/__tests__/input/helpers/validation.spec.ts +++ b/frontend/__tests__/input/helpers/validation.spec.ts @@ -16,7 +16,7 @@ vi.mock("../../../src/ts/test/funbox/list", () => ({ vi.mock("../../../src/ts/utils/strings", async () => { const actual = await vi.importActual( - "../../../src/ts/utils/strings" + "../../../src/ts/utils/strings", ); return { ...actual, @@ -36,7 +36,7 @@ describe("isCharCorrect", () => { strictSpace: false, }); (FunboxList.findSingleActiveFunboxWithFunction as any).mockReturnValue( - null + null, ); (Strings.areCharactersVisuallyEqual as any).mockReturnValue(false); }); @@ -54,7 +54,7 @@ describe("isCharCorrect", () => { inputValue: "test", targetWord: "word", correctShiftUsed: true, - }) + }), ).toBe(true); }); }); @@ -67,7 +67,7 @@ describe("isCharCorrect", () => { inputValue: "test", targetWord: "testA", correctShiftUsed: false, - }) + }), ).toBe(false); }); }); @@ -98,7 +98,7 @@ describe("isCharCorrect", () => { inputValue: input, targetWord: word, correctShiftUsed: true, - }) + }), ).toBe(expected); }); }); @@ -117,9 +117,9 @@ describe("isCharCorrect", () => { inputValue: input, targetWord: word, correctShiftUsed: true, - }) + }), ).toBe(expected); - } + }, ); }); @@ -130,7 +130,7 @@ describe("isCharCorrect", () => { inputValue: "val", targetWord: "word", correctShiftUsed: true, - }) + }), ).toThrow(); }); }); @@ -155,7 +155,7 @@ describe("shouldInsertSpaceCharacter", () => { data: "a", inputValue: "test", targetWord: "test", - }) + }), ).toBe(null); }); @@ -166,7 +166,7 @@ describe("shouldInsertSpaceCharacter", () => { data: " ", inputValue: "test", targetWord: "test", - }) + }), ).toBe(false); }); @@ -270,7 +270,7 @@ describe("shouldInsertSpaceCharacter", () => { data: " ", inputValue, targetWord, - }) + }), ).toBe(expected); }); }); diff --git a/frontend/__tests__/root/config-metadata.spec.ts b/frontend/__tests__/root/config-metadata.spec.ts index 918a87f84260..04434bfd2f58 100644 --- a/frontend/__tests__/root/config-metadata.spec.ts +++ b/frontend/__tests__/root/config-metadata.spec.ts @@ -44,7 +44,7 @@ describe("ConfigMeta", () => { "lazyMode", "layout", "codeUnindentOnBackspace", - ].sort() + ].sort(), ); }); @@ -61,7 +61,7 @@ describe("ConfigMeta", () => { "maxLineWidth", "tapeMode", "tapeMargin", - ].sort() + ].sort(), ); }); describe("overrideValue", () => { @@ -129,8 +129,8 @@ describe("ConfigMeta", () => { it.for( Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) + value.flatMap((it) => ({ key: key as ConfigKey, ...it })), + ), )( `$key value=$value given=$given expect=$expected`, ({ key, value, given, expected }) => { @@ -142,7 +142,7 @@ describe("ConfigMeta", () => { //THEN expect(getConfig()).toMatchObject(expected); - } + }, ); }); describe("isBlocked", () => { @@ -166,8 +166,8 @@ describe("ConfigMeta", () => { it.for( Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) + value.flatMap((it) => ({ key: key as ConfigKey, ...it })), + ), )( `$key value=$value given=$given fail=$fail`, ({ key, value, given, fail }) => { @@ -179,7 +179,7 @@ describe("ConfigMeta", () => { //THEN expect(applied).toEqual(!fail); - } + }, ); }); @@ -326,8 +326,8 @@ describe("ConfigMeta", () => { it.for( Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) + value.flatMap((it) => ({ key: key as ConfigKey, ...it })), + ), )( `$key value=$value given=$given expected=$expected`, ({ key, value, given, expected }) => { @@ -339,7 +339,7 @@ describe("ConfigMeta", () => { //THEN expect(getConfig()).toMatchObject(expected ?? {}); - } + }, ); }); }); diff --git a/frontend/__tests__/root/config.spec.ts b/frontend/__tests__/root/config.spec.ts index fa431d82b646..4200272685f1 100644 --- a/frontend/__tests__/root/config.spec.ts +++ b/frontend/__tests__/root/config.spec.ts @@ -26,11 +26,11 @@ describe("Config", () => { describe("test with mocks", () => { const canSetConfigWithCurrentFunboxesMock = vi.spyOn( FunboxValidation, - "canSetConfigWithCurrentFunboxes" + "canSetConfigWithCurrentFunboxes", ); const isConfigValueValidMock = vi.spyOn( ConfigValidation, - "isConfigValueValid" + "isConfigValueValid", ); const dispatchConfigEventMock = vi.spyOn(ConfigEvent, "dispatch"); const dbSaveConfigMock = vi.spyOn(DB, "saveConfig"); @@ -76,7 +76,7 @@ describe("Config", () => { expect(() => { Config.genericSet("nonExistentKey" as ConfigKey, true); }).toThrowError( - `Config metadata for key "nonExistentKey" is not defined.` + `Config metadata for key "nonExistentKey" is not defined.`, ); }); @@ -93,7 +93,7 @@ describe("Config", () => { 0, { important: true, - } + }, ); }); @@ -123,7 +123,7 @@ describe("Config", () => { expect(isConfigValueValidMock).toHaveBeenCalledWith( "caret style", "banana", - CaretStyleSchema + CaretStyleSchema, ); }); @@ -151,21 +151,21 @@ describe("Config", () => { "freedomMode", false, true, - true + true, ); expect(dispatchConfigEventMock).toHaveBeenCalledWith( "stopOnError", "off", false, - "letter" + "letter", ); expect(dispatchConfigEventMock).toHaveBeenCalledWith( "confidenceMode", "max", false, - "off" + "off", ); }); @@ -192,7 +192,7 @@ describe("Config", () => { //send event expect(dispatchConfigEventMock).toHaveBeenCalledWith( "saveToLocalStorage", - expect.stringContaining("numbers") + expect.stringContaining("numbers"), ); }); @@ -216,11 +216,11 @@ describe("Config", () => { //send event expect(dispatchConfigEventMock).toHaveBeenCalledWith( "saveToLocalStorage", - expect.stringContaining("minWpmCustomSpeed") + expect.stringContaining("minWpmCustomSpeed"), ); expect(dispatchConfigEventMock).toHaveBeenCalledWith( "saveToLocalStorage", - expect.stringContaining("minWpm") + expect.stringContaining("minWpm"), ); }); @@ -241,7 +241,7 @@ describe("Config", () => { expect(dispatchConfigEventMock).not.toHaveBeenCalledWith( "saveToLocalStorage", - expect.any(String) + expect.any(String), ); }); @@ -258,7 +258,7 @@ describe("Config", () => { "numbers", true, true, - false + false, ); }); @@ -294,7 +294,7 @@ describe("Config", () => { //THEN expect(notificationAddMock).toHaveBeenCalledWith( "Ad settings changed. Refreshing...", - 0 + 0, ); expect(miscReloadAfterMock).toHaveBeenCalledWith(3); }); @@ -329,7 +329,7 @@ describe("Config", () => { //arrays not having 4 values will get [on, on, on, on] as default expect(Config.setAccountChart(["on", "off"] as any)).toBe(false); expect(Config.setAccountChart(["on", "off", "on", "true"] as any)).toBe( - false + false, ); }); it("setStopOnError", () => { @@ -509,12 +509,12 @@ describe("Config", () => { expect(Config.setCustomBackgroundFilter([0, 1, 2, 3])).toBe(true); expect(Config.setCustomBackgroundFilter([0, 1, 2, 3, 4] as any)).toBe( - false + false, ); expect(Config.setCustomBackgroundFilter([] as any)).toBe(false); expect(Config.setCustomBackgroundFilter(["invalid"] as any)).toBe(false); expect(Config.setCustomBackgroundFilter([1, 2, 3, 4, 5, 6] as any)).toBe( - false + false, ); }); it("setMonkeyPowerLevel", () => { @@ -551,7 +551,7 @@ describe("Config", () => { expect(Config.setAccountChart(["on", "off", "off", "on"])).toBe(true); expect(Config.setAccountChart(["on", "off"] as any)).toBe(false); expect(Config.setAccountChart(["on", "off", "on", "true"] as any)).toBe( - false + false, ); }); it("setAlwaysShowDecimalPlaces", () => { @@ -732,28 +732,30 @@ describe("Config", () => { }); it("setCustomBackground", () => { expect(Config.setCustomBackground("http://example.com/test.png")).toBe( - true + true, ); expect(Config.setCustomBackground("https://www.example.com/test.gif")).toBe( - true + true, ); expect(Config.setCustomBackground("https://example.com/test.jpg")).toBe( - true + true, ); expect(Config.setCustomBackground("http://www.example.com/test.jpeg")).toBe( - true + true, ); //gets converted expect( - Config.setCustomBackground(" http://example.com/test.png ") + Config.setCustomBackground(" http://example.com/test.png "), ).toBe(true); expect(Config.setCustomBackground("http://www.example.com/test.tiff")).toBe( - false + false, ); expect( - Config.setCustomBackground("http://www.example.com/test?test=foo&bar=baz") + Config.setCustomBackground( + "http://www.example.com/test?test=foo&bar=baz", + ), ).toBe(false); expect(Config.setCustomBackground("invalid")).toBe(false); }); @@ -836,8 +838,8 @@ describe("Config", () => { const config = getConfig(); const applied = Object.fromEntries( Object.entries(config).filter(([key]) => - Object.keys(expected).includes(key) - ) + Object.keys(expected).includes(key), + ), ); expect(applied).toEqual(expected); }); @@ -872,8 +874,8 @@ describe("Config", () => { const config = getConfig(); const applied = Object.fromEntries( Object.entries(config).filter(([key]) => - Object.keys(expected).includes(key) - ) + Object.keys(expected).includes(key), + ), ); expect(applied).toEqual(expected); }); diff --git a/frontend/__tests__/test/british-english.spec.ts b/frontend/__tests__/test/british-english.spec.ts index edf4ab6a144d..b0650bc89bc0 100644 --- a/frontend/__tests__/test/british-english.spec.ts +++ b/frontend/__tests__/test/british-english.spec.ts @@ -32,10 +32,10 @@ describe("british-english", () => { it("should replace hyphenated words", async () => { await expect(replace("cream-colored", "")).resolves.toEqual( - "cream-coloured" + "cream-coloured", ); await expect(replace("armor-flavoring", "")).resolves.toEqual( - "armour-flavouring" + "armour-flavouring", ); }); @@ -43,7 +43,7 @@ describe("british-english", () => { await expect(replace('"hello"', "")).resolves.toEqual("'hello'"); await expect(replace('"test"', "")).resolves.toEqual("'test'"); await expect(replace('"Hello World"', "")).resolves.toEqual( - "'Hello World'" + "'Hello World'", ); }); @@ -55,7 +55,7 @@ describe("british-english", () => { it("should handle multiple double quotes in a word", async () => { await expect( - replace('He said "hello" and "goodbye"', "") + replace('He said "hello" and "goodbye"', ""), ).resolves.toEqual("He said 'hello' and 'goodbye'"); }); diff --git a/frontend/__tests__/test/funbox.spec.ts b/frontend/__tests__/test/funbox.spec.ts index d84f73103da4..a415602abbd1 100644 --- a/frontend/__tests__/test/funbox.spec.ts +++ b/frontend/__tests__/test/funbox.spec.ts @@ -17,7 +17,7 @@ describe("funbox", () => { } expect(packageFunctions, `Funbox ${funbox.name} ${message}`).toEqual( - implementations + implementations, ); } }); diff --git a/frontend/__tests__/test/funbox/funbox-validation.spec.ts b/frontend/__tests__/test/funbox/funbox-validation.spec.ts index 85feedf2ada3..776b757957d8 100644 --- a/frontend/__tests__/test/funbox/funbox-validation.spec.ts +++ b/frontend/__tests__/test/funbox/funbox-validation.spec.ts @@ -54,7 +54,7 @@ describe("funbox-validation", () => { value, funbox: [funbox], error: `You can't set mode to ${value} with currently active funboxes.`, - })) + })), ), { key: "mode", value: "quote", funbox: ["space_balls"] }, //no frontendFunctions ]; @@ -62,7 +62,7 @@ describe("funbox-validation", () => { `check $funbox with $key=$value`, ({ key, value, funbox, error }) => { expect( - canSetConfigWithCurrentFunboxes(key, value, funbox as FunboxName[]) + canSetConfigWithCurrentFunboxes(key, value, funbox as FunboxName[]), ).toBe(error === undefined); if (error !== undefined) { @@ -70,7 +70,7 @@ describe("funbox-validation", () => { duration: 5, }); } - } + }, ); }); }); diff --git a/frontend/__tests__/test/layout-emulator.spec.ts b/frontend/__tests__/test/layout-emulator.spec.ts index 4ea324ceebea..5dc0b902f5b9 100644 --- a/frontend/__tests__/test/layout-emulator.spec.ts +++ b/frontend/__tests__/test/layout-emulator.spec.ts @@ -15,12 +15,12 @@ describe("LayoutEmulator", () => { const createEvent = ( code: string, - type: string + type: string, ): JQuery.KeyboardEventBase => ({ code, type, - } as JQuery.KeyboardEventBase); + }) as JQuery.KeyboardEventBase; it("should set isAltGrPressed to true on AltRight keydown", () => { const event = createEvent("AltRight", "keydown"); diff --git a/frontend/__tests__/utils/colors.spec.ts b/frontend/__tests__/utils/colors.spec.ts index 53a51918c653..fbb37a473f30 100644 --- a/frontend/__tests__/utils/colors.spec.ts +++ b/frontend/__tests__/utils/colors.spec.ts @@ -154,7 +154,7 @@ describe("colors.ts", () => { ({ color1, color2, alpha, expected }) => { const result = blendTwoHexColors(color1, color2, alpha); expect(result).toBe(expected); - } + }, ); // cases.forEach(({ color1, color2, alpha, expected }) => { diff --git a/frontend/__tests__/utils/config.spec.ts b/frontend/__tests__/utils/config.spec.ts index ff76596eefa2..085cab2cf46c 100644 --- a/frontend/__tests__/utils/config.spec.ts +++ b/frontend/__tests__/utils/config.spec.ts @@ -65,7 +65,7 @@ describe("config.ts", () => { }, ])(`$given`, ({ given, expected }) => { const description = `given: ${JSON.stringify( - given + given, )}, expected: ${JSON.stringify(expected)} `; const result = migrateConfig(given); expect(result, description).toEqual(expect.objectContaining(expected)); @@ -105,7 +105,7 @@ describe("config.ts", () => { //WHEN const description = `given: ${JSON.stringify( - given + given, )}, expected: ${JSON.stringify(expected)} `; const result = migrateConfig(given); @@ -241,7 +241,7 @@ describe("config.ts", () => { }, ])(`$given`, ({ given, expected }) => { const description = `given: ${JSON.stringify( - given + given, )}, expected: ${JSON.stringify(expected)} `; const result = migrateConfig(given); diff --git a/frontend/__tests__/utils/date-and-time.spec.ts b/frontend/__tests__/utils/date-and-time.spec.ts index 93cd1a106061..9b7f13047ee5 100644 --- a/frontend/__tests__/utils/date-and-time.spec.ts +++ b/frontend/__tests__/utils/date-and-time.spec.ts @@ -81,9 +81,9 @@ describe("date-and-time", () => { expect(DateAndTime.getFirstDayOfTheWeek()).toEqual( firefoxFirstDayOfWeek !== undefined ? firefoxFirstDayOfWeek - : firstDayOfWeek + : firstDayOfWeek, ); - } + }, ); }); }); diff --git a/frontend/__tests__/utils/format.spec.ts b/frontend/__tests__/utils/format.spec.ts index 70b54494f80d..7bd477a67eea 100644 --- a/frontend/__tests__/utils/format.spec.ts +++ b/frontend/__tests__/utils/format.spec.ts @@ -49,12 +49,12 @@ describe("format.ts", () => { expect(format.typingSpeed(null, { fallback: "none" })).toEqual("none"); expect(format.typingSpeed(null, { fallback: "" })).toEqual(""); expect(format.typingSpeed(undefined, { fallback: "none" })).toEqual( - "none" + "none", ); expect(format.typingSpeed(undefined, { fallback: "" })).toEqual(""); expect(format.typingSpeed(undefined, { fallback: undefined })).toEqual( - "" + "", ); }); @@ -65,7 +65,7 @@ describe("format.ts", () => { alwaysShowDecimalPlaces: false, }); expect( - wpmNoDecimals.typingSpeed(100, { showDecimalPlaces: true }) + wpmNoDecimals.typingSpeed(100, { showDecimalPlaces: true }), ).toEqual("100.00"); //force without decimals const wpmWithDecimals = getInstance({ @@ -73,7 +73,7 @@ describe("format.ts", () => { alwaysShowDecimalPlaces: true, }); expect( - wpmWithDecimals.typingSpeed(100, { showDecimalPlaces: false }) + wpmWithDecimals.typingSpeed(100, { showDecimalPlaces: false }), ).toEqual("100"); }); @@ -120,7 +120,7 @@ describe("format.ts", () => { expect(format.percentage(null, { fallback: "none" })).toEqual("none"); expect(format.percentage(null, { fallback: "" })).toEqual(""); expect(format.percentage(undefined, { fallback: "none" })).toEqual( - "none" + "none", ); expect(format.percentage(undefined, { fallback: "" })).toEqual(""); @@ -131,12 +131,12 @@ describe("format.ts", () => { //force with decimals const noDecimals = getInstance({ alwaysShowDecimalPlaces: false }); expect(noDecimals.percentage(100, { showDecimalPlaces: true })).toEqual( - "100.00%" + "100.00%", ); //force without decimals const withDecimals = getInstance({ alwaysShowDecimalPlaces: true }); expect( - withDecimals.percentage(100, { showDecimalPlaces: false }) + withDecimals.percentage(100, { showDecimalPlaces: false }), ).toEqual("100%"); }); @@ -207,12 +207,12 @@ describe("format.ts", () => { //force with decimals const noDecimals = getInstance({ alwaysShowDecimalPlaces: false }); expect(noDecimals.decimals(100, { showDecimalPlaces: true })).toEqual( - "100.00" + "100.00", ); //force without decimals const withDecimals = getInstance({ alwaysShowDecimalPlaces: true }); expect(withDecimals.decimals(100, { showDecimalPlaces: false })).toEqual( - "100" + "100", ); }); diff --git a/frontend/__tests__/utils/generate.spec.ts b/frontend/__tests__/utils/generate.spec.ts index 544051a006a7..5765fc800d65 100644 --- a/frontend/__tests__/utils/generate.spec.ts +++ b/frontend/__tests__/utils/generate.spec.ts @@ -6,7 +6,7 @@ describe("hexadecimal", () => { const hex = generate.getHexadecimal(); expect(hex.length).toSatisfy( (len: number) => len % 2 === 0, - "The length of the hexadecimal string should be even." + "The length of the hexadecimal string should be even.", ); expect(hex.length).toBeGreaterThanOrEqual(2); diff --git a/frontend/__tests__/utils/ip-addresses.spec.ts b/frontend/__tests__/utils/ip-addresses.spec.ts index 5ae0476184b0..3dbf07f950c7 100644 --- a/frontend/__tests__/utils/ip-addresses.spec.ts +++ b/frontend/__tests__/utils/ip-addresses.spec.ts @@ -29,7 +29,7 @@ describe("IP Addresses", () => { for (let i = 0; i < rawIps.length; i++) { expect(IpAddresses.compressIpv6(rawIps[i] as string)).toEqual( - compressedIps[i] + compressedIps[i], ); } }); @@ -43,18 +43,18 @@ describe("IP Addresses", () => { const splitIpAddress = ipAddress.split("."); expect(splitIpAddress.length, "Make sure there are four parts").toEqual( - 4 + 4, ); for (let j = 0; j < 4; j++) { const currentNumber = Number(splitIpAddress[j]); expect( currentNumber, - "Each part of an IPv4 should be >= 0" + "Each part of an IPv4 should be >= 0", ).toBeGreaterThanOrEqual(0); expect( currentNumber, - "Each part of an IPv4 should be <= 255" + "Each part of an IPv4 should be <= 255", ).toBeLessThanOrEqual(255); } } @@ -69,32 +69,32 @@ describe("IP Addresses", () => { expect( splitIpAddress.length, - "Make sure there are eight parts" + "Make sure there are eight parts", ).toEqual(8); for (let j = 0; j < 8; j++) { const currentPart = splitIpAddress[j] as string; expect( currentPart.length, - "Each part of an IPv6 should be between 1 and 4 characters" + "Each part of an IPv6 should be between 1 and 4 characters", ).toBeGreaterThanOrEqual(1); expect( currentPart.length, - "Each part of an IPv6 should be between 1 and 4 characters" + "Each part of an IPv6 should be between 1 and 4 characters", ).toBeLessThanOrEqual(4); const currentNumber = parseInt(currentPart, 16); expect( currentNumber, - "Each part of an IPv6 should be a valid hexadecimal number" + "Each part of an IPv6 should be a valid hexadecimal number", ).not.toBeNaN(); expect( currentNumber, - "Each part of an IPv6 should be >= 0" + "Each part of an IPv6 should be >= 0", ).toBeGreaterThanOrEqual(0); expect( currentNumber, - "Each part of an IPv6 should be <= 65535" + "Each part of an IPv6 should be <= 65535", ).toBeLessThanOrEqual(65535); } } @@ -108,7 +108,7 @@ describe("IP Addresses", () => { const ipParts = cidr.split("/"); expect( ipParts.length, - "There should only be one '/' in the ip addresss" + "There should only be one '/' in the ip addresss", ).toEqual(2); const maskSize = Number(ipParts[1]); expect(maskSize).not.toBeNaN(); @@ -122,7 +122,7 @@ describe("IP Addresses", () => { const ipParts = cidr.split("/"); expect( ipParts.length, - "There should only be one '/' in the ip addresss" + "There should only be one '/' in the ip addresss", ).toEqual(2); console.log(cidr); const maskSize = Number(ipParts[1]); diff --git a/frontend/__tests__/utils/key-converter.spec.ts b/frontend/__tests__/utils/key-converter.spec.ts index ec09d2d33428..40be7199bfc3 100644 --- a/frontend/__tests__/utils/key-converter.spec.ts +++ b/frontend/__tests__/utils/key-converter.spec.ts @@ -5,14 +5,14 @@ import { layoutKeyToKeycode } from "../../src/ts/utils/key-converter"; const isoDvorak = JSON.parse( readFileSync( import.meta.dirname + "/../../static/layouts/swedish_dvorak.json", - "utf-8" - ) + "utf-8", + ), ); const dvorak = JSON.parse( readFileSync( import.meta.dirname + "/../../static/layouts/dvorak.json", - "utf-8" - ) + "utf-8", + ), ); describe("key-converter", () => { diff --git a/frontend/__tests__/utils/local-storage-with-schema.spec.ts b/frontend/__tests__/utils/local-storage-with-schema.spec.ts index ee9cd3d85e2a..112776c50aa2 100644 --- a/frontend/__tests__/utils/local-storage-with-schema.spec.ts +++ b/frontend/__tests__/utils/local-storage-with-schema.spec.ts @@ -52,7 +52,7 @@ describe("local-storage-with-schema.ts", () => { expect(localStorage.setItem).toHaveBeenCalledWith( "config", - JSON.stringify(defaultObject) + JSON.stringify(defaultObject), ); expect(res).toBe(true); }); @@ -116,7 +116,7 @@ describe("local-storage-with-schema.ts", () => { expect(getItemMock).toHaveBeenCalledWith("config"); expect(setItemMock).toHaveBeenCalledWith( "config", - JSON.stringify(defaultObject) + JSON.stringify(defaultObject), ); expect(res).toEqual(defaultObject); @@ -152,7 +152,7 @@ describe("local-storage-with-schema.ts", () => { expect(getItemMock).toHaveBeenCalledWith("config"); expect(setItemMock).toHaveBeenCalledWith( "config", - JSON.stringify(defaultObject) + JSON.stringify(defaultObject), ); expect(res).toEqual(defaultObject); @@ -186,11 +186,11 @@ describe("local-storage-with-schema.ts", () => { expect(getItemMock).toHaveBeenCalledWith("config"); expect(migrateFnMock).toHaveBeenCalledWith( existingValue, - expect.any(Array) + expect.any(Array), ); expect(setItemMock).toHaveBeenCalledWith( "config", - JSON.stringify(migrated) + JSON.stringify(migrated), ); expect(res).toEqual(migrated); @@ -224,11 +224,11 @@ describe("local-storage-with-schema.ts", () => { expect(getItemMock).toHaveBeenCalledWith("config"); expect(migrateFnMock).toHaveBeenCalledWith( existingValue, - expect.any(Array) + expect.any(Array), ); expect(setItemMock).toHaveBeenCalledWith( "config", - JSON.stringify(defaultObject) + JSON.stringify(defaultObject), ); expect(res).toEqual(defaultObject); diff --git a/frontend/__tests__/utils/sanitize.spec.ts b/frontend/__tests__/utils/sanitize.spec.ts index fe2b426ea840..b8de6b2e9c1e 100644 --- a/frontend/__tests__/utils/sanitize.spec.ts +++ b/frontend/__tests__/utils/sanitize.spec.ts @@ -29,7 +29,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.numbers === false ? () => sanitize(numberArraySchema, input) - : sanitize(numberArraySchema, input) + : sanitize(numberArraySchema, input), ); if (expected.numbers === false) { @@ -46,7 +46,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.numbersMin === false ? () => sanitize(numbersArrayMin2Schema, input) - : sanitize(numbersArrayMin2Schema, input) + : sanitize(numbersArrayMin2Schema, input), ); if (expected.numbersMin === false) { @@ -56,7 +56,7 @@ describe("sanitize function", () => { } else { sanitized.toStrictEqual(expected.numbersMin); } - } + }, ); }); describe("objects", () => { @@ -157,7 +157,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.mandatory === false ? () => sanitize(objectSchema, input as any) - : sanitize(objectSchema, input as any) + : sanitize(objectSchema, input as any), ); if (expected.mandatory === false) { @@ -174,7 +174,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.partial === false ? () => sanitize(objectSchemaFullPartial, input as any) - : sanitize(objectSchemaFullPartial, input as any) + : sanitize(objectSchemaFullPartial, input as any), ); if (expected.partial === false) { @@ -184,13 +184,13 @@ describe("sanitize function", () => { } else { sanitized.toStrictEqual(expected.partial); } - } + }, ); it.for(testCases)("object optional with $input", ({ input, expected }) => { const sanitized = expect( expected.optional === false ? () => sanitize(objectSchemaWithOptional, input as any) - : sanitize(objectSchemaWithOptional, input as any) + : sanitize(objectSchemaWithOptional, input as any), ); if (expected.optional === false) { @@ -284,7 +284,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.mandatory === false ? () => sanitize(nestedSchema, input as any) - : sanitize(nestedSchema, input as any) + : sanitize(nestedSchema, input as any), ); if (expected.mandatory === false) { @@ -299,7 +299,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.partial === false ? () => sanitize(nestedSchemaFullPartial, input as any) - : sanitize(nestedSchemaFullPartial, input as any) + : sanitize(nestedSchemaFullPartial, input as any), ); if (expected.partial === false) { @@ -316,7 +316,7 @@ describe("sanitize function", () => { const sanitized = expect( expected.minArray === false ? () => sanitize(nestedSchemaWithMin2Array, input as any) - : sanitize(nestedSchemaWithMin2Array, input as any) + : sanitize(nestedSchemaWithMin2Array, input as any), ); if (expected.minArray === false) { @@ -326,7 +326,7 @@ describe("sanitize function", () => { } else { sanitized.toStrictEqual(expected.minArray); } - } + }, ); }); @@ -366,7 +366,7 @@ describe("sanitize function", () => { expect(() => { sanitize(schema.required().strip(), obj); }).toThrowError( - "unable to sanitize: name: Required, age: Required, tags: Required, enumArray: Required" + "unable to sanitize: name: Required, age: Required, tags: Required, enumArray: Required", ); }); }); diff --git a/frontend/__tests__/utils/strings.spec.ts b/frontend/__tests__/utils/strings.spec.ts index ce49da897fd3..cae1aeef927d 100644 --- a/frontend/__tests__/utils/strings.spec.ts +++ b/frontend/__tests__/utils/strings.spec.ts @@ -136,19 +136,19 @@ describe("string utils", () => { "should highlight $description", ({ text, matches, expected }) => { expect(Strings.highlightMatches(text, matches)).toBe(expected); - } + }, ); it.each(shouldNotHighlight)( "should not highlight $description", ({ text, matches }) => { expect(Strings.highlightMatches(text, matches)).toBe(text); - } + }, ); it.each(returnOriginal)( "should return original text $description", ({ text, matches }) => { expect(Strings.highlightMatches(text, matches)).toBe(text); - } + }, ); }); @@ -213,7 +213,7 @@ describe("string utils", () => { "should convert %s to %s (%s)", (input: string, expected: string, _description: string) => { expect(Strings.replaceControlCharacters(input)).toBe(expected); - } + }, ); }); @@ -266,7 +266,7 @@ describe("string utils", () => { "should return %s for word '%s' (%s)", (expected: boolean, word: string, _description: string) => { expect(Strings.__testing.hasRTLCharacters(word)).toBe(expected); - } + }, ); }); @@ -319,10 +319,10 @@ describe("string utils", () => { expected: boolean, word: string, languageRTL: boolean, - _description: string + _description: string, ) => { expect(Strings.isWordRightToLeft(word, languageRTL)).toBe(expected); - } + }, ); it("should return languageRTL for undefined word", () => { @@ -499,13 +499,13 @@ describe("string utils", () => { char: string, expectedCodePoint: number | null, description: string, - expected: boolean + expected: boolean, ) => { if (expectedCodePoint !== null && char.length === 1) { expect(char.codePointAt(0)).toBe(expectedCodePoint); } expect(Strings.isSpace(char)).toBe(expected); - } + }, ); }); @@ -582,7 +582,7 @@ describe("string utils", () => { }, ])("$desc", ({ char1, char2, expected }) => { expect( - Strings.areCharactersVisuallyEqual(char1, char2, "russian") + Strings.areCharactersVisuallyEqual(char1, char2, "russian"), ).toBe(expected); }); }); diff --git a/frontend/__tests__/utils/tag-builder.spec.ts b/frontend/__tests__/utils/tag-builder.spec.ts index 546731c4994b..21bef2def757 100644 --- a/frontend/__tests__/utils/tag-builder.spec.ts +++ b/frontend/__tests__/utils/tag-builder.spec.ts @@ -8,7 +8,7 @@ describe("simple-modals", () => { }); it("builds with classes", () => { expect(buildTag({ tagname: "input", classes: ["hidden", "bold"] })).toBe( - '' + '', ); }); it("builds with attributes", () => { @@ -22,13 +22,13 @@ describe("simple-modals", () => { checked: true, missing: undefined, }, - }) + }), ).toBe(''); }); it("builds with innerHtml", () => { expect( - buildTag({ tagname: "textarea", innerHTML: "

Hello

" }) + buildTag({ tagname: "textarea", innerHTML: "

Hello

" }), ).toBe(""); }); it("builds with everything", () => { @@ -43,9 +43,9 @@ describe("simple-modals", () => { required: true, }, innerHTML: "

Hello

", - }) + }), ).toBe( - '' + '', ); }); }); diff --git a/frontend/__tests__/utils/url-handler.spec.ts b/frontend/__tests__/utils/url-handler.spec.ts index 2b7373afb7a9..ee7e0ebe5781 100644 --- a/frontend/__tests__/utils/url-handler.spec.ts +++ b/frontend/__tests__/utils/url-handler.spec.ts @@ -66,7 +66,7 @@ describe("url-handler", () => { it("handles mode2 as number", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ mode: "time", mode2: 60 }) + urlData({ mode: "time", mode2: 60 }), ); //WHEN @@ -80,7 +80,7 @@ describe("url-handler", () => { it("sets time", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ mode: "time", mode2: "30" }) + urlData({ mode: "time", mode2: "30" }), ); //WHEN @@ -94,7 +94,7 @@ describe("url-handler", () => { it("sets word count", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ mode: "words", mode2: "50" }) + urlData({ mode: "words", mode2: "50" }), ); //WHEN @@ -108,7 +108,7 @@ describe("url-handler", () => { it("sets quote length", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ mode: "quote", mode2: "512" }) + urlData({ mode: "quote", mode2: "512" }), ); //WHEN @@ -167,7 +167,7 @@ describe("url-handler", () => { it("sets funbox", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ funbox: ["crt", "choo_choo"] }) + urlData({ funbox: ["crt", "choo_choo"] }), ); //WHEN @@ -180,7 +180,7 @@ describe("url-handler", () => { it("sets funbox legacy", () => { //GIVEN findGetParameterMock.mockReturnValue( - urlData({ funbox: "crt#choo_choo" }) + urlData({ funbox: "crt#choo_choo" }), ); //WHEN @@ -207,7 +207,7 @@ describe("url-handler", () => { language: "english", difficulty: "master", funbox: ["ascii", "crt"], - }) + }), ); //WHEN @@ -220,7 +220,7 @@ describe("url-handler", () => { { duration: 10, allowHTML: true, - } + }, ); }); it("rejects invalid values", () => { @@ -240,7 +240,7 @@ describe("url-handler", () => { language: "invalid", difficulty: "invalid", funbox: ["invalid"], - } as any) + } as any), ); //WHEN @@ -249,7 +249,7 @@ describe("url-handler", () => { //THEN expect(addNotificationMock).toHaveBeenCalledWith( `Failed to load test settings from URL: JSON does not match schema: "0" invalid enum value. expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'invalidmode', "1" needs to be a number or a number represented as a string e.g. "10"., "2.mode" invalid enum value. expected 'repeat' | 'random' | 'shuffle', received 'invalid', "2.pipeDelimiter" expected boolean, received string, "2.limit" expected object, received string, "2.text" expected array, received string, "3" expected boolean, received string, "4" expected boolean, received string, "6" invalid enum value. expected 'normal' | 'expert' | 'master', received 'invalid', "7" invalid input`, - 0 + 0, ); }); }); @@ -265,7 +265,7 @@ const urlData = ( language: string; difficulty: Difficulty; funbox: FunboxName[] | string; - }> + }>, ): string => { return compressToURI( JSON.stringify([ @@ -277,6 +277,6 @@ const urlData = ( data.language ?? null, data.difficulty ?? null, data.funbox ?? null, - ]) + ]), ); }; diff --git a/frontend/scripts/check-assets.ts b/frontend/scripts/check-assets.ts index ac39cbdc1d5f..881d2e720d43 100644 --- a/frontend/scripts/check-assets.ts +++ b/frontend/scripts/check-assets.ts @@ -39,11 +39,11 @@ class Problems { public addValidation( key: K | T, - validationResult: z.SafeParseReturnType + validationResult: z.SafeParseReturnType, ): void { if (validationResult.success) return; validationResult.error.errors.forEach((e) => - this.add(key, `${e.path.join(".")}: ${e.message}`) + this.add(key, `${e.path.join(".")}: ${e.message}`), ); } @@ -92,7 +92,7 @@ async function validateChallenges(): Promise { fs.readFileSync("./static/challenges/_list.json", { encoding: "utf8", flag: "r", - }) + }), ) as Challenge; const validationResult = z.array(ChallengeSchema).safeParse(challengesData); problems.addValidation("_list.json", validationResult); @@ -114,18 +114,18 @@ async function validateLayouts(): Promise { if (!fs.existsSync(`./static/layouts/${layoutName}.json`)) { problems.add( layoutName, - `missing json file frontend/static/layouts/${layoutName}.json` + `missing json file frontend/static/layouts/${layoutName}.json`, ); continue; } try { layoutData = JSON.parse( - fs.readFileSync(`./static/layouts/${layoutName}.json`, "utf-8") + fs.readFileSync(`./static/layouts/${layoutName}.json`, "utf-8"), ) as LayoutObject; } catch (e) { problems.add( layoutName, - `Unable to parse ${e instanceof Error ? e.message : e}` + `Unable to parse ${e instanceof Error ? e.message : e}`, ); continue; } @@ -162,12 +162,12 @@ async function validateQuotes(): Promise { fs.readFileSync(`./static/quotes/${quotefilename}.json`, { encoding: "utf8", flag: "r", - }) + }), ) as QuoteData; } catch (e) { problems.add( quotefilename, - `Unable to parse ${e instanceof Error ? e.message : e}` + `Unable to parse ${e instanceof Error ? e.message : e}`, ); continue; } @@ -176,7 +176,7 @@ async function validateQuotes(): Promise { if (quoteData.language !== quotefilename) { problems.add( quotefilename, - `Name not matching language ${quoteData.language}` + `Name not matching language ${quoteData.language}`, ); } @@ -193,7 +193,7 @@ async function validateQuotes(): Promise { if (duplicates.length !== 0) { problems.add( quotefilename, - `contains ${duplicates.length} duplicates:\n ${duplicates.join(",")}` + `contains ${duplicates.length} duplicates:\n ${duplicates.join(",")}`, ); } @@ -203,8 +203,8 @@ async function validateQuotes(): Promise { .forEach((quote) => problems.add( quotefilename, - `ID ${quote.id}: expected length ${quote.text.length}` - ) + `ID ${quote.id}: expected length ${quote.text.length}`, + ), ); //check groups @@ -213,12 +213,12 @@ async function validateQuotes(): Promise { if (group[0] !== last + 1) { problems.add( quotefilename, - `error in group ${group}: expect to start at ${last + 1}` + `error in group ${group}: expect to start at ${last + 1}`, ); } else if (group[0] >= group[1]) { problems.add( quotefilename, - `error in group ${group}: second number to be greater than first number` + `error in group ${group}: second number to be greater than first number`, ); } last = group[1]; @@ -240,7 +240,7 @@ async function validateLanguages(): Promise { "Language files present but missing in packages/schemas/src/languages.ts", _groups: "Problems in LanguageGroups in frontend/src/ts/constants/languages.ts", - } + }, ); const duplicatePercentageThreshold = 0.0001; @@ -251,12 +251,12 @@ async function validateLanguages(): Promise { fs.readFileSync(`./static/languages/${language}.json`, { encoding: "utf8", flag: "r", - }) + }), ) as LanguageObject; } catch (e) { problems.add( language, - `missing json file frontend/static/languages/${language}.json` + `missing json file frontend/static/languages/${language}.json`, ); continue; @@ -265,7 +265,7 @@ async function validateLanguages(): Promise { language, LanguageObjectSchema.extend({ _comment: z.string().optional(), - }).safeParse(languageFileData) + }).safeParse(languageFileData), ); if (languageFileData.name !== language) { @@ -278,8 +278,8 @@ async function validateLanguages(): Promise { problems.add( language, `contains ${duplicates.length} (${Math.round( - duplicatePercentage - )}%) duplicates:\n ${duplicates.join(",")}` + duplicatePercentage, + )}%) duplicates:\n ${duplicates.join(",")}`, ); } } @@ -305,18 +305,18 @@ async function validateLanguages(): Promise { problems.add( "_groups", `languages with multiple groups: ${languagesWithMultipleGroups.join( - ", " - )}` + ", ", + )}`, ); } const languagesMissingGroup = LanguageList.filter( - (lang) => !groupByLanguage.has(lang) + (lang) => !groupByLanguage.has(lang), ); if (languagesMissingGroup.length !== 0) { problems.add( "_groups", - `languages missing group: ${languagesMissingGroup.join(", ")}` + `languages missing group: ${languagesMissingGroup.join(", ")}`, ); } @@ -350,15 +350,15 @@ async function validateFonts(): Promise { .forEach(([name, config]) => problems.add( name as KnownFontName, - `missing file frontend/static/webfonts/${config.fileName}` - ) + `missing file frontend/static/webfonts/${config.fileName}`, + ), ); //additional font files const expectedFontFiles = new Set( Object.entries(Fonts) .filter(([_name, config]) => !config.systemFont) - .map(([_name, config]) => config.fileName as string) + .map(([_name, config]) => config.fileName as string), ); fontFiles @@ -386,8 +386,8 @@ async function validateThemes(): Promise { (it) => problems.add( it.name, - `missing file frontend/static/themes/${it.name}.css` - ) + `missing file frontend/static/themes/${it.name}.css`, + ), ); //additional theme files @@ -431,7 +431,7 @@ async function main(): Promise { flags.has("--pass-with-no-validators") || flags.has("-p"); const tasks: Set = new Set( - validateAll ? Object.values(validators).flat() : [] + validateAll ? Object.values(validators).flat() : [], ); for (const key of keys) { if (!Object.keys(validators).includes(key)) { diff --git a/frontend/scripts/fill-colors.js b/frontend/scripts/fill-colors.js index 807b2ed4968e..e3fbc612e743 100644 --- a/frontend/scripts/fill-colors.js +++ b/frontend/scripts/fill-colors.js @@ -6,7 +6,7 @@ function main() { const listFile = JSON.parse( fs.readFileSync("../static/themes/_list.json", { encoding: "utf8", - }) + }), ); const themeFiles = fs.readdirSync("../static/themes/"); // themeFiles.forEach((filename) => { @@ -28,16 +28,16 @@ function main() { const textMatches = /--text-color: (#.+);/g.exec(themeData); listFile.find( - (theme) => theme.name === filename.split(".css")[0] + (theme) => theme.name === filename.split(".css")[0], ).subColor = subMatches[1]; listFile.find( - (theme) => theme.name === filename.split(".css")[0] + (theme) => theme.name === filename.split(".css")[0], ).textColor = textMatches[1]; listFile.find( - (theme) => theme.name === filename.split(".css")[0] + (theme) => theme.name === filename.split(".css")[0], ).bgColor = bgMatches[1]; listFile.find( - (theme) => theme.name === filename.split(".css")[0] + (theme) => theme.name === filename.split(".css")[0], ).mainColor = mainMatches[1]; // console.log(themeData); @@ -49,7 +49,7 @@ function main() { } fs.writeFileSync( `../static/themes/_list.json`, - JSON.stringify(listFile, null, 2) + JSON.stringify(listFile, null, 2), ); resolve(); }); diff --git a/frontend/scripts/fix-quote-lengths.cjs b/frontend/scripts/fix-quote-lengths.cjs index d900bbad2ac8..94cc7f718d6e 100644 --- a/frontend/scripts/fix-quote-lengths.cjs +++ b/frontend/scripts/fix-quote-lengths.cjs @@ -10,7 +10,7 @@ function fixQuoteLengths() { fs.readFileSync(`../static/quotes/${quotefilename}.json`, { encoding: "utf8", flag: "r", - }) + }), ); quoteData.quotes.forEach((quote) => { @@ -19,7 +19,7 @@ function fixQuoteLengths() { fs.writeFileSync( `../static/quotes/${quotefilename}.json`, - JSON.stringify(quoteData, null, 2) + JSON.stringify(quoteData, null, 2), ); }); resolve(); diff --git a/frontend/src/404.html b/frontend/src/404.html index d364b4e4ce3e..d67396cfb11a 100644 --- a/frontend/src/404.html +++ b/frontend/src/404.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/email-handler.html b/frontend/src/email-handler.html index 0215c10c94e3..160ad19080de 100644 --- a/frontend/src/email-handler.html +++ b/frontend/src/email-handler.html @@ -1,4 +1,4 @@ - + @@ -187,7 +187,7 @@ const hasCapital = !!password.match(/[A-Z]/); const hasNumber = !!password.match(/[\d]/); const hasSpecial = !!password.match( - /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/ + /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/, ); const isLong = password.length >= 8; const isShort = password.length <= 64; @@ -201,7 +201,7 @@ $("main .preloader .icon").html(``); $("main .preloader .text").text( - `Your email address has been verified` + `Your email address has been verified`, ); $("main .preloader .subText").text(`You can now close this tab`); }) @@ -209,7 +209,7 @@ console.error(error); $("main .preloader .icon").html(``); $("main .preloader .text").text( - `Fatal error: ${error.message}. If this issue persists, please report it.` + `Fatal error: ${error.message}. If this issue persists, please report it.`, ); // Code is invalid or expired. Ask the user to verify their email address // again. @@ -245,7 +245,7 @@ if (!isPasswordStrong(newPassword)) { alert( - "Password must contain at least one capital letter, number, a special character and must be between 8 and 64 characters long" + "Password must contain at least one capital letter, number, a special character and must be between 8 and 64 characters long", ); showResetPassword(); return; @@ -256,7 +256,7 @@ .then((resp) => { // Password reset has been confirmed and new password updated. $("main .preloader .icon").html( - `` + ``, ); $("main .preloader .text").text(`Your password has been changed`); $("main .preloader .subText").text(`You can now close this tab`); @@ -266,10 +266,10 @@ .catch((error) => { console.error(error); $("main .preloader .icon").html( - `` + ``, ); $("main .preloader .text").text( - `Fatal error: ${error.message}. If this issue persists, please report it.` + `Fatal error: ${error.message}. If this issue persists, please report it.`, ); // Error occurred during confirmation. The code might have expired or the // password is too weak. @@ -279,7 +279,7 @@ console.error(error); $("main .preloader .icon").html(``); $("main .preloader .text").text( - `Fatal error: ${error.message}. If this issue persists, please report it.` + `Fatal error: ${error.message}. If this issue persists, please report it.`, ); // $("main .preloader .subText").text(error); @@ -377,7 +377,7 @@ if (!mode) { $("main .preloader .icon").html( - `` + ``, ); $("main .preloader .text").text(`Mode parameter not found`); return; @@ -385,7 +385,7 @@ if (!actionCode) { $("main .preloader .icon").html( - `` + ``, ); $("main .preloader .text").text(`Action code parameter not found`); return; @@ -411,7 +411,7 @@ break; default: $("main .preloader .icon").html( - `` + ``, ); $("main .preloader .text").text(`Invalid mode`); console.error("no mode found"); @@ -428,11 +428,11 @@ } catch (e) { $("main .preloader .icon").html(``); $("main .preloader .text").text( - `Fatal error: ${e.message}. If this issue persists, please report it.` + `Fatal error: ${e.message}. If this issue persists, please report it.`, ); } }, - false + false, ); document.querySelector("header").addEventListener("click", () => { diff --git a/frontend/src/index.html b/frontend/src/index.html index f48a35a4f755..872c4197c4f5 100644 --- a/frontend/src/index.html +++ b/frontend/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/privacy-policy.html b/frontend/src/privacy-policy.html index c3c1b6539bc8..170d44206f9c 100644 --- a/frontend/src/privacy-policy.html +++ b/frontend/src/privacy-policy.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/security-policy.html b/frontend/src/security-policy.html index 4e9a70600ef5..41432356f486 100644 --- a/frontend/src/security-policy.html +++ b/frontend/src/security-policy.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/styles/buttons.scss b/frontend/src/styles/buttons.scss index e2ce02afe5f9..4f0d559bd348 100644 --- a/frontend/src/styles/buttons.scss +++ b/frontend/src/styles/buttons.scss @@ -28,7 +28,10 @@ input[type="submit"] { text-align: center; color: var(--text-color); cursor: pointer; - transition: background 0.125s, color 0.125s, opacity 0.125s; + transition: + background 0.125s, + color 0.125s, + opacity 0.125s; padding: 0.5em; border-radius: var(--roundness); background: var(--sub-alt-color); @@ -85,7 +88,9 @@ input[type="submit"] { outline: none; } &:focus-visible { - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); outline: none; } &:active { @@ -99,7 +104,10 @@ button.text, .textButton { color: var(--sub-color); cursor: pointer; - transition: background 0.125s, color 0.125s, opacity 0.125s; + transition: + background 0.125s, + color 0.125s, + opacity 0.125s; padding: 0.5em; border-radius: var(--roundness); background: none; diff --git a/frontend/src/styles/core.scss b/frontend/src/styles/core.scss index 5a58e961930d..a51fab99bfb6 100644 --- a/frontend/src/styles/core.scss +++ b/frontend/src/styles/core.scss @@ -140,13 +140,18 @@ html { a { display: inline-block; color: var(--sub-color); - transition: color 0.125s, opacity 0.125s, background 0.125s; + transition: + color 0.125s, + opacity 0.125s, + background 0.125s; &:hover { color: var(--text-color); } &:focus-visible { outline: none; - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); border-radius: calc(var(--roundness) / 2); } } @@ -336,7 +341,10 @@ key { .avatar { --size: 1em; - transition: opacity 0.125s, filter 0.125s, webkit-filter 0.125s; + transition: + opacity 0.125s, + filter 0.125s, + webkit-filter 0.125s; width: var(--size); height: var(--size); font-size: var(--size); diff --git a/frontend/src/styles/inputs.scss b/frontend/src/styles/inputs.scss index 9dddddb21729..ca0768d7920c 100644 --- a/frontend/src/styles/inputs.scss +++ b/frontend/src/styles/inputs.scss @@ -11,7 +11,9 @@ textarea { caret-color: var(--main-color); line-height: 1.25em; &:focus-visible { - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); } } @@ -76,7 +78,9 @@ input[type="range"] { } } &:focus-visible { - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); } } @@ -220,7 +224,9 @@ select:-webkit-autofill:focus { box-shadow: inherit; } &:focus-visible { - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); } .ss-arrow path { stroke: var(--text-color); @@ -299,7 +305,9 @@ select:-webkit-autofill:focus { font-size: 1em; padding: 0.5em; &:focus-visible { - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); } &:focus { border: none; diff --git a/frontend/src/styles/nav.scss b/frontend/src/styles/nav.scss index 846be5224904..0ee7840309ea 100644 --- a/frontend/src/styles/nav.scss +++ b/frontend/src/styles/nav.scss @@ -296,7 +296,9 @@ header { font-size: 0.325em; line-height: 0.325em; color: var(--sub-color); - transition: color 0.125s, opacity 0.125s; + transition: + color 0.125s, + opacity 0.125s; } position: relative; font-size: 2rem; @@ -339,7 +341,9 @@ header { } &:focus-visible { outline: none; - box-shadow: 0 0 0 0.1rem var(--bg-color), 0 0 0 0.2rem var(--text-color); + box-shadow: + 0 0 0 0.1rem var(--bg-color), + 0 0 0 0.2rem var(--text-color); border-radius: var(--roundness); .text .top { opacity: 0; diff --git a/frontend/src/styles/test.scss b/frontend/src/styles/test.scss index 49587b8b2c01..8abc16b7dd92 100644 --- a/frontend/src/styles/test.scss +++ b/frontend/src/styles/test.scss @@ -17,7 +17,10 @@ z-index: 1; &.withAnimation { - transition: left 0.25s ease, right 0.25s ease, opacity 0.125s linear; + transition: + left 0.25s ease, + right 0.25s ease, + opacity 0.125s linear; } &.highlight-hidden { @@ -558,12 +561,14 @@ &.error { /* margin-bottom: 1px; */ border-bottom: 2px solid var(--error-color); - text-shadow: 1px 0px 0px var(--bg-color), + text-shadow: + 1px 0px 0px var(--bg-color), // 2px 0px 0px var(--bg-color), -1px 0px 0px var(--bg-color), // -2px 0px 0px var(--bg-color), 0px 1px 0px var(--bg-color), - 1px 1px 0px var(--bg-color), -1px 1px 0px var(--bg-color); + 1px 1px 0px var(--bg-color), + -1px 1px 0px var(--bg-color); } } @@ -1074,7 +1079,10 @@ align-items: center; justify-items: center; - transition: opacity 0.125s, background 0.125s, color 0.125s, + transition: + opacity 0.125s, + background 0.125s, + color 0.125s, outline 0.125s; i { @@ -1334,7 +1342,9 @@ right: 0; padding: var(--verticalPadding) var(--horizontalPadding); z-index: 1; - transition: opacity 0.25s, right 0.25s; + transition: + opacity 0.25s, + right 0.25s; opacity: 0; } diff --git a/frontend/src/terms-of-service.html b/frontend/src/terms-of-service.html index 494a49fb2d3f..4d29f5d3fd54 100644 --- a/frontend/src/terms-of-service.html +++ b/frontend/src/terms-of-service.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/ts/ape/adapters/ts-rest-adapter.ts b/frontend/src/ts/ape/adapters/ts-rest-adapter.ts index 35e9e0e4ec60..7f2a8ebbf8da 100644 --- a/frontend/src/ts/ape/adapters/ts-rest-adapter.ts +++ b/frontend/src/ts/ape/adapters/ts-rest-adapter.ts @@ -51,7 +51,7 @@ function buildApi(timeout: number): (args: ApiFetcherArgs) => Promise<{ } const compatibilityCheckHeader = response.headers.get( - COMPATIBILITY_CHECK_HEADER + COMPATIBILITY_CHECK_HEADER, ); if (compatibilityCheckHeader !== null) { @@ -95,7 +95,7 @@ function buildApi(timeout: number): (args: ApiFetcherArgs) => Promise<{ export function buildClient( contract: T, baseUrl: string, - timeout: number = 10_000 + timeout: number = 10_000, ) { return initClient(contract, { baseUrl: baseUrl, diff --git a/frontend/src/ts/auth.ts b/frontend/src/ts/auth.ts index 04d0ec3cbc1a..65be9fbeecae 100644 --- a/frontend/src/ts/auth.ts +++ b/frontend/src/ts/auth.ts @@ -50,7 +50,7 @@ async function sendVerificationEmail(): Promise { Loader.hide(); Notifications.add( "Failed to request verification email: " + result.body.message, - -1 + -1, ); } else { Loader.hide(); @@ -65,7 +65,7 @@ async function getDataAndInit(): Promise { if (snapshot === false) { throw new Error( - "Snapshot didn't initialize due to lacking authentication even though user is authenticated" + "Snapshot didn't initialize due to lacking authentication even though user is authenticated", ); } @@ -77,7 +77,7 @@ async function getDataAndInit(): Promise { undefined, true, undefined, - true + true, ); } @@ -86,7 +86,7 @@ async function getDataAndInit(): Promise { if (Config === undefined || !areConfigsEqual) { console.log( - "no local config or local and db configs are different - applying db" + "no local config or local and db configs are different - applying db", ); await UpdateConfig.apply(snapshot.config); UpdateConfig.saveFullConfigToLocalStorage(true); @@ -108,14 +108,14 @@ async function getDataAndInit(): Promise { 0, { duration: 0, - } + }, ); Notifications.add( "You will run into this error if you refresh the website to restart the test. It is NOT recommended to do that. Instead, use tab + enter or just tab (with quick tab mode enabled) to restart the test.", 0, { duration: 0, - } + }, ); } @@ -138,7 +138,7 @@ export async function loadUser(_user: UserType): Promise { export async function onAuthStateChanged( authInitialisedAndConnected: boolean, - user: UserType | null + user: UserType | null, ): Promise { console.debug(`account controller ready`); @@ -216,11 +216,11 @@ export async function signIn(email: string, password: string): Promise { } const rememberMe = $(".pageLogin .login #rememberMe input").prop( - "checked" + "checked", ) as boolean; const { error } = await tryCatch( - signInWithEmailAndPassword(email, password, rememberMe) + signInWithEmailAndPassword(email, password, rememberMe), ); if (error !== null) { @@ -250,7 +250,7 @@ async function signInWithProvider(provider: AuthProvider): Promise { LoginPage.disableInputs(); LoginPage.disableSignUpButton(); const rememberMe = $(".pageLogin .login #rememberMe input").prop( - "checked" + "checked", ) as boolean; const { error } = await tryCatch(signInWithPopup(provider, rememberMe)); @@ -284,7 +284,7 @@ async function addGithubAuth(): Promise { async function addAuthProvider( providerName: string, - provider: AuthProvider + provider: AuthProvider, ): Promise { if (!ConnectionState.get()) { Notifications.add("You are offline", 0, { @@ -310,7 +310,7 @@ async function addAuthProvider( Loader.hide(); const message = Misc.createErrorMessage( error, - `Failed to add ${providerName} authentication` + `Failed to add ${providerName} authentication`, ); Notifications.add(message, -1); } @@ -363,7 +363,7 @@ async function signUp(): Promise { try { const createdAuthUser = await createUserWithEmailAndPassword( email, - password + password, ); const signInResponse = await Ape.users.create({ @@ -392,7 +392,7 @@ async function signUp(): Promise { if ("code" in e && e.code === "auth/email-already-in-use") { message = Misc.createErrorMessage( { message: "Email already in use" }, - "Failed to create account" + "Failed to create account", ); } } diff --git a/frontend/src/ts/commandline/commandline-metadata.ts b/frontend/src/ts/commandline/commandline-metadata.ts index 4d2d2ebb12af..0269d74f191e 100644 --- a/frontend/src/ts/commandline/commandline-metadata.ts +++ b/frontend/src/ts/commandline/commandline-metadata.ts @@ -66,7 +66,7 @@ export type SecondaryInputProps = { export type CommandlineConfigMetadata< T extends keyof ConfigSchemas.Config, - T2 extends keyof ConfigSchemas.Config + T2 extends keyof ConfigSchemas.Config, > = { alias?: string; display?: string; @@ -82,7 +82,7 @@ export type SubgroupProps = { isVisible?: (value: ConfigSchemas.Config[T]) => boolean; isAvailable?: (value: ConfigSchemas.Config[T]) => (() => boolean) | undefined; customData?: ( - value: ConfigSchemas.Config[T] + value: ConfigSchemas.Config[T], ) => Record; hover?: (value: ConfigSchemas.Config[T]) => void; afterExec?: (value: ConfigSchemas.Config[T]) => void; @@ -589,8 +589,8 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = { subgroup: { options: typedKeys(Fonts).sort((a, b) => (Fonts[a]?.display ?? a.replace(/_/g, " ")).localeCompare( - Fonts[b]?.display ?? b.replace(/_/g, " ") - ) + Fonts[b]?.display ?? b.replace(/_/g, " "), + ), ), display: (name) => Fonts[name as KnownFontName]?.display ?? name.replaceAll(/_/g, " "), diff --git a/frontend/src/ts/commandline/commandline.ts b/frontend/src/ts/commandline/commandline.ts index 888cfb84f4d3..b24021d4717b 100644 --- a/frontend/src/ts/commandline/commandline.ts +++ b/frontend/src/ts/commandline/commandline.ts @@ -76,7 +76,7 @@ type ShowSettings = { export function show( settings?: ShowSettings, - modalShowSettings?: ShowOptions + modalShowSettings?: ShowOptions, ): void { void modal.show({ ...modalShowSettings, @@ -96,12 +96,12 @@ export function show( if (settings?.subgroupOverride !== undefined) { if (typeof settings.subgroupOverride === "string") { const exists = CommandlineLists.doesListExist( - settings.subgroupOverride + settings.subgroupOverride, ); if (exists) { Loader.show(); subgroupOverride = await CommandlineLists.getList( - settings.subgroupOverride as CommandlineLists.ListsObjectKeys + settings.subgroupOverride as CommandlineLists.ListsObjectKeys, ); Loader.hide(); } else { @@ -109,7 +109,7 @@ export function show( usingSingleList = Config.singleListCommandLine === "on"; Notifications.add( `Command list ${settings.subgroupOverride} not found`, - 0 + 0, ); } } else { @@ -125,14 +125,14 @@ export function show( if (settings?.commandOverride !== undefined) { const command = (await getList()).find( - (c) => c.id === settings.commandOverride + (c) => c.id === settings.commandOverride, ); if (command === undefined) { Notifications.add(`Command ${settings.commandOverride} not found`, 0); } else if (command?.input !== true) { Notifications.add( `Command ${settings.commandOverride} is not an input command`, - 0 + 0, ); } else { showInputCommand = command; @@ -266,7 +266,7 @@ async function filterSubgroup(): Promise { const displayAliasSplit = displaySplit.concat(aliasSplit); const displayAliasMatchArray: (number | null)[] = displayAliasSplit.map( - () => null + () => null, ); let matchStrength = 0; @@ -416,11 +416,11 @@ async function showCommands(): Promise { if (Array.isArray(command.configValue)) { isActive = areUnsortedArraysEqual( intersect(Config[configKey] as unknown[], command.configValue), - command.configValue + command.configValue, ); } else { isActive = (Config[configKey] as unknown[]).includes( - command.configValue + command.configValue, ); } } else { @@ -465,7 +465,7 @@ async function showCommands(): Promise { display = display.replace( ``, `` + - configIconHtml + configIconHtml, ); } } @@ -660,7 +660,7 @@ function keepActiveCommandInView(): void { if (mouseMode) return; const active: HTMLElement | null = document.querySelector( - ".suggestions .command.active" + ".suggestions .command.active", ); if (active === null || active.dataset["index"] === lastActiveIndex) { @@ -673,7 +673,7 @@ function keepActiveCommandInView(): void { async function updateInput(setInput?: string): Promise { const iconElement: HTMLElement | null = document.querySelector( - "#commandLine .searchicon" + "#commandLine .searchicon", ); const element: HTMLInputElement | null = document.querySelector("#commandLine input"); @@ -779,7 +779,7 @@ function hideWarning(): void { } function updateValidationResult( - validation: NonNullable + validation: NonNullable, ): void { inputModeParams.validation = validation; if (validation.status === "checking") { @@ -809,7 +809,7 @@ function createValidationHandler(command: Command): void { commandWithValidation.validation, "inputValueConvert" in commandWithValidation ? commandWithValidation.inputValueConvert - : undefined + : undefined, ); handlersCache.set(command.id, handler); } @@ -846,7 +846,7 @@ const modal = new AnimatedModal({ await filterSubgroup(); await showCommands(); await updateActiveCommand(); - }) + }), ); input.addEventListener("keydown", async (e) => { @@ -917,7 +917,7 @@ const modal = new AnimatedModal({ const handler = handlersCache.get(inputModeParams.command.id); if (handler === undefined) { throw new Error( - `Expected handler for command ${inputModeParams.command.id} is missing` + `Expected handler for command ${inputModeParams.command.id} is missing`, ); } diff --git a/frontend/src/ts/commandline/lists.ts b/frontend/src/ts/commandline/lists.ts index 565123e0373a..b303fbda4c31 100644 --- a/frontend/src/ts/commandline/lists.ts +++ b/frontend/src/ts/commandline/lists.ts @@ -39,7 +39,7 @@ challengesPromise }) .catch((e: unknown) => { console.error( - Misc.createErrorMessage(e, "Failed to update challenges commands") + Misc.createErrorMessage(e, "Failed to update challenges commands"), ); }); @@ -122,7 +122,7 @@ export const commands: CommandsSubgroup = { "britishEnglish", ...FunboxCommands, "customLayoutfluid", - "customPolyglot" + "customPolyglot", ), //input @@ -137,7 +137,7 @@ export const commands: CommandsSubgroup = { "hideExtraLetters", lazyModeCommand, layoutCommand, - "codeUnindentOnBackspace" + "codeUnindentOnBackspace", ), //sound @@ -145,7 +145,7 @@ export const commands: CommandsSubgroup = { "soundVolume", "playSoundOnClick", "playSoundOnError", - "playTimeWarning" + "playTimeWarning", ), //caret @@ -154,7 +154,7 @@ export const commands: CommandsSubgroup = { "caretStyle", paceCaretCommand, "repeatedPace", - "paceCaretStyle" + "paceCaretStyle", ), //appearence @@ -183,7 +183,7 @@ export const commands: CommandsSubgroup = { "keymapLegendStyle", "keymapSize", keymapLayoutCommand, - "keymapShowTopRow" + "keymapShowTopRow", ), //theme @@ -198,7 +198,7 @@ export const commands: CommandsSubgroup = { ...CustomBackgroundCommands, "customBackgroundSize", ...CustomBackgroundFilterCommands, - "randomTheme" + "randomTheme", ), { @@ -219,7 +219,7 @@ export const commands: CommandsSubgroup = { showAverageCommand, showPbCommand, "monkeyPowerLevel", - "monkey" + "monkey", ), //danger zone @@ -301,7 +301,7 @@ export const commands: CommandsSubgroup = { .catch((e: unknown) => { const message = Misc.createErrorMessage( e, - "Failed to copy to clipboard" + "Failed to copy to clipboard", ); Notifications.add(message, -1); }); @@ -352,7 +352,7 @@ export const commands: CommandsSubgroup = { .querySelector(".centerbox") ?.insertAdjacentHTML( "beforeend", - `

If your skill issue is not fixed yet, please wait a bit longer...

` + `

If your skill issue is not fixed yet, please wait a bit longer...

`, ); }, 5000); }, @@ -398,7 +398,7 @@ export function doesListExist(listName: string): boolean { } export async function getList( - listName: ListsObjectKeys + listName: ListsObjectKeys, ): Promise { await Promise.allSettled([challengesPromise]); @@ -458,7 +458,7 @@ export async function getSingleSubgroup(): Promise { function buildSingleListCommands( command: Command, - parentCommand?: Command + parentCommand?: Command, ): Command[] { const commands: Command[] = []; if (command.subgroup) { @@ -479,7 +479,7 @@ function buildSingleListCommands( if (parentCommand) { const parentCommandDisplay = parentCommand.display.replace( /\s?\.\.\.$/g, - "" + "", ); const singleListDisplay = parentCommandDisplay + @@ -524,6 +524,6 @@ function buildCommands( ...commands: (Command | keyof CommandlineConfigMetadataObject)[] ): Command[] { return commands.map((it) => - typeof it === "string" ? buildCommandForConfigKey(it) : it + typeof it === "string" ? buildCommandForConfigKey(it) : it, ); } diff --git a/frontend/src/ts/commandline/lists/custom-background.ts b/frontend/src/ts/commandline/lists/custom-background.ts index 75c91afb4c80..93353f40c4e9 100644 --- a/frontend/src/ts/commandline/lists/custom-background.ts +++ b/frontend/src/ts/commandline/lists/custom-background.ts @@ -58,7 +58,7 @@ const customBackgroundCommand: Command = { } catch (e) { Notifications.add( "Error uploading background: " + (e as Error).message, - 0 + 0, ); } cleanup(); @@ -85,7 +85,7 @@ const customBackgroundCommand: Command = { } catch (e) { Notifications.add( "Error removing background: " + (e as Error).message, - 0 + 0, ); } }, diff --git a/frontend/src/ts/commandline/lists/font-family.ts b/frontend/src/ts/commandline/lists/font-family.ts index af1550afee85..c60293147428 100644 --- a/frontend/src/ts/commandline/lists/font-family.ts +++ b/frontend/src/ts/commandline/lists/font-family.ts @@ -65,7 +65,7 @@ if (fromMeta.subgroup) { ) { Notifications.add( "Unsupported font format, must be woff, woff2, ttf or otf.", - 0 + 0, ); cleanup(); return; @@ -81,7 +81,7 @@ if (fromMeta.subgroup) { } catch (e) { Notifications.add( "Error uploading font: " + (e as Error).message, - 0 + 0, ); } cleanup(); @@ -108,7 +108,7 @@ if (fromMeta.subgroup) { } catch (e) { Notifications.add( "Error removing font: " + (e as Error).message, - 0 + 0, ); } }, diff --git a/frontend/src/ts/commandline/lists/min-burst.ts b/frontend/src/ts/commandline/lists/min-burst.ts index 631663be3e2a..c2468aa0093e 100644 --- a/frontend/src/ts/commandline/lists/min-burst.ts +++ b/frontend/src/ts/commandline/lists/min-burst.ts @@ -23,7 +23,7 @@ const subgroup: CommandsSubgroup = { if (input === undefined || input === "") return; UpdateConfig.setMinBurst("fixed"); const newVal = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( - parseInt(input) + parseInt(input), ); UpdateConfig.setMinBurstCustomSpeed(newVal); }, @@ -37,7 +37,7 @@ const subgroup: CommandsSubgroup = { if (input === undefined || input === "") return; UpdateConfig.setMinBurst("flex"); const newVal = getTypingSpeedUnit(Config.typingSpeedUnit).toWpm( - parseInt(input) + parseInt(input), ); UpdateConfig.setMinBurstCustomSpeed(newVal); }, diff --git a/frontend/src/ts/commandline/lists/quote-favorites.ts b/frontend/src/ts/commandline/lists/quote-favorites.ts index 38149266b81a..c97566927dee 100644 --- a/frontend/src/ts/commandline/lists/quote-favorites.ts +++ b/frontend/src/ts/commandline/lists/quote-favorites.ts @@ -26,7 +26,7 @@ const commands: Command[] = [ Loader.show(); await QuotesController.setQuoteFavorite( TestWords.currentQuote as Quote, - true + true, ); Loader.hide(); Notifications.add("Quote added to favorites", 1); @@ -34,7 +34,7 @@ const commands: Command[] = [ Loader.hide(); const message = createErrorMessage( e, - "Failed to add quote to favorites" + "Failed to add quote to favorites", ); Notifications.add(message, -1); } @@ -58,7 +58,7 @@ const commands: Command[] = [ Loader.show(); await QuotesController.setQuoteFavorite( TestWords.currentQuote as Quote, - false + false, ); Loader.hide(); Notifications.add("Quote removed from favorites", 1); @@ -66,7 +66,7 @@ const commands: Command[] = [ Loader.hide(); const message = createErrorMessage( e, - "Failed to remove quote from favorites" + "Failed to remove quote from favorites", ); Notifications.add(message, -1); } diff --git a/frontend/src/ts/commandline/lists/result-screen.ts b/frontend/src/ts/commandline/lists/result-screen.ts index 60207281b555..60b528594ca4 100644 --- a/frontend/src/ts/commandline/lists/result-screen.ts +++ b/frontend/src/ts/commandline/lists/result-screen.ts @@ -148,7 +148,7 @@ const commands: Command[] = [ }, () => { Notifications.add("Failed to copy!", -1); - } + }, ); }, available: (): boolean => { diff --git a/frontend/src/ts/commandline/lists/themes.ts b/frontend/src/ts/commandline/lists/themes.ts index 4cdf2e858a83..701a230c9936 100644 --- a/frontend/src/ts/commandline/lists/themes.ts +++ b/frontend/src/ts/commandline/lists/themes.ts @@ -52,7 +52,7 @@ const subgroup: CommandsSubgroup = { title: "Theme...", configKey: "theme", list: sortThemesByFavorite(ThemesList).map((theme) => - createThemeCommand(theme) + createThemeCommand(theme), ), }; @@ -71,7 +71,7 @@ export function update(themes: Theme[]): void { // rebuild with favorites first, then non-favorites subgroup.list = sortThemesByFavorite(themes).map((theme) => - createThemeCommand(theme) + createThemeCommand(theme), ); } @@ -83,7 +83,7 @@ ConfigEvent.subscribe((eventKey, _eventValue) => { update(ThemesList); } catch (e: unknown) { console.error( - Misc.createErrorMessage(e, "Failed to update themes commands") + Misc.createErrorMessage(e, "Failed to update themes commands"), ); } } diff --git a/frontend/src/ts/commandline/util.ts b/frontend/src/ts/commandline/util.ts index 347baeddc49f..a75089d441b9 100644 --- a/frontend/src/ts/commandline/util.ts +++ b/frontend/src/ts/commandline/util.ts @@ -29,7 +29,7 @@ function getOptions(schema: T): undefined | z.infer[] { export function buildCommandForConfigKey< // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters - K extends keyof CommandlineConfigMetadataObject + K extends keyof CommandlineConfigMetadataObject, >(key: K): Command { const configMeta = configMetadata[key]; const commandMeta = commandlineConfigMetadata[key]; @@ -38,14 +38,14 @@ export function buildCommandForConfigKey< return _buildCommandForConfigKey(key, configMeta, commandMeta, schema); } function _buildCommandForConfigKey< - K extends keyof CommandlineConfigMetadataObject + K extends keyof CommandlineConfigMetadataObject, >( key: K, configMeta: ConfigMetadata, commandMeta: | CommandlineConfigMetadata | undefined, - schema: ZodSchema + schema: ZodSchema, ): Command { if (commandMeta === undefined || commandMeta === null) { throw new Error(`No commandline metadata found for config key "${key}".`); @@ -60,7 +60,7 @@ function _buildCommandForConfigKey< commandMeta.alias, commandMeta.subgroup, configMeta, - schema + schema, ); } @@ -89,7 +89,7 @@ function _buildCommandForConfigKey< if (result === undefined) { throw new Error( - `Nothing returned for config key "${key}". This is a bug in the commandline metadata.` + `Nothing returned for config key "${key}". This is a bug in the commandline metadata.`, ); } return result; @@ -101,7 +101,7 @@ function buildCommandWithSubgroup( rootAlias: string | undefined, subgroupProps: SubgroupProps, configMeta: ConfigMetadata, - schema: ZodSchema + schema: ZodSchema, ): Command { if (subgroupProps === null) { throw new Error(`No commandline metadata found for config key "${key}".`); @@ -121,11 +121,11 @@ function buildCommandWithSubgroup( if (values === undefined) { throw new Error( //@ts-expect-error todo - `Unsupported schema type for key "${key}": ${schema._def.typeName}` + `Unsupported schema type for key "${key}": ${schema._def.typeName}`, ); } const list = values.map((value) => - buildSubgroupCommand(key, value, subgroupProps) + buildSubgroupCommand(key, value, subgroupProps), ); list.sort((a, b) => { @@ -159,7 +159,7 @@ function buildSubgroupCommand( isVisible: isCommandVisible, isAvailable: isCommandAvailable, customData: commandCustomData, - }: SubgroupProps + }: SubgroupProps, ): Command { const val = value; @@ -177,7 +177,7 @@ function buildSubgroupCommand( return { id: `set${capitalizeFirstLetter(key)}${capitalizeFirstLetter( - val.toString() + val.toString(), )}`, display: displayString, configValueMode: commandConfigValueMode?.(value), @@ -226,7 +226,7 @@ function buildInputCommand({ inputProps?.defaultValue ?? (() => Config[key]?.toString() ?? ""), configValue: inputProps !== undefined && "configValue" in inputProps - ? inputProps.configValue ?? undefined + ? (inputProps.configValue ?? undefined) : undefined, display: displayString, alias: inputProps?.alias ?? undefined, diff --git a/frontend/src/ts/config-metadata.ts b/frontend/src/ts/config-metadata.ts index 62650b386c79..5ad4f4d97ce2 100644 --- a/frontend/src/ts/config-metadata.ts +++ b/frontend/src/ts/config-metadata.ts @@ -267,9 +267,9 @@ export const configMetadata: ConfigMetadataObject = { if (!checkCompatibility(value)) { Notifications.add( `${capitalizeFirstLetter( - value.join(", ") + value.join(", "), )} is an invalid combination of funboxes`, - 0 + 0, ); return true; } @@ -278,7 +278,7 @@ export const configMetadata: ConfigMetadataObject = { if (!canSetFunboxWithConfig(funbox, currentConfig)) { Notifications.add( `${value}" cannot be enabled with the current config`, - 0 + 0, ); return true; } @@ -428,7 +428,7 @@ export const configMetadata: ConfigMetadataObject = { if ((value === "pb" || value === "tagPb") && !isAuthenticated()) { Notifications.add( `Pace caret "pb" and "tag pb" are unavailable without an account`, - 0 + 0, ); return true; } @@ -666,21 +666,21 @@ export const configMetadata: ConfigMetadataObject = { if (!isAuthenticated()) { Notifications.add( "Random theme 'custom' is unavailable without an account", - 0 + 0, ); return true; } if (!snapshot) { Notifications.add( "Random theme 'custom' requires a snapshot to be set", - 0 + 0, ); return true; } if (snapshot?.customThemes?.length === 0) { Notifications.add( "Random theme 'custom' requires at least one custom theme to be saved", - 0 + 0, ); return true; } diff --git a/frontend/src/ts/config-validation.ts b/frontend/src/ts/config-validation.ts index 55a4b829a136..9f3172fcb74a 100644 --- a/frontend/src/ts/config-validation.ts +++ b/frontend/src/ts/config-validation.ts @@ -11,7 +11,7 @@ import * as Sentry from "./sentry"; export function invalid( key: string, val: unknown, - customMessage?: string + customMessage?: string, ): void { let message = `Invalid value for ${key} (${val}). Please try to change this setting again.`; @@ -27,7 +27,7 @@ export function invalid( export function isConfigValueValid( key: string, val: T, - schema: ZodSchema + schema: ZodSchema, ): boolean { const isValid = schema.safeParse(val).success; if (!isValid) invalid(key, val, undefined); diff --git a/frontend/src/ts/config.ts b/frontend/src/ts/config.ts index de1054e21a6b..1f447a12b532 100644 --- a/frontend/src/ts/config.ts +++ b/frontend/src/ts/config.ts @@ -60,7 +60,7 @@ const saveToDatabase = debounce(1000, () => { function saveToLocalStorage( key: keyof Config, nosave = false, - noDbCheck = false + noDbCheck = false, ): void { if (nosave) return; configLS.set(config); @@ -98,7 +98,7 @@ function isConfigChangeBlocked(): boolean { export function genericSet( key: T, value: ConfigSchemas.Config[T], - nosave: boolean = false + nosave: boolean = false, ): boolean { const metadata = configMetadata[key] as ConfigMetadataObject[T]; if (metadata === undefined) { @@ -125,8 +125,8 @@ export function genericSet( }); console.warn( `Could not set config key "${key}" with value "${JSON.stringify( - value - )}" - no quit funbox active.` + value, + )}" - no quit funbox active.`, ); return false; } @@ -134,8 +134,8 @@ export function genericSet( if (metadata.isBlocked?.({ value, currentConfig: config })) { console.warn( `Could not set config key "${key}" with value "${JSON.stringify( - value - )}" - blocked.` + value, + )}" - blocked.`, ); return false; } @@ -145,8 +145,8 @@ export function genericSet( if (!isConfigValueValid(metadata.displayString ?? key, value, schema)) { console.warn( `Could not set config key "${key}" with value "${JSON.stringify( - value - )}" - invalid value.` + value, + )}" - invalid value.`, ); return false; } @@ -154,8 +154,8 @@ export function genericSet( if (!canSetConfigWithCurrentFunboxes(key, value, config.funbox)) { console.warn( `Could not set config key "${key}" with value "${JSON.stringify( - value - )}" - funbox conflict.` + value, + )}" - funbox conflict.`, ); return false; } @@ -178,7 +178,7 @@ export function genericSet( const set = genericSet(targetKey, targetValue, nosave); if (!set) { throw new Error( - `Failed to set config key "${targetKey}" with value "${targetValue}" for ${metadata.displayString} config override.` + `Failed to set config key "${targetKey}" with value "${targetValue}" for ${metadata.displayString} config override.`, ); } } @@ -213,28 +213,28 @@ export function setMode(mode: Mode, nosave?: boolean): boolean { export function setPlaySoundOnError( val: ConfigSchemas.PlaySoundOnError, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("playSoundOnError", val, nosave); } export function setPlaySoundOnClick( val: ConfigSchemas.PlaySoundOnClick, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("playSoundOnClick", val, nosave); } export function setSoundVolume( val: ConfigSchemas.SoundVolume, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("soundVolume", val, nosave); } export function setPlayTimeWarning( value: ConfigSchemas.PlayTimeWarning, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("playTimeWarning", value, nosave); } @@ -242,7 +242,7 @@ export function setPlayTimeWarning( //difficulty export function setDifficulty( diff: ConfigSchemas.Difficulty, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("difficulty", diff, nosave); } @@ -250,14 +250,14 @@ export function setDifficulty( //set fav themes export function setFavThemes( themes: ConfigSchemas.FavThemes, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("favThemes", themes, nosave); } export function setFunbox( funbox: ConfigSchemas.Funbox, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("funbox", funbox, nosave); } @@ -295,35 +295,35 @@ export function setBlindMode(blind: boolean, nosave?: boolean): boolean { export function setAccountChart( array: ConfigSchemas.AccountChart, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("accountChart", array, nosave); } export function setStopOnError( soe: ConfigSchemas.StopOnError, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("stopOnError", soe, nosave); } export function setAlwaysShowDecimalPlaces( val: boolean, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("alwaysShowDecimalPlaces", val, nosave); } export function setTypingSpeedUnit( val: ConfigSchemas.TypingSpeedUnit, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("typingSpeedUnit", val, nosave); } export function setShowOutOfFocusWarning( val: boolean, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("showOutOfFocusWarning", val, nosave); } @@ -331,14 +331,14 @@ export function setShowOutOfFocusWarning( //pace caret export function setPaceCaret( val: ConfigSchemas.PaceCaret, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("paceCaret", val, nosave); } export function setPaceCaretCustomSpeed( val: ConfigSchemas.PaceCaretCustomSpeed, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("paceCaretCustomSpeed", val, nosave); } @@ -350,14 +350,14 @@ export function setRepeatedPace(pace: boolean, nosave?: boolean): boolean { //min wpm export function setMinWpm( minwpm: ConfigSchemas.MinimumWordsPerMinute, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minWpm", minwpm, nosave); } export function setMinWpmCustomSpeed( val: ConfigSchemas.MinWpmCustomSpeed, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minWpmCustomSpeed", val, nosave); } @@ -365,14 +365,14 @@ export function setMinWpmCustomSpeed( //min acc export function setMinAcc( min: ConfigSchemas.MinimumAccuracy, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minAcc", min, nosave); } export function setMinAccCustom( val: ConfigSchemas.MinimumAccuracyCustom, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minAccCustom", val, nosave); } @@ -380,14 +380,14 @@ export function setMinAccCustom( //min burst export function setMinBurst( min: ConfigSchemas.MinimumBurst, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minBurst", min, nosave); } export function setMinBurstCustomSpeed( val: ConfigSchemas.MinimumBurstCustomSpeed, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("minBurstCustomSpeed", val, nosave); } @@ -395,7 +395,7 @@ export function setMinBurstCustomSpeed( //always show words history export function setAlwaysShowWordsHistory( val: boolean, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("alwaysShowWordsHistory", val, nosave); } @@ -403,7 +403,7 @@ export function setAlwaysShowWordsHistory( //single list command line export function setSingleListCommandLine( option: ConfigSchemas.SingleListCommandLine, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("singleListCommandLine", option, nosave); } @@ -427,7 +427,7 @@ export function setAds(val: ConfigSchemas.Ads, nosave?: boolean): boolean { export function setRepeatQuotes( val: ConfigSchemas.RepeatQuotes, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("repeatQuotes", val, nosave); } @@ -450,49 +450,49 @@ export function setStrictSpace(val: boolean, nosave?: boolean): boolean { //opposite shift space export function setOppositeShiftMode( val: ConfigSchemas.OppositeShiftMode, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("oppositeShiftMode", val, nosave); } export function setCaretStyle( caretStyle: ConfigSchemas.CaretStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("caretStyle", caretStyle, nosave); } export function setPaceCaretStyle( caretStyle: ConfigSchemas.CaretStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("paceCaretStyle", caretStyle, nosave); } export function setShowAverage( value: ConfigSchemas.ShowAverage, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("showAverage", value, nosave); } export function setHighlightMode( mode: ConfigSchemas.HighlightMode, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("highlightMode", mode, nosave); } export function setTapeMode( mode: ConfigSchemas.TapeMode, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("tapeMode", mode, nosave); } export function setTapeMargin( value: ConfigSchemas.TapeMargin, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("tapeMargin", value, nosave); } @@ -503,41 +503,41 @@ export function setHideExtraLetters(val: boolean, nosave?: boolean): boolean { export function setTimerStyle( style: ConfigSchemas.TimerStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("timerStyle", style, nosave); } export function setLiveSpeedStyle( style: ConfigSchemas.LiveSpeedAccBurstStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("liveSpeedStyle", style, nosave); } export function setLiveAccStyle( style: ConfigSchemas.LiveSpeedAccBurstStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("liveAccStyle", style, nosave); } export function setLiveBurstStyle( style: ConfigSchemas.LiveSpeedAccBurstStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("liveBurstStyle", style, nosave); } export function setTimerColor( color: ConfigSchemas.TimerColor, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("timerColor", color, nosave); } export function setTimerOpacity( opacity: ConfigSchemas.TimerOpacity, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("timerOpacity", opacity, nosave); } @@ -550,14 +550,14 @@ export function setKeyTips(keyTips: boolean, nosave?: boolean): boolean { //mode export function setTimeConfig( time: ConfigSchemas.TimeConfig, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("time", time, nosave); } export function setQuoteLength( len: ConfigSchemas.QuoteLengthConfig, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("quoteLength", len, nosave); } @@ -568,7 +568,7 @@ export function setQuoteLengthAll(nosave?: boolean): boolean { export function setWordCount( wordCount: ConfigSchemas.WordCount, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("words", wordCount, nosave); } @@ -576,14 +576,14 @@ export function setWordCount( //caret export function setSmoothCaret( mode: ConfigSchemas.SmoothCaret, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("smoothCaret", mode, nosave); } export function setCodeUnindentOnBackspace( mode: boolean, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("codeUnindentOnBackspace", mode, nosave); } @@ -600,7 +600,7 @@ export function setSmoothLineScroll(mode: boolean, nosave?: boolean): boolean { //quick restart export function setQuickRestartMode( mode: ConfigSchemas.QuickRestart, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("quickRestart", mode, nosave); } @@ -617,21 +617,21 @@ export function setFreedomMode(freedom: boolean, nosave?: boolean): boolean { export function setConfidenceMode( cm: ConfigSchemas.ConfidenceMode, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("confidenceMode", cm, nosave); } export function setIndicateTypos( value: ConfigSchemas.IndicateTypos, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("indicateTypos", value, nosave); } export function setAutoSwitchTheme( boolean: boolean, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("autoSwitchTheme", boolean, nosave); } @@ -642,28 +642,28 @@ export function setCustomTheme(boolean: boolean, nosave?: boolean): boolean { export function setTheme( name: ConfigSchemas.ThemeName, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("theme", name, nosave); } export function setThemeLight( name: ConfigSchemas.ThemeName, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("themeLight", name, nosave); } export function setThemeDark( name: ConfigSchemas.ThemeName, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("themeDark", name, nosave); } export function setRandomTheme( val: ConfigSchemas.RandomTheme, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("randomTheme", val, nosave); } @@ -678,7 +678,7 @@ export function setLazyMode(val: boolean, nosave?: boolean): boolean { export function setCustomThemeColors( colors: ConfigSchemas.CustomThemeColors, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customThemeColors", colors, nosave); } @@ -693,105 +693,105 @@ export function setMonkey(monkey: boolean, nosave?: boolean): boolean { export function setKeymapMode( mode: ConfigSchemas.KeymapMode, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapMode", mode, nosave); } export function setKeymapLegendStyle( style: ConfigSchemas.KeymapLegendStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapLegendStyle", style, nosave); } export function setKeymapStyle( style: ConfigSchemas.KeymapStyle, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapStyle", style, nosave); } export function setKeymapLayout( layout: ConfigSchemas.KeymapLayout, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapLayout", layout, nosave); } export function setKeymapShowTopRow( show: ConfigSchemas.KeymapShowTopRow, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapShowTopRow", show, nosave); } export function setKeymapSize( keymapSize: ConfigSchemas.KeymapSize, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("keymapSize", keymapSize, nosave); } export function setLayout( layout: ConfigSchemas.Layout, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("layout", layout, nosave); } export function setFontSize( fontSize: ConfigSchemas.FontSize, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("fontSize", fontSize, nosave); } export function setMaxLineWidth( maxLineWidth: ConfigSchemas.MaxLineWidth, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("maxLineWidth", maxLineWidth, nosave); } export function setCustomBackground( value: ConfigSchemas.CustomBackground, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customBackground", value, nosave); } export function setCustomLayoutfluid( value: ConfigSchemas.CustomLayoutFluid, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customLayoutfluid", value, nosave); } export function setCustomPolyglot( value: ConfigSchemas.CustomPolyglot, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customPolyglot", value, nosave); } export function setCustomBackgroundSize( value: ConfigSchemas.CustomBackgroundSize, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customBackgroundSize", value, nosave); } export function setCustomBackgroundFilter( array: ConfigSchemas.CustomBackgroundFilter, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("customBackgroundFilter", array, nosave); } export function setMonkeyPowerLevel( level: ConfigSchemas.MonkeyPowerLevel, - nosave?: boolean + nosave?: boolean, ): boolean { return genericSet("monkeyPowerLevel", level, nosave); } @@ -832,7 +832,7 @@ export async function apply(partialConfig: Partial): Promise { const configKeysToReset: (keyof Config)[] = []; const firstKeys = typedKeys(fullConfig).filter( - (key) => !lastConfigsToApply.has(key) + (key) => !lastConfigsToApply.has(key), ); for (const configKey of [...firstKeys, ...lastConfigsToApply]) { @@ -854,7 +854,7 @@ export async function apply(partialConfig: Partial): Promise { undefined, undefined, undefined, - config + config, ); ConfigEvent.dispatch("fullConfigChangeFinished"); } @@ -902,7 +902,7 @@ export async function applyFromJson(json: string): Promise { } return migrateConfig(value); }, - } + }, ); await apply(parsedConfig); saveFullConfigToLocalStorage(); diff --git a/frontend/src/ts/constants/languages.ts b/frontend/src/ts/constants/languages.ts index c4c921fffb12..af5eddfd3565 100644 --- a/frontend/src/ts/constants/languages.ts +++ b/frontend/src/ts/constants/languages.ts @@ -367,7 +367,7 @@ export const LanguageGroups: Record = { export type LanguageGroupName = keyof typeof LanguageGroups; export const LanguageGroupNames: LanguageGroupName[] = Array.from( - Object.keys(LanguageGroups) + Object.keys(LanguageGroups), ); /** @@ -376,7 +376,7 @@ export const LanguageGroupNames: LanguageGroupName[] = Array.from( * @returns the language group. */ export function getGroupForLanguage( - language: Language + language: Language, ): LanguageGroupName | undefined { return LanguageGroupNames.find((group) => group.includes(language)); } diff --git a/frontend/src/ts/constants/themes.ts b/frontend/src/ts/constants/themes.ts index b7147af8068c..a01a9d96b7a9 100644 --- a/frontend/src/ts/constants/themes.ts +++ b/frontend/src/ts/constants/themes.ts @@ -1135,7 +1135,7 @@ export const ThemesList: Theme[] = Object.keys(themes) ({ ...themes[it as ThemeName], name: it, - } as Theme) + }) as Theme, ); export const ThemesListSorted = [ diff --git a/frontend/src/ts/controllers/analytics-controller.ts b/frontend/src/ts/controllers/analytics-controller.ts index cd58280d1989..b16b41502d04 100644 --- a/frontend/src/ts/controllers/analytics-controller.ts +++ b/frontend/src/ts/controllers/analytics-controller.ts @@ -10,7 +10,7 @@ let analytics: AnalyticsType; export async function log( eventName: string, - params?: Record + params?: Record, ): Promise { try { logEvent(analytics, eventName, params); diff --git a/frontend/src/ts/controllers/badge-controller.ts b/frontend/src/ts/controllers/badge-controller.ts index 779e4f58fd58..2532ab4ed4d8 100644 --- a/frontend/src/ts/controllers/badge-controller.ts +++ b/frontend/src/ts/controllers/badge-controller.ts @@ -159,7 +159,7 @@ export function getHTMLById( id: number, noText = false, noBalloon = false, - showUnknown = false + showUnknown = false, ): string { const badge = badges[id] as UserBadge | undefined; diff --git a/frontend/src/ts/controllers/captcha-controller.ts b/frontend/src/ts/controllers/captcha-controller.ts index 66782db53504..7b85f6942e05 100644 --- a/frontend/src/ts/controllers/captcha-controller.ts +++ b/frontend/src/ts/controllers/captcha-controller.ts @@ -6,7 +6,7 @@ const captchas: Record = {}; type Grecaptcha = { render: ( element: HTMLElement, - options: { sitekey: string; callback?: (responseToken: string) => void } + options: { sitekey: string; callback?: (responseToken: string) => void }, ) => number; reset: (widgetId: number) => void; getResponse: (widgetId: number) => string; @@ -27,7 +27,7 @@ export function isCaptchaAvailable(): boolean { export function render( element: HTMLElement, id: string, - callback?: (responseToken: string) => void + callback?: (responseToken: string) => void, ): void { if (captchas[id] !== undefined && captchas[id] !== null) { return; diff --git a/frontend/src/ts/controllers/challenge-controller.ts b/frontend/src/ts/controllers/challenge-controller.ts index 30b6c5b6cc56..e69cc8041c29 100644 --- a/frontend/src/ts/controllers/challenge-controller.ts +++ b/frontend/src/ts/controllers/challenge-controller.ts @@ -37,7 +37,7 @@ export function clearActive(): void { function verifyRequirement( result: CompletedEvent, requirements: NonNullable, - requirementType: keyof NonNullable + requirementType: keyof NonNullable, ): [boolean, string[]] { let requirementsMet = true; let failReasons: string[] = []; @@ -154,19 +154,19 @@ export function verify(result: CompletedEvent): string | null { if (TestState.activeChallenge.requirements === undefined) { Notifications.add( `${TestState.activeChallenge.display} challenge passed!`, - 1 + 1, ); return TestState.activeChallenge.name; } else { let requirementsMet = true; const failReasons: string[] = []; for (const requirementType of Misc.typedKeys( - TestState.activeChallenge.requirements + TestState.activeChallenge.requirements, )) { const [passed, requirementFailReasons] = verifyRequirement( result, TestState.activeChallenge.requirements, - requirementType + requirementType, ); if (!passed) { requirementsMet = false; @@ -180,12 +180,12 @@ export function verify(result: CompletedEvent): string | null { 1, { duration: 5, - } + }, ); } Notifications.add( `${TestState.activeChallenge.display} challenge passed!`, - 1 + 1, ); return TestState.activeChallenge.name; } else { @@ -193,7 +193,7 @@ export function verify(result: CompletedEvent): string | null { `${ TestState.activeChallenge.display } challenge failed: ${failReasons.join(", ")}`, - 0 + 0, ); return null; } @@ -202,7 +202,7 @@ export function verify(result: CompletedEvent): string | null { console.error(e); Notifications.add( `Something went wrong when verifying challenge: ${(e as Error).message}`, - 0 + 0, ); return null; } @@ -226,7 +226,7 @@ export async function setup(challengeName: string): Promise { } const challenge = list.find( - (c) => c.name.toLowerCase() === challengeName.toLowerCase() + (c) => c.name.toLowerCase() === challengeName.toLowerCase(), ); let notitext; try { @@ -263,7 +263,7 @@ export async function setup(challengeName: string): Promise { } else if (challenge.type === "script") { Loader.show(); const response = await fetch( - "/challenges/" + (challenge.parameters[0] as string) + "/challenges/" + (challenge.parameters[0] as string), ); Loader.hide(); if (response.status !== 200) { @@ -330,7 +330,7 @@ export async function setup(challengeName: string): Promise { } catch (e) { Notifications.add( Misc.createErrorMessage(e, "Failed to load challenge"), - -1 + -1, ); return false; } diff --git a/frontend/src/ts/controllers/chart-controller.ts b/frontend/src/ts/controllers/chart-controller.ts index 117e914fe5bd..9aa4fe2f4b21 100644 --- a/frontend/src/ts/controllers/chart-controller.ts +++ b/frontend/src/ts/controllers/chart-controller.ts @@ -48,7 +48,7 @@ Chart.register( TimeSeriesScale, Tooltip, chartTrendline, - chartAnnotation + chartAnnotation, ); ( @@ -73,12 +73,12 @@ class ChartWithUpdateColors< TType extends ChartType = ChartType, TData = DefaultDataPoint, TLabel = unknown, - DatasetIds = never + DatasetIds = never, > extends Chart { // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor( item: ChartItem, - config: ChartConfiguration + config: ChartConfiguration, ) { super(item, config); } @@ -99,7 +99,7 @@ class ChartWithUpdateColors< } getScale( - id: DatasetIds extends never ? never : "x" | DatasetIds + id: DatasetIds extends never ? never : "x" | DatasetIds, ): DatasetIds extends never ? never : CartesianScaleOptions { //@ts-expect-error its too difficult to figure out these types, but this works // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access @@ -292,7 +292,7 @@ export const result = new ChartWithUpdateColors< } void ResultWordHighlight.highlightWordsInRange( firstHighlightWordIndex, - lastHighlightWordIndex + lastHighlightWordIndex, ); } catch {} return ""; @@ -355,7 +355,7 @@ export const accountHistory = new ChartWithUpdateColors< | "accAvgHundred" >( document.querySelector( - ".pageAccount #accountHistoryChart" + ".pageAccount #accountHistoryChart", ) as HTMLCanvasElement, { type: "line", @@ -573,7 +573,7 @@ export const accountHistory = new ChartWithUpdateColors< tooltipItem.dataIndex ] as AccChartData; return `error rate: ${Numbers.roundTo2( - resultData.errorRate + resultData.errorRate, )}%\nacc: ${Numbers.roundTo2(100 - resultData.errorRate)}%`; } const resultData = tooltipItem.dataset.data[ @@ -609,7 +609,7 @@ export const accountHistory = new ChartWithUpdateColors< "\n\n" + `date: ${format( new Date(resultData.timestamp), - "dd MMM yyyy HH:mm" + "dd MMM yyyy HH:mm", )}`; return label; @@ -625,7 +625,7 @@ export const accountHistory = new ChartWithUpdateColors< }, }, }, - } + }, ); export const accountActivity = new ChartWithUpdateColors< @@ -635,7 +635,7 @@ export const accountActivity = new ChartWithUpdateColors< "count" | "avgWpm" >( document.querySelector( - ".pageAccount #accountActivityChart" + ".pageAccount #accountActivityChart", ) as HTMLCanvasElement, { type: "bar", @@ -752,24 +752,24 @@ export const accountActivity = new ChartWithUpdateColors< tooltipItem.dataIndex ] as ActivityChartDataPoint; const typingSpeedUnit = getTypingSpeedUnit( - Config.typingSpeedUnit + Config.typingSpeedUnit, ); return `Time Typing: ${DateTime.secondsToString( Math.round(resultData.y * 60), true, - true + true, )}\nTests Completed: ${ resultData.amount }\nRestarts per test: ${Numbers.roundTo2( - (resultData.restarts ?? 0) / (resultData.amount ?? 0) + (resultData.restarts ?? 0) / (resultData.amount ?? 0), )}\nHighest ${Config.typingSpeedUnit.toUpperCase()}: ${Numbers.roundTo2( - typingSpeedUnit.fromWpm(resultData.maxWpm ?? 0) + typingSpeedUnit.fromWpm(resultData.maxWpm ?? 0), )}\nAverage ${Config.typingSpeedUnit.toUpperCase()}: ${Numbers.roundTo2( - typingSpeedUnit.fromWpm(resultData.avgWpm ?? 0) + typingSpeedUnit.fromWpm(resultData.avgWpm ?? 0), )}\nAverage Accuracy: ${Numbers.roundTo2( - resultData.avgAcc ?? 0 + resultData.avgAcc ?? 0, )}%\nAverage Consistency: ${Numbers.roundTo2( - resultData.avgCon ?? 0 + resultData.avgCon ?? 0, )}%`; }, label: function (): string { @@ -779,7 +779,7 @@ export const accountActivity = new ChartWithUpdateColors< }, }, }, - } + }, ); export const accountHistogram = new ChartWithUpdateColors< @@ -789,7 +789,7 @@ export const accountHistogram = new ChartWithUpdateColors< "count" >( document.querySelector( - ".pageAccount #accountHistogramChart" + ".pageAccount #accountHistogramChart", ) as HTMLCanvasElement, { type: "bar", @@ -882,7 +882,7 @@ export const accountHistogram = new ChartWithUpdateColors< }, }, }, - } + }, ); export const globalSpeedHistogram = new ChartWithUpdateColors< @@ -892,7 +892,7 @@ export const globalSpeedHistogram = new ChartWithUpdateColors< "count" >( document.querySelector( - ".pageAbout #publicStatsHistogramChart" + ".pageAbout #publicStatsHistogramChart", ) as HTMLCanvasElement, { type: "bar", @@ -951,7 +951,7 @@ export const globalSpeedHistogram = new ChartWithUpdateColors< }, }, }, - } + }, ); export const miniResult = new ChartWithUpdateColors< @@ -1101,7 +1101,7 @@ export function updateAccountChartButtons(): void { function updateAccountChartButton( isActive: boolean, - className: ButtonBelowChart + className: ButtonBelowChart, ): void { isActive ? $(`.pageAccount ${className}`).addClass("active") @@ -1138,7 +1138,7 @@ function updateAccuracy(updateChart = true): void { } else { const minAccRoundedTo10 = Math.floor( - Math.min(...accountHistory.getDataset("acc").data.map((x) => x.y)) / 5 + Math.min(...accountHistory.getDataset("acc").data.map((x) => x.y)) / 5, ) * 5; accountHistory.getScale("acc").min = minAccRoundedTo10; @@ -1186,7 +1186,7 @@ async function updateColors< | AccChartData[] | ActivityChartDataPoint[] | number[], - TLabel = string + TLabel = string, >(chart: ChartWithUpdateColors): Promise { const bgcolor = await ThemeColors.get("bg"); const subcolor = await ThemeColors.get("sub"); @@ -1231,7 +1231,7 @@ async function updateColors< burst.backgroundColor = blendTwoHexColors( subaltcolor, subaltcolor + "00", - 0.5 + 0.5, ); burst.borderColor = subcolor; burst.pointBackgroundColor = subcolor; @@ -1260,7 +1260,7 @@ async function updateColors< burst.backgroundColor = blendTwoHexColors( subaltcolor, subaltcolor + "00", - 0.75 + 0.75, ); burst.borderColor = subcolor; burst.pointBackgroundColor = subcolor; diff --git a/frontend/src/ts/controllers/page-controller.ts b/frontend/src/ts/controllers/page-controller.ts index 8745cea66ae4..2950baf11e5f 100644 --- a/frontend/src/ts/controllers/page-controller.ts +++ b/frontend/src/ts/controllers/page-controller.ts @@ -87,7 +87,7 @@ async function showSyncLoading({ await getLoadingPromiseWithBarKeyframes( options, fillDivider, - currentOffset + currentOffset, ); void PageLoading.updateBar(100, 125); PageLoading.updateText("Done"); @@ -114,7 +114,7 @@ async function getLoadingPromiseWithBarKeyframes( { style: "bar" } >, fillDivider: number, - fillOffset: number + fillOffset: number, ): Promise { let loadingPromise = loadingOptions.loadingPromise(); @@ -131,7 +131,7 @@ async function getLoadingPromiseWithBarKeyframes( } await PageLoading.updateBar( fillOffset + keyframe.percentage / fillDivider, - keyframe.durationMs + keyframe.durationMs, ); } })(); @@ -158,7 +158,7 @@ async function getLoadingPromiseWithBarKeyframes( export async function change( pageName: PageName, - options = {} as ChangeOptions + options = {} as ChangeOptions, ): Promise { const defaultOptions = { force: false, @@ -168,7 +168,7 @@ export async function change( if (PageTransition.get() && !options.force) { console.debug( - `change page to ${pageName} stopped, page transition is true` + `change page to ${pageName} stopped, page transition is true`, ); return false; } @@ -251,7 +251,7 @@ export async function change( PageLoading.updateText( `Failed to load the ${nextPage.id} page: ${ error instanceof Error ? error.message : String(error) - }` + }`, ); PageTransition.set(false); return false; diff --git a/frontend/src/ts/controllers/quotes-controller.ts b/frontend/src/ts/controllers/quotes-controller.ts index 5d6528fa937c..db31b80138b1 100644 --- a/frontend/src/ts/controllers/quotes-controller.ts +++ b/frontend/src/ts/controllers/quotes-controller.ts @@ -39,13 +39,13 @@ class QuotesController { async getQuotes( language: Language, - quoteLengths?: number[] + quoteLengths?: number[], ): Promise { const normalizedLanguage = removeLanguageSize(language); if (this.quoteCollection.language !== normalizedLanguage) { const { data, error } = await tryCatch( - cachedFetchJson(`quotes/${normalizedLanguage}.json`) + cachedFetchJson(`quotes/${normalizedLanguage}.json`), ); if (error) { if ( @@ -200,7 +200,7 @@ class QuotesController { return false; } return (favoriteQuotes[language] ?? []).includes(id.toString()); - } + }, ); return matchedLanguage !== undefined; @@ -223,7 +223,7 @@ class QuotesController { if (response.status === 200) { const quoteIndex = snapshot.favoriteQuotes?.[quote.language]?.indexOf( - `${quote.id}` + `${quote.id}`, ) as number; snapshot.favoriteQuotes?.[quote.language]?.splice(quoteIndex, 1); } else { diff --git a/frontend/src/ts/controllers/route-controller.ts b/frontend/src/ts/controllers/route-controller.ts index 1aa6eab0af00..918b310d0281 100644 --- a/frontend/src/ts/controllers/route-controller.ts +++ b/frontend/src/ts/controllers/route-controller.ts @@ -21,7 +21,7 @@ type NavigateOptions = { function pathToRegex(path: string): RegExp { return new RegExp( - "^" + path.replace(/\//g, "\\/").replace(/:\w+/g, "(.+)") + "$" + "^" + path.replace(/\//g, "\\/").replace(/:\w+/g, "(.+)") + "$", ); } @@ -31,7 +31,7 @@ function getParams(match: { }): Record { const values = match.result.slice(1); const keys = Array.from(match.route.path.matchAll(/:(\w+)/g)).map( - (result) => result[1] + (result) => result[1], ); const a = keys.map((key, index) => [key, values[index]]); @@ -42,7 +42,7 @@ type Route = { path: string; load: ( params: Record, - navigateOptions: NavigateOptions + navigateOptions: NavigateOptions, ) => Promise; }; @@ -166,7 +166,7 @@ export async function navigate( url = window.location.pathname + window.location.search + window.location.hash, - options = {} as NavigateOptions + options = {} as NavigateOptions, ): Promise { if ( !options.force && @@ -179,7 +179,7 @@ export async function navigate( TestState.testRestarting }, resultCalculating: ${ TestUI.resultCalculating - }, pageTransition: ${PageTransition.get()})` + }, pageTransition: ${PageTransition.get()})`, ); return; } @@ -229,7 +229,7 @@ async function router(options = {} as NavigateOptions): Promise { {}, { force: true, - } + }, ); return; } diff --git a/frontend/src/ts/controllers/sound-controller.ts b/frontend/src/ts/controllers/sound-controller.ts index 57105b3b27c6..007774b11b38 100644 --- a/frontend/src/ts/controllers/sound-controller.ts +++ b/frontend/src/ts/controllers/sound-controller.ts @@ -462,7 +462,7 @@ type GetNoteFrequencyCallback = (octave: number) => number; function bindToNote( noteFrequencies: ValidFrequencies, - octaveOffset = 0 + octaveOffset = 0, ): GetNoteFrequencyCallback { return (octave: number): number => { return noteFrequencies[octave + octaveOffset] ?? 0; @@ -534,7 +534,7 @@ function initAudioContext(): void { Notifications.add( createErrorMessage(e, "Error initializing audio context") + ". Notes will not play.", - -1 + -1, ); } } @@ -640,7 +640,7 @@ export async function playTimeWarning(): Promise { function playNote( codeOverride?: string, - oscillatorTypeOverride?: SupportedOscillatorTypes + oscillatorTypeOverride?: SupportedOscillatorTypes, ): void { if (audioCtx === undefined) { initAudioContext(); diff --git a/frontend/src/ts/controllers/theme-controller.ts b/frontend/src/ts/controllers/theme-controller.ts index 340b18cb6628..fd326b3f51fd 100644 --- a/frontend/src/ts/controllers/theme-controller.ts +++ b/frontend/src/ts/controllers/theme-controller.ts @@ -77,7 +77,7 @@ export async function loadStyle(name: string): Promise { const next = $("#nextTheme"); if (next.length === 0) { console.debug( - "Theme controller failed to swap elements, next is missing" + "Theme controller failed to swap elements, next is missing", ); return; } @@ -89,7 +89,7 @@ export async function loadStyle(name: string): Promise { loadStyleLoaderTimeouts.push( setTimeout(() => { Loader.show(); - }, 100) + }, 100), ); $("#nextTheme").remove(); const headScript = document.querySelector("#currentTheme"); @@ -129,7 +129,7 @@ export async function loadStyle(name: string): Promise { } else { console.debug( "Theme controller inserting link after current theme", - link + link, ); headScript.after(link); } @@ -146,13 +146,13 @@ export async function loadStyle(name: string): Promise { async function apply( themeName: string, customColorsOverride?: string[], - isPreview = false + isPreview = false, ): Promise { console.debug( "Theme controller applying theme", themeName, customColorsOverride, - isPreview + isPreview, ); const name = customColorsOverride ? "custom" : themeName; @@ -196,7 +196,7 @@ async function apply( function updateFooterIndicator(nameOverride?: string): void { const indicator = document.querySelector( - "footer .right .current-theme" + "footer .right .current-theme", ); const text = indicator?.querySelector(".text"); const favIcon = indicator?.querySelector(".favIndicator"); @@ -246,7 +246,7 @@ let previewState: PreviewState = null; export function preview( themeIdentifier: string, - customColorsOverride?: string[] + customColorsOverride?: string[], ): void { previewState = { theme: themeIdentifier, colors: customColorsOverride }; debouncedPreview(); @@ -261,12 +261,12 @@ const debouncedPreview = debounce<() => void>(250, () => { async function set( themeIdentifier: string, - isAutoSwitch = false + isAutoSwitch = false, ): Promise { console.debug( "Theme controller setting theme", themeIdentifier, - isAutoSwitch + isAutoSwitch, ); await apply(themeIdentifier, undefined, isAutoSwitch); @@ -344,7 +344,7 @@ export async function randomizeTheme(): Promise { if (Config.randomTheme === "custom") { const theme = DB.getSnapshot()?.customThemes?.find( - (ct) => ct._id === randomTheme + (ct) => ct._id === randomTheme, ); colorsOverride = theme?.colors; randomTheme = "custom"; @@ -398,7 +398,7 @@ export async function applyCustomBackground(): Promise { let backgroundUrl = Config.customBackground; $( - ".pageSettings .section[data-config-name='customBackgroundSize'] input[type='text']" + ".pageSettings .section[data-config-name='customBackgroundSize'] input[type='text']", ).val(backgroundUrl); //if there is a localBackgroundFile available, use it. @@ -410,7 +410,7 @@ export async function applyCustomBackground(): Promise { // hide the filter section initially and always $( - ".pageSettings .section[data-config-name='customBackgroundFilter']" + ".pageSettings .section[data-config-name='customBackgroundFilter']", ).addClass("hidden"); if (backgroundUrl === "") { @@ -428,12 +428,12 @@ export async function applyCustomBackground(): Promise { img.setAttribute("src", backgroundUrl); img.setAttribute( "onError", - "javascript:this.style.display='none'; window.dispatchEvent(new Event('customBackgroundFailed'))" + "javascript:this.style.display='none'; window.dispatchEvent(new Event('customBackgroundFailed'))", ); img.onload = () => { // show the filter section only if the image loads successfully $( - ".pageSettings .section[data-config-name='customBackgroundFilter']" + ".pageSettings .section[data-config-name='customBackgroundFilter']", ).removeClass("hidden"); }; @@ -466,7 +466,7 @@ export async function applyFontFamily(): Promise { document.documentElement.style.setProperty( "--font", - `"${font}", "Roboto Mono", "Vazirmatn", monospace` + `"${font}", "Roboto Mono", "Vazirmatn", monospace`, ); } @@ -575,7 +575,7 @@ window.addEventListener("customBackgroundFailed", () => { Notifications.add( "Custom background link is either temporarily unavailable or expired. Please make sure the URL is correct or change it", 0, - { duration: 5 } + { duration: 5 }, ); }); diff --git a/frontend/src/ts/controllers/user-flag-controller.ts b/frontend/src/ts/controllers/user-flag-controller.ts index 5660750233b6..790f83dcd8bc 100644 --- a/frontend/src/ts/controllers/user-flag-controller.ts +++ b/frontend/src/ts/controllers/user-flag-controller.ts @@ -82,7 +82,7 @@ function toHtml(flag: UserFlag, formatOptions: UserFlagOptions): string { export function getHtmlByUserFlags( source: SupportsFlags, - options?: UserFlagOptions + options?: UserFlagOptions, ): string { const formatOptions = { ...USER_FLAG_OPTIONS_DEFAULT, ...options }; return getMatchingFlags(source) diff --git a/frontend/src/ts/db.ts b/frontend/src/ts/db.ts index 8c1039c6415c..367ce51ad3d3 100644 --- a/frontend/src/ts/db.ts +++ b/frontend/src/ts/db.ts @@ -41,7 +41,10 @@ let dbSnapshot: Snapshot | undefined; const firstDayOfTheWeek = getFirstDayOfTheWeek(); export class SnapshotInitError extends Error { - constructor(message: string, public responseCode: number) { + constructor( + message: string, + public responseCode: number, + ) { super(message); this.name = "SnapshotInitError"; // TODO INVESTIGATE @@ -56,7 +59,7 @@ export function getSnapshot(): Snapshot | undefined { export function setSnapshot( newSnapshot: Snapshot | undefined, - options?: { dispatchEvent?: boolean } + options?: { dispatchEvent?: boolean }, ): void { const originalBanned = dbSnapshot?.banned; const originalVerified = dbSnapshot?.verified; @@ -107,25 +110,25 @@ export async function initSnapshot(): Promise { if (userResponse.status !== 200) { throw new SnapshotInitError( `${userResponse.body.message} (user)`, - userResponse.status + userResponse.status, ); } if (configResponse.status !== 200) { throw new SnapshotInitError( `${configResponse.body.message} (config)`, - configResponse.status + configResponse.status, ); } if (presetsResponse.status !== 200) { throw new SnapshotInitError( `${presetsResponse.body.message} (presets)`, - presetsResponse.status + presetsResponse.status, ); } if (connectionsResponse.status !== 200) { throw new SnapshotInitError( `${connectionsResponse.body.message} (connections)`, - connectionsResponse.status + connectionsResponse.status, ); } @@ -137,13 +140,13 @@ export async function initSnapshot(): Promise { if (userData === null) { throw new SnapshotInitError( `Request was successful but user data is null`, - 200 + 200, ); } if (configData !== null && "config" in configData) { throw new Error( - "Config data is not in the correct format. Please refresh the page or contact support." + "Config data is not in the correct format. Please refresh the page or contact support.", ); } @@ -190,7 +193,7 @@ export async function initSnapshot(): Promise { snap.testActivity = new ModifiableTestActivityCalendar( userData.testActivity.testsByDays, new Date(userData.testActivity.lastDay), - firstDayOfTheWeek + firstDayOfTheWeek, ); } @@ -265,7 +268,7 @@ export async function initSnapshot(): Promise { } else { return 0; } - } + }, ); } @@ -332,7 +335,7 @@ export async function getUserResults(offset?: number): Promise { const oldestTimestamp = lastElementFromArray(dbSnapshot.results) ?.timestamp as number; const resultsWithoutDuplicates = results.filter( - (it) => it.timestamp < oldestTimestamp + (it) => it.timestamp < oldestTimestamp, ); dbSnapshot.results.push(...resultsWithoutDuplicates); } else { @@ -346,7 +349,7 @@ function _getCustomThemeById(themeID: string): CustomTheme | undefined { } export async function addCustomTheme( - theme: Omit + theme: Omit, ): Promise { if (!dbSnapshot) return false; @@ -363,7 +366,7 @@ export async function addCustomTheme( if (response.status !== 200) { Notifications.add( "Error adding custom theme: " + response.body.message, - -1 + -1, ); return false; } @@ -384,7 +387,7 @@ export async function addCustomTheme( export async function editCustomTheme( themeId: string, - newTheme: Omit + newTheme: Omit, ): Promise { if (!isAuthenticated()) return false; if (!dbSnapshot) return false; @@ -397,7 +400,7 @@ export async function editCustomTheme( if (!customTheme) { Notifications.add( "Editing failed: Custom theme with id: " + themeId + " does not exist", - -1 + -1, ); return false; } @@ -408,7 +411,7 @@ export async function editCustomTheme( if (response.status !== 200) { Notifications.add( "Error editing custom theme: " + response.body.message, - -1 + -1, ); return false; } @@ -435,13 +438,13 @@ export async function deleteCustomTheme(themeId: string): Promise { if (response.status !== 200) { Notifications.add( "Error deleting custom theme: " + response.body.message, - -1 + -1, ); return false; } dbSnapshot.customThemes = dbSnapshot.customThemes?.filter( - (t) => t._id !== themeId + (t) => t._id !== themeId, ); return true; @@ -454,7 +457,7 @@ export async function getUserAverage10( numbers: boolean, language: string, difficulty: Difficulty, - lazyMode: boolean + lazyMode: boolean, ): Promise<[number, number]> { const snapshot = getSnapshot(); @@ -539,7 +542,7 @@ export async function getUserDailyBest( numbers: boolean, language: string, difficulty: Difficulty, - lazyMode: boolean + lazyMode: boolean, ): Promise { const snapshot = getSnapshot(); @@ -604,7 +607,7 @@ export async function getActiveTagsPB( numbers: boolean, language: string, difficulty: Difficulty, - lazyMode: boolean + lazyMode: boolean, ): Promise { const snapshot = getSnapshot(); if (!snapshot) return 0; @@ -620,7 +623,7 @@ export async function getActiveTagsPB( numbers, language, difficulty, - lazyMode + lazyMode, ); if (currTagPB > tagPbWpm) tagPbWpm = currTagPB; } @@ -636,7 +639,7 @@ export async function getLocalPB( language: string, difficulty: Difficulty, lazyMode: boolean, - funboxes: FunboxMetadata[] + funboxes: FunboxMetadata[], ): Promise { if (!funboxes.every((f) => f.canGetPb)) { return undefined; @@ -652,7 +655,7 @@ export async function getLocalPB( (pb.numbers ?? false) === numbers && pb.difficulty === difficulty && pb.language === language && - (pb.lazyMode ?? false) === lazyMode + (pb.lazyMode ?? false) === lazyMode, ); } @@ -667,7 +670,7 @@ function saveLocalPB( wpm: number, acc: number, raw: number, - consistency: number + consistency: number, ): void { if (mode === "quote") return; if (!dbSnapshot) return; @@ -723,7 +726,7 @@ function saveLocalPB( raw, timestamp: Date.now(), consistency, - } + }, ); } } @@ -741,7 +744,7 @@ export async function getLocalTagPB( numbers: boolean, language: string, difficulty: Difficulty, - lazyMode: boolean + lazyMode: boolean, ): Promise { if (dbSnapshot === null) return 0; @@ -776,7 +779,7 @@ export async function getLocalTagPB( (pb.numbers ?? false) === numbers && pb.difficulty === difficulty && pb.language === language && - (pb.lazyMode === lazyMode || (pb.lazyMode === undefined && !lazyMode)) + (pb.lazyMode === lazyMode || (pb.lazyMode === undefined && !lazyMode)), )?.wpm ?? 0; return ret; @@ -794,13 +797,13 @@ export async function saveLocalTagPB( wpm: number, acc: number, raw: number, - consistency: number + consistency: number, ): Promise { if (!dbSnapshot) return; if (mode === "quote") return; function cont(): void { const filteredtag = dbSnapshot?.tags?.find( - (t) => t._id === tagId + (t) => t._id === tagId, ) as SnapshotUserTag; filteredtag.personalBests ??= { @@ -895,7 +898,7 @@ export async function updateLbMemory( mode2: Mode2, language: Language, rank: number, - api = false + api = false, ): Promise { if (mode === "time") { const timeMode = mode; @@ -996,7 +999,7 @@ export function saveLocalResult(data: SaveLocalResultData): void { data.result.wpm, data.result.acc, data.result.rawWpm, - data.result.consistency + data.result.consistency, ); } } @@ -1056,7 +1059,7 @@ export function addBadge(badge: Badge): void { } export async function getTestActivityCalendar( - yearString: string + yearString: string, ): Promise { if (!isAuthenticated() || dbSnapshot === undefined) return undefined; @@ -1077,7 +1080,7 @@ export async function getTestActivityCalendar( if (response.status !== 200) { Notifications.add( "Error getting test activities: " + response.body.message, - -1 + -1, ); Loader.hide(); return undefined; @@ -1089,14 +1092,14 @@ export async function getTestActivityCalendar( const testsByDays = response.body.data[year] ?? []; const lastDay = Dates.addDays( new Date(parseInt(year), 0, 1), - testsByDays.length + testsByDays.length, ); dbSnapshot.testActivityByYear[year] = new TestActivityCalendar( testsByDays, lastDay, firstDayOfTheWeek, - true + true, ); } Loader.hide(); @@ -1119,7 +1122,7 @@ export function mergeConnections(connections: Connection[]): void { } function convertConnections( - connectionsData: Connection[] + connectionsData: Connection[], ): Snapshot["connections"] { return Object.fromEntries( connectionsData.map((connection) => { @@ -1132,7 +1135,7 @@ function convertConnections( ? "incoming" : connection.status, ]; - }) + }), ); } @@ -1143,7 +1146,7 @@ export function isFriend(uid: string | undefined): boolean { if (!snapshot) return false; return Object.entries(snapshot.connections).some( - ([receiverUid, status]) => receiverUid === uid && status === "accepted" + ([receiverUid, status]) => receiverUid === uid && status === "accepted", ); } diff --git a/frontend/src/ts/elements/account-button.ts b/frontend/src/ts/elements/account-button.ts index 90f5b444cf0a..6e4a6de7c2cd 100644 --- a/frontend/src/ts/elements/account-button.ts +++ b/frontend/src/ts/elements/account-button.ts @@ -25,7 +25,7 @@ export function updateName(name: string): void { function updateFlags(flags: SupportsFlags): void { $("nav .textButton.view-account > .text").append( - getHtmlByUserFlags(flags, { iconsOnly: true }) + getHtmlByUserFlags(flags, { iconsOnly: true }), ); } @@ -55,12 +55,12 @@ export function update(): void { $("nav .accountButtonAndMenu .menu .items .goToProfile").attr( "href", - `/profile/${name}` + `/profile/${name}`, ); void Misc.swapElements( document.querySelector("nav .textButton.view-login") as HTMLElement, document.querySelector("nav .accountButtonAndMenu") as HTMLElement, - 250 + 250, ); } else { void Misc.swapElements( @@ -72,7 +72,7 @@ export function update(): void { updateFlags({}); XpBar.setXp(0); updateAvatar(); - } + }, ); } @@ -84,7 +84,7 @@ export function updateFriendRequestsIndicator(): void { if (friends !== undefined) { const pendingFriendRequests = Object.values(friends).filter( - (it) => it === "incoming" + (it) => it === "incoming", ).length; if (pendingFriendRequests > 0) { $("nav .view-account > .notificationBubble").removeClass("hidden"); diff --git a/frontend/src/ts/elements/account-settings/ape-key-table.ts b/frontend/src/ts/elements/account-settings/ape-key-table.ts index 18c1624edef6..83c27771c161 100644 --- a/frontend/src/ts/elements/account-settings/ape-key-table.ts +++ b/frontend/src/ts/elements/account-settings/ape-key-table.ts @@ -187,7 +187,7 @@ function showLoaderRow(): void { table.empty(); table.append( - "" + "", ); } @@ -199,7 +199,7 @@ function refreshList(): void { const apeKeyIds = Object.keys(data); if (apeKeyIds.length === 0) { table.append( - "No keys found" + "No keys found", ); return; } @@ -282,7 +282,7 @@ export async function update(onApeKeyChangee?: () => void): Promise { $(".pageAccountSettings .tab[data-tab='apeKeys'] table").remove(); $(".pageAccountSettings .section.apeKeys .buttons").remove(); $(".pageAccountSettings .section.apeKeys .lostAccess").removeClass( - "hidden" + "hidden", ); return; } diff --git a/frontend/src/ts/elements/account-settings/blocked-user-table.ts b/frontend/src/ts/elements/account-settings/blocked-user-table.ts index db5ef9a096c0..77d88bb34ae6 100644 --- a/frontend/src/ts/elements/account-settings/blocked-user-table.ts +++ b/frontend/src/ts/elements/account-settings/blocked-user-table.ts @@ -26,7 +26,7 @@ async function getData(): Promise { blockedUsers = []; Notifications.add( "Error getting blocked users: " + response.body.message, - -1 + -1, ); return false; } @@ -44,7 +44,7 @@ function showLoaderRow(): void { table.empty(); table.append( - "" + "", ); } @@ -53,7 +53,7 @@ function refreshList(): void { table.empty(); if (blockedUsers.length === 0) { table.append( - "No blocked users" + "No blocked users", ); return; } @@ -61,8 +61,8 @@ function refreshList(): void { (blocked) => ` ${blocked.initiatorName} + blocked.initiatorUid + }?isUid" router-link>${blocked.initiatorName} ${format(new Date(blocked.lastModified), "dd MMM yyyy HH:mm")} - ` + `, ); table.append(content.join()); } diff --git a/frontend/src/ts/elements/account/pb-tables.ts b/frontend/src/ts/elements/account/pb-tables.ts index fa724d0a6a14..8a56e2f74333 100644 --- a/frontend/src/ts/elements/account/pb-tables.ts +++ b/frontend/src/ts/elements/account/pb-tables.ts @@ -122,7 +122,7 @@ export function update(personalBests?: PersonalBests, isProfile = false): void { function buildPbHtml( pbs: PersonalBests, mode: "time" | "words", - mode2: StringNumber + mode2: StringNumber, ): string { let retval = ""; let dateText = ""; diff --git a/frontend/src/ts/elements/account/result-filters.ts b/frontend/src/ts/elements/account/result-filters.ts index 9848c4ac1ef8..2c92f185aab7 100644 --- a/frontend/src/ts/elements/account/result-filters.ts +++ b/frontend/src/ts/elements/account/result-filters.ts @@ -22,7 +22,7 @@ import * as AuthEvent from "../../observables/auth-event"; import { sanitize } from "../../utils/sanitize"; export function mergeWithDefaultFilters( - filters: Partial + filters: Partial, ): ResultFilters { try { const merged = {} as ResultFilters; @@ -58,7 +58,7 @@ const resultFiltersLS = new LocalStorageWithSchema({ return defaultResultFilters; } return mergeWithDefaultFilters( - sanitize(ResultFiltersSchema.partial().strip(), unknown as ResultFilters) + sanitize(ResultFiltersSchema.partial().strip(), unknown as ResultFilters), ); }, }); @@ -115,7 +115,7 @@ export async function load(): Promise { async function updateFilterPresets(): Promise { const parent = document.querySelector(".pageAccount .presetFilterButtons"); const buttons = document.querySelector( - ".pageAccount .presetFilterButtons .filterBtns" + ".pageAccount .presetFilterButtons .filterBtns", ); if (!parent || !buttons) return; @@ -148,7 +148,7 @@ async function updateFilterPresets(): Promise { // sets the current filter to be a user custom filter export async function setFilterPreset(id: string): Promise { const filter = DB.getSnapshot()?.filterPresets.find( - (filter) => filter._id === id + (filter) => filter._id === id, ); if (filter) { // deep copy filter @@ -160,12 +160,12 @@ export async function setFilterPreset(id: string): Promise { // make all filter preset butons inactive $( - `.pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset` + `.pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset`, ).removeClass("active"); // make current filter presest button active $( - `.pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset[data-id=${id}]` + `.pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset[data-id=${id}]`, ).addClass("active"); } @@ -180,7 +180,7 @@ function addFilterPresetToSnapshot(filter: ResultFilters): void { // callback function called by popup once user inputs name export async function createFilterPreset( - name: string + name: string, ): Promise { name = name.replace(/ /g, "_"); Loader.show(); @@ -225,7 +225,7 @@ async function deleteFilterPreset(id: string): Promise { } else { Notifications.add( "Error deleting filter preset: " + result.body.message, - -1 + -1, ); console.log("error deleting filter preset", result.body.message); } @@ -234,7 +234,7 @@ async function deleteFilterPreset(id: string): Promise { function deSelectFilterPreset(): void { // make all filter preset buttons inactive $( - ".pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset" + ".pageAccount .group.presetFilterButtons .filterBtns .filterPresets .select-filter-preset", ).removeClass("active"); } @@ -252,7 +252,7 @@ function getGroup(group: G): ResultFilters[G] { export function getFilter( group: G, - filter: ResultFiltersGroupItem + filter: ResultFiltersGroupItem, ): ResultFilters[G][ResultFiltersGroupItem] { return filters[group][filter]; } @@ -260,7 +260,7 @@ export function getFilter( function setFilter( group: G, filter: ResultFiltersGroupItem, - value: boolean + value: boolean, ): void { filters[group][filter] = value as (typeof filters)[G][typeof filter]; } @@ -312,7 +312,7 @@ export function updateActive(): void { const filterValue = getFilter( group, - filter as ResultFiltersGroupItem + filter as ResultFiltersGroupItem, ); if (filterValue === true) { groupAboveChartDisplay.array?.push(filter); @@ -324,7 +324,7 @@ export function updateActive(): void { if (groupsUsingSelect.has(group)) { const option = $( - `.pageAccount .group.filterButtons .filterGroup[group="${group}"] option[value="${filter}"]` + `.pageAccount .group.filterButtons .filterGroup[group="${group}"] option[value="${filter}"]`, ); if (filterValue === true) { option.prop("selected", true); @@ -335,11 +335,11 @@ export function updateActive(): void { let buttonEl; if (group === "date") { buttonEl = $( - `.pageAccount .group.topFilters .filterGroup[group="${group}"] button[filter="${filter}"]` + `.pageAccount .group.topFilters .filterGroup[group="${group}"] button[filter="${filter}"]`, ); } else { buttonEl = $( - `.pageAccount .group.filterButtons .filterGroup[group="${group}"] button[filter="${filter}"]` + `.pageAccount .group.filterButtons .filterGroup[group="${group}"] button[filter="${filter}"]`, ); } if (filterValue === true) { @@ -359,7 +359,7 @@ export function updateActive(): void { const newData = ss.store.getData(); const allOption = $( - `.pageAccount .group.filterButtons .filterGroup[group="${id}"] option[value="all"]` + `.pageAccount .group.filterButtons .filterGroup[group="${id}"] option[value="all"]`, ); if (everythingSelected) { @@ -497,7 +497,7 @@ export function updateActive(): void { function toggle( group: G, - filter: ResultFiltersGroupItem + filter: ResultFiltersGroupItem, ): void { // user is changing the filters -> current filter is no longer a filter preset deSelectFilterPreset(); @@ -514,7 +514,7 @@ function toggle( } catch (e) { Notifications.add( "Something went wrong toggling filter. Reverting to defaults.", - 0 + 0, ); console.log("toggling filter error"); console.error(e); @@ -524,7 +524,7 @@ function toggle( } $( - ".pageAccount .filterButtons .buttonsAndTitle .buttons, .pageAccount .group.topFilters .buttonsAndTitle.testDate .buttons" + ".pageAccount .filterButtons .buttonsAndTitle .buttons, .pageAccount .group.topFilters .buttonsAndTitle.testDate .buttons", ).on("click", "button", (e) => { const group = $(e.target) .parents(".buttons") @@ -676,13 +676,13 @@ $(".pageAccount .topFilters button.currentConfigFilter").on("click", () => { $(".pageAccount .topFilters button.toggleAdvancedFilters").on("click", () => { $(".pageAccount .filterButtons").slideToggle(250); $(".pageAccount .topFilters button.toggleAdvancedFilters").toggleClass( - "active" + "active", ); }); function adjustScrollposition( group: ResultFiltersGroup, - topItem: number = 0 + topItem: number = 0, ): void { const slimSelect = groupSelects[group]; if (slimSelect === undefined) return; @@ -695,25 +695,25 @@ function adjustScrollposition( function selectBeforeChangeFn( group: ResultFiltersGroup, selectedOptions: Option[], - oldSelectedOptions: Option[] + oldSelectedOptions: Option[], ): boolean { const includesAllNow = selectedOptions.some( - (option) => option.value === "all" + (option) => option.value === "all", ); const includedAllBefore = oldSelectedOptions.some( - (option) => option.value === "all" + (option) => option.value === "all", ); if (includesAllNow) { if (!includedAllBefore) { // all option was selected selectedOptions = selectedOptions.filter( - (option) => option.value === "all" + (option) => option.value === "all", ); } else if (selectedOptions.length < oldSelectedOptions.length) { // options other than all were deselcted selectedOptions = selectedOptions.filter( - (option) => option.value !== "all" + (option) => option.value !== "all", ); } } else { @@ -733,7 +733,7 @@ function selectBeforeChangeFn( setFilter( group, selectedOption.value as ResultFiltersGroupItem, - true + true, ); } @@ -755,7 +755,7 @@ export function updateTagsDropdownOptions(): void { } const newTags = snapshot.tags.filter( - (it) => defaultResultFilters.tags[it._id] === undefined + (it) => defaultResultFilters.tags[it._id] === undefined, ); if (newTags.length > 0) { const everythingSelected = Object.values(filters.tags).every((v) => v); @@ -768,13 +768,13 @@ export function updateTagsDropdownOptions(): void { filters.tags = { ...filters.tags, ...Object.fromEntries( - newTags.map((tag) => [tag._id, everythingSelected]) + newTags.map((tag) => [tag._id, everythingSelected]), ), }; } const el = document.querySelector( - ".pageAccount .content .filterButtons .buttonsAndTitle.tags .select select" + ".pageAccount .content .filterButtons .buttonsAndTitle.tags .select select", ); if (!(el instanceof HTMLElement)) return; @@ -794,7 +794,7 @@ export function updateTagsDropdownOptions(): void { let buttonsAppended = false; export async function appendDropdowns( - selectChangeCallback: () => void + selectChangeCallback: () => void, ): Promise { //snapshot at this point is guaranteed to exist const snapshot = DB.getSnapshot() as Snapshot; @@ -827,7 +827,7 @@ export async function appendDropdowns( return selectBeforeChangeFn( "language", selectedOptions, - oldSelectedOptions + oldSelectedOptions, ); }, beforeOpen: (): void => { @@ -859,7 +859,7 @@ export async function appendDropdowns( return selectBeforeChangeFn( "funbox", selectedOptions, - oldSelectedOptions + oldSelectedOptions, ); }, beforeOpen: (): void => { @@ -874,7 +874,7 @@ export async function appendDropdowns( function tagDropdownUpdate(snapshot: Snapshot): void { const tagsSection = $( - ".pageAccount .content .filterButtons .buttonsAndTitle.tags" + ".pageAccount .content .filterButtons .buttonsAndTitle.tags", ); if (snapshot.tags.length === 0) { @@ -892,7 +892,7 @@ function tagDropdownUpdate(snapshot: Snapshot): void { // Only create SlimSelect if it doesn't exist yet if (!groupSelects["tags"]) { const selectEl = document.querySelector( - ".pageAccount .content .filterButtons .buttonsAndTitle.tags .select .tagsSelect" + ".pageAccount .content .filterButtons .buttonsAndTitle.tags .select .tagsSelect", ); if (selectEl) { @@ -909,7 +909,7 @@ function tagDropdownUpdate(snapshot: Snapshot): void { return selectBeforeChangeFn( "tags", selectedOptions, - oldSelectedOptions + oldSelectedOptions, ); }, beforeOpen: (): void => { @@ -927,12 +927,12 @@ $(".group.presetFilterButtons .filterBtns").on( ".filterPresets .delete-filter-preset", (e) => { void deleteFilterPreset($(e.currentTarget).data("id") as string); - } + }, ); function verifyResultFiltersStructure(filterIn: ResultFilters): ResultFilters { const filter = mergeWithDefaultFilters( - sanitize(ResultFiltersSchema.partial().strip(), structuredClone(filterIn)) + sanitize(ResultFiltersSchema.partial().strip(), structuredClone(filterIn)), ); return filter; diff --git a/frontend/src/ts/elements/alerts.ts b/frontend/src/ts/elements/alerts.ts index 779b67f79ef8..ccd81a8a42e7 100644 --- a/frontend/src/ts/elements/alerts.ts +++ b/frontend/src/ts/elements/alerts.ts @@ -89,7 +89,7 @@ function hide(): void { duration: 5, customTitle: "Reward", customIcon: "gift", - } + }, ); } @@ -203,7 +203,7 @@ async function getAccountAlerts(): Promise {
${formatDistanceToNowStrict( - new Date(ie.timestamp) + new Date(ie.timestamp), )} ago
${ie.subject}
@@ -237,7 +237,7 @@ export function addPSA(message: string, level: number): void { function fillPSAs(): void { if (state.psas.length === 0) { $("#alertsPopup .psas .list").html( - `
Nothing to show
` + `
Nothing to show
`, ); } else { $("#alertsPopup .psas .list").empty(); @@ -267,7 +267,7 @@ function fillPSAs(): void { function fillNotifications(): void { if (state.notifications.length === 0) { $("#alertsPopup .notificationHistory .list").html( - `
Nothing to show
` + `
Nothing to show
`, ); } else { $("#alertsPopup .notificationHistory .list").empty(); @@ -312,7 +312,7 @@ export function setNotificationBubbleVisible(tf: boolean): void { function updateInboxSize(): void { const remainingItems = accountAlerts.length - mailToDelete.length; $("#alertsPopup .accountAlerts .title .right").text( - `${remainingItems}/${maxMail}` + `${remainingItems}/${maxMail}`, ); } @@ -340,7 +340,7 @@ function markReadAlert(id: string): void { item .find(".buttons") .append( - `` + ``, ); animate(item.find(".rewards")[0] as HTMLElement, { @@ -457,7 +457,7 @@ const modal = new AnimatedModal({ .closest(".item") .attr("data-id") as string; deleteAlert(id); - } + }, ); $("#alertsPopup .accountAlerts .list").on( @@ -468,7 +468,7 @@ const modal = new AnimatedModal({ .closest(".item") .attr("data-id") as string; markReadAlert(id); - } + }, ); }, }); diff --git a/frontend/src/ts/elements/composition-display.ts b/frontend/src/ts/elements/composition-display.ts index 908bbbf106c5..13b2a6b7de34 100644 --- a/frontend/src/ts/elements/composition-display.ts +++ b/frontend/src/ts/elements/composition-display.ts @@ -1,7 +1,7 @@ import Config from "../config"; const compositionDisplay = document.getElementById( - "compositionDisplay" + "compositionDisplay", ) as HTMLElement; const languagesToShow = ["korean", "japanese", "chinese"]; diff --git a/frontend/src/ts/elements/custom-background-filter.ts b/frontend/src/ts/elements/custom-background-filter.ts index 87da2102db0a..822b04da7991 100644 --- a/frontend/src/ts/elements/custom-background-filter.ts +++ b/frontend/src/ts/elements/custom-background-filter.ts @@ -50,31 +50,31 @@ export function apply(): void { function syncSliders(): void { $(".section[data-config-name='customBackgroundFilter'] .blur input").val( - filters.blur.value + filters.blur.value, ); $( - ".section[data-config-name='customBackgroundFilter'] .brightness input" + ".section[data-config-name='customBackgroundFilter'] .brightness input", ).val(filters.brightness.value); $(".section[data-config-name='customBackgroundFilter'] .saturate input").val( - filters.saturate.value + filters.saturate.value, ); $(".section[data-config-name='customBackgroundFilter'] .opacity input").val( - filters.opacity.value + filters.opacity.value, ); } function updateNumbers(): void { $(".section[data-config-name='customBackgroundFilter'] .blur .value").html( - filters.blur.value.toFixed(1) + filters.blur.value.toFixed(1), ); $( - ".section[data-config-name='customBackgroundFilter'] .brightness .value" + ".section[data-config-name='customBackgroundFilter'] .brightness .value", ).html(filters.brightness.value.toFixed(1)); $( - ".section[data-config-name='customBackgroundFilter'] .saturate .value" + ".section[data-config-name='customBackgroundFilter'] .saturate .value", ).html(filters.saturate.value.toFixed(1)); $(".section[data-config-name='customBackgroundFilter'] .opacity .value").html( - filters.opacity.value.toFixed(1) + filters.opacity.value.toFixed(1), ); } @@ -96,12 +96,12 @@ $(".section[data-config-name='customBackgroundFilter'] .blur input").on( () => { filters.blur.value = parseFloat( $( - ".section[data-config-name='customBackgroundFilter'] .blur input" - ).val() as string + ".section[data-config-name='customBackgroundFilter'] .blur input", + ).val() as string, ); updateNumbers(); apply(); - } + }, ); $(".section[data-config-name='customBackgroundFilter'] .brightness input").on( @@ -109,12 +109,12 @@ $(".section[data-config-name='customBackgroundFilter'] .brightness input").on( () => { filters.brightness.value = parseFloat( $( - ".section[data-config-name='customBackgroundFilter'] .brightness input" - ).val() as string + ".section[data-config-name='customBackgroundFilter'] .brightness input", + ).val() as string, ); updateNumbers(); apply(); - } + }, ); $(".section[data-config-name='customBackgroundFilter'] .saturate input").on( @@ -122,12 +122,12 @@ $(".section[data-config-name='customBackgroundFilter'] .saturate input").on( () => { filters.saturate.value = parseFloat( $( - ".section[data-config-name='customBackgroundFilter'] .saturate input" - ).val() as string + ".section[data-config-name='customBackgroundFilter'] .saturate input", + ).val() as string, ); updateNumbers(); apply(); - } + }, ); $(".section[data-config-name='customBackgroundFilter'] .opacity input").on( @@ -135,24 +135,24 @@ $(".section[data-config-name='customBackgroundFilter'] .opacity input").on( () => { filters.opacity.value = parseFloat( $( - ".section[data-config-name='customBackgroundFilter'] .opacity input" - ).val() as string + ".section[data-config-name='customBackgroundFilter'] .opacity input", + ).val() as string, ); updateNumbers(); apply(); - } + }, ); $(".section[data-config-name='customBackgroundFilter'] input").on( "input", () => { debouncedSave(); - } + }, ); const debouncedSave = debounce(2000, async () => { const arr = Object.keys(filters).map( - (filterKey) => filters[filterKey as keyof typeof filters].value + (filterKey) => filters[filterKey as keyof typeof filters].value, ) as CustomBackgroundFilter; UpdateConfig.setCustomBackgroundFilter(arr, false); }); diff --git a/frontend/src/ts/elements/input-indicator.ts b/frontend/src/ts/elements/input-indicator.ts index ab32e754a51d..a5c970dcf591 100644 --- a/frontend/src/ts/elements/input-indicator.ts +++ b/frontend/src/ts/elements/input-indicator.ts @@ -13,7 +13,7 @@ export class InputIndicator { constructor( inputElement: JQuery | HTMLInputElement, - options: Record + options: Record, ) { this.inputElement = inputElement; $(this.inputElement).wrap(`
`); @@ -35,11 +35,11 @@ export class InputIndicator { : "" } data-balloon-pos="left" - ${option.message ?? "" ? `aria-label="${option.message}"` : ""} + ${(option.message ?? "") ? `aria-label="${option.message}"` : ""} > + option.spinIcon ? "fa-spin" : "" + }">
`; } diff --git a/frontend/src/ts/elements/input-validation.ts b/frontend/src/ts/elements/input-validation.ts index 277bcd8d37f5..33caf8d9c3da 100644 --- a/frontend/src/ts/elements/input-validation.ts +++ b/frontend/src/ts/elements/input-validation.ts @@ -39,7 +39,7 @@ export type Validation = { // oxlint-disable-next-line no-explicit-any export function debounceIfNeeded any>( delay: number, - callback: T + callback: T, ): T | debounce { if (delay <= 0) { return callback; @@ -58,7 +58,7 @@ export function debounceIfNeeded any>( export function createInputEventHandler( callback: (result: ValidationResult) => void, validation: Validation, - inputValueConvert?: (val: string) => T + inputValueConvert?: (val: string) => T, ): (e: Event) => Promise { let callIsValid = validation.isValid !== undefined @@ -67,7 +67,7 @@ export function createInputEventHandler( async ( originalInput: HTMLInputElement, currentValue: string, - checkValue: T + checkValue: T, ) => { const result = await validation.isValid?.(checkValue); if (originalInput.value !== currentValue) { @@ -90,7 +90,7 @@ export function createInputEventHandler( }); } } - } + }, ) : undefined; @@ -185,7 +185,7 @@ export class ValidatedHtmlInputElement { const handler = createInputEventHandler( callback, options, - "inputValueConvert" in options ? options.inputValueConvert : undefined + "inputValueConvert" in options ? options.inputValueConvert : undefined, ); inputElement.addEventListener("input", handler); diff --git a/frontend/src/ts/elements/keymap.ts b/frontend/src/ts/elements/keymap.ts index 2234c66cfd49..a8c881a008a9 100644 --- a/frontend/src/ts/elements/keymap.ts +++ b/frontend/src/ts/elements/keymap.ts @@ -313,7 +313,7 @@ function buildRow(options: { const keyElement = `
${keyDisplay}${ bump ? "
" : "" }
`; @@ -409,7 +409,7 @@ export async function refresh(): Promise { } catch (e) { Notifications.add( Misc.createErrorMessage(e, `Failed to load keymap ${layoutName}`), - -1 + -1, ); return; } @@ -466,7 +466,7 @@ export async function refresh(): Promise { } catch (e) { if (e instanceof Error) { console.log( - "something went wrong when changing layout, resettings: " + e.message + "something went wrong when changing layout, resettings: " + e.message, ); // UpdateConfig.setKeymapLayout("qwerty", true); } @@ -520,11 +520,11 @@ async function updateLegends(): Promise { const isNotSpace = !el.classList.contains("keySpace"); return isKeymapKey && isNotSpace; - } + }, ) as HTMLElement[]; const layoutKeys = keymapKeys.map((el) => - el.dataset["key"]?.split(keyDataDelimiter) + el.dataset["key"]?.split(keyDataDelimiter), ); if (layoutKeys.includes(undefined)) return; @@ -561,7 +561,7 @@ async function updateLegends(): Promise { continue; const keyIsSymbol = [lowerCaseCharacter, upperCaseCharacter].some( - (character) => symbolsPattern.test(character ?? "") + (character) => symbolsPattern.test(character ?? ""), ); const keycode = KeyConverter.layoutKeyToKeycode(lowerCaseCharacter, layout); diff --git a/frontend/src/ts/elements/last-10-average.ts b/frontend/src/ts/elements/last-10-average.ts index 88411a4eac5c..6e2e846638c8 100644 --- a/frontend/src/ts/elements/last-10-average.ts +++ b/frontend/src/ts/elements/last-10-average.ts @@ -18,7 +18,7 @@ export async function update(): Promise { Config.numbers, Config.language, Config.difficulty, - Config.lazyMode + Config.lazyMode, ) ).map(Numbers.roundTo2) as [number, number]; diff --git a/frontend/src/ts/elements/merch-banner.ts b/frontend/src/ts/elements/merch-banner.ts index f303abb36052..9cf21f622b70 100644 --- a/frontend/src/ts/elements/merch-banner.ts +++ b/frontend/src/ts/elements/merch-banner.ts @@ -18,7 +18,7 @@ export function showIfNotClosedBefore(): void { () => { closed.set(true); }, - true + true, ); } } diff --git a/frontend/src/ts/elements/modes-notice.ts b/frontend/src/ts/elements/modes-notice.ts index 43c708eca211..d526d8151a39 100644 --- a/frontend/src/ts/elements/modes-notice.ts +++ b/frontend/src/ts/elements/modes-notice.ts @@ -42,28 +42,28 @@ export async function update(): Promise { if (TestState.isRepeated && Config.mode !== "quote") { $(".pageTest #testModesNotice").append( - `
repeated
` + `
repeated
`, ); } if (!TestState.savingEnabled) { $(".pageTest #testModesNotice").append( - `
saving disabled
` + `
saving disabled
`, ); } if (TestWords.hasTab) { if (Config.quickRestart === "esc") { $(".pageTest #testModesNotice").append( - `
shift + tab to open commandline
` + `
shift + tab to open commandline
`, ); $(".pageTest #testModesNotice").append( - `
shift + esc to restart
` + `
shift + esc to restart
`, ); } if (Config.quickRestart === "tab") { $(".pageTest #testModesNotice").append( - `
shift + tab to restart
` + `
shift + tab to restart
`, ); } } @@ -73,7 +73,7 @@ export async function update(): Promise { Config.quickRestart === "enter" ) { $(".pageTest #testModesNotice").append( - `
shift + enter to restart
` + `
shift + enter to restart
`, ); } @@ -82,20 +82,20 @@ export async function update(): Promise { if (Config.mode === "custom" && customTextName !== "" && isLong) { $(".pageTest #testModesNotice").append( `
${escapeHTML( - customTextName - )} (shift + enter to save progress)
` + customTextName, + )} (shift + enter to save progress)
`, ); } if (TestState.activeChallenge) { $(".pageTest #testModesNotice").append( - `
${TestState.activeChallenge.display}
` + `
${TestState.activeChallenge.display}
`, ); } if (Config.mode === "zen") { $(".pageTest #testModesNotice").append( - `
shift + enter to finish zen
` + `
shift + enter to finish zen
`, ); } @@ -105,8 +105,8 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + Config.mode === "quote", + )}`, ); } @@ -119,29 +119,29 @@ export async function update(): Promise { .join(", "); $(".pageTest #testModesNotice").append( - `` + ``, ); } if (Config.difficulty === "expert") { $(".pageTest #testModesNotice").append( - `` + ``, ); } else if (Config.difficulty === "master") { $(".pageTest #testModesNotice").append( - `` + ``, ); } if (Config.blindMode) { $(".pageTest #testModesNotice").append( - `` + ``, ); } if (Config.lazyMode) { $(".pageTest #testModesNotice").append( - `` + ``, ); } @@ -159,15 +159,15 @@ export async function update(): Promise { Config.paceCaret === "average" ? "average" : Config.paceCaret === "pb" - ? "pb" - : Config.paceCaret === "tagPb" - ? "tag pb" - : Config.paceCaret === "last" - ? "last" - : Config.paceCaret === "daily" - ? "daily" - : "custom" - } pace ${speed}` + ? "pb" + : Config.paceCaret === "tagPb" + ? "tag pb" + : Config.paceCaret === "last" + ? "last" + : Config.paceCaret === "daily" + ? "daily" + : "custom" + } pace ${speed}`, ); } @@ -187,7 +187,7 @@ export async function update(): Promise { const text = `${avgWPMText} ${avgAccText}`.trim(); $(".pageTest #testModesNotice").append( - `` + ``, ); } } @@ -205,7 +205,7 @@ export async function update(): Promise { Config.language, Config.difficulty, Config.lazyMode, - getActiveFunboxes() + getActiveFunboxes(), ); let str = "no pb"; @@ -218,7 +218,7 @@ export async function update(): Promise { } $(".pageTest #testModesNotice").append( - `` + ``, ); } @@ -226,14 +226,14 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + { showDecimalPlaces: false, suffix: ` ${Config.typingSpeedUnit}` }, + )}`, ); } if (Config.minAcc !== "off") { $(".pageTest #testModesNotice").append( - `` + ``, ); } @@ -241,10 +241,10 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + }`, ); } @@ -252,24 +252,24 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + .join(", ")}`, ); } if (Config.confidenceMode === "on") { $(".pageTest #testModesNotice").append( - `` + ``, ); } if (Config.confidenceMode === "max") { $(".pageTest #testModesNotice").append( - `` + ``, ); } if (Config.stopOnError !== "off") { $(".pageTest #testModesNotice").append( - `` + ``, ); } @@ -277,8 +277,8 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + " ", + )}`, ); } @@ -286,7 +286,7 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + }`, ); } @@ -302,8 +302,8 @@ export async function update(): Promise { $(".pageTest #testModesNotice").append( `` + tagsString.length - 2, + )}`, ); } } catch {} diff --git a/frontend/src/ts/elements/monkey-power.ts b/frontend/src/ts/elements/monkey-power.ts index 7904caef6f26..b40d86d3dade 100644 --- a/frontend/src/ts/elements/monkey-power.ts +++ b/frontend/src/ts/elements/monkey-power.ts @@ -146,7 +146,7 @@ function render(): void { ctx.context2d.beginPath(); ctx.context2d.moveTo( Math.round(particle.prev.x), - Math.round(particle.prev.y) + Math.round(particle.prev.y), ); ctx.context2d.lineTo(Math.round(particle.x), Math.round(particle.y)); ctx.context2d.stroke(); @@ -177,7 +177,7 @@ export function reset(immediate = false): void { $("html").css("overflow", "inherit"); $("html").css("overflow-y", "scroll"); }, - immediate ? 0 : 1000 + immediate ? 0 : 1000, ); } @@ -212,7 +212,7 @@ export async function addPower(good = true, extra = false): Promise { ]; $(document.body).css( "transform", - `translate(${shake[0]}px, ${shake[1]}px)` + `translate(${shake[0]}px, ${shake[1]}px)`, ); if (isSafeNumber(ctx.resetTimeOut)) clearTimeout(ctx.resetTimeOut); ctx.resetTimeOut = setTimeout(reset, 2000) as unknown as number; @@ -228,7 +228,7 @@ export async function addPower(good = true, extra = false): Promise { for ( let i = Math.round( (particleCreateCount[0] + Math.random() * particleCreateCount[1]) * - (extra ? 2 : 1) + (extra ? 2 : 1), ); i > 0; i-- @@ -236,10 +236,10 @@ export async function addPower(good = true, extra = false): Promise { const color = ["2", "4"].includes(Config.monkeyPowerLevel) ? randomColor() : good - ? await ThemeColors.get("caret") - : await ThemeColors.get("error"); + ? await ThemeColors.get("caret") + : await ThemeColors.get("error"); ctx.particles.push( - createParticle(...(coords as [x: number, y: number]), color) + createParticle(...(coords as [x: number, y: number]), color), ); } diff --git a/frontend/src/ts/elements/no-css.ts b/frontend/src/ts/elements/no-css.ts index 0bb3ac546264..003180775bc7 100644 --- a/frontend/src/ts/elements/no-css.ts +++ b/frontend/src/ts/elements/no-css.ts @@ -9,7 +9,7 @@ $("#nocss .requestedStylesheets").html( ) .map((l) => l.href) .filter((l) => /\/css\/style/gi.test(l)) - .join("
") + .join("
"), ); $("#nocss .requestedJs").html( @@ -19,7 +19,7 @@ $("#nocss .requestedJs").html( .filter((l) => /(\/js\/mon|\/js\/vendor)/gi.test(l)) .join("
") + "

Client version:
" + - envConfig.clientVersion + envConfig.clientVersion, ); if (window.navigator.userAgent.toLowerCase().includes("mac")) { diff --git a/frontend/src/ts/elements/notifications.ts b/frontend/src/ts/elements/notifications.ts index 425d9031cc01..ece7ac415797 100644 --- a/frontend/src/ts/elements/notifications.ts +++ b/frontend/src/ts/elements/notifications.ts @@ -36,7 +36,7 @@ class Notification { closeCallback = (): void => { // }, - allowHTML?: boolean + allowHTML?: boolean, ) { this.type = type; this.message = allowHTML ? message : Misc.escapeHTML(message); @@ -106,7 +106,7 @@ class Notification { `); const notif = document.querySelector( - `#notificationCenter .notif[id='${this.id}']` + `#notificationCenter .notif[id='${this.id}']`, ); if (notif === null) return; @@ -128,7 +128,7 @@ class Notification { }); const historyElement = document.querySelector( - "#notificationCenter .history" + "#notificationCenter .history", ) as HTMLElement; animate(historyElement, { marginTop: { @@ -151,8 +151,8 @@ class Notification { $("#bannerCenter").prepend(`
+ withImage ? "withImage" : "" + }" id="${this.id}">
${leftside}
@@ -174,7 +174,7 @@ class Notification { BannerEvent.dispatch(); if (this.duration >= 0) { $( - `#bannerCenter .banner[id='${this.id}'] .closeButton, #bannerCenter .psa[id='${this.id}'] .closeButton` + `#bannerCenter .banner[id='${this.id}'] .closeButton, #bannerCenter .psa[id='${this.id}'] .closeButton`, ).on("click", () => { this.hide(); this.closeCallback(); @@ -184,11 +184,11 @@ class Notification { if (/please ()?refresh/i.test(this.message)) { // add pointer when refresh is needed $( - `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']` + `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']`, ).addClass("clickable"); // refresh on clicking banner $( - `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']` + `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']`, ).on("click", () => { window.location.reload(); }); @@ -203,7 +203,7 @@ class Notification { hide(): void { if (this.type === "notification") { const elem = document.querySelector( - `#notificationCenter .notif[id='${this.id}']` + `#notificationCenter .notif[id='${this.id}']`, ) as HTMLElement; const duration = Misc.applyReducedMotion(250); @@ -229,7 +229,7 @@ class Notification { }); } else if (this.type === "banner" || this.type === "psa") { $( - `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']` + `#bannerCenter .banner[id='${this.id}'], #bannerCenter .psa[id='${this.id}']`, ).remove(); updateMargin(); BannerEvent.dispatch(); @@ -259,7 +259,7 @@ export type AddNotificationOptions = { export function add( message: string, level = 0, - options: AddNotificationOptions = {} + options: AddNotificationOptions = {}, ): void { NotificationEvent.dispatch(message, level, options.customTitle); @@ -272,7 +272,7 @@ export function add( options.customTitle, options.customIcon, options.closeCallback, - options.allowHTML + options.allowHTML, ).show(); } @@ -282,7 +282,7 @@ export function addBanner( customIcon = "bullhorn", sticky = false, closeCallback?: () => void, - allowHTML?: boolean + allowHTML?: boolean, ): number { const banner = new Notification( "banner", @@ -293,7 +293,7 @@ export function addBanner( undefined, customIcon, closeCallback, - allowHTML + allowHTML, ); banner.show(); return banner.id; @@ -305,7 +305,7 @@ export function addPSA( customIcon = "bullhorn", sticky = false, closeCallback?: () => void, - allowHTML?: boolean + allowHTML?: boolean, ): number { const psa = new Notification( "psa", @@ -316,7 +316,7 @@ export function addPSA( undefined, customIcon, closeCallback, - allowHTML + allowHTML, ); psa.show(); return psa.id; diff --git a/frontend/src/ts/elements/profile.ts b/frontend/src/ts/elements/profile.ts index a9159b02cb49..40a13c64923b 100644 --- a/frontend/src/ts/elements/profile.ts +++ b/frontend/src/ts/elements/profile.ts @@ -28,7 +28,7 @@ type UserProfileOrSnapshot = UserProfile | Snapshot; export async function update( where: ProfileViewPaths, - profile: UserProfileOrSnapshot + profile: UserProfileOrSnapshot, ): Promise { const elementClass = where.charAt(0).toUpperCase() + where.slice(1); const profileElement = $(`.page${elementClass} .profile`); @@ -74,7 +74,7 @@ export async function update( details .find(".userFlags") .html( - getHtmlByUserFlags({ ...profile, isFriend: DB.isFriend(profile.uid) }) + getHtmlByUserFlags({ ...profile, isFriend: DB.isFriend(profile.uid) }), ); if (profile.lbOptOut === true) { @@ -83,7 +83,7 @@ export async function update( .find(".lbOptOutReminder") .removeClass("hidden") .text( - "Note: This account has opted out of the leaderboards, meaning their results aren't verified by the anticheat system and may not be legitimate." + "Note: This account has opted out of the leaderboards, meaning their results aren't verified by the anticheat system and may not be legitimate.", ); } else { profileElement.find(".lbOptOutReminder").addClass("hidden"); @@ -109,7 +109,7 @@ export async function update( .text( `Current streak: ${profile.streak} ${ profile.streak === 1 ? "day" : "days" - }` + }`, ); hoverText = `Longest streak: ${profile.maxStreak} ${ profile.maxStreak === 1 ? "day" : "days" @@ -138,13 +138,13 @@ export async function update( console.debug("dayInMilis", dayInMilis); console.debug( "difTarget", - new Date(DateTime.getCurrentDayTimestamp(streakOffset) + dayInMilis) + new Date(DateTime.getCurrentDayTimestamp(streakOffset) + dayInMilis), ); console.debug("timeDif", timeDif); console.debug( "DateTime.getCurrentDayTimestamp()", DateTime.getCurrentDayTimestamp(), - new Date(DateTime.getCurrentDayTimestamp()) + new Date(DateTime.getCurrentDayTimestamp()), ); console.debug("profile.streakHourOffset", streakOffset); @@ -153,13 +153,13 @@ export async function update( const isToday = DateTime.isToday(lastResult.timestamp, streakOffset); const isYesterday = DateTime.isYesterday( lastResult.timestamp, - streakOffset + streakOffset, ); console.debug( "lastResult.timestamp", lastResult.timestamp, - new Date(lastResult.timestamp) + new Date(lastResult.timestamp), ); console.debug("isToday", isToday); console.debug("isYesterday", isYesterday); @@ -193,7 +193,7 @@ export async function update( .attr("data-balloon-break", ""); const { completedPercentage, restartRatio } = Misc.formatTypingStatsRatio( - profile.typingStats + profile.typingStats, ); const typingStatsEl = details.find(".typingStats"); @@ -206,7 +206,7 @@ export async function update( .attr("data-balloon-pos", "up") .attr( "aria-label", - `${completedPercentage}% (${restartRatio} restarts per completed test)` + `${completedPercentage}% (${restartRatio} restarts per completed test)`, ); typingStatsEl .find(".timeTyping .value") @@ -214,8 +214,8 @@ export async function update( secondsToString( Math.round(profile.typingStats?.timeTyping ?? 0), true, - true - ) + true, + ), ); let bio = false; @@ -245,10 +245,10 @@ export async function update( if (git) { socialsEl.append( `` + git, + )}" data-balloon-pos="up" class="textButton">`, ); } @@ -256,10 +256,10 @@ export async function update( if (twitter) { socialsEl.append( `` + twitter, + )}" data-balloon-pos="up" class="textButton">`, ); } @@ -272,10 +272,10 @@ export async function update( if (website) { socialsEl.append( `` + websiteName ?? "", + )}" data-balloon-pos="up" class="textButton">`, ); } } @@ -372,7 +372,7 @@ export async function update( export function updateXp( where: ProfileViewPaths, xp: number, - sameUserCheck = false + sameUserCheck = false, ): void { const elementClass = where.charAt(0).toUpperCase() + where.slice(1); const profileElement = $(`.page${elementClass} .profile`); @@ -397,7 +397,7 @@ export function updateXp( .text(`${formatXp(xpToDisplay)}/${formatXp(xpForLevel)}`) .attr( "aria-label", - `${formatXp(xpForLevel - xpToDisplay)} xp until next level` + `${formatXp(xpForLevel - xpToDisplay)} xp until next level`, ); details .find(".xpBar .bar") diff --git a/frontend/src/ts/elements/psa.ts b/frontend/src/ts/elements/psa.ts index ad8d4a17b690..673c4e3ff813 100644 --- a/frontend/src/ts/elements/psa.ts +++ b/frontend/src/ts/elements/psa.ts @@ -41,7 +41,7 @@ async function getLatest(): Promise { "Dev Info: Backend server not running", 0, "exclamation-triangle", - false + false, ); } else { type InstatusSummary = { @@ -73,7 +73,7 @@ async function getLatest(): Promise { }; const { data: instatus, error } = await tryCatch( - fetch("https://monkeytype.instatus.com/summary.json") + fetch("https://monkeytype.instatus.com/summary.json"), ); let maintenanceData: undefined | InstatusSummary["activeMaintenances"]; @@ -99,7 +99,7 @@ async function getLatest(): Promise { "bullhorn", true, undefined, - true + true, ); } else { Notifications.addPSA( @@ -108,7 +108,7 @@ async function getLatest(): Promise { "exclamation-triangle", false, undefined, - true + true, ); } } @@ -120,7 +120,7 @@ async function getLatest(): Promise { "bullhorn", true, undefined, - true + true, ); return null; } else if (response.status !== 200) { @@ -147,16 +147,16 @@ export async function show(): Promise { false, "text", false, - true + true, ); psa.message = psa.message.replace("{dateDifference}", string); psa.message = psa.message.replace( "{dateNoTime}", - format(dateObj, "dd MMM yyyy") + format(dateObj, "dd MMM yyyy"), ); psa.message = psa.message.replace( "{date}", - format(dateObj, "dd MMM yyyy HH:mm") + format(dateObj, "dd MMM yyyy HH:mm"), ); } @@ -174,7 +174,7 @@ export async function show(): Promise { () => { setMemory(psa._id); }, - true + true, ); }); } diff --git a/frontend/src/ts/elements/result-batches.ts b/frontend/src/ts/elements/result-batches.ts index 624d98ce5117..9f129de2b1f4 100644 --- a/frontend/src/ts/elements/result-batches.ts +++ b/frontend/src/ts/elements/result-batches.ts @@ -17,7 +17,7 @@ export async function update(): Promise { if (results === undefined) { console.error( - "(Result batches) Results are missing but they should be available at the time of drawing the account page?" + "(Result batches) Results are missing but they should be available at the time of drawing the account page?", ); hide(); return; @@ -27,7 +27,7 @@ export async function update(): Promise { const completedTests = DB.getSnapshot()?.typingStats?.completedTests ?? 0; const percentageDownloaded = Math.round( - (results.length / completedTests) * 100 + (results.length / completedTests) * 100, ); const limits = ServerConfiguration.get()?.results.limits ?? { regularUser: 0, @@ -53,7 +53,7 @@ export async function update(): Promise { bars.downloaded.fill.css("width", Math.min(percentageDownloaded, 100) + "%"); bars.downloaded.rightText.text( - `${results?.length} / ${completedTests} (${percentageDownloaded}%)` + `${results?.length} / ${completedTests} (${percentageDownloaded}%)`, ); const colors = await ThemeColors.getAll(); @@ -63,11 +63,11 @@ export async function update(): Promise { background: blendTwoHexColors( colors.sub, colors.error, - mapRange(percentageLimit, 50, 100, 0, 1) + mapRange(percentageLimit, 50, 100, 0, 1), ), }); bars.limit.rightText.text( - `${results?.length} / ${currentLimit} (${percentageLimit}%)` + `${results?.length} / ${currentLimit} (${percentageLimit}%)`, ); const text = $(".pageAccount .resultBatches > .text"); diff --git a/frontend/src/ts/elements/result-word-highlight.ts b/frontend/src/ts/elements/result-word-highlight.ts index bfd4505b2bee..e29b7f5e2c42 100644 --- a/frontend/src/ts/elements/result-word-highlight.ts +++ b/frontend/src/ts/elements/result-word-highlight.ts @@ -60,7 +60,7 @@ let isInitInProgress = false; // Highlights .word elements in range [firstWordIndex, lastWordIndex] export async function highlightWordsInRange( firstWordIndex: number, - lastWordIndex: number + lastWordIndex: number, ): Promise { // Early exit if not hovering over chart if (!isHoveringChart) { @@ -102,7 +102,7 @@ export async function highlightWordsInRange( const newHighlightElementPositions = getHighlightElementPositions( firstWordIndex, lastWordIndex, - TestState.isLanguageRightToLeft + TestState.isLanguageRightToLeft, ); // For each line... @@ -191,8 +191,8 @@ async function init(): Promise { await new Promise((resolve) => setTimeout( resolve, - TOGGLE_RESULT_WORDS_BUFFER - TIME_DIFF_SINCE_LAST_TOGGLE - ) + TOGGLE_RESULT_WORDS_BUFFER - TIME_DIFF_SINCE_LAST_TOGGLE, + ), ); } @@ -346,7 +346,7 @@ type HighlightPosition = { function getHighlightElementPositions( firstWordIndex: number, lastWordIndex: number, - isRTL = false + isRTL = false, ): HighlightPosition[] { const lineIndexOfFirstWord = wordIndexToLineIndexDict[ firstWordIndex @@ -360,7 +360,7 @@ function getHighlightElementPositions( const highlightWidth: number = getHighlightWidth( firstWordIndex, - lastWordIndex + lastWordIndex, ); const firstWordEl = wordEls[firstWordIndex]; @@ -500,7 +500,7 @@ function getHighlightElementPositions( // Function to calculate the width of the highlight for a given range of words function getHighlightWidth( wordStartIndex: number, - wordEndIndex: number + wordEndIndex: number, ): number { const lineIndexOfWordStart = wordIndexToLineIndexDict[wordStartIndex]; const lineIndexOfWordEnd = wordIndexToLineIndexDict[wordEndIndex]; diff --git a/frontend/src/ts/elements/settings/custom-background-picker.ts b/frontend/src/ts/elements/settings/custom-background-picker.ts index 17daad85c3a3..025eccca1c86 100644 --- a/frontend/src/ts/elements/settings/custom-background-picker.ts +++ b/frontend/src/ts/elements/settings/custom-background-picker.ts @@ -3,7 +3,7 @@ import * as Notifications from "../notifications"; import { applyCustomBackground } from "../../controllers/theme-controller"; const parentEl = document.querySelector( - ".pageSettings .section[data-config-name='customBackgroundSize']" + ".pageSettings .section[data-config-name='customBackgroundSize']", ); const usingLocalImageEl = parentEl?.querySelector(".usingLocalImage"); const separatorEl = parentEl?.querySelector(".separator"); diff --git a/frontend/src/ts/elements/settings/custom-font-picker.ts b/frontend/src/ts/elements/settings/custom-font-picker.ts index 6384a2275bbe..07d807c85b60 100644 --- a/frontend/src/ts/elements/settings/custom-font-picker.ts +++ b/frontend/src/ts/elements/settings/custom-font-picker.ts @@ -3,7 +3,7 @@ import * as Notifications from "../notifications"; import { applyFontFamily } from "../../controllers/theme-controller"; const parentEl = document.querySelector( - ".pageSettings .section[data-config-name='fontFamily']" + ".pageSettings .section[data-config-name='fontFamily']", ); const usingLocalFontEl = parentEl?.querySelector(".usingLocalFont"); const separatorEl = parentEl?.querySelector(".separator"); @@ -58,7 +58,7 @@ uploadContainerEl ) { Notifications.add( "Unsupported font format, must be woff, woff2, ttf or otf.", - 0 + 0, ); fileInput.value = ""; return; diff --git a/frontend/src/ts/elements/settings/fps-limit-section.ts b/frontend/src/ts/elements/settings/fps-limit-section.ts index 1c0e52303fe0..6e1fc483e751 100644 --- a/frontend/src/ts/elements/settings/fps-limit-section.ts +++ b/frontend/src/ts/elements/settings/fps-limit-section.ts @@ -3,11 +3,11 @@ import { ValidatedHtmlInputElement } from "../input-validation"; import * as Notifications from "../notifications"; const section = document.querySelector( - "#pageSettings .section.fpsLimit" + "#pageSettings .section.fpsLimit", ) as HTMLElement; const button = section.querySelector( - "button[data-fpsLimit='native']" + "button[data-fpsLimit='native']", ) as HTMLButtonElement; const input = new ValidatedHtmlInputElement( @@ -15,7 +15,7 @@ const input = new ValidatedHtmlInputElement( { schema: fpsLimitSchema, inputValueConvert: (val: string) => parseInt(val, 10), - } + }, ); export function update(): void { diff --git a/frontend/src/ts/elements/settings/settings-group.ts b/frontend/src/ts/elements/settings/settings-group.ts index c590bda6dec7..37320f9f2053 100644 --- a/frontend/src/ts/elements/settings/settings-group.ts +++ b/frontend/src/ts/elements/settings/settings-group.ts @@ -41,7 +41,7 @@ export default class SettingsGroup { : SimpleValidation & { inputValueConvert: (val: string) => T; }; - } + }, ) { this.configName = configName; this.mode = mode; @@ -66,7 +66,7 @@ export default class SettingsGroup { if (this.mode === "select") { const el = document.querySelector( - `.pageSettings .section[data-config-name=${this.configName}] select` + `.pageSettings .section[data-config-name=${this.configName}] select`, ); if (el === null) { @@ -75,7 +75,7 @@ export default class SettingsGroup { if (el.hasAttribute("multiple")) { throw new Error( - "multi-select dropdowns not supported. Config: " + this.configName + "multi-select dropdowns not supported. Config: " + this.configName, ); } @@ -109,11 +109,11 @@ export default class SettingsGroup { let value = button.getAttribute("data-config-value"); if (value === null || value === "") { console.error( - `Failed to handle settings button click for ${configName}: data-${configName} is missing or empty.` + `Failed to handle settings button click for ${configName}: data-${configName} is missing or empty.`, ); Notifications.add( "Button is missing data property. Please report this.", - -1 + -1, ); return; } @@ -152,7 +152,7 @@ export default class SettingsGroup { this.elements = [input]; } else if (this.mode === "range") { const el = document.querySelector( - `.pageSettings .section[data-config-name=${this.configName}] input[type=range]` + `.pageSettings .section[data-config-name=${this.configName}] input[type=range]`, ); if (el === null) { @@ -182,7 +182,7 @@ export default class SettingsGroup { if (this.elements.length === 0 || this.elements === undefined) { throw new Error( - `Failed to find elements for ${configName} with mode ${mode}` + `Failed to find elements for ${configName} with mode ${mode}`, ); } @@ -236,7 +236,7 @@ export default class SettingsGroup { const range = this.elements?.[0] as HTMLInputElement | null | undefined; const rangeValue = document.querySelector( - `.pageSettings .section[data-config-name='${this.configName}'] .value` + `.pageSettings .section[data-config-name='${this.configName}'] .value`, ); if (range === undefined || range === null || rangeValue === null) { diff --git a/frontend/src/ts/elements/settings/theme-picker.ts b/frontend/src/ts/elements/settings/theme-picker.ts index a0fccef20127..9ecbfe6e5234 100644 --- a/frontend/src/ts/elements/settings/theme-picker.ts +++ b/frontend/src/ts/elements/settings/theme-picker.ts @@ -31,7 +31,7 @@ function updateActiveButton(): void { }); document .querySelector( - `.pageSettings .section.themes .theme[theme='${activeThemeName}']` + `.pageSettings .section.themes .theme[theme='${activeThemeName}']`, ) ?.classList.add("active"); } @@ -40,7 +40,7 @@ function updateColors( colorPicker: JQuery, color: string, onlyStyle = false, - noThemeUpdate = false + noThemeUpdate = false, ): void { if (onlyStyle) { const colorID = colorPicker.find("input.color").attr("id"); @@ -90,7 +90,7 @@ function updateColors( $(".colorConverter").css("color", color); const hexColor: string | undefined = Colors.rgbStringtoHex( - $(".colorConverter").css("color") + $(".colorConverter").css("color"), ); if (hexColor === undefined) { return; @@ -120,10 +120,10 @@ function updateColors( export async function fillPresetButtons(): Promise { // Update theme buttons const favThemesEl = document.querySelector( - ".pageSettings .section.themes .favThemes.buttons" + ".pageSettings .section.themes .favThemes.buttons", ); const themesEl = document.querySelector( - ".pageSettings .section.themes .allThemes.buttons" + ".pageSettings .section.themes .allThemes.buttons", ); if (favThemesEl === null || themesEl === null) { @@ -216,11 +216,11 @@ export async function fillPresetButtons(): Promise { export async function fillCustomButtons(): Promise { // Update custom theme buttons const customThemesEl = $( - ".pageSettings .section.themes .allCustomThemes.buttons" + ".pageSettings .section.themes .allCustomThemes.buttons", ).empty(); const addButton = $(".pageSettings .section.themes .addCustomThemeButton"); const saveButton = $( - ".pageSettings .section.themes .tabContent.customTheme #saveCustomThemeButton" + ".pageSettings .section.themes .tabContent.customTheme #saveCustomThemeButton", ); if (!isAuthenticated()) { @@ -251,18 +251,18 @@ export async function fillCustomButtons(): Promise {
${customTheme.name.replace(/_/g, " ")}
-
` +
`, ); } } export function setCustomInputs(noThemeUpdate = false): void { $( - ".pageSettings .section.themes .tabContainer .customTheme .colorPicker" + ".pageSettings .section.themes .tabContainer .customTheme .colorPicker", ).each((_index, element: HTMLElement) => { const currentColor = Config.customThemeColors[ ThemeController.colorVars.indexOf( - $(element).find("input.color").attr("id") as string + $(element).find("input.color").attr("id") as string, ) ] as string; updateColors($(element), currentColor, false, noThemeUpdate); @@ -287,8 +287,8 @@ function saveCustomThemeColors(): void { for (const color of ThemeController.colorVars) { newColors.push( $(`.pageSettings .tabContent.customTheme #${color}[type='color']`).attr( - "value" - ) as string + "value", + ) as string, ); } UpdateConfig.setCustomThemeColors(newColors as CustomThemeColors); @@ -302,28 +302,28 @@ export function updateActiveTab(): void { $( `.pageSettings .section.themes .tabs button[data-tab="${ Config.customTheme ? "custom" : "preset" - }"]` + }"]`, ).addClass("active"); if (Config.customTheme) { void Misc.swapElements( document.querySelector( - '.pageSettings [tabContent="preset"]' + '.pageSettings [tabContent="preset"]', ) as HTMLElement, document.querySelector( - '.pageSettings [tabContent="custom"]' + '.pageSettings [tabContent="custom"]', ) as HTMLElement, - 250 + 250, ); } else { void Misc.swapElements( document.querySelector( - '.pageSettings [tabContent="custom"]' + '.pageSettings [tabContent="custom"]', ) as HTMLElement, document.querySelector( - '.pageSettings [tabContent="preset"]' + '.pageSettings [tabContent="preset"]', ) as HTMLElement, - 250 + 250, ); } } @@ -357,14 +357,14 @@ $(".pageSettings").on("click", " .section.themes .customTheme.button", (e) => { if ($(e.target).hasClass("editButton")) return; const customThemeId = $(e.currentTarget).attr("customThemeId") ?? ""; const theme = DB.getSnapshot()?.customThemes?.find( - (e) => e._id === customThemeId + (e) => e._id === customThemeId, ); if (theme === undefined) { //this shouldnt happen but typescript needs this check console.error( "Could not find custom theme in snapshot for id ", - customThemeId + customThemeId, ); return; } @@ -381,7 +381,7 @@ $(".pageSettings").on("click", ".section.themes .theme .favButton", (e) => { toggleFavourite(theme); } else { console.error( - "Could not find the theme attribute attached to the button clicked!" + "Could not find the theme attribute attached to the button clicked!", ); } }); @@ -395,7 +395,7 @@ $(".pageSettings").on("click", ".section.themes .theme.button", (e) => { }); $( - ".pageSettings .section.themes .tabContainer .customTheme input[type=color]" + ".pageSettings .section.themes .tabContainer .customTheme input[type=color]", ).on("input", (e) => { const $colorVar = $(e.currentTarget).attr("id") as string; const $pickedColor = $(e.currentTarget).val() as string; @@ -404,7 +404,7 @@ $( }); $( - ".pageSettings .section.themes .tabContainer .customTheme input[type=color]" + ".pageSettings .section.themes .tabContainer .customTheme input[type=color]", ).on("change", (e) => { const $colorVar = $(e.currentTarget).attr("id") as string; const $pickedColor = $(e.currentTarget).val() as string; diff --git a/frontend/src/ts/elements/test-activity-calendar.ts b/frontend/src/ts/elements/test-activity-calendar.ts index 27476e8312d5..a9b0c7495a5c 100644 --- a/frontend/src/ts/elements/test-activity-calendar.ts +++ b/frontend/src/ts/elements/test-activity-calendar.ts @@ -41,7 +41,7 @@ export class TestActivityCalendar implements TestActivityCalendar { data: (number | null | undefined)[], lastDay: Date, firstDayOfWeek: Day, - fullYear = false + fullYear = false, ) { this.firstDayOfWeek = firstDayOfWeek; const local = new UTCDateMini(lastDay); @@ -69,11 +69,11 @@ export class TestActivityCalendar implements TestActivityCalendar { protected buildData( data: (number | null | undefined)[], - lastDay: Date + lastDay: Date, ): (number | null | undefined)[] { //fill calendar with enough values const values = new Array(Math.max(0, 386 - data.length)).fill( - undefined + undefined, ) as (number | null | undefined)[]; values.push(...data); @@ -180,7 +180,7 @@ export class TestActivityCalendar implements TestActivityCalendar { const trimmed = sorted.slice( Math.round(sorted.length * 0.1), - sorted.length - Math.round(sorted.length * 0.1) + sorted.length - Math.round(sorted.length * 0.1), ); const sum = trimmed.reduce((a, c) => a + c, 0); const mid = sum / trimmed.length; @@ -248,7 +248,7 @@ export class ModifiableTestActivityCalendar this.data, this.lastDay, this.firstDayOfWeek, - true + true, ); } } diff --git a/frontend/src/ts/elements/test-activity.ts b/frontend/src/ts/elements/test-activity.ts index 26b4cbe0a4d0..12808f082956 100644 --- a/frontend/src/ts/elements/test-activity.ts +++ b/frontend/src/ts/elements/test-activity.ts @@ -14,7 +14,7 @@ let yearSelector: SlimSelect | undefined = undefined; export function init( element: HTMLElement, calendar?: TestActivityCalendar, - userSignUpDate?: Date + userSignUpDate?: Date, ): void { if (calendar === undefined) { clear(element); @@ -27,7 +27,7 @@ export function init( initYearSelector( element, "current", - safeNumber(userSignUpDate?.getFullYear()) ?? 2022 + safeNumber(userSignUpDate?.getFullYear()) ?? 2022, ); } updateLabels(element, calendar.firstDayOfWeek); @@ -79,7 +79,7 @@ function update(element: HTMLElement, calendar?: TestActivityCalendar): void { export function initYearSelector( element: HTMLElement, selectedYear: number | "current", - startYear: number + startYear: number, ): void { const currentYear = new Date().getFullYear(); const years: DataObjectPartial[] = [ @@ -120,7 +120,7 @@ function updateMonths(months: TestActivityMonth[]): void { element.innerHTML = months .map( (month) => - `
${month.text}
` + `
${month.text}
`, ) .join(""); } @@ -165,7 +165,7 @@ function updateLabels(element: HTMLElement, firstDayOfWeek: number): void { days.push( i % 2 !== firstDayOfWeek % 2 ? daysDisplay[(firstDayOfWeek + i) % 7] - : undefined + : undefined, ); } @@ -178,7 +178,7 @@ function updateLabels(element: HTMLElement, firstDayOfWeek: number): void { .map((it) => it !== undefined ? `
${shorten(it)}
` - : "
" + : "
", ) .join(""); }; diff --git a/frontend/src/ts/elements/test-init-failed.ts b/frontend/src/ts/elements/test-init-failed.ts index 95f60baf7f15..6ef90ab81ef6 100644 --- a/frontend/src/ts/elements/test-init-failed.ts +++ b/frontend/src/ts/elements/test-init-failed.ts @@ -1,7 +1,7 @@ const elem = document.querySelector(".pageTest #testInitFailed"); const testElem = document.querySelector(".pageTest #typingTest"); const errorElem = document.querySelector( - ".pageTest #testInitFailed .error" + ".pageTest #testInitFailed .error", ); export function show(): void { diff --git a/frontend/src/ts/elements/xp-bar.ts b/frontend/src/ts/elements/xp-bar.ts index 6c1b8c229d69..453ff8fc068f 100644 --- a/frontend/src/ts/elements/xp-bar.ts +++ b/frontend/src/ts/elements/xp-bar.ts @@ -20,10 +20,10 @@ let lastUpdate: { }; const xpBreakdownTotalEl = document.querySelector( - "nav .xpBar .xpBreakdown .total" + "nav .xpBar .xpBreakdown .total", ) as HTMLElement; const xpBreakdownListEl = document.querySelector( - "nav .xpBar .xpBreakdown .list" + "nav .xpBar .xpBreakdown .list", ) as HTMLElement; const levelEl = document.querySelector("nav .level") as HTMLElement; const barEl = document.querySelector("nav .xpBar .bar") as HTMLElement; @@ -50,11 +50,11 @@ export async function skipBreakdown(): Promise { }); levelEl.textContent = `${Levels.getLevelFromTotalXp( - lastUpdate.currentXp + lastUpdate.addedXp + lastUpdate.currentXp + lastUpdate.addedXp, )}`; const endingDetails = Levels.getXpDetails( - lastUpdate.currentXp + lastUpdate.addedXp + lastUpdate.currentXp + lastUpdate.addedXp, ); const endingLevel = endingDetails.level + @@ -80,7 +80,7 @@ export function setXp(xp: number): void { export async function update( currentXp: number, addedXp: number, - breakdown?: XpBreakdown + breakdown?: XpBreakdown, ): Promise { skip = false; breakdownVisible = true; @@ -165,14 +165,14 @@ async function flashTotalXp(totalXp: number, force = false): Promise { async function addBreakdownListItem( string: string, amount: number | string | undefined, - options?: { extraClass?: string; noAnimation?: boolean } + options?: { extraClass?: string; noAnimation?: boolean }, ): Promise { if (skip) return; if (amount === undefined) { xpBreakdownListEl.insertAdjacentHTML( "beforeend", - `
${string}
` + `
${string}
`, ); } else if (typeof amount === "string") { xpBreakdownListEl.insertAdjacentHTML( @@ -181,7 +181,7 @@ async function addBreakdownListItem(
${string}
${amount}
-
` +
`, ); } else { const positive = amount === undefined ? undefined : amount >= 0; @@ -193,16 +193,16 @@ async function addBreakdownListItem(
${string}
${positive ? "+" : "-"}${Math.abs(amount)}
- ` + options?.extraClass + }">${positive ? "+" : "-"}${Math.abs(amount)} + `, ); } if (options?.noAnimation) return; const el = xpBreakdownListEl.querySelector( - `.line[data-string='${string}']` + `.line[data-string='${string}']`, ) as HTMLElement; await Misc.promiseAnimate(el, { @@ -213,7 +213,7 @@ async function addBreakdownListItem( async function animateXpBreakdown( addedXp: number, - breakdown?: XpBreakdown + breakdown?: XpBreakdown, ): Promise { if (skip) return; @@ -315,7 +315,7 @@ async function animateXpBreakdown( void flashTotalXp(total); await addBreakdownListItem( "global multiplier", - `x${breakdown.configMultiplier}` + `x${breakdown.configMultiplier}`, ); } @@ -337,7 +337,7 @@ async function animateXpBreakdown( async function animateXpBar( startingLevel: number, - endingLevel: number + endingLevel: number, ): Promise { if (skip) return; diff --git a/frontend/src/ts/event-handlers/account.ts b/frontend/src/ts/event-handlers/account.ts index d9327ad794d0..d852e07144f6 100644 --- a/frontend/src/ts/event-handlers/account.ts +++ b/frontend/src/ts/event-handlers/account.ts @@ -27,7 +27,7 @@ $(accountPage).on("click", ".editProfileButton", () => { if (!snapshot) { Notifications.add( "Failed to open edit profile modal: No user snapshot found", - -1 + -1, ); return; } @@ -47,7 +47,7 @@ $(accountPage).on("click", ".group.history .resultEditTagsButton", (e) => { EditResultTagsModal.show( resultid ?? "", parseJsonWithSchema(tags ?? "[]", TagsArraySchema), - "accountPage" + "accountPage", ); }); diff --git a/frontend/src/ts/event-handlers/footer.ts b/frontend/src/ts/event-handlers/footer.ts index 88bcad26e4b5..5f4dc60aff13 100644 --- a/frontend/src/ts/event-handlers/footer.ts +++ b/frontend/src/ts/event-handlers/footer.ts @@ -38,8 +38,8 @@ document lastSeenServerCompatibility, }, null, - 2 - ) + 2, + ), ); } else { VersionHistoryModal.show(); diff --git a/frontend/src/ts/event-handlers/global.ts b/frontend/src/ts/event-handlers/global.ts index 9bf0658af3ca..58b1f9c2a6d1 100644 --- a/frontend/src/ts/event-handlers/global.ts +++ b/frontend/src/ts/event-handlers/global.ts @@ -115,7 +115,7 @@ window.onunhandledrejection = function (e): void { customTitle: "DEV: Unhandled rejection", duration: 5, important: true, - } + }, ); } }; diff --git a/frontend/src/ts/event-handlers/leaderboards.ts b/frontend/src/ts/event-handlers/leaderboards.ts index 9faa3a20ef96..56875b74df9e 100644 --- a/frontend/src/ts/event-handlers/leaderboards.ts +++ b/frontend/src/ts/event-handlers/leaderboards.ts @@ -3,7 +3,7 @@ import { showPopup } from "../modals/simple-modals"; const lb = document.getElementById("pageLeaderboards"); for (const button of lb?.querySelectorAll( - ".jumpButtons button[data-action='goToPage']" + ".jumpButtons button[data-action='goToPage']", ) ?? []) { button?.addEventListener("click", () => { showPopup("lbGoToPage"); diff --git a/frontend/src/ts/event-handlers/settings.ts b/frontend/src/ts/event-handlers/settings.ts index 87b09f983894..13137de1b6a5 100644 --- a/frontend/src/ts/event-handlers/settings.ts +++ b/frontend/src/ts/event-handlers/settings.ts @@ -38,7 +38,7 @@ settingsPage ) { Notifications.add( "Failed to edit preset: Could not find preset id or name", - -1 + -1, ); return; } @@ -56,7 +56,7 @@ settingsPage ) { Notifications.add( "Failed to remove preset: Could not find preset id or name", - -1 + -1, ); return; } @@ -81,7 +81,7 @@ settingsPage?.querySelector(".section.tags")?.addEventListener("click", (e) => { ) { Notifications.add( "Failed to edit tag: Could not find tag id or name", - -1 + -1, ); return; } @@ -99,7 +99,7 @@ settingsPage?.querySelector(".section.tags")?.addEventListener("click", (e) => { ) { Notifications.add( "Failed to clear tag PB: Could not find tag id or name", - -1 + -1, ); return; } @@ -117,7 +117,7 @@ settingsPage?.querySelector(".section.tags")?.addEventListener("click", (e) => { ) { Notifications.add( "Failed to remove tag: Could not find tag id or name", - -1 + -1, ); return; } diff --git a/frontend/src/ts/event-handlers/test.ts b/frontend/src/ts/event-handlers/test.ts index 9309834c5b69..fa839c1b6c4f 100644 --- a/frontend/src/ts/event-handlers/test.ts +++ b/frontend/src/ts/event-handlers/test.ts @@ -49,10 +49,10 @@ $(".pageTest").on("click", "#testConfig .shareButton", (e) => { $(".pageTest").on("click", ".tags .editTagsButton", () => { if ((DB.getSnapshot()?.tags?.length ?? 0) > 0) { const resultid = $(".pageTest .tags .editTagsButton").attr( - "data-result-id" + "data-result-id", ) as string; const activeTagIds = $(".pageTest .tags .editTagsButton").attr( - "data-active-tag-ids" + "data-active-tag-ids", ) as string; const tags = activeTagIds === "" ? [] : activeTagIds.split(","); EditResultTagsModal.show(resultid, tags, "resultPage"); @@ -102,7 +102,7 @@ $(".pageTest #dailyLeaderboardRank").on("click", async () => { void navigate( `/leaderboards?type=daily&language=${Config.language}&mode2=${getMode2( Config, - null - )}&goToUserPage=true` + null, + )}&goToUserPage=true`, ); }); diff --git a/frontend/src/ts/firebase.ts b/frontend/src/ts/firebase.ts index a7ab4a8ae816..dd2a6354201b 100644 --- a/frontend/src/ts/firebase.ts +++ b/frontend/src/ts/firebase.ts @@ -61,7 +61,7 @@ export async function init(callback: ReadyCallback): Promise { .firebaseConfig; } else { throw new Error( - "No config file found. Make sure frontend/src/ts/constants/firebase-config.ts exists" + "No config file found. Make sure frontend/src/ts/constants/firebase-config.ts exists", ); } @@ -88,7 +88,7 @@ export async function init(callback: ReadyCallback): Promise { createErrorMessage(e, "Firebase uninitialized"), 0, undefined, - false + false, ); } } finally { @@ -124,19 +124,19 @@ export async function signOut(): Promise { export async function signInWithEmailAndPassword( email: string, password: string, - rememberMe: boolean + rememberMe: boolean, ): Promise { if (Auth === undefined) throw new Error("Authentication uninitialized"); await setPersistence(rememberMe, true); const { data: result, error } = await tryCatch( - firebaseSignInWithEmailAndPassword(Auth, email, password) + firebaseSignInWithEmailAndPassword(Auth, email, password), ); if (error !== null) { console.error(error); throw translateFirebaseError( error, - "Failed to sign in with email and password" + "Failed to sign in with email and password", ); } @@ -145,14 +145,14 @@ export async function signInWithEmailAndPassword( export async function signInWithPopup( provider: AuthProvider, - rememberMe: boolean + rememberMe: boolean, ): Promise { if (Auth === undefined) throw new Error("Authentication uninitialized"); await setPersistence(rememberMe, true); ignoreAuthCallback = true; const { data: signedInUser, error } = await tryCatch( - firebaseSignInWithPopup(Auth, provider) + firebaseSignInWithPopup(Auth, provider), ); if (error !== null) { ignoreAuthCallback = false; @@ -170,14 +170,14 @@ export async function signInWithPopup( export async function createUserWithEmailAndPassword( email: string, - password: string + password: string, ): Promise { if (Auth === undefined) throw new Error("Authentication uninitialized"); ignoreAuthCallback = true; const result = await firebaseCreateUserWithEmailAndPassword( Auth, email, - password + password, ); return result; @@ -190,7 +190,7 @@ export async function getIdToken(): Promise { } async function setPersistence( rememberMe: boolean, - store = false + store = false, ): Promise { if (Auth === undefined) throw new Error("Authentication uninitialized"); const persistence = rememberMe @@ -200,7 +200,7 @@ async function setPersistence( if (store) { window.localStorage.setItem( "firebasePersistence", - rememberMe ? "LOCAL" : "SESSION" + rememberMe ? "LOCAL" : "SESSION", ); } @@ -209,7 +209,7 @@ async function setPersistence( function translateFirebaseError( error: Error | FirebaseError, - defaultMessage: string + defaultMessage: string, ): Error { let message = createErrorMessage(error, defaultMessage); diff --git a/frontend/src/ts/input/handlers/before-delete.ts b/frontend/src/ts/input/handlers/before-delete.ts index d704b7667469..a16d1c0a661d 100644 --- a/frontend/src/ts/input/handlers/before-delete.ts +++ b/frontend/src/ts/input/handlers/before-delete.ts @@ -16,7 +16,7 @@ export function onBeforeDelete(event: InputEvent): void { if (inputIsEmpty) { // this is nested because we only wanna pull the element from the dom if needed const previousWordElement = TestUI.getWordElement( - TestState.activeWordIndex - 1 + TestState.activeWordIndex - 1, ); if (previousWordElement === null) { event.preventDefault(); diff --git a/frontend/src/ts/input/handlers/insert-text.ts b/frontend/src/ts/input/handlers/insert-text.ts index a3e09211b483..b3c1f67ca22c 100644 --- a/frontend/src/ts/input/handlers/insert-text.ts +++ b/frontend/src/ts/input/handlers/insert-text.ts @@ -90,7 +90,7 @@ export async function onInsertText(options: OnInsertTextParams): Promise { ) { // replace the data with the override setInputElementValue( - inputValue.slice(0, -options.data.length) + charOverride + inputValue.slice(0, -options.data.length) + charOverride, ); await onInsertText({ ...options, @@ -108,7 +108,7 @@ export async function onInsertText(options: OnInsertTextParams): Promise { const normalizedData = normalizeDataAndUpdateInputIfNeeded( options.data, testInput, - currentWord + currentWord, ); const data = normalizedData ?? options.data; @@ -134,10 +134,10 @@ export async function onInsertText(options: OnInsertTextParams): Promise { // is char correct const funboxCorrect = findSingleActiveFunboxWithFunction( - "isCharCorrect" + "isCharCorrect", )?.functions.isCharCorrect( data, - currentWord[(testInput + data).length - 1] ?? "" + currentWord[(testInput + data).length - 1] ?? "", ); const correct = funboxCorrect ?? @@ -292,7 +292,7 @@ export async function onInsertText(options: OnInsertTextParams): Promise { function normalizeDataAndUpdateInputIfNeeded( data: string, testInput: string, - currentWord: string + currentWord: string, ): string | null { let normalizedData: string | null = null; const targetChar = currentWord[testInput.length]; @@ -307,7 +307,7 @@ function normalizeDataAndUpdateInputIfNeeded( } export async function emulateInsertText( - options: OnInsertTextParams + options: OnInsertTextParams, ): Promise { const inputStopped = onBeforeInsertText(options.data); diff --git a/frontend/src/ts/input/handlers/keydown.ts b/frontend/src/ts/input/handlers/keydown.ts index a1014ab211bf..dc87f89f3459 100644 --- a/frontend/src/ts/input/handlers/keydown.ts +++ b/frontend/src/ts/input/handlers/keydown.ts @@ -45,7 +45,7 @@ export async function handleTab(e: KeyboardEvent, now: number): Promise { export async function handleEnter( e: KeyboardEvent, - now: number + now: number, ): Promise { if (e.shiftKey) { if (Config.mode === "zen") { @@ -57,7 +57,7 @@ export async function handleEnter( Config.words, Config.time, CustomText.getData(), - CustomTextState.isCustomTextLong() ?? false + CustomTextState.isCustomTextLong() ?? false, ) ) { const delay = Date.now() - getLastBailoutAttempt(); @@ -70,7 +70,7 @@ export async function handleEnter( { important: true, duration: 5, - } + }, ); } return; @@ -108,7 +108,7 @@ export async function handleOppositeShift(event: KeyboardEvent): Promise { Config.keymapLayout !== "overrideSync" ) { let keymapLayout = await JSONData.getLayout(Config.keymapLayout).catch( - () => undefined + () => undefined, ); if (keymapLayout === undefined) { Notifications.add("Failed to load keymap layout", -1); @@ -124,18 +124,18 @@ export async function handleOppositeShift(event: KeyboardEvent): Promise { const keycode = KeyConverter.layoutKeyToKeycode(event.key, keymapLayout); setCorrectShiftUsed( - keycode === undefined ? true : ShiftTracker.isUsingOppositeShift(keycode) + keycode === undefined ? true : ShiftTracker.isUsingOppositeShift(keycode), ); } else { setCorrectShiftUsed( - ShiftTracker.isUsingOppositeShift(event.code as KeyConverter.Keycode) + ShiftTracker.isUsingOppositeShift(event.code as KeyConverter.Keycode), ); } } async function handleFunboxes( event: KeyboardEvent, - now: number + now: number, ): Promise { for (const fb of getActiveFunboxesWithFunction("handleKeydown")) { void fb.functions.handleKeydown(event); diff --git a/frontend/src/ts/input/helpers/input-type.ts b/frontend/src/ts/input/helpers/input-type.ts index d6ea52b9c97d..a30d5b70d176 100644 --- a/frontend/src/ts/input/helpers/input-type.ts +++ b/frontend/src/ts/input/helpers/input-type.ts @@ -16,7 +16,7 @@ const SUPPORTED_INPUT_TYPES: Set = new Set([ ]); export function isSupportedInputType( - inputType: string + inputType: string, ): inputType is SupportedInputType { return SUPPORTED_INPUT_TYPES.has(inputType as SupportedInputType); } diff --git a/frontend/src/ts/input/helpers/word-navigation.ts b/frontend/src/ts/input/helpers/word-navigation.ts index a9149525652f..ff88066fe924 100644 --- a/frontend/src/ts/input/helpers/word-navigation.ts +++ b/frontend/src/ts/input/helpers/word-navigation.ts @@ -42,7 +42,7 @@ export async function goToNextWord({ TestUI.beforeTestWordChange( "forward", correctInsert, - isCompositionEnding || zenNewline === true + isCompositionEnding || zenNewline === true, ); if (correctInsert) { @@ -95,7 +95,7 @@ export async function goToNextWord({ export function goToPreviousWord( inputType: DeleteInputType, - forceUpdateActiveWordLetters = false + forceUpdateActiveWordLetters = false, ): void { if (TestState.activeWordIndex === 0) { setInputElementValue(""); diff --git a/frontend/src/ts/modals/cookies.ts b/frontend/src/ts/modals/cookies.ts index 58d6f1749681..91fc4403cc80 100644 --- a/frontend/src/ts/modals/cookies.ts +++ b/frontend/src/ts/modals/cookies.ts @@ -94,7 +94,7 @@ const modal = new AnimatedModal({ console.error("Failed to open ad consent UI"); Notifications.add( "Failed to open Ad consent popup. Do you have an ad or cookie popup blocker enabled?", - -1 + -1, ); } }); diff --git a/frontend/src/ts/modals/custom-generator.ts b/frontend/src/ts/modals/custom-generator.ts index 37917c589a95..7c4d77fba5a4 100644 --- a/frontend/src/ts/modals/custom-generator.ts +++ b/frontend/src/ts/modals/custom-generator.ts @@ -106,7 +106,7 @@ function hide(hideOptions?: HideOptions): void { function generateWords(): string[] { const characterInput = $( - "#customGeneratorModal .characterInput" + "#customGeneratorModal .characterInput", ).val() as string; const minLength = parseInt($("#customGeneratorModal .minLengthInput").val() as string) || 2; @@ -148,7 +148,7 @@ async function apply(set: boolean): Promise { } const customText = generatedWords.join( - CustomText.getPipeDelimiter() ? "|" : " " + CustomText.getPipeDelimiter() ? "|" : " ", ); hide({ diff --git a/frontend/src/ts/modals/custom-test-duration.ts b/frontend/src/ts/modals/custom-test-duration.ts index fb43b9235bb7..fe5197f3b682 100644 --- a/frontend/src/ts/modals/custom-test-duration.ts +++ b/frontend/src/ts/modals/custom-test-duration.ts @@ -73,9 +73,8 @@ export function show(showOptions?: ShowOptions): void { ...showOptions, focusFirstInput: "focusAndSelect", beforeAnimation: async (modalEl) => { - ( - modalEl.querySelector("input") as HTMLInputElement - ).value = `${Config.time}`; + (modalEl.querySelector("input") as HTMLInputElement).value = + `${Config.time}`; previewDuration(); }, }); @@ -102,7 +101,7 @@ function apply(): void { 0, { duration: 7, - } + }, ); } } else { diff --git a/frontend/src/ts/modals/custom-text.ts b/frontend/src/ts/modals/custom-text.ts index e14b3c5f197d..062bc6ffdcc0 100644 --- a/frontend/src/ts/modals/custom-text.ts +++ b/frontend/src/ts/modals/custom-text.ts @@ -36,7 +36,7 @@ type State = { const state: State = { textarea: CustomText.getText().join( - CustomText.getPipeDelimiter() ? "|" : " " + CustomText.getPipeDelimiter() ? "|" : " ", ), longCustomTextWarning: false, challengeWarning: false, @@ -56,47 +56,47 @@ const state: State = { function updateUI(): void { $(`${popup} .inputs .group[data-id="mode"] button`).removeClass("active"); $( - `${popup} .inputs .group[data-id="mode"] button[value="${state.customTextMode}"]` + `${popup} .inputs .group[data-id="mode"] button[value="${state.customTextMode}"]`, ).addClass("active"); $(`${popup} .inputs .group[data-id="limit"] input.words`).addClass("hidden"); $(`${popup} .inputs .group[data-id="limit"] input.sections`).addClass( - "hidden" + "hidden", ); $(`${popup} .inputs .group[data-id="limit"] input.words`).val( - state.customTextLimits.word + state.customTextLimits.word, ); $(`${popup} .inputs .group[data-id="limit"] input.time`).val( - state.customTextLimits.time + state.customTextLimits.time, ); $(`${popup} .inputs .group[data-id="limit"] input.sections`).val( - state.customTextLimits.section + state.customTextLimits.section, ); if (state.customTextLimits.word !== "") { $(`${popup} .inputs .group[data-id="limit"] input.words`).removeClass( - "hidden" + "hidden", ); } if (state.customTextLimits.section !== "") { $(`${popup} .inputs .group[data-id="limit"] input.sections`).removeClass( - "hidden" + "hidden", ); } if (state.customTextPipeDelimiter) { $(`${popup} .inputs .group[data-id="limit"] input.sections`).removeClass( - "hidden" + "hidden", ); $(`${popup} .inputs .group[data-id="limit"] input.words`).addClass( - "hidden" + "hidden", ); } else { $(`${popup} .inputs .group[data-id="limit"] input.words`).removeClass( - "hidden" + "hidden", ); $(`${popup} .inputs .group[data-id="limit"] input.sections`).addClass( - "hidden" + "hidden", ); } @@ -111,31 +111,31 @@ function updateUI(): void { $(`${popup} .inputs .group[data-id="fancy"] button`).removeClass("active"); $( - `${popup} .inputs .group[data-id="fancy"] button[value="${state.removeFancyTypographyEnabled}"]` + `${popup} .inputs .group[data-id="fancy"] button[value="${state.removeFancyTypographyEnabled}"]`, ).addClass("active"); $(`${popup} .inputs .group[data-id="control"] button`).removeClass("active"); $( - `${popup} .inputs .group[data-id="control"] button[value="${state.replaceControlCharactersEnabled}"]` + `${popup} .inputs .group[data-id="control"] button[value="${state.replaceControlCharactersEnabled}"]`, ).addClass("active"); $(`${popup} .inputs .group[data-id="zeroWidth"] button`).removeClass( - "active" + "active", ); $( - `${popup} .inputs .group[data-id="zeroWidth"] button[value="${state.removeZeroWidthCharactersEnabled}"]` + `${popup} .inputs .group[data-id="zeroWidth"] button[value="${state.removeZeroWidthCharactersEnabled}"]`, ).addClass("active"); $(`${popup} .inputs .group[data-id="delimiter"] button`).removeClass( - "active" + "active", ); $( - `${popup} .inputs .group[data-id="delimiter"] button[value="${state.customTextPipeDelimiter}"]` + `${popup} .inputs .group[data-id="delimiter"] button[value="${state.customTextPipeDelimiter}"]`, ).addClass("active"); $(`${popup} .inputs .group[data-id="newlines"] button`).removeClass("active"); $( - `${popup} .inputs .group[data-id="newlines"] button[value="${state.replaceNewlines}"]` + `${popup} .inputs .group[data-id="newlines"] button[value="${state.replaceNewlines}"]`, ).addClass("active"); $(`${popup} textarea`).val(state.textarea); @@ -167,7 +167,7 @@ function updateUI(): void { async function beforeAnimation( modalEl: HTMLElement, - modalChainData?: IncomingData + modalChainData?: IncomingData, ): Promise { state.customTextMode = CustomText.getMode(); @@ -203,7 +203,7 @@ async function beforeAnimation( } const newText = - modalChainData.set ?? true + (modalChainData.set ?? true) ? modalChainData.text : state.textarea + " " + modalChainData.text; state.textarea = newText; @@ -349,7 +349,7 @@ function apply(): void { 0, { duration: 7, - } + }, ); } @@ -425,7 +425,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='fancy'] button" + ".group[data-id='fancy'] button", )) { button.addEventListener("click", (e) => { state.removeFancyTypographyEnabled = @@ -435,7 +435,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='control'] button" + ".group[data-id='control'] button", )) { button.addEventListener("click", (e) => { state.replaceControlCharactersEnabled = @@ -445,7 +445,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='zeroWidth'] button" + ".group[data-id='zeroWidth'] button", )) { button.addEventListener("click", (e) => { state.removeZeroWidthCharactersEnabled = @@ -455,7 +455,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='delimiter'] button" + ".group[data-id='delimiter'] button", )) { button.addEventListener("click", (e) => { state.customTextPipeDelimiter = @@ -475,7 +475,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='newlines'] button" + ".group[data-id='newlines'] button", )) { button.addEventListener("click", (e) => { state.replaceNewlines = (e.target as HTMLButtonElement).value as diff --git a/frontend/src/ts/modals/custom-word-amount.ts b/frontend/src/ts/modals/custom-word-amount.ts index e325ed6b43c8..2b75dfd12445 100644 --- a/frontend/src/ts/modals/custom-word-amount.ts +++ b/frontend/src/ts/modals/custom-word-amount.ts @@ -9,9 +9,8 @@ export function show(showOptions?: ShowOptions): void { ...showOptions, focusFirstInput: "focusAndSelect", beforeAnimation: async (modalEl) => { - ( - modalEl.querySelector("input") as HTMLInputElement - ).value = `${Config.words}`; + (modalEl.querySelector("input") as HTMLInputElement).value = + `${Config.words}`; }, }); } @@ -25,7 +24,7 @@ function hide(clearChain = false): void { function apply(): void { const val = parseInt( modal.getModal().querySelector("input")?.value as string, - 10 + 10, ); if (val !== null && !isNaN(val) && val >= 0 && isFinite(val)) { @@ -40,7 +39,7 @@ function apply(): void { 0, { duration: 7, - } + }, ); } } diff --git a/frontend/src/ts/modals/dev-options.ts b/frontend/src/ts/modals/dev-options.ts index dc34a0627b53..36c632e53dc4 100644 --- a/frontend/src/ts/modals/dev-options.ts +++ b/frontend/src/ts/modals/dev-options.ts @@ -43,7 +43,7 @@ async function setup(modalEl: HTMLElement): Promise { } Notifications.add( `Setting media query debug level to ${mediaQueryDebugLevel}`, - 5 + 5, ); setMediaQueryDebugLevel(mediaQueryDebugLevel); }); @@ -60,7 +60,7 @@ async function setup(modalEl: HTMLElement): Promise { ) { Notifications.add( "Quick login credentials not set. Add QUICK_LOGIN_EMAIL and QUICK_LOGIN_PASSWORD to your frontend .env file.", - -1 + -1, ); return; } @@ -68,7 +68,7 @@ async function setup(modalEl: HTMLElement): Promise { void signIn(envConfig.quickLoginEmail, envConfig.quickLoginPassword).then( () => { Loader.hide(); - } + }, ); void modal.hide(); }); @@ -108,7 +108,7 @@ export function appendButton(): void {
- ` + `, ); document .querySelector("#devButtons .button.showDevOptionsModal") diff --git a/frontend/src/ts/modals/edit-preset.ts b/frontend/src/ts/modals/edit-preset.ts index 3efa27fd463a..0a0911b7519a 100644 --- a/frontend/src/ts/modals/edit-preset.ts +++ b/frontend/src/ts/modals/edit-preset.ts @@ -26,7 +26,7 @@ import { ValidatedHtmlInputElement } from "../elements/input-validation"; const state = { presetType: "full" as PresetType, checkboxes: new Map( - ConfigGroupNameSchema.options.map((key: ConfigGroupName) => [key, true]) + ConfigGroupNameSchema.options.map((key: ConfigGroupName) => [key, true]), ), setPresetToCurrent: false, }; @@ -49,11 +49,11 @@ export function show(action: string, id?: string, name?: string): void { if (!presetNameEl) { presetNameEl = new ValidatedHtmlInputElement( document.querySelector( - "#editPresetModal .modal input" + "#editPresetModal .modal input", ) as HTMLInputElement, { schema: PresetNameSchema, - } + }, ); } if (action === "add") { @@ -64,7 +64,7 @@ export function show(action: string, id?: string, name?: string): void { presetNameEl?.native.parentElement?.classList.remove("hidden"); $("#editPresetModal .modal input").removeClass("hidden"); $( - "#editPresetModal .modal label.changePresetToCurrentCheckbox" + "#editPresetModal .modal label.changePresetToCurrentCheckbox", ).addClass("hidden"); $("#editPresetModal .modal .inputs").removeClass("hidden"); $("#editPresetModal .modal .presetType").removeClass("hidden"); @@ -80,7 +80,7 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal input").removeClass("hidden"); $( - "#editPresetModal .modal label.changePresetToCurrentCheckbox" + "#editPresetModal .modal label.changePresetToCurrentCheckbox", ).removeClass("hidden"); $("#editPresetModal .modal .presetNameTitle").removeClass("hidden"); state.setPresetToCurrent = false; @@ -96,11 +96,11 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal .submit").html("delete"); $("#editPresetModal .modal input").addClass("hidden"); $( - "#editPresetModal .modal label.changePresetToCurrentCheckbox" + "#editPresetModal .modal label.changePresetToCurrentCheckbox", ).addClass("hidden"); $("#editPresetModal .modal .text").removeClass("hidden"); $("#editPresetModal .modal .deletePrompt").text( - `Are you sure you want to delete the preset ${name}?` + `Are you sure you want to delete the preset ${name}?`, ); $("#editPresetModal .modal .inputs").addClass("hidden"); $("#editPresetModal .modal .presetType").addClass("hidden"); @@ -132,7 +132,7 @@ async function initializeEditState(id: string): Promise { } else { state.presetType = "partial"; edittedPreset.settingGroups.forEach((currentActiveSettingGroup) => - state.checkboxes.set(currentActiveSettingGroup, true) + state.checkboxes.set(currentActiveSettingGroup, true), ); } state.setPresetToCurrent = false; @@ -142,22 +142,22 @@ async function initializeEditState(id: string): Promise { function addCheckboxListeners(): void { ConfigGroupNameSchema.options.forEach((settingGroup: ConfigGroupName) => { const checkboxInput = $( - `#editPresetModal .modal .checkboxList .checkboxTitlePair[data-id="${settingGroup}"] input` + `#editPresetModal .modal .checkboxList .checkboxTitlePair[data-id="${settingGroup}"] input`, ); checkboxInput.on("change", (e) => { state.checkboxes.set( settingGroup, - checkboxInput.prop("checked") as boolean + checkboxInput.prop("checked") as boolean, ); }); }); const presetToCurrentCheckbox = $( - `#editPresetModal .modal .changePresetToCurrentCheckbox input` + `#editPresetModal .modal .changePresetToCurrentCheckbox input`, ); presetToCurrentCheckbox.on("change", async () => { state.setPresetToCurrent = presetToCurrentCheckbox.prop( - "checked" + "checked", ) as boolean; await updateEditPresetUI(); }); @@ -168,7 +168,7 @@ function addCheckBoxes(): void { return input.replace(/([a-z])([A-Z])/g, "$1 $2"); } const settingGroupListEl = $( - "#editPresetModal .modal .inputs .checkboxList" + "#editPresetModal .modal .inputs .checkboxList", ).empty(); ConfigGroupNameSchema.options.forEach((currSettingGroup) => { const currSettingGroupTitle = camelCaseToSpaced(currSettingGroup); @@ -187,12 +187,12 @@ function addCheckBoxes(): void { function updateUI(): void { ConfigGroupNameSchema.options.forEach((settingGroup: ConfigGroupName) => { $( - `#editPresetModal .modal .checkboxList .checkboxTitlePair[data-id="${settingGroup}"] input` + `#editPresetModal .modal .checkboxList .checkboxTitlePair[data-id="${settingGroup}"] input`, ).prop("checked", state.checkboxes.get(settingGroup)); }); $(`#editPresetModal .modal .presetType button`).removeClass("active"); $( - `#editPresetModal .modal .presetType button[value="${state.presetType}"]` + `#editPresetModal .modal .presetType button[value="${state.presetType}"]`, ).addClass("active"); $(`#editPresetModal .modal .partialPresetGroups`).removeClass("hidden"); if (state.presetType === "full") { @@ -202,11 +202,11 @@ function updateUI(): void { async function updateEditPresetUI(): Promise { $("#editPresetModal .modal label.changePresetToCurrentCheckbox input").prop( "checked", - state.setPresetToCurrent + state.setPresetToCurrent, ); if (state.setPresetToCurrent) { const presetId = $("#editPresetModal .modal").attr( - "data-preset-id" + "data-preset-id", ) as string; await initializeEditState(presetId); $("#editPresetModal .modal .inputs").removeClass("hidden"); @@ -226,11 +226,11 @@ async function apply(): Promise { const propPresetName = $("#editPresetModal .modal input").val() as string; const presetName = propPresetName.replaceAll(" ", "_"); const presetId = $("#editPresetModal .modal").attr( - "data-preset-id" + "data-preset-id", ) as string; const updateConfig = $("#editPresetModal .modal label input").prop( - "checked" + "checked", ) as boolean; const snapshotPresets = DB.getSnapshot()?.presets ?? []; @@ -246,7 +246,7 @@ async function apply(): Promise { if (noPartialGroupSelected) { Notifications.add( "At least one setting group must be active while saving partial presets", - 0 + 0, ); return; } @@ -289,7 +289,7 @@ async function apply(): Promise { Notifications.add( "Failed to add preset: " + response.body.message.replace(presetName, propPresetName), - -1 + -1, ); } else { Notifications.add("Preset added", 1, { @@ -307,7 +307,7 @@ async function apply(): Promise { } } else if (action === "edit") { const preset = snapshotPresets.find( - (preset: SnapshotPreset) => preset._id === presetId + (preset: SnapshotPreset) => preset._id === presetId, ) as SnapshotPreset; if (preset === undefined) { Notifications.add("Preset not found", -1); @@ -349,7 +349,7 @@ async function apply(): Promise { if (response.status !== 200) { Notifications.add( "Failed to remove preset: " + response.body.message, - -1 + -1, ); } else { Notifications.add("Preset removed", 1); @@ -370,7 +370,7 @@ function getSettingGroup(configFieldName: ConfigKey): ConfigGroupName { } function getPartialConfigChanges( - configChanges: Partial + configChanges: Partial, ): Partial { const activeConfigChanges: Partial = {}; const defaultConfig = getDefaultConfig(); @@ -427,7 +427,7 @@ async function setup(modalEl: HTMLElement): Promise { }); PresetTypeSchema.options.forEach((presetType) => { const presetOption = modalEl.querySelector( - `.presetType button[value="${presetType}"]` + `.presetType button[value="${presetType}"]`, ); if (presetOption === null) return; diff --git a/frontend/src/ts/modals/edit-profile.ts b/frontend/src/ts/modals/edit-profile.ts index d4e9a1395aa7..a389d4d26e64 100644 --- a/frontend/src/ts/modals/edit-profile.ts +++ b/frontend/src/ts/modals/edit-profile.ts @@ -44,14 +44,14 @@ function hide(): void { const bioInput: JQuery = $("#editProfileModal .bio"); const keyboardInput: JQuery = $( - "#editProfileModal .keyboard" + "#editProfileModal .keyboard", ); const twitterInput = $("#editProfileModal .twitter"); const githubInput = $("#editProfileModal .github"); const websiteInput = $("#editProfileModal .website"); const badgeIdsSelect = $("#editProfileModal .badgeSelectionContainer"); const showActivityOnPublicProfileInput = document.querySelector( - "#editProfileModal .editProfileShowActivityOnPublicProfile" + "#editProfileModal .editProfileShowActivityOnPublicProfile", ) as HTMLInputElement; const indicators = [ @@ -99,7 +99,7 @@ function hydrateInputs(): void {
none
- ` + `, ); $(".badgeSelectionItem").on("click", ({ currentTarget }) => { @@ -154,7 +154,7 @@ async function updateProfile(): Promise { ) { Notifications.add( `GitHub username exceeds maximum allowed length (${githubLengthLimit} characters).`, - -1 + -1, ); return; } @@ -166,7 +166,7 @@ async function updateProfile(): Promise { ) { Notifications.add( `Twitter username exceeds maximum allowed length (${twitterLengthLimit} characters).`, - -1 + -1, ); return; } @@ -226,7 +226,7 @@ function addValidation(element: JQuery, schema: Zod.Schema): InputIndicator { if (!validationResult.success) { indicator.show( "invalid", - validationResult.error.errors.map((err) => err.message).join(", ") + validationResult.error.errors.map((err) => err.message).join(", "), ); return; } diff --git a/frontend/src/ts/modals/edit-result-tags.ts b/frontend/src/ts/modals/edit-result-tags.ts index f6d2ee932ac8..6ce533a4349c 100644 --- a/frontend/src/ts/modals/edit-result-tags.ts +++ b/frontend/src/ts/modals/edit-result-tags.ts @@ -25,7 +25,7 @@ const state: State = { export function show( resultId: string, tags: string[], - source: "accountPage" | "resultPage" + source: "accountPage" | "resultPage", ): void { if (!ConnectionState.get()) { Notifications.add("You are offline", 0, { @@ -36,7 +36,7 @@ export function show( if (resultId === "") { Notifications.add( "Failed to show edit result tags modal: result id is empty", - -1 + -1, ); return; } @@ -64,7 +64,7 @@ function appendButtons(): void { if (buttonsEl === null) { Notifications.add( "Failed to append buttons to edit result tags modal: could not find buttons element", - -1 + -1, ); return; } @@ -123,7 +123,7 @@ async function save(): Promise { if (response.status !== 200) { Notifications.add( "Failed to update result tags: " + response.body.message, - -1 + -1, ); return; } diff --git a/frontend/src/ts/modals/edit-tag.ts b/frontend/src/ts/modals/edit-tag.ts index eacd882fd775..880531a57357 100644 --- a/frontend/src/ts/modals/edit-tag.ts +++ b/frontend/src/ts/modals/edit-tag.ts @@ -157,7 +157,7 @@ export function show( action: Action, id?: string, name?: string, - modalChain?: AnimatedModal + modalChain?: AnimatedModal, ): void { const options: ShowOptions = { modalChain, diff --git a/frontend/src/ts/modals/forgot-password.ts b/frontend/src/ts/modals/forgot-password.ts index 5c2066f2f0fd..cae09613f961 100644 --- a/frontend/src/ts/modals/forgot-password.ts +++ b/frontend/src/ts/modals/forgot-password.ts @@ -9,7 +9,7 @@ export function show(): void { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show forgot password popup: Captcha is not available. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); return; } @@ -24,7 +24,7 @@ export function show(): void { "forgotPasswordModal", async () => { await submit(); - } + }, ); }, }); @@ -64,7 +64,7 @@ async function submit(): Promise { if (result.status !== 200) { Notifications.add( "Failed to send password reset email: " + result.body.message, - -1 + -1, ); return; } diff --git a/frontend/src/ts/modals/google-sign-up.ts b/frontend/src/ts/modals/google-sign-up.ts index 5724456d321a..fc783ce3522d 100644 --- a/frontend/src/ts/modals/google-sign-up.ts +++ b/frontend/src/ts/modals/google-sign-up.ts @@ -30,14 +30,14 @@ function show(credential: UserCredential): void { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show google sign up popup: Captcha is not avilable. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); return; } CaptchaController.reset("googleSignUpModal"); CaptchaController.render( $("#googleSignUpModal .captcha")[0] as HTMLElement, - "googleSignUpModal" + "googleSignUpModal", ); enableInput(); disableButton(); @@ -77,7 +77,7 @@ async function apply(): Promise { if (!signedInUser) { Notifications.add( "Missing user credential. Please close the popup and try again.", - -1 + -1, ); return; } @@ -142,7 +142,7 @@ function disableButton(): void { } const nameInputEl = document.querySelector( - "#googleSignUpModal input" + "#googleSignUpModal input", ) as HTMLInputElement; function enableInput(): void { @@ -157,7 +157,7 @@ new ValidatedHtmlInputElement(nameInputEl, { schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), - { check: (data) => data.available || "Name not available" } + { check: (data) => data.available || "Name not available" }, ), debounceDelay: 1000, callback: (result) => { diff --git a/frontend/src/ts/modals/last-signed-out-result.ts b/frontend/src/ts/modals/last-signed-out-result.ts index 17117f40a564..5205f803b7d9 100644 --- a/frontend/src/ts/modals/last-signed-out-result.ts +++ b/frontend/src/ts/modals/last-signed-out-result.ts @@ -83,7 +83,7 @@ function fillData(): void { function fillGroup( groupClass: string, text: string | number, - html = false + html = false, ): void { if (html) { $(modal.getModal()).find(`.group.${groupClass} .val`).html(`${text}`); @@ -96,7 +96,7 @@ export function show(): void { if (!TestLogic.notSignedInLastResult) { Notifications.add( "Failed to show last signed out result modal: no last result", - -1 + -1, ); return; } diff --git a/frontend/src/ts/modals/mini-result-chart.ts b/frontend/src/ts/modals/mini-result-chart.ts index 6ed2b7e1f3ea..81388b1cc309 100644 --- a/frontend/src/ts/modals/mini-result-chart.ts +++ b/frontend/src/ts/modals/mini-result-chart.ts @@ -22,10 +22,10 @@ function updateData(data: ChartData): void { ChartController.miniResult.getDataset("error").data = data.err; const maxChartVal = Math.max( - ...[Math.max(...data.wpm), Math.max(...data.burst)] + ...[Math.max(...data.wpm), Math.max(...data.burst)], ); const minChartVal = Math.min( - ...[Math.min(...data.wpm), Math.min(...data.burst)] + ...[Math.min(...data.wpm), Math.min(...data.burst)], ); ChartController.miniResult.getScale("wpm").max = Math.round(maxChartVal); diff --git a/frontend/src/ts/modals/mobile-test-config.ts b/frontend/src/ts/modals/mobile-test-config.ts index cda2df05d02e..92ae57c65859 100644 --- a/frontend/src/ts/modals/mobile-test-config.ts +++ b/frontend/src/ts/modals/mobile-test-config.ts @@ -40,7 +40,7 @@ function update(): void { el.find(".numbers").removeClass("disabled"); } else if (Config.mode === "words") { el.find(`.wordsGroup button[data-words='${Config.words}']`).addClass( - "active" + "active", ); el.find(".punctuation").removeClass("disabled"); el.find(".numbers").removeClass("disabled"); @@ -50,7 +50,7 @@ function update(): void { } else { for (const ql of Config.quoteLength) { el.find(`.quoteGroup button[data-quoteLength='${ql}']`).addClass( - "active" + "active", ); } } diff --git a/frontend/src/ts/modals/pb-tables.ts b/frontend/src/ts/modals/pb-tables.ts index 3c45ea19bae5..f00ce6160f66 100644 --- a/frontend/src/ts/modals/pb-tables.ts +++ b/frontend/src/ts/modals/pb-tables.ts @@ -75,7 +75,7 @@ function update(mode: Mode): void { ${pb.lazyMode ? '' : ""} ${dateText} - ` + `, ); mode2memory = pb.mode2; }); diff --git a/frontend/src/ts/modals/practise-words.ts b/frontend/src/ts/modals/practise-words.ts index f8d58445a139..134a7126a189 100644 --- a/frontend/src/ts/modals/practise-words.ts +++ b/frontend/src/ts/modals/practise-words.ts @@ -17,12 +17,12 @@ const practiseModal = "#practiseWordsModal .modal"; function updateUI(): void { $(`${practiseModal} .group[data-id="missed"] button`).removeClass("active"); $( - `${practiseModal} .group[data-id="missed"] button[value="${state.missed}"]` + `${practiseModal} .group[data-id="missed"] button[value="${state.missed}"]`, ).addClass("active"); $(`${practiseModal} .group[data-id="slow"] button`).removeClass("active"); $( - `${practiseModal} .group[data-id="slow"] button[value="${state.slow}"]` + `${practiseModal} .group[data-id="slow"] button[value="${state.slow}"]`, ).addClass("active"); if (state.missed === "off" && !state.slow) { @@ -34,7 +34,7 @@ function updateUI(): void { async function setup(modalEl: HTMLElement): Promise { for (const button of modalEl.querySelectorAll( - ".group[data-id='missed'] button" + ".group[data-id='missed'] button", )) { button.addEventListener("click", (e) => { state.missed = (e.target as HTMLButtonElement).value as @@ -46,7 +46,7 @@ async function setup(modalEl: HTMLElement): Promise { } for (const button of modalEl.querySelectorAll( - ".group[data-id='slow'] button" + ".group[data-id='slow'] button", )) { button.addEventListener("click", (e) => { state.slow = (e.target as HTMLButtonElement).value === "true"; diff --git a/frontend/src/ts/modals/quote-approve.ts b/frontend/src/ts/modals/quote-approve.ts index 7d18370d461a..f017c7f27bc1 100644 --- a/frontend/src/ts/modals/quote-approve.ts +++ b/frontend/src/ts/modals/quote-approve.ts @@ -31,7 +31,7 @@ function updateList(): void { }
${format( new Date(quote.timestamp), - "dd MMM yyyy HH:mm" + "dd MMM yyyy HH:mm", )}
@@ -40,25 +40,25 @@ function updateList(): void { quoteEl.find(".source").on("input", () => { $(`#quoteApproveModal .quote[data-id=${index}] .undo`).prop( "disabled", - false + false, ); $(`#quoteApproveModal .quote[data-id=${index}] .approve`).addClass( - "hidden" + "hidden", ); $(`#quoteApproveModal .quote[data-id=${index}] .edit`).removeClass( - "hidden" + "hidden", ); }); quoteEl.find(".text").on("input", () => { $(`#quoteApproveModal .quote[data-id=${index}] .undo`).prop( "disabled", - false + false, ); $(`#quoteApproveModal .quote[data-id=${index}] .approve`).addClass( - "hidden" + "hidden", ); $(`#quoteApproveModal .quote[data-id=${index}] .edit`).removeClass( - "hidden" + "hidden", ); updateQuoteLength(index); }); @@ -82,7 +82,7 @@ function updateQuoteLength(index: number): void { $(`#quoteApproveModal .quote[data-id=${index}] .text`).val() as string )?.length; $(`#quoteApproveModal .quote[data-id=${index}] .length`).html( - `${len}` + `${len}`, ); if (len < 60) { $(`#quoteApproveModal .quote[data-id=${index}] .length`).addClass("red"); @@ -131,14 +131,14 @@ function resetButtons(index: number): void { function undoQuote(index: number): void { $(`#quoteApproveModal .quote[data-id=${index}] .text`).val( - quotes[index]?.text ?? "" + quotes[index]?.text ?? "", ); $(`#quoteApproveModal .quote[data-id=${index}] .source`).val( - quotes[index]?.source ?? "" + quotes[index]?.source ?? "", ); $(`#quoteApproveModal .quote[data-id=${index}] .undo`).prop("disabled", true); $(`#quoteApproveModal .quote[data-id=${index}] .approve`).removeClass( - "hidden" + "hidden", ); $(`#quoteApproveModal .quote[data-id=${index}] .edit`).addClass("hidden"); updateQuoteLength(index); @@ -195,10 +195,10 @@ async function refuseQuote(index: number, dbid: string): Promise { async function editQuote(index: number, dbid: string): Promise { if (!confirm("Are you sure?")) return; const editText = $( - `#quoteApproveModal .quote[data-id=${index}] .text` + `#quoteApproveModal .quote[data-id=${index}] .text`, ).val() as string; const editSource = $( - `#quoteApproveModal .quote[data-id=${index}] .source` + `#quoteApproveModal .quote[data-id=${index}] .source`, ).val() as string; const quote = $(`#quoteApproveModal .quotes .quote[data-id=${index}]`); quote.find("button").prop("disabled", true); @@ -223,7 +223,7 @@ async function editQuote(index: number, dbid: string): Promise { Notifications.add( `Quote edited and approved. ${response.body.message ?? ""}`, - 1 + 1, ); quotes.splice(index, 1); updateList(); diff --git a/frontend/src/ts/modals/quote-rate.ts b/frontend/src/ts/modals/quote-rate.ts index 3e27231a34f3..132eef7bf2c0 100644 --- a/frontend/src/ts/modals/quote-rate.ts +++ b/frontend/src/ts/modals/quote-rate.ts @@ -47,7 +47,7 @@ function getRatingAverage(quoteStats: QuoteStats): number { } export async function getQuoteStats( - quote?: Quote + quote?: Quote, ): Promise { if (!quote) { return; @@ -62,7 +62,7 @@ export async function getQuoteStats( if (response.status !== 200) { Notifications.add( "Failed to get quote ratings: " + response.body.message, - -1 + -1, ); return; } @@ -91,7 +91,7 @@ async function updateRatingStats(): Promise { if (!quoteStats) await getQuoteStats(); $("#quoteRateModal .ratingCount .val").text(quoteStats?.ratings ?? "0"); $("#quoteRateModal .ratingAverage .val").text( - quoteStats?.average?.toFixed(1) ?? "-" + quoteStats?.average?.toFixed(1) ?? "-", ); } @@ -158,7 +158,7 @@ async function submit(): Promise { if (response.status !== 200) { Notifications.add( "Failed to submit quote rating: " + response.body.message, - -1 + -1, ); return; } @@ -208,7 +208,7 @@ async function submit(): Promise { quoteStats.average = getRatingAverage(quoteStats); $(".pageTest #result #rateQuoteButton .rating").text( - quoteStats.average?.toFixed(1) + quoteStats.average?.toFixed(1), ); $(".pageTest #result #rateQuoteButton .icon").removeClass("far"); $(".pageTest #result #rateQuoteButton .icon").addClass("fas"); @@ -222,14 +222,14 @@ async function setup(modalEl: HTMLElement): Promise { for (const button of starButtons) { button.addEventListener("click", (e) => { const ratingValue = parseInt( - (e.currentTarget as HTMLElement).getAttribute("data-rating") as string + (e.currentTarget as HTMLElement).getAttribute("data-rating") as string, ); rating = ratingValue; refreshStars(); }); button.addEventListener("mouseenter", (e) => { const ratingHover = parseInt( - (e.currentTarget as HTMLElement).getAttribute("data-rating") as string + (e.currentTarget as HTMLElement).getAttribute("data-rating") as string, ); refreshStars(ratingHover); }); diff --git a/frontend/src/ts/modals/quote-report.ts b/frontend/src/ts/modals/quote-report.ts index dabbe57eaaaf..dd47b817d91c 100644 --- a/frontend/src/ts/modals/quote-report.ts +++ b/frontend/src/ts/modals/quote-report.ts @@ -22,12 +22,12 @@ const state: State = { export async function show( quoteId: number, - showOptions?: ShowOptions + showOptions?: ShowOptions, ): Promise { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show quote report popup: Captcha is not available. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); return; } @@ -38,7 +38,7 @@ export async function show( beforeAnimation: async () => { CaptchaController.render( document.querySelector("#quoteReportModal .g-recaptcha") as HTMLElement, - "quoteReportModal" + "quoteReportModal", ); const language = @@ -102,7 +102,7 @@ async function submitReport(): Promise { const characterDifference = comment.length - 250; if (characterDifference > 0) { Notifications.add( - `Report comment is ${characterDifference} character(s) too long` + `Report comment is ${characterDifference} character(s) too long`, ); return; } diff --git a/frontend/src/ts/modals/quote-search.ts b/frontend/src/ts/modals/quote-search.ts index 1d2c15df679d..12d02d3ee16a 100644 --- a/frontend/src/ts/modals/quote-search.ts +++ b/frontend/src/ts/modals/quote-search.ts @@ -30,7 +30,7 @@ let currentPageNumber = 1; function getSearchService( language: string, data: T[], - textExtractor: TextExtractor + textExtractor: TextExtractor, ): SearchService { if (language in searchServiceCache) { return searchServiceCache[language] as unknown as SearchService; @@ -46,17 +46,17 @@ function getSearchService( function applyQuoteLengthFilter(quotes: Quote[]): Quote[] { if (!modal.isOpen()) return []; const quoteLengthFilterValue = $( - "#quoteSearchModal .quoteLengthFilter" + "#quoteSearchModal .quoteLengthFilter", ).val() as string[]; if (quoteLengthFilterValue.length === 0) { return quotes; } const quoteLengthFilter = new Set( - quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)) + quoteLengthFilterValue.map((filterValue) => parseInt(filterValue, 10)), ); const filteredQuotes = quotes.filter((quote) => - quoteLengthFilter.has(quote.group) + quoteLengthFilter.has(quote.group), ); return filteredQuotes; @@ -81,7 +81,7 @@ function applyQuoteFavFilter(quotes: Quote[]): Quote[] { function buildQuoteSearchResult( quote: Quote, - matchedSearchTerms: string[] + matchedSearchTerms: string[], ): string { let lengthDesc; if (quote.length < 101) { @@ -147,13 +147,13 @@ async function updateResults(searchText: string): Promise { quotes, (quote: Quote) => { return `${quote.text} ${quote.id} ${quote.source}`; - } + }, ); const { results: matches, matchedQueryTerms } = quoteSearchService.query(searchText); const quotesToShow = applyQuoteLengthFilter( - applyQuoteFavFilter(searchText === "" ? quotes : matches) + applyQuoteFavFilter(searchText === "" ? quotes : matches), ); const resultsList = $("#quoteSearchResults"); @@ -182,7 +182,7 @@ async function updateResults(searchText: string): Promise { const endIndex = Math.min(currentPageNumber * pageSize, quotesToShow.length); $("#quoteSearchModal .pageInfo").html( - `${startIndex + 1} - ${endIndex} of ${quotesToShow.length}` + `${startIndex + 1} - ${endIndex} of ${quotesToShow.length}`, ); quotesToShow.slice(startIndex, endIndex).forEach((quote) => { @@ -202,7 +202,7 @@ async function updateResults(searchText: string): Promise { if (quoteId === undefined || isNaN(quoteId)) { Notifications.add( "Could not toggle quote favorite: quote id is not a number", - -1 + -1, ); return; } @@ -215,7 +215,7 @@ async function updateResults(searchText: string): Promise { if (quoteId === undefined || isNaN(quoteId)) { Notifications.add( "Could not open quote report modal: quote id is not a number", - -1 + -1, ); return; } @@ -286,7 +286,7 @@ export async function show(showOptions?: ShowOptions): Promise { }, afterAnimation: async () => { const quoteSearchInputValue = $( - "#quoteSearchModal input" + "#quoteSearchModal input", ).val() as string; currentPageNumber = 1; @@ -304,7 +304,7 @@ function hide(clearChain = false): void { function apply(val: number): void { if (isNaN(val)) { val = parseInt( - (document.getElementById("searchBox") as HTMLInputElement).value + (document.getElementById("searchBox") as HTMLInputElement).value, ); } if (val !== null && !isNaN(val) && val >= 0) { @@ -343,7 +343,7 @@ async function toggleFavoriteForQuote(quoteId: string): Promise { const alreadyFavorited = QuotesController.isQuoteFavorite(quote); const $button = $( - `#quoteSearchModal .searchResult[data-quote-id=${quoteId}] .textButton.favorite i` + `#quoteSearchModal .searchResult[data-quote-id=${quoteId}] .textButton.favorite i`, ); const dbSnapshot = DB.getSnapshot(); if (!dbSnapshot) return; @@ -358,7 +358,7 @@ async function toggleFavoriteForQuote(quoteId: string): Promise { Loader.hide(); const message = createErrorMessage( e, - "Failed to remove quote from favorites" + "Failed to remove quote from favorites", ); Notifications.add(message, -1); } @@ -412,7 +412,7 @@ async function setup(modalEl: HTMLElement): Promise { 0, { duration: 5, - } + }, ); return; } diff --git a/frontend/src/ts/modals/quote-submit.ts b/frontend/src/ts/modals/quote-submit.ts index 8ec80a2b140e..172f5e64bd7f 100644 --- a/frontend/src/ts/modals/quote-submit.ts +++ b/frontend/src/ts/modals/quote-submit.ts @@ -17,7 +17,7 @@ async function initDropdown(): Promise { for (const group of LanguageGroupNames) { if (group === "swiss_german") continue; $("#quoteSubmitModal .newQuoteLanguage").append( - `` + ``, ); } dropdownReady = true; @@ -57,7 +57,7 @@ export async function show(showOptions: ShowOptions): Promise { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show quote submit popup: Captcha is not available. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); return; } @@ -69,7 +69,7 @@ export async function show(showOptions: ShowOptions): Promise { afterAnimation: async () => { CaptchaController.render( document.querySelector("#quoteSubmitModal .g-recaptcha") as HTMLElement, - "submitQuote" + "submitQuote", ); await initDropdown(); @@ -78,7 +78,7 @@ export async function show(showOptions: ShowOptions): Promise { }); $("#quoteSubmitModal .newQuoteLanguage").val( - Strings.removeLanguageSize(Config.language) + Strings.removeLanguageSize(Config.language), ); $("#quoteSubmitModal .newQuoteLanguage").trigger("change"); $("#quoteSubmitModal input").val(""); diff --git a/frontend/src/ts/modals/register-captcha.ts b/frontend/src/ts/modals/register-captcha.ts index 2fb7bbd9fa87..55bf621c0a64 100644 --- a/frontend/src/ts/modals/register-captcha.ts +++ b/frontend/src/ts/modals/register-captcha.ts @@ -11,7 +11,7 @@ export async function show(): Promise { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show register popup: Captcha is not available. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); resolve(undefined); return; @@ -29,7 +29,7 @@ export async function show(): Promise { (token) => { resolve(token); hide(); - } + }, ); }, }); diff --git a/frontend/src/ts/modals/save-custom-text.ts b/frontend/src/ts/modals/save-custom-text.ts index cde6e32dce73..1f5771526123 100644 --- a/frontend/src/ts/modals/save-custom-text.ts +++ b/frontend/src/ts/modals/save-custom-text.ts @@ -31,7 +31,7 @@ const validatedInput = new ValidatedHtmlInputElement( }), isValid: async (value) => { const checkbox = $("#saveCustomTextModal .isLongText").prop( - "checked" + "checked", ) as boolean; const names = CustomText.getCustomTextNames(checkbox); return !names.includes(value) ? true : "Duplicate name"; @@ -43,7 +43,7 @@ const validatedInput = new ValidatedHtmlInputElement( $("#saveCustomTextModal button.save").prop("disabled", true); } }, - } + }, ); export async function show(options: ShowOptions): Promise { @@ -62,7 +62,7 @@ export async function show(options: ShowOptions): Promise { function save(): boolean { const name = $("#saveCustomTextModal .textName").val() as string; const checkbox = $("#saveCustomTextModal .isLongText").prop( - "checked" + "checked", ) as boolean; if (!name) { diff --git a/frontend/src/ts/modals/saved-texts.ts b/frontend/src/ts/modals/saved-texts.ts index e2bd4de6a0e7..24869352f7af 100644 --- a/frontend/src/ts/modals/saved-texts.ts +++ b/frontend/src/ts/modals/saved-texts.ts @@ -72,7 +72,7 @@ async function fill(): Promise { showPopup("deleteCustomTextLong", [name], { modalChain: modal as AnimatedModal, }); - } + }, ); $("#savedTextsModal .listLong .savedLongText .button.resetProgress").on( @@ -88,7 +88,7 @@ async function fill(): Promise { showPopup("resetProgressCustomTextLong", [name], { modalChain: modal as AnimatedModal, }); - } + }, ); $("#savedTextsModal .list .savedText .button.name").on("click", (e) => { @@ -105,7 +105,7 @@ async function fill(): Promise { CustomTextState.setCustomTextName(name, true); const text = getSavedText(name, true); hide({ modalChainData: { text, long: true } }); - } + }, ); } diff --git a/frontend/src/ts/modals/share-custom-theme.ts b/frontend/src/ts/modals/share-custom-theme.ts index 657cc49692ea..5fbfb8794bd9 100644 --- a/frontend/src/ts/modals/share-custom-theme.ts +++ b/frontend/src/ts/modals/share-custom-theme.ts @@ -31,8 +31,8 @@ async function generateUrl(): Promise { c: ThemeController.colorVars.map( (color) => $(`.pageSettings .tabContent.customTheme #${color}[type='color']`).attr( - "value" - ) as string + "value", + ) as string, ), }; @@ -60,7 +60,7 @@ async function copy(): Promise { 0, { duration: 5, - } + }, ); void urlModal.show({ modalChain: modal, diff --git a/frontend/src/ts/modals/share-test-settings.ts b/frontend/src/ts/modals/share-test-settings.ts index 914c93e80c91..c510bb4af965 100644 --- a/frontend/src/ts/modals/share-test-settings.ts +++ b/frontend/src/ts/modals/share-test-settings.ts @@ -9,7 +9,7 @@ import { Mode, Mode2 } from "@monkeytype/schemas/shared"; function getCheckboxValue(checkbox: string): boolean { return $(`#shareTestSettingsModal label.${checkbox} input`).prop( - "checked" + "checked", ) as boolean; } @@ -21,13 +21,13 @@ type SharedTestSettings = [ boolean | null, string | null, Difficulty | null, - FunboxName[] | null + FunboxName[] | null, ]; function updateURL(): void { const baseUrl = location.origin + "?testSettings="; const settings: SharedTestSettings = new Array(8).fill( - null + null, ) as SharedTestSettings; const settingsMap = [ diff --git a/frontend/src/ts/modals/simple-modals.ts b/frontend/src/ts/modals/simple-modals.ts index 3cc424b10cc5..b7e76dbed64d 100644 --- a/frontend/src/ts/modals/simple-modals.ts +++ b/frontend/src/ts/modals/simple-modals.ts @@ -117,7 +117,7 @@ type ReauthenticateOptions = { }; function getPreferredAuthenticationMethod( - exclude?: AuthMethod + exclude?: AuthMethod, ): AuthMethod | undefined { const authMethods = ["password", "github.com", "google.com"] as AuthMethod[]; const filteredMethods = authMethods.filter((it) => it !== exclude); @@ -142,13 +142,13 @@ function isUsingGoogleAuthentication(): boolean { function isUsingAuthentication(authProvider: AuthMethod): boolean { return ( getAuthenticatedUser()?.providerData.some( - (p) => p.providerId === authProvider + (p) => p.providerId === authProvider, ) || false ); } async function reauthenticate( - options: ReauthenticateOptions + options: ReauthenticateOptions, ): Promise { if (!isAuthAvailable()) { return { @@ -185,7 +185,7 @@ async function reauthenticate( } const credential = EmailAuthProvider.credential( user.email as string, - options.password + options.password, ); await reauthenticateWithCredential(user, credential); } else { @@ -261,7 +261,7 @@ list.updateEmail = new SimpleModal({ _thisPopup, password, email, - emailConfirm + emailConfirm, ): Promise => { if (email !== emailConfirm) { return { @@ -444,7 +444,7 @@ list.removePasswordAuth = new SimpleModal({ } catch (e) { const message = createErrorMessage( e, - "Failed to remove password authentication" + "Failed to remove password authentication", ); return { status: -1, @@ -482,7 +482,7 @@ list.updateName = new SimpleModal({ schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), - { check: (data) => data.available || "Name not available" } + { check: (data) => data.available || "Name not available" }, ), debounceDelay: 1000, }, @@ -567,7 +567,7 @@ list.updatePassword = new SimpleModal({ _thisPopup, previousPass, newPassword, - newPassConfirm + newPassConfirm, ): Promise => { if (newPassword !== newPassConfirm) { return { @@ -651,7 +651,7 @@ list.addPasswordAuth = new SimpleModal({ email, emailConfirm, password, - passConfirm + passConfirm, ): Promise => { if (email !== emailConfirm) { return { @@ -681,7 +681,7 @@ list.addPasswordAuth = new SimpleModal({ } catch (e) { const message = createErrorMessage( e, - "Failed to add password authentication" + "Failed to add password authentication", ); return { status: -1, @@ -1078,7 +1078,7 @@ list.resetProgressCustomTextLong = new SimpleModal({ CustomText.setCustomTextLongProgress(_thisPopup.parameters[0] as string, 0); const text = CustomText.getCustomText( _thisPopup.parameters[0] as string, - true + true, ); CustomText.setText(text); return { @@ -1119,7 +1119,7 @@ list.updateCustomTheme = new SimpleModal({ } const customTheme = snapshot.customThemes?.find( - (t) => t._id === _thisPopup.parameters[0] + (t) => t._id === _thisPopup.parameters[0], ); if (customTheme === undefined) { return { @@ -1133,8 +1133,8 @@ list.updateCustomTheme = new SimpleModal({ for (const color of ThemeController.colorVars) { newColors.push( $( - `.pageSettings .tabContent.customTheme #${color}[type='color']` - ).attr("value") as string + `.pageSettings .tabContent.customTheme #${color}[type='color']`, + ).attr("value") as string, ); } } else { @@ -1165,7 +1165,7 @@ list.updateCustomTheme = new SimpleModal({ if (!snapshot) return; const customTheme = snapshot.customThemes?.find( - (t) => t._id === _thisPopup.parameters[0] + (t) => t._id === _thisPopup.parameters[0], ); if (!customTheme) return; (_thisPopup.inputs[0] as TextInput).initVal = customTheme.name; @@ -1201,7 +1201,7 @@ list.devGenerateData = new SimpleModal({ oninput: (event): void => { const target = event.target as HTMLInputElement; const span = document.querySelector( - "#devGenerateData_1 + span" + "#devGenerateData_1 + span", ) as HTMLInputElement; span.innerHTML = `if checked, user will be created with ${target.value}@example.com and password: password`; return; @@ -1253,7 +1253,7 @@ list.devGenerateData = new SimpleModal({ firstTestTimestamp, lastTestTimestamp, minTestsPerDay, - maxTestsPerDay + maxTestsPerDay, ): Promise => { const request: GenerateDataRequest = { username, @@ -1312,7 +1312,7 @@ list.lbGoToPage = new SimpleModal({ export function showPopup( key: PopupKey, showParams = [] as string[], - showOptions: ShowOptions = {} + showOptions: ShowOptions = {}, ): void { const popup = list[key]; if (popup === undefined) { @@ -1390,7 +1390,7 @@ $(".pageSettings").on( const $parentElement = $(e.currentTarget).parent(".customTheme.button"); const customThemeId = $parentElement.attr("customThemeId") as string; showPopup("deleteCustomTheme", [customThemeId]); - } + }, ); $(".pageSettings").on( @@ -1402,7 +1402,7 @@ $(".pageSettings").on( showPopup("updateCustomTheme", [customThemeId], { focusFirstInput: "focusAndSelect", }); - } + }, ); $(".pageSettings").on( @@ -1410,5 +1410,5 @@ $(".pageSettings").on( ".section[data-config-name='fontFamily'] button[data-config-value='custom']", () => { showPopup("applyCustomFont"); - } + }, ); diff --git a/frontend/src/ts/modals/streak-hour-offset.ts b/frontend/src/ts/modals/streak-hour-offset.ts index e272eeb6ba8c..b81cc48e9784 100644 --- a/frontend/src/ts/modals/streak-hour-offset.ts +++ b/frontend/src/ts/modals/streak-hour-offset.ts @@ -36,7 +36,7 @@ export function show(): void { function updatePreview(): void { const inputValue = parseInt( modal.getModal().querySelector("input")?.value as string, - 10 + 10, ); const preview = modal.getModal().querySelector(".preview") as HTMLElement; @@ -68,7 +68,7 @@ function hide(): void { async function apply(): Promise { const value = parseInt( modal.getModal().querySelector("input")?.value as string, - 10 + 10, ); if (isNaN(value)) { @@ -90,7 +90,7 @@ async function apply(): Promise { if (response.status !== 200) { Notifications.add( "Failed to set streak hour offset: " + response.body.message, - -1 + -1, ); } else { Notifications.add("Streak hour offset set", 1); diff --git a/frontend/src/ts/modals/support.ts b/frontend/src/ts/modals/support.ts index afb7da8def1b..e1b0bb770edf 100644 --- a/frontend/src/ts/modals/support.ts +++ b/frontend/src/ts/modals/support.ts @@ -13,7 +13,7 @@ const modal = new AnimatedModal({ { subgroupOverride: "enableAds" }, { modalChain: modal, - } + }, ); }); }, diff --git a/frontend/src/ts/modals/user-report.ts b/frontend/src/ts/modals/user-report.ts index a74ecccd8d7d..972293ad3517 100644 --- a/frontend/src/ts/modals/user-report.ts +++ b/frontend/src/ts/modals/user-report.ts @@ -35,7 +35,7 @@ export async function show(options: ShowOptions): Promise { if (!CaptchaController.isCaptchaAvailable()) { Notifications.add( "Could not show user report popup: Captcha is not available. This could happen due to a blocked or failed network request. Please refresh the page or contact support if this issue persists.", - -1 + -1, ); return; } @@ -46,7 +46,7 @@ export async function show(options: ShowOptions): Promise { beforeAnimation: async (modalEl) => { CaptchaController.render( modalEl.querySelector(".g-recaptcha") as HTMLElement, - "userReportModal" + "userReportModal", ); const { name } = options; @@ -102,7 +102,7 @@ async function submitReport(): Promise { 0, { duration: 10, - } + }, ); return; } @@ -110,7 +110,7 @@ async function submitReport(): Promise { const characterDifference = comment.length - 250; if (characterDifference > 0) { Notifications.add( - `Report comment is ${characterDifference} character(s) too long` + `Report comment is ${characterDifference} character(s) too long`, ); return; } diff --git a/frontend/src/ts/modals/version-history.ts b/frontend/src/ts/modals/version-history.ts index a091eabb88f7..bc569b0652ab 100644 --- a/frontend/src/ts/modals/version-history.ts +++ b/frontend/src/ts/modals/version-history.ts @@ -29,7 +29,7 @@ export function show(): void { //replace links with a tags body = body.replace( /\[(.*?)\]\((.*?)\)/g, - '$1' + '$1', ); $("#versionHistoryModal .modal .releases").append(` @@ -37,7 +37,7 @@ export function show(): void {
${release.name}
${format( new Date(release.published_at), - "dd MMM yyyy" + "dd MMM yyyy", )}
${body}
@@ -48,7 +48,7 @@ export function show(): void { .catch((e: unknown) => { const msg = createErrorMessage(e, "Failed to fetch version history"); $("#versionHistoryModal .modal").html( - `
${msg}${msg} { for (const [presetId, preset] of Object.entries(presets)) { $("#wordFilterModal .presetInput").append( - `` + ``, ); } } @@ -176,12 +176,12 @@ async function filter(language: Language): Promise { const filteredWords = []; const { data: languageWordList, error } = await tryCatch( - JSONData.getLanguage(language) + JSONData.getLanguage(language), ); if (error) { Notifications.add( Misc.createErrorMessage(error, "Failed to filter language words"), - -1 + -1, ); return []; } @@ -225,7 +225,7 @@ async function apply(set: boolean): Promise { } const customText = filteredWords.join( - CustomText.getPipeDelimiter() ? "|" : " " + CustomText.getPipeDelimiter() ? "|" : " ", ); hide({ @@ -268,13 +268,13 @@ async function setup(): Promise { presetToApply .getIncludeString(layout) .map((x) => x[0]) - .join(" ") + .join(" "), ); $("#wordExcludeInput").val( presetToApply .getExcludeString(layout) .map((x) => x[0]) - .join(" ") + .join(" "), ); }); $("#wordFilterModal button.addButton").on("click", () => { diff --git a/frontend/src/ts/observables/config-event.ts b/frontend/src/ts/observables/config-event.ts index 6cfb1f8b9109..3856d711f3d8 100644 --- a/frontend/src/ts/observables/config-event.ts +++ b/frontend/src/ts/observables/config-event.ts @@ -13,7 +13,7 @@ type SubscribeFunction = ( newValue?: ConfigValue, nosave?: boolean, previousValue?: ConfigValue, - fullConfig?: Config + fullConfig?: Config, ) => void; const subscribers: SubscribeFunction[] = []; @@ -27,7 +27,7 @@ export function dispatch( newValue?: ConfigValue, nosave?: boolean, previousValue?: ConfigValue, - fullConfig?: Config + fullConfig?: Config, ): void { subscribers.forEach((fn) => { try { diff --git a/frontend/src/ts/observables/google-sign-up-event.ts b/frontend/src/ts/observables/google-sign-up-event.ts index d995a251da10..07e8d0b31b90 100644 --- a/frontend/src/ts/observables/google-sign-up-event.ts +++ b/frontend/src/ts/observables/google-sign-up-event.ts @@ -2,7 +2,7 @@ import { UserCredential } from "firebase/auth"; type SubscribeFunction = ( signedInUser: UserCredential, - isNewUser: boolean + isNewUser: boolean, ) => void; const subscribers: SubscribeFunction[] = []; @@ -13,7 +13,7 @@ export function subscribe(fn: SubscribeFunction): void { export function dispatch( signedInUser: UserCredential, - isNewUser: boolean + isNewUser: boolean, ): void { subscribers.forEach((fn) => { try { diff --git a/frontend/src/ts/observables/keymap-event.ts b/frontend/src/ts/observables/keymap-event.ts index d3c5d47faa07..48fa8b4a9d2b 100644 --- a/frontend/src/ts/observables/keymap-event.ts +++ b/frontend/src/ts/observables/keymap-event.ts @@ -1,7 +1,7 @@ type SubscribeFunction = ( mode: "highlight" | "flash", key: string, - correct?: boolean + correct?: boolean, ) => void; const subscribers: SubscribeFunction[] = []; diff --git a/frontend/src/ts/observables/notification-event.ts b/frontend/src/ts/observables/notification-event.ts index ea4fdf9cd759..cf05dc18b12e 100644 --- a/frontend/src/ts/observables/notification-event.ts +++ b/frontend/src/ts/observables/notification-event.ts @@ -1,7 +1,7 @@ type SubscribeFunction = ( message: string, level: number, - customTitle?: string + customTitle?: string, ) => void; const subscribers: SubscribeFunction[] = []; @@ -13,7 +13,7 @@ export function subscribe(fn: SubscribeFunction): void { export function dispatch( message: string, level: number, - customTitle?: string + customTitle?: string, ): void { subscribers.forEach((fn) => { try { diff --git a/frontend/src/ts/pages/about.ts b/frontend/src/ts/pages/about.ts index 0656a87f913e..6761be0b7a5a 100644 --- a/frontend/src/ts/pages/about.ts +++ b/frontend/src/ts/pages/about.ts @@ -26,7 +26,7 @@ function updateStatsAndHistogram(): void { if (speedHistogramResponseData) { void ChartController.globalSpeedHistogram.updateColors(); const bucketedSpeedStats = getHistogramDataBucketed( - speedHistogramResponseData + speedHistogramResponseData, ); ChartController.globalSpeedHistogram.data.labels = bucketedSpeedStats.labels; @@ -43,46 +43,46 @@ function updateStatsAndHistogram(): void { }); $(".pageAbout #totalTimeTypingStat .val").text( - timeTypingDuration.years?.toString() ?? "" + timeTypingDuration.years?.toString() ?? "", ); $(".pageAbout #totalTimeTypingStat .valSmall").text("years"); $(".pageAbout #totalTimeTypingStat").attr( "aria-label", - numberWithSpaces(Math.round(secondsRounded / 3600)) + " hours" + numberWithSpaces(Math.round(secondsRounded / 3600)) + " hours", ); const startedWithMagnitude = getNumberWithMagnitude( - typingStatsResponseData.testsStarted + typingStatsResponseData.testsStarted, ); $(".pageAbout #totalStartedTestsStat .val").text( startedWithMagnitude.rounded < 10 ? startedWithMagnitude.roundedTo2 - : startedWithMagnitude.rounded + : startedWithMagnitude.rounded, ); $(".pageAbout #totalStartedTestsStat .valSmall").text( - startedWithMagnitude.orderOfMagnitude + startedWithMagnitude.orderOfMagnitude, ); $(".pageAbout #totalStartedTestsStat").attr( "aria-label", - numberWithSpaces(typingStatsResponseData.testsStarted) + " tests" + numberWithSpaces(typingStatsResponseData.testsStarted) + " tests", ); const completedWIthMagnitude = getNumberWithMagnitude( - typingStatsResponseData.testsCompleted + typingStatsResponseData.testsCompleted, ); $(".pageAbout #totalCompletedTestsStat .val").text( completedWIthMagnitude.rounded < 10 ? completedWIthMagnitude.roundedTo2 - : completedWIthMagnitude.rounded + : completedWIthMagnitude.rounded, ); $(".pageAbout #totalCompletedTestsStat .valSmall").text( - completedWIthMagnitude.orderOfMagnitude + completedWIthMagnitude.orderOfMagnitude, ); $(".pageAbout #totalCompletedTestsStat").attr( "aria-label", - numberWithSpaces(typingStatsResponseData.testsCompleted) + " tests" + numberWithSpaces(typingStatsResponseData.testsCompleted) + " tests", ); } } @@ -109,7 +109,7 @@ async function getStatsAndHistogramData(): Promise { } else { Notifications.add( `Failed to get global speed stats for histogram: ${speedStats.body.message}`, - -1 + -1, ); } const typingStats = await Ape.public.getTypingStats(); @@ -118,29 +118,29 @@ async function getStatsAndHistogramData(): Promise { } else { Notifications.add( `Failed to get global typing stats: ${speedStats.body.message}`, - -1 + -1, ); } } async function fill(): Promise { const { data: supporters, error: supportersError } = await tryCatch( - JSONData.getSupportersList() + JSONData.getSupportersList(), ); if (supportersError) { Notifications.add( Misc.createErrorMessage(supportersError, "Failed to get supporters"), - -1 + -1, ); } const { data: contributors, error: contributorsError } = await tryCatch( - JSONData.getContributorsList() + JSONData.getContributorsList(), ); if (contributorsError) { Notifications.add( Misc.createErrorMessage(contributorsError, "Failed to get contributors"), - -1 + -1, ); } @@ -176,7 +176,7 @@ function getHistogramDataBucketed(data: Record): { const labels: string[] = []; const keys = Object.keys(data).sort( - (a, b) => parseInt(a, 10) - parseInt(b, 10) + (a, b) => parseInt(a, 10) - parseInt(b, 10), ); // for (let i = 0; i < keys.length; i++) { for (const [i, key] of keys.entries()) { diff --git a/frontend/src/ts/pages/account-settings.ts b/frontend/src/ts/pages/account-settings.ts index 402b4bec8ee6..534ed19bdfa1 100644 --- a/frontend/src/ts/pages/account-settings.ts +++ b/frontend/src/ts/pages/account-settings.ts @@ -41,13 +41,13 @@ function updateAuthenticationSections(): void { if (user === null) return; const passwordProvider = user.providerData.some( - (provider) => provider.providerId === "password" + (provider) => provider.providerId === "password", ); const googleProvider = user.providerData.some( - (provider) => provider.providerId === "google.com" + (provider) => provider.providerId === "google.com", ); const githubProvider = user.providerData.some( - (provider) => provider.providerId === "github.com" + (provider) => provider.providerId === "github.com", ); if (passwordProvider) { @@ -142,7 +142,7 @@ function updateTabs(): void { async () => { pageElement.find(".tab").removeClass("active"); pageElement.find(`.tab[data-tab="${state.tab}"]`).addClass("active"); - } + }, ); pageElement.find("button").removeClass("active"); pageElement.find(`button[data-tab="${state.tab}"]`).addClass("active"); @@ -201,7 +201,7 @@ $(".page.pageAccountSettings").on("click", ".tabs button", (event) => { }); $( - ".page.pageAccountSettings .section.discordIntegration .getLinkAndGoToOauth" + ".page.pageAccountSettings .section.discordIntegration .getLinkAndGoToOauth", ).on("click", () => { Loader.show(); void Ape.users.getDiscordOAuth().then((response) => { @@ -210,7 +210,7 @@ $( } else { Notifications.add( "Failed to get OAuth from discord: " + response.body.message, - -1 + -1, ); } }); diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index 0f5f24cfb4be..897aa745798b 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -78,7 +78,7 @@ function buildResultRow(result: SnapshotResult): HTMLTableRowElement { let icons = ``; if (diff === "normal") { @@ -109,7 +109,7 @@ function buildResultRow(result: SnapshotResult): HTMLTableRowElement { icons += ``; } @@ -228,7 +228,7 @@ async function fillContent(): Promise { TestActivity.init( testActivityEl as HTMLElement, snapshot.testActivity, - new Date(snapshot.addedAt) + new Date(snapshot.addedAt), ); void ResultBatches.update(); @@ -321,7 +321,7 @@ async function fillContent(): Promise { let timefilter: Mode2<"time"> | "custom" = "custom"; if ( ["15", "30", "60", "120"].includes( - `${result.mode2}` //legacy results could have a number in mode2 + `${result.mode2}`, //legacy results could have a number in mode2 ) ) { timefilter = `${result.mode2}` as `${number}`; @@ -329,7 +329,7 @@ async function fillContent(): Promise { if ( !ResultFilters.getFilter( "time", - timefilter as "custom" | "15" | "30" | "60" | "120" + timefilter as "custom" | "15" | "30" | "60" | "120", ) ) { if (filterDebug) { @@ -341,7 +341,7 @@ async function fillContent(): Promise { let wordfilter: Mode2Custom<"words"> = "custom"; if ( ["10", "25", "50", "100", "200"].includes( - `${result.mode2}` //legacy results could have a number in mode2 + `${result.mode2}`, //legacy results could have a number in mode2 ) ) { wordfilter = `${result.mode2}` as `${number}`; @@ -349,7 +349,7 @@ async function fillContent(): Promise { if ( !ResultFilters.getFilter( "words", - wordfilter as "custom" | "10" | "25" | "50" | "100" + wordfilter as "custom" | "10" | "25" | "50" | "100", ) ) { if (filterDebug) { @@ -507,7 +507,7 @@ async function fillContent(): Promise { } catch (e) { Notifications.add( "Something went wrong when filtering. Resetting filters.", - 0 + 0, ); console.log(result); console.error(e); @@ -560,7 +560,7 @@ async function fillContent(): Promise { const bucketSize = typingSpeedUnit.histogramDataBucketSize; const bucket = Math.floor( - Math.round(typingSpeedUnit.fromWpm(result.wpm)) / bucketSize + Math.round(typingSpeedUnit.fromWpm(result.wpm)) / bucketSize, ); //grow array if needed @@ -679,7 +679,7 @@ async function fillContent(): Promise { historyTable.setData(filteredResults); $(".pageAccount .group.history table thead tr td:nth-child(2)").text( - Config.typingSpeedUnit + Config.typingSpeedUnit, ); await Misc.sleep(0); @@ -711,7 +711,7 @@ async function fillContent(): Promise { activityChartData_avgWpm.push({ x: dateInt, y: Numbers.roundTo2( - typingSpeedUnit.fromWpm(dataPoint.totalWpm) / dataPoint.amount + typingSpeedUnit.fromWpm(dataPoint.totalWpm) / dataPoint.amount, ), }); } @@ -879,7 +879,7 @@ async function fillContent(): Promise { } $(".pageAccount .timeTotalFiltered .val").text( - DateTime.secondsToString(Math.round(totalSecondsFiltered), true, true) + DateTime.secondsToString(Math.round(totalSecondsFiltered), true, true), ); const speedUnit = Config.typingSpeedUnit; @@ -889,14 +889,14 @@ async function fillContent(): Promise { $(".pageAccount .averageWpm .title").text(`average ${speedUnit}`); $(".pageAccount .averageWpm .val").text( - Format.typingSpeed(totalWpm / testCount) + Format.typingSpeed(totalWpm / testCount), ); $(".pageAccount .averageWpm10 .title").text( - `average ${speedUnit} (last 10 tests)` + `average ${speedUnit} (last 10 tests)`, ); $(".pageAccount .averageWpm10 .val").text( - Format.typingSpeed(wpmLast10total / last10) + Format.typingSpeed(wpmLast10total / last10), ); $(".pageAccount .highestRaw .title").text(`highest raw ${speedUnit}`); @@ -904,14 +904,14 @@ async function fillContent(): Promise { $(".pageAccount .averageRaw .title").text(`average raw ${speedUnit}`); $(".pageAccount .averageRaw .val").text( - Format.typingSpeed(rawWpm.total / rawWpm.count) + Format.typingSpeed(rawWpm.total / rawWpm.count), ); $(".pageAccount .averageRaw10 .title").text( - `average raw ${speedUnit} (last 10 tests)` + `average raw ${speedUnit} (last 10 tests)`, ); $(".pageAccount .averageRaw10 .val").text( - Format.typingSpeed(rawWpm.last10Total / rawWpm.last10Count) + Format.typingSpeed(rawWpm.last10Total / rawWpm.last10Count), ); $(".pageAccount .highestWpm .mode").html(topMode); @@ -928,19 +928,19 @@ async function fillContent(): Promise { $(".pageAccount .highestCons .val").text(Format.percentage(topCons)); $(".pageAccount .avgCons .val").text( - Format.percentage(totalCons / consCount) + Format.percentage(totalCons / consCount), ); $(".pageAccount .avgCons10 .val").text( - Format.percentage(totalCons10 / Math.min(last10, consCount)) + Format.percentage(totalCons10 / Math.min(last10, consCount)), ); } $(".pageAccount .testsStarted .val").text(`${testCount + testRestarts}`); $(".pageAccount .testsCompleted .val").text( `${testCount}(${Math.floor( - (testCount / (testCount + testRestarts)) * 100 - )}%)` + (testCount / (testCount + testRestarts)) * 100, + )}%)`, ); $(".pageAccount .testsCompleted .avgres").text(` @@ -957,7 +957,7 @@ async function fillContent(): Promise { $(".pageAccount .group.chart .below .text").text( `Speed change per hour spent typing: ${ plus + Format.typingSpeed(wpmChangePerHour, { showDecimalPlaces: true }) - } ${Config.typingSpeedUnit}` + } ${Config.typingSpeedUnit}`, ); } $(".pageAccount .estimatedWordsTyped .val").text(totalEstimatedWords); @@ -1018,7 +1018,7 @@ export function updateTagsForResult(resultId: string, tagIds: string[]): void { } const el = $( - `.pageAccount .resultEditTagsButton[data-result-id='${resultId}']` + `.pageAccount .resultEditTagsButton[data-result-id='${resultId}']`, ); el.attr("data-tags", JSON.stringify(tagIds)); @@ -1121,7 +1121,7 @@ $(".pageAccount").on("click", ".miniResultChartButton", async (event) => { //update local cache result.chartData = chartData; const dbResult = DB.getSnapshot()?.results?.find( - (it) => it._id === result._id + (it) => it._id === result._id, ); if (dbResult !== undefined) { dbResult["chartData"] = result.chartData; @@ -1130,7 +1130,7 @@ $(".pageAccount").on("click", ".miniResultChartButton", async (event) => { if (response.body.data.chartData === "toolong") { target.attr( "aria-label", - "Graph history is not available for long tests" + "Graph history is not available for long tests", ); target.attr("data-baloon-pos", "up"); target.addClass("disabled"); @@ -1150,7 +1150,7 @@ $(".pageAccount .group.topFilters, .pageAccount .filterButtons").on( setTimeout(() => { void update(); }, 0); - } + }, ); $(".pageAccount .group.presetFilterButtons").on( @@ -1159,7 +1159,7 @@ $(".pageAccount .group.presetFilterButtons").on( async (e) => { await ResultFilters.setFilterPreset($(e.target).data("id") as string); void update(); - } + }, ); $(".pageAccount .content .group.aboveHistory .exportCSV").on("click", () => { @@ -1178,7 +1178,7 @@ $(".pageAccount .profile").on("click", ".details .copyLink", () => { }, function () { alert("Failed to copy using the Clipboard API. Here's the link: " + url); - } + }, ); }); @@ -1214,7 +1214,7 @@ export const page = new Page({ loadingPromise: async () => { if (DB.getSnapshot() === null) { throw new Error( - "Looks like your account data didn't download correctly. Please refresh the page.
If this error persists, please contact support." + "Looks like your account data didn't download correctly. Please refresh the page.
If this error persists, please contact support.", ); } return downloadResults(); @@ -1240,13 +1240,13 @@ export const page = new Page({ await Misc.sleep(0); testActivityEl = document.querySelector( - ".page.pageAccount .testActivity" + ".page.pageAccount .testActivity", ) as HTMLElement; TestActivity.initYearSelector( testActivityEl, "current", - snapshot !== undefined ? new Date(snapshot.addedAt).getFullYear() : 2020 + snapshot !== undefined ? new Date(snapshot.addedAt).getFullYear() : 2020, ); if (historyTable === undefined) { @@ -1266,7 +1266,7 @@ export const page = new Page({ $(".pageAccount .content .accountVerificatinNotice").remove(); if (getAuthenticatedUser()?.emailVerified === false) { $(".pageAccount .content").prepend( - `

Your email address is still not verified

` + `

Your email address is still not verified

`, ); } ResultBatches.showOrHideIfNeeded(); diff --git a/frontend/src/ts/pages/friends.ts b/frontend/src/ts/pages/friends.ts index 0f7152e13022..15f2eaccdafd 100644 --- a/frontend/src/ts/pages/friends.ts +++ b/frontend/src/ts/pages/friends.ts @@ -39,7 +39,7 @@ let pendingRequests: Connection[] | undefined; let friendsList: Friend[] | undefined; export function getReceiverUid( - connection: Pick + connection: Pick, ): string { const me = getAuthenticatedUser(); if (me === null) @@ -78,7 +78,7 @@ const addFriendModal = new SimpleModal({ schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), - { check: (data) => !data.available || "Unknown user" } + { check: (data) => !data.available || "Unknown user" }, ), debounceDelay: 1000, }, @@ -131,7 +131,7 @@ const removeFriendModal = new SimpleModal({ return { status: -1, message: result.body.message }; } else { friendsList = friendsList?.filter( - (it) => it.connectionId !== connectionId + (it) => it.connectionId !== connectionId, ); friendsTable?.setData(friendsList ?? []); friendsTable?.updateBody(); @@ -173,7 +173,7 @@ function updatePendingConnections(): void { ${formatAge(item.lastModified)} ago @@ -189,7 +189,7 @@ function updatePendingConnections(): void { - ` + `, ) .join("\n"); @@ -263,10 +263,10 @@ function buildFriendRow(entry: Friend): HTMLTableRowElement {
${ - entry.name - }
+ entry.uid + }?isUid" class="entryName" uid=${entry.uid} router-link>${ + entry.name + }
${getHtmlByUserFlags(entry)} ${ isSafeNumber(entry.badgeId) @@ -281,41 +281,41 @@ function buildFriendRow(entry: Friend): HTMLTableRowElement { ? "since " + format(entry.lastModified, "dd MMM yyyy HH:mm") : "" }">${ - entry.lastModified !== undefined - ? formatAge(entry.lastModified, "short") - : "-" - } + entry.lastModified !== undefined + ? formatAge(entry.lastModified, "short") + : "-" + } ${xpDetails.level} ${ - entry.completedTests - }/${entry.startedTests} + testStats.restartRatio + } restarts per completed test)" data-balloon-pos="up">${ + entry.completedTests + }/${entry.startedTests} ${secondsToString( Math.round(entry.timeTyping ?? 0), true, - true + true, )} ${formatStreak(entry.streak?.length)} ${ - top15?.wpm ?? "-" - }
${top15?.acc ?? "-"}
+ top15?.wpm ?? "-" + }
${top15?.acc ?? "-"}
${ - top60?.wpm ?? "-" - }
${top60?.acc ?? "-"}
+ top60?.wpm ?? "-" + }
${top60?.acc ?? "-"}
${actions} @@ -330,7 +330,7 @@ function buildFriendRow(entry: Friend): HTMLTableRowElement { function formatAge( timestamp: number | undefined, - format?: "short" | "full" + format?: "short" | "full", ): string { if (timestamp === undefined) return ""; let formatted = ""; @@ -393,7 +393,7 @@ $(".pageFriends button.friendAdd").on("click", () => { // need to set the listener for action buttons on the table because the table content is getting replaced $(".pageFriends .pendingRequests table").on("click", async (e) => { const action = Array.from(e.target.classList).find((it) => - ["accepted", "rejected", "blocked"].includes(it) + ["accepted", "rejected", "blocked"].includes(it), ) as "accepted" | "rejected" | "blocked"; if (action === undefined) return; @@ -420,7 +420,7 @@ $(".pageFriends .pendingRequests table").on("click", async (e) => { if (result.status !== 200) { Notifications.add( `Cannot update friend request: ${result.body.message}`, - -1 + -1, ); } else { //remove from cache @@ -464,7 +464,7 @@ $(".pageFriends .pendingRequests table").on("click", async (e) => { // need to set the listener for action buttons on the table because the table content is getting replaced $(".pageFriends .friends table").on("click", async (e) => { const action = Array.from(e.target.classList).find((it) => - ["remove"].includes(it) + ["remove"].includes(it), ); if (action === undefined) return; diff --git a/frontend/src/ts/pages/leaderboards.ts b/frontend/src/ts/pages/leaderboards.ts index 282793bdb83f..602b78633a85 100644 --- a/frontend/src/ts/pages/leaderboards.ts +++ b/frontend/src/ts/pages/leaderboards.ts @@ -154,8 +154,8 @@ function updateTitle(): void { state.type === "allTime" ? "All-time" : state.type === "weekly" - ? "Weekly XP" - : "Daily"; + ? "Weekly XP" + : "Daily"; const friend = state.friendsOnly ? "Friends " : ""; @@ -177,22 +177,22 @@ function updateTitle(): void { if (state.type === "daily") { $(".page.pageLeaderboards .bigtitle .subtext").removeClass("hidden"); $( - ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']" + ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']", ).removeClass("hidden"); $(".page.pageLeaderboards .bigtitle .subtext .divider").removeClass( - "hidden" + "hidden", ); if (state.yesterday) { $( - ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']" + ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']", ).html(` show today `); } else { $( - ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']" + ".page.pageLeaderboards .bigtitle button[data-action='toggleYesterday']", ).html(` show yesterday @@ -207,15 +207,15 @@ function updateTitle(): void { updateTimeText( format(timestamp, utcDateFormat) + " UTC", utcToLocalDate(timestamp), - utcToLocalDate(endOfDay(timestamp)) + utcToLocalDate(endOfDay(timestamp)), ); } else if (state.type === "weekly") { $(".page.pageLeaderboards .bigtitle .subtext").removeClass("hidden"); $( - ".page.pageLeaderboards .bigtitle button[data-action='toggleLastWeek']" + ".page.pageLeaderboards .bigtitle button[data-action='toggleLastWeek']", ).removeClass("hidden"); $(".page.pageLeaderboards .bigtitle .subtext .divider").removeClass( - "hidden" + "hidden", ); if (state.lastWeek) { @@ -240,12 +240,12 @@ function updateTitle(): void { const dateString = `${format(timestamp, utcDateFormat)} - ${format( endingTimestamp, - utcDateFormat + utcDateFormat, )} UTC`; updateTimeText( dateString, utcToLocalDate(timestamp), - utcToLocalDate(endingTimestamp) + utcToLocalDate(endingTimestamp), ); } } @@ -267,7 +267,7 @@ async function requestData(update = false): Promise { query: TQuery & PaginationQuery & FriendsOnlyQuery; }) => Promise, rank: (args: { query: TQuery }) => Promise, - baseQuery: TQuery + baseQuery: TQuery, ): { rank: undefined | (() => Promise); data: () => Promise; @@ -306,7 +306,7 @@ async function requestData(update = false): Promise { mode: state.mode, mode2: state.mode2, daysBefore: state.yesterday ? 1 : undefined, - } + }, ); } else if (state.type === "weekly") { requests = defineRequests( @@ -314,7 +314,7 @@ async function requestData(update = false): Promise { Ape.leaderboards.getWeeklyXpRank, { weeksBefore: state.lastWeek ? 1 : undefined, - } + }, ); } else { throw new Error("unknown state type"); @@ -363,7 +363,7 @@ async function requestData(update = false): Promise { state.error = "Something went wrong"; Notifications.add( "Failed to get leaderboard: " + dataResponse.body.message, - -1 + -1, ); } } @@ -450,8 +450,8 @@ function buildTableRow(entry: LeaderboardEntry, me = false): HTMLElement {
${entry.name} + entry.uid + }?isUid" class="entryName" uid=${entry.uid} router-link>${entry.name}
${getHtmlByUserFlags({ ...entry, @@ -478,7 +478,7 @@ function buildTableRow(entry: LeaderboardEntry, me = false): HTMLElement { ${formatted.con} ${format( entry.timestamp, - "dd MMM yyyy" + "dd MMM yyyy", )}
${format(entry.timestamp, "HH:mm")}
`; @@ -490,7 +490,7 @@ function buildTableRow(entry: LeaderboardEntry, me = false): HTMLElement { function buildWeeklyTableRow( entry: XpLeaderboardEntry, - me = false + me = false, ): HTMLElement { const activeDiff = formatDistanceToNow(entry.lastActivityTimestamp, { addSuffix: true, @@ -507,8 +507,8 @@ function buildWeeklyTableRow(
${entry.name} + entry.uid + }?isUid" class="entryName" uid=${entry.uid} router-link>${entry.name}
${getHtmlByUserFlags({ ...entry, @@ -527,7 +527,7 @@ function buildWeeklyTableRow( Math.round(entry.timeTypedSeconds), true, true, - ":" + ":", )} ${entry.totalXp < 1000 ? entry.totalXp : abbreviateNumber(entry.totalXp)} @@ -535,7 +535,7 @@ function buildWeeklyTableRow( Math.round(entry.timeTypedSeconds), true, true, - ":" + ":", )} @@ -565,7 +565,7 @@ function fillTable(): void { $(".page.pageLeaderboards table thead").addClass("hidden"); if (state.type === "allTime" || state.type === "daily") { $(".page.pageLeaderboards table thead.allTimeAndDaily").removeClass( - "hidden" + "hidden", ); } else if (state.type === "weekly") { $(".page.pageLeaderboards table thead.weekly").removeClass("hidden"); @@ -612,14 +612,14 @@ function getLbMemoryDifference(): number | null { function fillUser(): void { if (isAuthenticated() && DB.getSnapshot()?.lbOptOut === true) { $(".page.pageLeaderboards .bigUser").html( - '
You have opted out of the leaderboards.
' + '
You have opted out of the leaderboards.
', ); return; } if (isAuthenticated() && DB.getSnapshot()?.banned === true) { $(".page.pageLeaderboards .bigUser").html( - '
Your account is banned
' + '
Your account is banned
', ); return; } @@ -634,8 +634,8 @@ function fillUser(): void { ) { $(".page.pageLeaderboards .bigUser").html( `
Your account must have ${formatDuration( - intervalToDuration({ start: 0, end: minTimeTyping * 1000 }) - )} typed to be placed on the leaderboard.
` + intervalToDuration({ start: 0, end: minTimeTyping * 1000 }), + )} typed to be placed on the leaderboard.
`, ); return; } @@ -651,14 +651,14 @@ function fillUser(): void { } $(".page.pageLeaderboards .bigUser").html( - `
${str}
` + `
${str}
`, ); return; } if (isAuthenticated() && state.userData === null) { $(".page.pageLeaderboards .bigUser").html( - `
Not qualified
` + `
Not qualified
`, ); return; } @@ -671,7 +671,7 @@ function fillUser(): void { if (!state.userData || !state.count) { $(".page.pageLeaderboards .bigUser").addClass("hidden"); $(".page.pageLeaderboards .tableAndUser > .divider").removeClass( - "hidden" + "hidden", ); return; } @@ -696,12 +696,12 @@ function fillUser(): void { diffText = ` ( = since you last checked)`; } else if (diff > 0) { diffText = ` (${Math.abs( - diff + diff, )} since you last checked )`; } else { diffText = ` (${Math.abs( - diff + diff, )} since you last checked )`; } @@ -739,7 +739,7 @@ function fillUser(): void {
date
${format( userData.timestamp, - "dd MMM yyyy HH:mm" + "dd MMM yyyy HH:mm", )}
@@ -785,12 +785,12 @@ function fillUser(): void { diffText = ` ( = since you last checked)`; } else if (diff > 0) { diffText = ` (${Math.abs( - diff + diff, )} since you last checked )`; } else { diffText = ` (${Math.abs( - diff + diff, )} since you last checked )`; } @@ -804,7 +804,7 @@ function fillUser(): void { Math.round(userData.timeTypedSeconds), true, true, - ":" + ":", ), }; @@ -830,14 +830,14 @@ function fillUser(): void {
last activity
${format( userData.lastActivityTimestamp, - "dd MMM yyyy HH:mm" + "dd MMM yyyy HH:mm", )}
${format(userData.lastActivityTimestamp, "dd MMM yyyy")}
${format( userData.lastActivityTimestamp, - "HH:mm" + "HH:mm", )}
`; @@ -892,7 +892,7 @@ function updateContent(): void { fillTable(); for (const element of document.querySelectorAll( - ".page.pageLeaderboards .wide.speedUnit, .page.pageLeaderboards .narrow.speedUnit span" + ".page.pageLeaderboards .wide.speedUnit, .page.pageLeaderboards .narrow.speedUnit span", )) { element.innerHTML = Config.typingSpeedUnit; } @@ -920,7 +920,7 @@ function updateTypeButtons(): void { function updateFriendsButtons(): void { const friendsOnlyGroup = $( - ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons" + ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons", ); if ( isAuthenticated() && @@ -934,10 +934,10 @@ function updateFriendsButtons(): void { } const everyoneButton = $( - ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons .everyone" + ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons .everyone", ); const friendsOnlyButton = $( - ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons .friendsOnly" + ".page.pageLeaderboards .buttonGroup.friendsOnlyButtons .friendsOnly", ); if (state.friendsOnly) { friendsOnlyButton.addClass("active"); @@ -958,22 +958,22 @@ function updateModeButtons(): void { const el = $(".page.pageLeaderboards .buttonGroup.modeButtons"); el.find("button").removeClass("active"); el.find( - `button[data-mode=${state.mode}][data-mode2=${state.mode2}]` + `button[data-mode=${state.mode}][data-mode2=${state.mode2}]`, ).addClass("active"); //hide all mode buttons $(`.page.pageLeaderboards .buttonGroup.modeButtons button`).addClass( - "hidden" + "hidden", ); //show all valid ones for (const mode of Object.keys(validLeaderboards[state.type]) as Mode[]) { for (const mode2 of Object.keys( // oxlint-disable-next-line no-non-null-assertion - validLeaderboards[state.type][mode]! + validLeaderboards[state.type][mode]!, )) { $( - `.page.pageLeaderboards .buttonGroup.modeButtons button[data-mode="${mode}"][data-mode2="${mode2}"]` + `.page.pageLeaderboards .buttonGroup.modeButtons button[data-mode="${mode}"][data-mode2="${mode2}"]`, ).removeClass("hidden"); } } @@ -985,7 +985,7 @@ function updateLanguageButtons(): void { return; } $(".page.pageLeaderboards .buttonGroup.languageButtons").removeClass( - "hidden" + "hidden", ); const el = $(".page.pageLeaderboards .buttonGroup.languageButtons"); @@ -994,14 +994,14 @@ function updateLanguageButtons(): void { //hide all languages $(`.page.pageLeaderboards .buttonGroup.languageButtons button`).addClass( - "hidden" + "hidden", ); //show all valid ones for (const lang of validLeaderboards[state.type][state.mode]?.[state.mode2] ?? []) { $( - `.page.pageLeaderboards .buttonGroup.languageButtons button[data-language="${lang}"]` + `.page.pageLeaderboards .buttonGroup.languageButtons button[data-language="${lang}"]`, ).removeClass("hidden"); } } @@ -1013,7 +1013,7 @@ function updateTimerElement(): void { const diff = differenceInSeconds(new Date(), endOfDay(new UTCDateMini())); $(".page.pageLeaderboards .titleAndButtons .timer").text( - "Next reset in: " + DateTime.secondsToString(diff, true) + "Next reset in: " + DateTime.secondsToString(diff, true), ); } else if (state.type === "allTime") { const date = new Date(); @@ -1021,14 +1021,14 @@ function updateTimerElement(): void { const secondsToNextUpdate = 60 - date.getSeconds(); const totalSeconds = minutesToNextUpdate * 60 + secondsToNextUpdate; $(".page.pageLeaderboards .titleAndButtons .timer").text( - "Next update in: " + DateTime.secondsToString(totalSeconds, true) + "Next update in: " + DateTime.secondsToString(totalSeconds, true), ); } else if (state.type === "weekly") { const nextWeekTimestamp = endOfWeek(new UTCDateMini(), { weekStartsOn: 1 }); const totalSeconds = differenceInSeconds(new Date(), nextWeekTimestamp); $(".page.pageLeaderboards .titleAndButtons .timer").text( "Next reset in: " + - DateTime.secondsToString(totalSeconds, true, true, ":", true, true) + DateTime.secondsToString(totalSeconds, true, true, ":", true, true), ); } } @@ -1045,7 +1045,7 @@ function updateTimerVisibility(): void { if (visible) { $(".page.pageLeaderboards .titleAndButtons .timer").removeClass( - "invisible" + "invisible", ); } else { $(".page.pageLeaderboards .titleAndButtons .timer").addClass("invisible"); @@ -1078,7 +1078,7 @@ async function updateValidDailyLeaderboards(): Promise { if (dailyRulesConfig === undefined) { throw new Error( - "cannot load server configuration for dailyLeaderboards.validModeRules" + "cannot load server configuration for dailyLeaderboards.validModeRules", ); } @@ -1133,11 +1133,11 @@ function checkIfLeaderboardIsValid(): void { let supportedLanguages = validModes2[state.mode2]; if (supportedLanguages === undefined) { const firstMode2 = Object.keys(validModes2).sort( - (a, b) => parseInt(a) - parseInt(b) + (a, b) => parseInt(a) - parseInt(b), )[0]; if (firstMode2 === undefined) { throw new Error( - `no valid leaderboard config for type ${state.type} and mode ${state.mode}` + `no valid leaderboard config for type ${state.type} and mode ${state.mode}`, ); } state.mode2 = firstMode2; @@ -1146,7 +1146,7 @@ function checkIfLeaderboardIsValid(): void { if (supportedLanguages === undefined || supportedLanguages.length < 1) { throw new Error( - `Daily leaderboard config not valid for mode:${state.mode} mode2:${state.mode2}` + `Daily leaderboard config not valid for mode:${state.mode} mode2:${state.mode2}`, ); } @@ -1159,18 +1159,18 @@ async function appendModeAndLanguageButtons(): Promise { const modes = Array.from( new Set( Object.values(validLeaderboards).flatMap( - (rule) => Object.keys(rule) as Mode[] - ) - ) + (rule) => Object.keys(rule) as Mode[], + ), + ), ).sort(); const mode2Buttons = modes.flatMap((mode) => { const modes2 = Array.from( new Set( Object.values(validLeaderboards).flatMap((rule) => - Object.keys(rule[mode] ?? {}) - ) - ) + Object.keys(rule[mode] ?? {}), + ), + ), ).sort((a, b) => parseInt(a) - parseInt(b)); const icon = mode === "time" ? "fas fa-clock" : "fas fa-align-left"; @@ -1179,11 +1179,11 @@ async function appendModeAndLanguageButtons(): Promise { (mode2) => `` + `, ); }); $(".modeButtons").html( - `
` + mode2Buttons.join("\n") + `
` + mode2Buttons.join("\n"), ); const availableLanguages = Array.from( @@ -1191,8 +1191,8 @@ async function appendModeAndLanguageButtons(): Promise { Object.values(validLeaderboards) .flatMap((rule) => Object.values(rule)) .flatMap((mode) => Object.values(mode)) - .flatMap((it) => it) - ) + .flatMap((it) => it), + ), ).sort(); const languageButtons = availableLanguages.map( @@ -1200,10 +1200,10 @@ async function appendModeAndLanguageButtons(): Promise { `` + `, ); $(".languageButtons").html( - `
` + languageButtons.join("\n") + `
` + languageButtons.join("\n"), ); } @@ -1364,7 +1364,7 @@ function utcToLocalDate(timestamp: UTCDateMini): Date { function updateTimeText( dateString: string, localStart: Date, - localEnd: Date + localEnd: Date, ): void { const localDateString = "local time \n" + @@ -1418,7 +1418,7 @@ $(".page.pageLeaderboards .buttonGroup.typeButtons").on( updateSideButtons(); updateContent(); updateGetParameters(); - } + }, ); $(".page.pageLeaderboards .buttonGroup.modeButtons").on( @@ -1447,7 +1447,7 @@ $(".page.pageLeaderboards .buttonGroup.modeButtons").on( updateTitle(); updateContent(); updateGetParameters(); - } + }, ); $(".page.pageLeaderboards .buttonGroup.languageButtons").on( @@ -1470,7 +1470,7 @@ $(".page.pageLeaderboards .buttonGroup.languageButtons").on( updateTitle(); updateContent(); updateGetParameters(); - } + }, ); $(".page.pageLeaderboards .buttonGroup.friendsOnlyButtons").on( @@ -1484,7 +1484,7 @@ $(".page.pageLeaderboards .buttonGroup.friendsOnlyButtons").on( updateSideButtons(); updateContent(); updateGetParameters(); - } + }, ); export const page = new PageWithUrlParams({ diff --git a/frontend/src/ts/pages/loading.ts b/frontend/src/ts/pages/loading.ts index 2aa0b084ff04..98580073a7ff 100644 --- a/frontend/src/ts/pages/loading.ts +++ b/frontend/src/ts/pages/loading.ts @@ -10,7 +10,7 @@ const textEl = pageEl.find(".text"); export async function updateBar( percentage: number, - duration: number + duration: number, ): Promise { await promiseAnimate(barEl[0]?.querySelector(".fill") as HTMLElement, { width: percentage + "%", diff --git a/frontend/src/ts/pages/login.ts b/frontend/src/ts/pages/login.ts index 8380fc158acb..9422ddf920eb 100644 --- a/frontend/src/ts/pages/login.ts +++ b/frontend/src/ts/pages/login.ts @@ -70,13 +70,13 @@ export function getSignupData(): SignupData | false { } const nameInputEl = document.querySelector( - ".page.pageLogin .register.side input.usernameInput" + ".page.pageLogin .register.side input.usernameInput", ) as HTMLInputElement; new ValidatedHtmlInputElement(nameInputEl, { schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), - { check: (data) => data.available || "Name not available" } + { check: (data) => data.available || "Name not available" }, ), debounceDelay: 1000, callback: (result) => { @@ -92,7 +92,7 @@ let moduleLoadAttempted = false; const emailInputEl = new ValidatedHtmlInputElement( document.querySelector( - ".page.pageLogin .register.side input.emailInput" + ".page.pageLogin .register.side input.emailInput", ) as HTMLInputElement, { schema: UserEmailSchema, @@ -140,7 +140,7 @@ const emailInputEl = new ValidatedHtmlInputElement( emailVerifyInputEl.dispatchEvent(new Event("input")); } }, - } + }, ); emailInputEl.native.addEventListener("focus", async () => { @@ -155,7 +155,7 @@ emailInputEl.native.addEventListener("focus", async () => { }); const emailVerifyInputEl = document.querySelector( - ".page.pageLogin .register.side input.verifyEmailInput" + ".page.pageLogin .register.side input.verifyEmailInput", ) as HTMLInputElement; new ValidatedHtmlInputElement(emailVerifyInputEl, { isValid: async (emailVerify: string) => { @@ -176,7 +176,7 @@ new ValidatedHtmlInputElement(emailVerifyInputEl, { const passwordInputEl = new ValidatedHtmlInputElement( document.querySelector( - ".page.pageLogin .register.side .passwordInput" + ".page.pageLogin .register.side .passwordInput", ) as HTMLInputElement, { schema: isDevEnvironment() ? z.string().min(6) : PasswordSchema, @@ -186,11 +186,11 @@ const passwordInputEl = new ValidatedHtmlInputElement( passwordVerifyInputEl.dispatchEvent(new Event("input")); } }, - } + }, ); const passwordVerifyInputEl = document.querySelector( - ".page.pageLogin .register.side .verifyPasswordInput" + ".page.pageLogin .register.side .verifyPasswordInput", ) as HTMLInputElement; new ValidatedHtmlInputElement(passwordVerifyInputEl, { isValid: async (passwordVerify: string) => { diff --git a/frontend/src/ts/pages/page.ts b/frontend/src/ts/pages/page.ts index 722ee1826002..e177c663c0d3 100644 --- a/frontend/src/ts/pages/page.ts +++ b/frontend/src/ts/pages/page.ts @@ -126,7 +126,7 @@ type PagePropertiesWithUrlParams = Omit< export class PageWithUrlParams extends Page { private urlSchema: U; protected override _beforeShow: ( - options: OptionsWithUrlParams + options: OptionsWithUrlParams, ) => Promise; constructor(props: PagePropertiesWithUrlParams) { diff --git a/frontend/src/ts/pages/profile-search.ts b/frontend/src/ts/pages/profile-search.ts index ceac50af37a3..173e3a41c3ea 100644 --- a/frontend/src/ts/pages/profile-search.ts +++ b/frontend/src/ts/pages/profile-search.ts @@ -30,7 +30,7 @@ export const page = new Page({ if (nameInputEl === null) { nameInputEl = new ValidatedHtmlInputElement( document.querySelector( - ".page.pageProfileSearch input" + ".page.pageProfileSearch input", ) as HTMLInputElement, { schema: UserNameSchema, @@ -43,7 +43,7 @@ export const page = new Page({ return true; }, on4xx: () => "Unknown user", - } + }, ), callback: (result) => { if (result.status === "success") { @@ -53,7 +53,7 @@ export const page = new Page({ lastProfile = null; } }, - } + }, ); } diff --git a/frontend/src/ts/pages/profile.ts b/frontend/src/ts/pages/profile.ts index 1de3ceea099a..2ee81a6467e7 100644 --- a/frontend/src/ts/pages/profile.ts +++ b/frontend/src/ts/pages/profile.ts @@ -166,7 +166,7 @@ function reset(): void { `); const testActivityEl = document.querySelector( - ".page.pageProfile .testActivity" + ".page.pageProfile .testActivity", ); if (testActivityEl !== null) { TestActivity.clear(testActivityEl as HTMLElement); @@ -186,7 +186,7 @@ async function update(options: UpdateOptions): Promise { PbTables.update( // this cast is fine because pb tables can handle the partial data inside user profiles options.data.personalBests as unknown as PersonalBests, - true + true, ); } else if (options.uidOrName !== undefined && options.uidOrName !== "") { const response = await Ape.users.getProfile({ @@ -211,14 +211,14 @@ async function update(options: UpdateOptions): Promise { PbTables.update(profile.personalBests as unknown as PersonalBests, true); const testActivity = document.querySelector( - ".page.pageProfile .testActivity" + ".page.pageProfile .testActivity", ) as HTMLElement; if (profile.testActivity !== undefined) { const calendar = new TestActivityCalendar( profile.testActivity.testsByDays, new Date(profile.testActivity.lastDay), - firstDayOfTheWeek + firstDayOfTheWeek, ); TestActivity.init(testActivity, calendar); const title = testActivity.querySelector(".top .title") as HTMLElement; diff --git a/frontend/src/ts/pages/settings.ts b/frontend/src/ts/pages/settings.ts index 338dc063a732..0c60509f463e 100644 --- a/frontend/src/ts/pages/settings.ts +++ b/frontend/src/ts/pages/settings.ts @@ -60,7 +60,7 @@ const HighlightSchema = ConfigKeySchema.or( "theme", "presets", "tags", - ]) + ]), ); type Highlight = z.infer; @@ -74,27 +74,27 @@ async function initGroups(): Promise { groups["smoothCaret"] = new SettingsGroup( "smoothCaret", UpdateConfig.setSmoothCaret, - "button" + "button", ); groups["codeUnindentOnBackspace"] = new SettingsGroup( "codeUnindentOnBackspace", UpdateConfig.setCodeUnindentOnBackspace, - "button" + "button", ); groups["difficulty"] = new SettingsGroup( "difficulty", UpdateConfig.setDifficulty, - "button" + "button", ); groups["quickRestart"] = new SettingsGroup( "quickRestart", UpdateConfig.setQuickRestartMode, - "button" + "button", ); groups["showAverage"] = new SettingsGroup( "showAverage", UpdateConfig.setShowAverage, - "button" + "button", ); groups["keymapMode"] = new SettingsGroup( "keymapMode", @@ -104,69 +104,69 @@ async function initGroups(): Promise { updateCallback: () => { if (Config.keymapMode === "off") { $(".pageSettings .section[data-config-name='keymapStyle']").addClass( - "hidden" + "hidden", ); $(".pageSettings .section[data-config-name='keymapLayout']").addClass( - "hidden" + "hidden", ); $( - ".pageSettings .section[data-config-name='keymapLegendStyle']" + ".pageSettings .section[data-config-name='keymapLegendStyle']", ).addClass("hidden"); $( - ".pageSettings .section[data-config-name='keymapShowTopRow']" + ".pageSettings .section[data-config-name='keymapShowTopRow']", ).addClass("hidden"); $(".pageSettings .section[data-config-name='keymapSize']").addClass( - "hidden" + "hidden", ); } else { $( - ".pageSettings .section[data-config-name='keymapStyle']" + ".pageSettings .section[data-config-name='keymapStyle']", ).removeClass("hidden"); $( - ".pageSettings .section[data-config-name='keymapLayout']" + ".pageSettings .section[data-config-name='keymapLayout']", ).removeClass("hidden"); $( - ".pageSettings .section[data-config-name='keymapLegendStyle']" + ".pageSettings .section[data-config-name='keymapLegendStyle']", ).removeClass("hidden"); $( - ".pageSettings .section[data-config-name='keymapShowTopRow']" + ".pageSettings .section[data-config-name='keymapShowTopRow']", ).removeClass("hidden"); $( - ".pageSettings .section[data-config-name='keymapSize']" + ".pageSettings .section[data-config-name='keymapSize']", ).removeClass("hidden"); } }, - } + }, ); groups["keymapStyle"] = new SettingsGroup( "keymapStyle", UpdateConfig.setKeymapStyle, - "button" + "button", ); groups["keymapLayout"] = new SettingsGroup( "keymapLayout", UpdateConfig.setKeymapLayout, - "select" + "select", ); groups["keymapLegendStyle"] = new SettingsGroup( "keymapLegendStyle", UpdateConfig.setKeymapLegendStyle, - "button" + "button", ); groups["keymapShowTopRow"] = new SettingsGroup( "keymapShowTopRow", UpdateConfig.setKeymapShowTopRow, - "button" + "button", ); groups["keymapSize"] = new SettingsGroup( "keymapSize", UpdateConfig.setKeymapSize, - "range" + "range", ); groups["showKeyTips"] = new SettingsGroup( "showKeyTips", UpdateConfig.setKeyTips, - "button" + "button", ); groups["freedomMode"] = new SettingsGroup( "freedomMode", @@ -176,17 +176,17 @@ async function initGroups(): Promise { setCallback: () => { groups["confidenceMode"]?.updateUI(); }, - } + }, ); groups["strictSpace"] = new SettingsGroup( "strictSpace", UpdateConfig.setStrictSpace, - "button" + "button", ); groups["oppositeShiftMode"] = new SettingsGroup( "oppositeShiftMode", UpdateConfig.setOppositeShiftMode, - "button" + "button", ); groups["confidenceMode"] = new SettingsGroup( "confidenceMode", @@ -197,83 +197,83 @@ async function initGroups(): Promise { groups["freedomMode"]?.updateUI(); groups["stopOnError"]?.updateUI(); }, - } + }, ); groups["indicateTypos"] = new SettingsGroup( "indicateTypos", UpdateConfig.setIndicateTypos, - "button" + "button", ); groups["hideExtraLetters"] = new SettingsGroup( "hideExtraLetters", UpdateConfig.setHideExtraLetters, - "button" + "button", ); groups["blindMode"] = new SettingsGroup( "blindMode", UpdateConfig.setBlindMode, - "button" + "button", ); groups["quickEnd"] = new SettingsGroup( "quickEnd", UpdateConfig.setQuickEnd, - "button" + "button", ); groups["repeatQuotes"] = new SettingsGroup( "repeatQuotes", UpdateConfig.setRepeatQuotes, - "button" + "button", ); groups["ads"] = new SettingsGroup("ads", UpdateConfig.setAds, "button"); groups["alwaysShowWordsHistory"] = new SettingsGroup( "alwaysShowWordsHistory", UpdateConfig.setAlwaysShowWordsHistory, - "button" + "button", ); groups["britishEnglish"] = new SettingsGroup( "britishEnglish", UpdateConfig.setBritishEnglish, - "button" + "button", ); groups["singleListCommandLine"] = new SettingsGroup( "singleListCommandLine", UpdateConfig.setSingleListCommandLine, - "button" + "button", ); groups["capsLockWarning"] = new SettingsGroup( "capsLockWarning", UpdateConfig.setCapsLockWarning, - "button" + "button", ); groups["flipTestColors"] = new SettingsGroup( "flipTestColors", UpdateConfig.setFlipTestColors, - "button" + "button", ); groups["showOutOfFocusWarning"] = new SettingsGroup( "showOutOfFocusWarning", UpdateConfig.setShowOutOfFocusWarning, - "button" + "button", ); groups["colorfulMode"] = new SettingsGroup( "colorfulMode", UpdateConfig.setColorfulMode, - "button" + "button", ); groups["startGraphsAtZero"] = new SettingsGroup( "startGraphsAtZero", UpdateConfig.setStartGraphsAtZero, - "button" + "button", ); groups["autoSwitchTheme"] = new SettingsGroup( "autoSwitchTheme", UpdateConfig.setAutoSwitchTheme, - "button" + "button", ); groups["randomTheme"] = new SettingsGroup( "randomTheme", UpdateConfig.setRandomTheme, - "button" + "button", ); groups["stopOnError"] = new SettingsGroup( "stopOnError", @@ -283,12 +283,12 @@ async function initGroups(): Promise { setCallback: () => { groups["confidenceMode"]?.updateUI(); }, - } + }, ); groups["soundVolume"] = new SettingsGroup( "soundVolume", UpdateConfig.setSoundVolume, - "range" + "range", ); groups["playTimeWarning"] = new SettingsGroup( "playTimeWarning", @@ -298,7 +298,7 @@ async function initGroups(): Promise { setCallback: () => { if (Config.playTimeWarning !== "off") void Sound.playTimeWarning(); }, - } + }, ); groups["playSoundOnError"] = new SettingsGroup( "playSoundOnError", @@ -308,7 +308,7 @@ async function initGroups(): Promise { setCallback: () => { if (Config.playSoundOnError !== "off") void Sound.playError(); }, - } + }, ); groups["playSoundOnClick"] = new SettingsGroup( "playSoundOnClick", @@ -318,125 +318,125 @@ async function initGroups(): Promise { setCallback: () => { if (Config.playSoundOnClick !== "off") void Sound.playClick("KeyQ"); }, - } + }, ); groups["showAllLines"] = new SettingsGroup( "showAllLines", UpdateConfig.setShowAllLines, - "button" + "button", ); groups["paceCaret"] = new SettingsGroup( "paceCaret", UpdateConfig.setPaceCaret, - "button" + "button", ); groups["repeatedPace"] = new SettingsGroup( "repeatedPace", UpdateConfig.setRepeatedPace, - "button" + "button", ); groups["minWpm"] = new SettingsGroup( "minWpm", UpdateConfig.setMinWpm, - "button" + "button", ); groups["minAcc"] = new SettingsGroup( "minAcc", UpdateConfig.setMinAcc, - "button" + "button", ); groups["minBurst"] = new SettingsGroup( "minBurst", UpdateConfig.setMinBurst, - "button" + "button", ); groups["smoothLineScroll"] = new SettingsGroup( "smoothLineScroll", UpdateConfig.setSmoothLineScroll, - "button" + "button", ); groups["lazyMode"] = new SettingsGroup( "lazyMode", UpdateConfig.setLazyMode, - "button" + "button", ); groups["layout"] = new SettingsGroup( "layout", UpdateConfig.setLayout, - "select" + "select", ); groups["language"] = new SettingsGroup( "language", UpdateConfig.setLanguage, - "select" + "select", ); groups["fontSize"] = new SettingsGroup( "fontSize", UpdateConfig.setFontSize, "input", - { validation: { schema: true, inputValueConvert: Number } } + { validation: { schema: true, inputValueConvert: Number } }, ); groups["maxLineWidth"] = new SettingsGroup( "maxLineWidth", UpdateConfig.setMaxLineWidth, "input", - { validation: { schema: true, inputValueConvert: Number } } + { validation: { schema: true, inputValueConvert: Number } }, ); groups["caretStyle"] = new SettingsGroup( "caretStyle", UpdateConfig.setCaretStyle, - "button" + "button", ); groups["paceCaretStyle"] = new SettingsGroup( "paceCaretStyle", UpdateConfig.setPaceCaretStyle, - "button" + "button", ); groups["timerStyle"] = new SettingsGroup( "timerStyle", UpdateConfig.setTimerStyle, - "button" + "button", ); groups["liveSpeedStyle"] = new SettingsGroup( "liveSpeedStyle", UpdateConfig.setLiveSpeedStyle, - "button" + "button", ); groups["liveAccStyle"] = new SettingsGroup( "liveAccStyle", UpdateConfig.setLiveAccStyle, - "button" + "button", ); groups["liveBurstStyle"] = new SettingsGroup( "liveBurstStyle", UpdateConfig.setLiveBurstStyle, - "button" + "button", ); groups["highlightMode"] = new SettingsGroup( "highlightMode", UpdateConfig.setHighlightMode, - "button" + "button", ); groups["tapeMode"] = new SettingsGroup( "tapeMode", UpdateConfig.setTapeMode, - "button" + "button", ); groups["tapeMargin"] = new SettingsGroup( "tapeMargin", UpdateConfig.setTapeMargin, "input", - { validation: { schema: true, inputValueConvert: Number } } + { validation: { schema: true, inputValueConvert: Number } }, ); groups["timerOpacity"] = new SettingsGroup( "timerOpacity", UpdateConfig.setTimerOpacity, - "button" + "button", ); groups["timerColor"] = new SettingsGroup( "timerColor", UpdateConfig.setTimerColor, - "button" + "button", ); groups["fontFamily"] = new SettingsGroup( "fontFamily", @@ -445,12 +445,12 @@ async function initGroups(): Promise { { updateCallback: () => { const customButton = $( - ".pageSettings .section[data-config-name='fontFamily'] .buttons button[data-config-value='custom']" + ".pageSettings .section[data-config-name='fontFamily'] .buttons button[data-config-value='custom']", ); if ( $( - ".pageSettings .section[data-config-name='fontFamily'] .buttons .active" + ".pageSettings .section[data-config-name='fontFamily'] .buttons .active", ).length === 0 ) { customButton.addClass("active"); @@ -459,22 +459,22 @@ async function initGroups(): Promise { customButton.text("Custom"); } }, - } + }, ); groups["alwaysShowDecimalPlaces"] = new SettingsGroup( "alwaysShowDecimalPlaces", UpdateConfig.setAlwaysShowDecimalPlaces, - "button" + "button", ); groups["typingSpeedUnit"] = new SettingsGroup( "typingSpeedUnit", UpdateConfig.setTypingSpeedUnit, - "button" + "button", ); groups["customBackgroundSize"] = new SettingsGroup( "customBackgroundSize", UpdateConfig.setCustomBackgroundSize, - "button" + "button", ); } @@ -501,7 +501,7 @@ async function fillSettingsPage(): Promise { data: [ { text: "off", value: "default" }, ...LayoutsList.filter((layout) => layout !== "korean").map( - layoutToOption + layoutToOption, ), ], }); @@ -537,7 +537,7 @@ async function fillSettingsPage(): Promise { }); const funboxEl = document.querySelector( - ".pageSettings .section[data-config-name='funbox'] .buttons" + ".pageSettings .section[data-config-name='funbox'] .buttons", ) as HTMLDivElement; let funboxElHTML = ""; @@ -549,7 +549,7 @@ async function fillSettingsPage(): Promise { funbox.description }" data-balloon-pos="up" data-balloon-length="fit" style="transform:scaleX(-1);">${funbox.name.replace( /_/g, - " " + " ", )}`; } else if (funbox.name === "upside_down") { funboxElHTML += `
"; } catch (e) { @@ -1372,7 +1372,7 @@ export function toggleResultWords(noAnimation = false): void { if ($("#resultWordsHistory .words .word").length === 0) { $("#words").html( - `
` + `
`, ); void loadWordsHistory().then(() => { if (Config.burstHeatmap) { @@ -1484,7 +1484,7 @@ export async function applyBurstHeatmap(): Promise { } $("#resultWordsHistory .heatmapLegend .box" + index).html( - `
${string}
` + `
${string}
`, ); }); @@ -1495,7 +1495,7 @@ export async function applyBurstHeatmap(): Promise { } else { let wordBurstVal = parseInt(wordBurstAttr); wordBurstVal = Math.round( - getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm(wordBurstVal) + getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm(wordBurstVal), ); steps.forEach((step) => { if (wordBurstVal >= step.val) { @@ -1639,7 +1639,7 @@ export function getActiveWordTopAfterAppend(data: string): number { // this means input, delete or composition function afterAnyTestInput( type: "textInput" | "delete" | "compositionUpdate", - correctInput: boolean | null + correctInput: boolean | null, ): void { if (type === "textInput" || type === "compositionUpdate") { if ( @@ -1664,7 +1664,7 @@ function afterAnyTestInput( if (Config.keymapMode === "next") { void KeymapEvent.highlight( - TestWords.words.getCurrent().charAt(TestInput.input.current.length) + TestWords.words.getCurrent().charAt(TestInput.input.current.length), ); } @@ -1676,7 +1676,7 @@ function afterAnyTestInput( export function afterTestTextInput( correct: boolean, increasedWordIndex: boolean | null, - inputOverride?: string + inputOverride?: string, ): void { //nospace cant be handled here becauseword index // is already increased at this point @@ -1708,17 +1708,17 @@ export function afterTestDelete(): void { export function beforeTestWordChange( direction: "forward", correct: boolean, - forceUpdateActiveWordLetters: boolean + forceUpdateActiveWordLetters: boolean, ): void; export function beforeTestWordChange( direction: "back", correct: null, - forceUpdateActiveWordLetters: boolean + forceUpdateActiveWordLetters: boolean, ): void; export function beforeTestWordChange( direction: "forward" | "back", correct: boolean | null, - forceUpdateActiveWordLetters: boolean + forceUpdateActiveWordLetters: boolean, ): void { const nospaceEnabled = isFunboxActiveWithProperty("nospace"); if ( @@ -1739,7 +1739,7 @@ export function beforeTestWordChange( } export async function afterTestWordChange( - direction: "forward" | "back" + direction: "forward" | "back", ): Promise { updateActiveElement(); Caret.updatePosition(); @@ -1877,7 +1877,7 @@ $(".pageTest #resultWordsHistory").on("mouseenter", ".words .word", (e) => { ${Format.typingSpeed(burst, { showDecimalPlaces: false })} ${Config.typingSpeedUnit}
-
` +
`, ); } } diff --git a/frontend/src/ts/test/timer-progress.ts b/frontend/src/ts/test/timer-progress.ts index ffba8b5572b0..12f33754566f 100644 --- a/frontend/src/ts/test/timer-progress.ts +++ b/frontend/src/ts/test/timer-progress.ts @@ -11,10 +11,10 @@ import { animate } from "animejs"; const barEl = document.querySelector("#barTimerProgress .bar") as HTMLElement; const barOpacityEl = document.querySelector( - "#barTimerProgress .opacityWrapper" + "#barTimerProgress .opacityWrapper", ) as HTMLElement; const textEl = document.querySelector( - "#liveStatsTextTop .timerProgress" + "#liveStatsTextTop .timerProgress", ) as HTMLElement; const miniEl = document.querySelector("#liveStatsMini .time") as HTMLElement; @@ -150,7 +150,7 @@ export function update(): void { } if (Config.timerStyle === "bar") { const percent = Math.floor( - ((TestState.activeWordIndex + 1) / outof) * 100 + ((TestState.activeWordIndex + 1) / outof) * 100, ); animate(barEl, { diff --git a/frontend/src/ts/test/wikipedia.ts b/frontend/src/ts/test/wikipedia.ts index 98fbe277e898..ddb2bc7cbd29 100644 --- a/frontend/src/ts/test/wikipedia.ts +++ b/frontend/src/ts/test/wikipedia.ts @@ -8,7 +8,7 @@ import { getGroupForLanguage, LanguageGroupName } from "../constants/languages"; import { Language } from "@monkeytype/schemas/languages"; export async function getTLD( - languageGroup: LanguageGroupName + languageGroup: LanguageGroupName, ): Promise< | "en" | "es" @@ -252,13 +252,13 @@ const SectionSchema = z.object({ z.string(), z.object({ extract: z.string(), - }) + }), ), }), }); export async function getSection( - language: Language + language: Language, ): Promise { // console.log("Getting section"); Loader.show(); @@ -296,7 +296,7 @@ export async function getSection( if (sectionReq.status === 200) { const parsedResponse = parseJsonWithSchema( sectionReq.responseText, - SectionSchema + SectionSchema, ); const page = parsedResponse.query.pages[pageid.toString()]; if (!page) { @@ -337,7 +337,7 @@ export async function getSection( const section = new JSONData.Section( sectionObj.title, sectionObj.author, - words + words, ); Loader.hide(); res(section); diff --git a/frontend/src/ts/test/words-generator.ts b/frontend/src/ts/test/words-generator.ts index 820006e9b04c..d61029e9a6e8 100644 --- a/frontend/src/ts/test/words-generator.ts +++ b/frontend/src/ts/test/words-generator.ts @@ -39,7 +39,7 @@ export async function punctuateWord( previousWord: string, currentWord: string, index: number, - maxindex: number + maxindex: number, ): Promise { let word = currentWord; @@ -346,7 +346,7 @@ async function getFunboxSection(): Promise { function getFunboxWord( word: string, wordIndex: number, - wordset?: Wordset + wordset?: Wordset, ): string { const funbox = findSingleActiveFunboxWithFunction("getWord"); @@ -359,7 +359,7 @@ function getFunboxWord( function applyFunboxesToWord( word: string, wordIndex: number, - wordsBound: number + wordsBound: number, ): string { for (const fb of getActiveFunboxesWithFunction("alterText")) { word = fb.functions.alterText(word, wordIndex, wordsBound); @@ -369,7 +369,7 @@ function applyFunboxesToWord( async function applyBritishEnglishToWord( word: string, - previousWord: string + previousWord: string, ): Promise { if (!Config.britishEnglish) return word; if (!Config.language.includes("english")) return word; @@ -494,7 +494,7 @@ export function getLimit(): number { async function getQuoteWordList( language: LanguageObject, - wordOrder?: FunboxWordOrder + wordOrder?: FunboxWordOrder, ): Promise { if (TestState.isRepeated) { if (currentWordset === null) { @@ -518,7 +518,7 @@ async function getQuoteWordList( Loader.show(); const quotesCollection = await QuotesController.getQuotes( languageToGet, - Config.quoteLength + Config.quoteLength, ); Loader.hide(); @@ -527,25 +527,25 @@ async function getQuoteWordList( throw new WordGenError( `No ${Config.language .replace(/_\d*k$/g, "") - .replace(/_/g, " ")} quotes found` + .replace(/_/g, " ")} quotes found`, ); } let rq: Quote; if (Config.quoteLength.includes(-2) && Config.quoteLength.length === 1) { const targetQuote = QuotesController.getQuoteById( - TestState.selectedQuoteId + TestState.selectedQuoteId, ); if (targetQuote === undefined) { UpdateConfig.setQuoteLengthAll(); throw new WordGenError( - `Quote ${TestState.selectedQuoteId} does not exist` + `Quote ${TestState.selectedQuoteId} does not exist`, ); } rq = targetQuote; } else if (Config.quoteLength.includes(-3)) { const randomQuote = QuotesController.getRandomFavoriteQuote( - Config.language + Config.language, ); if (randomQuote === null) { UpdateConfig.setQuoteLengthAll(); @@ -606,7 +606,7 @@ type GenerateWordsReturn = { let previousRandomQuote: QuoteWithTextSplit | null = null; export async function generateWords( - language: LanguageObject + language: LanguageObject, ): Promise { if (!TestState.isRepeated) { previousGetNextWordReturns = []; @@ -645,7 +645,7 @@ export async function generateWords( const limit = getLimit(); console.debug( - `${customAndUsingPipeDelimiter ? "Section" : "Word"} limit ${limit}` + `${customAndUsingPipeDelimiter ? "Section" : "Word"} limit ${limit}`, ); if (wordOrder === "reverse") { @@ -661,7 +661,7 @@ export async function generateWords( currentWordset = polyglotResult; // set allLigatures if any language in languageProperties has ligatures true ret.allLigatures = Array.from( - polyglotResult.languageProperties.values() + polyglotResult.languageProperties.values(), ).some((props) => !!props.ligatures); } else { currentWordset = result; @@ -683,7 +683,7 @@ export async function generateWords( i, limit, Arrays.nthElementFromArray(ret.words, -1) ?? "", - Arrays.nthElementFromArray(ret.words, -2) ?? "" + Arrays.nthElementFromArray(ret.words, -2) ?? "", ); ret.words.push(nextWord.word); ret.sectionIndexes.push(nextWord.sectionIndex); @@ -740,7 +740,7 @@ export async function getNextWord( wordIndex: number, wordsBound: number, previousWord: string, - previousWord2: string | undefined + previousWord2: string | undefined, ): Promise { console.debug("Getting next word", { isRepeated: TestState.isRepeated, @@ -791,7 +791,7 @@ export async function getNextWord( throw new WordGenError("Repeated word is undefined"); } else { console.debug( - "Repeated word is undefined but random generation is allowed - getting random word" + "Repeated word is undefined but random generation is allowed - getting random word", ); } } else { @@ -847,7 +847,7 @@ export async function getNextWord( let firstAfterSplit = (randomWord.split(" ")[0] as string).toLowerCase(); let firstAfterSplitLazy = applyLazyModeToWord( firstAfterSplit, - currentLanguage + currentLanguage, ); while ( regenarationCount < 100 && @@ -869,7 +869,7 @@ export async function getNextWord( firstAfterSplit = randomWord.split(" ")[0] as string; firstAfterSplitLazy = applyLazyModeToWord( firstAfterSplit, - currentLanguage + currentLanguage, ); } } @@ -933,7 +933,7 @@ export async function getNextWord( previousWord, randomWord, wordIndex, - wordsBound + wordsBound, ); } if (Config.numbers) { diff --git a/frontend/src/ts/ui.ts b/frontend/src/ts/ui.ts index 414d7f0be9e3..780537796083 100644 --- a/frontend/src/ts/ui.ts +++ b/frontend/src/ts/ui.ts @@ -16,7 +16,7 @@ let isPreviewingFont = false; export function previewFontFamily(font: FontName): void { document.documentElement.style.setProperty( "--font", - '"' + font.replaceAll(/_/g, " ") + '", "Roboto Mono", "Vazirmatn"' + '"' + font.replaceAll(/_/g, " ") + '", "Roboto Mono", "Vazirmatn"', ); void TestUI.updateHintsPositionDebounced(); isPreviewingFont = true; @@ -61,7 +61,7 @@ if (isDevEnvironment()) { $("header #logo .top").text("localhost"); $("head title").text($("head title").text() + " (localhost)"); $("body").append( - `
local
local
` + `
local
local
`, ); } @@ -73,7 +73,7 @@ window.addEventListener("beforeunload", (event) => { Config.words, Config.time, CustomText.getData(), - isCustomTextLong() ?? false + isCustomTextLong() ?? false, ) ) { //ignore diff --git a/frontend/src/ts/utils/animated-modal.ts b/frontend/src/ts/utils/animated-modal.ts index 4cf42771d7b4..e89cd86cee01 100644 --- a/frontend/src/ts/utils/animated-modal.ts +++ b/frontend/src/ts/utils/animated-modal.ts @@ -54,7 +54,7 @@ const MODAL_ONLY_ANIMATION_MULTIPLIER = 0.75; export default class AnimatedModal< IncomingModalChainData = unknown, - OutgoingModalChainData = unknown + OutgoingModalChainData = unknown, > { private wrapperEl: HTMLDialogElement; private modalEl: HTMLElement; @@ -86,12 +86,12 @@ export default class AnimatedModal< const dialogElement = document.getElementById(constructorParams.dialogId); const modalElement = document.querySelector( - `#${constructorParams.dialogId} > .modal` + `#${constructorParams.dialogId} > .modal`, ) as HTMLElement; if (dialogElement === null) { throw new Error( - `Dialog element with id ${constructorParams.dialogId} not found` + `Dialog element with id ${constructorParams.dialogId} not found`, ); } @@ -101,13 +101,13 @@ export default class AnimatedModal< if (dialogElement === null) { throw new Error( - `Dialog element with id ${constructorParams.dialogId} not found` + `Dialog element with id ${constructorParams.dialogId} not found`, ); } if (modalElement === null) { throw new Error( - `Div element inside #${constructorParams.dialogId} with class 'modal' not found` + `Div element inside #${constructorParams.dialogId} with class 'modal' not found`, ); } @@ -221,7 +221,7 @@ export default class AnimatedModal< DEFAULT_ANIMATION_DURATION) * (options?.modalChain !== undefined ? MODAL_ONLY_ANIMATION_MULTIPLIER - : 1) + : 1), ); if (options?.modalChain !== undefined) { @@ -264,13 +264,13 @@ export default class AnimatedModal< const wrapperAnimationDuration = applyReducedMotion( options?.customAnimation?.wrapper?.duration ?? this.customShowAnimations?.wrapper?.duration ?? - DEFAULT_ANIMATION_DURATION + DEFAULT_ANIMATION_DURATION, ); const animationMode = this.previousModalInChain !== undefined ? "modalOnly" - : options?.animationMode ?? "both"; + : (options?.animationMode ?? "both"); if (animationMode === "both" || animationMode === "none") { if (hasModalAnimation) { @@ -292,7 +292,7 @@ export default class AnimatedModal< this.focusFirstInput(options?.focusFirstInput); await options?.afterAnimation?.( this.modalEl, - options?.modalChainData + options?.modalChainData, ); resolve(); }, @@ -307,7 +307,7 @@ export default class AnimatedModal< this.focusFirstInput(options?.focusFirstInput); await options?.afterAnimation?.( this.modalEl, - options?.modalChainData + options?.modalChainData, ); resolve(); }, @@ -346,7 +346,7 @@ export default class AnimatedModal< DEFAULT_ANIMATION_DURATION) * (this.previousModalInChain !== undefined ? MODAL_ONLY_ANIMATION_MULTIPLIER - : 1) + : 1), ); const wrapperAnimation = options?.customAnimation?.wrapper ?? this.customHideAnimations?.wrapper ?? { @@ -355,12 +355,12 @@ export default class AnimatedModal< const wrapperAnimationDuration = applyReducedMotion( options?.customAnimation?.wrapper?.duration ?? this.customHideAnimations?.wrapper?.duration ?? - DEFAULT_ANIMATION_DURATION + DEFAULT_ANIMATION_DURATION, ); const animationMode = this.previousModalInChain !== undefined ? "modalOnly" - : options?.animationMode ?? "both"; + : (options?.animationMode ?? "both"); if (animationMode === "both" || animationMode === "none") { if (hasModalAnimation) { diff --git a/frontend/src/ts/utils/arrays.ts b/frontend/src/ts/utils/arrays.ts index 5c18e8f7fae4..9a094f905bd4 100644 --- a/frontend/src/ts/utils/arrays.ts +++ b/frontend/src/ts/utils/arrays.ts @@ -10,7 +10,7 @@ import { randomIntFromRange } from "@monkeytype/util/numbers"; export function smooth( arr: number[], windowSize: number, - getter = (value: number): number => value + getter = (value: number): number => value, ): number[] { const get = getter; const result = []; @@ -47,7 +47,7 @@ export function smoothWithValueWindow( arr: number[], windowSize: number, valueWindowSize: number, - getter = (value: number): number => value + getter = (value: number): number => value, ): number[] { const get = getter; const result = []; @@ -139,7 +139,7 @@ export function randomElementFromArray(array: T[]): T { */ export function nthElementFromArray( array: T[], - index: number + index: number, ): T | undefined { index = index < 0 ? array.length + index : index; return array[index]; diff --git a/frontend/src/ts/utils/async-modules.ts b/frontend/src/ts/utils/async-modules.ts index bf5a222a9c49..ea50e333ec83 100644 --- a/frontend/src/ts/utils/async-modules.ts +++ b/frontend/src/ts/utils/async-modules.ts @@ -22,7 +22,7 @@ export async function getDevOptionsModal(): Promise< ) { Notifications.add( "Failed to load dev options module: could not fetch", - -1 + -1, ); } else { const msg = createErrorMessage(e, "Failed to load dev options module"); diff --git a/frontend/src/ts/utils/caret.ts b/frontend/src/ts/utils/caret.ts index ef7d00ff4b7a..3e000a1b6297 100644 --- a/frontend/src/ts/utils/caret.ts +++ b/frontend/src/ts/utils/caret.ts @@ -8,7 +8,7 @@ import { animate, EasingParam, JSAnimation } from "animejs"; const wordsCache = document.querySelector("#words") as HTMLElement; const wordsWrapperCache = document.querySelector( - "#wordsWrapper" + "#wordsWrapper", ) as HTMLElement; let lockedMainCaretInTape = true; @@ -64,7 +64,7 @@ export class Caret { "carrot", "banana", "monkey", - ] + ], ); this.element.classList.add(style); } @@ -244,12 +244,12 @@ export class Caret { Config.smoothCaret === "off" ? 0 : Config.smoothCaret === "slow" - ? 150 - : Config.smoothCaret === "medium" - ? 100 - : Config.smoothCaret === "fast" - ? 85 - : 0; + ? 150 + : Config.smoothCaret === "medium" + ? 100 + : Config.smoothCaret === "fast" + ? 85 + : 0; const finalDuration = options.duration ?? smoothCaretSpeed; @@ -283,7 +283,7 @@ export class Caret { if (this.style === "off") return; requestDebouncedAnimationFrame(`caret.${this.id}.goTo`, () => { const word = wordsCache.querySelector( - `.word[data-wordindex="${options.wordIndex}"]` + `.word[data-wordindex="${options.wordIndex}"]`, ); const letters = word?.querySelectorAll("letter") ?? []; const wordText = TestWords.words.get(options.wordIndex); @@ -400,7 +400,7 @@ export class Caret { const isWordRTL = isWordRightToLeft( options.wordText, options.isLanguageRightToLeft, - options.isDirectionReversed + options.isDirectionReversed, ); //if the letter is not visible, use the closest visible letter diff --git a/frontend/src/ts/utils/colors.ts b/frontend/src/ts/utils/colors.ts index 7704391cb569..2dc62862085e 100644 --- a/frontend/src/ts/utils/colors.ts +++ b/frontend/src/ts/utils/colors.ts @@ -12,7 +12,7 @@ export function blendTwoHexColors( color1: string, color2: string, - opacity: number + opacity: number, ): string { const rgb1 = hexToRgb(color1); const rgb2 = hexToRgb(color2); @@ -245,7 +245,7 @@ export function isColorDark(hex: string): boolean { */ export function rgbStringtoHex(rgb: string): string | undefined { const match: RegExpMatchArray | null = rgb.match( - /^rgb\((\d+), \s*(\d+), \s*(\d+)\)$/ + /^rgb\((\d+), \s*(\d+), \s*(\d+)\)$/, ); if (match === null) return; if (match.length < 3) return; diff --git a/frontend/src/ts/utils/config.ts b/frontend/src/ts/utils/config.ts index 064004b0953a..c8ccd6feac54 100644 --- a/frontend/src/ts/utils/config.ts +++ b/frontend/src/ts/utils/config.ts @@ -32,14 +32,14 @@ function mergeWithDefaultConfig(config: PartialConfig): Config { * remove all values from the config which are not valid */ function sanitizeConfig( - config: ConfigSchemas.PartialConfig + config: ConfigSchemas.PartialConfig, ): ConfigSchemas.PartialConfig { //make sure to use strip() return sanitize(ConfigSchemas.PartialConfigSchema.strip(), config); } function replaceLegacyValues( - configObj: ConfigSchemas.PartialConfig + configObj: ConfigSchemas.PartialConfig, ): ConfigSchemas.PartialConfig { //@ts-expect-error legacy configs if (configObj.quickTab === true && configObj.quickRestart === undefined) { @@ -128,14 +128,14 @@ function replaceLegacyValues( configObj.funbox = []; } else { configObj.funbox = (configObj.funbox as string).split( - "#" + "#", ) as FunboxName[]; } } if (typeof configObj.customLayoutfluid === "string") { configObj.customLayoutfluid = (configObj.customLayoutfluid as string).split( - "#" + "#", ) as ConfigSchemas.CustomLayoutFluid; } diff --git a/frontend/src/ts/utils/date-and-time.ts b/frontend/src/ts/utils/date-and-time.ts index 4dc30a8417f8..711953183dd3 100644 --- a/frontend/src/ts/utils/date-and-time.ts +++ b/frontend/src/ts/utils/date-and-time.ts @@ -17,7 +17,7 @@ export function secondsToString( alwaysShowHours = false, delimiter: ":" | "text" = ":", showSeconds = true, - showDays = false + showDays = false, ): string { sec = Math.abs(sec); let days = 0; diff --git a/frontend/src/ts/utils/debounced-animation-frame.ts b/frontend/src/ts/utils/debounced-animation-frame.ts index afb60c3e9c33..a491768aabfe 100644 --- a/frontend/src/ts/utils/debounced-animation-frame.ts +++ b/frontend/src/ts/utils/debounced-animation-frame.ts @@ -2,7 +2,7 @@ const pendingFrames = new Map(); export function requestDebouncedAnimationFrame( frameId: string, - callback: () => void + callback: () => void, ): void { cancelIfPending(frameId); const frame = requestAnimationFrame(() => { diff --git a/frontend/src/ts/utils/debug.ts b/frontend/src/ts/utils/debug.ts index 91f23f41fc9f..240f999ce2ad 100644 --- a/frontend/src/ts/utils/debug.ts +++ b/frontend/src/ts/utils/debug.ts @@ -5,15 +5,15 @@ const timings = new Map(); // Overloads for sync and async functions export function debugFunctionExecutionTime( func: (...options: unknown[]) => T, - funcName: string + funcName: string, ): T; export function debugFunctionExecutionTime( func: (...options: unknown[]) => Promise, - funcName: string + funcName: string, ): Promise; export function debugFunctionExecutionTime( func: (...options: unknown[]) => T | Promise, - funcName: string + funcName: string, ): T | Promise { const start = performance.now(); const ret = func(); @@ -58,7 +58,7 @@ function logTiming(start: number, funcName: string): void { start, end, funcName, - "monkeytype" + "monkeytype", ); console.timeStamp( `#${arr.length} profiling overhead`, @@ -66,6 +66,6 @@ function logTiming(start: number, funcName: string): void { end, endOverhead, funcName, - "monkeytype" + "monkeytype", ); } diff --git a/frontend/src/ts/utils/discord-avatar.ts b/frontend/src/ts/utils/discord-avatar.ts index 3748846fc5fe..b25cf6a33987 100644 --- a/frontend/src/ts/utils/discord-avatar.ts +++ b/frontend/src/ts/utils/discord-avatar.ts @@ -47,7 +47,7 @@ export function getAvatarElement( discordId?: string; discordAvatar?: string; }, - options?: Options + options?: Options, ): HTMLElement { if ( discordId === undefined || @@ -60,7 +60,7 @@ export function getAvatarElement( const element = buildElement( `https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png`, - options + options, ); return element; diff --git a/frontend/src/ts/utils/format.ts b/frontend/src/ts/utils/format.ts index 3daa0f1fe5f2..054d4d8fde8c 100644 --- a/frontend/src/ts/utils/format.ts +++ b/frontend/src/ts/utils/format.ts @@ -27,7 +27,7 @@ export class Formatting { typingSpeed( wpm: number | null | undefined, - formatOptions: FormatOptions = {} + formatOptions: FormatOptions = {}, ): string { const options = { ...FORMAT_DEFAULT_OPTIONS, ...formatOptions }; if (wpm === undefined || wpm === null) return options.fallback ?? ""; @@ -39,7 +39,7 @@ export class Formatting { percentage( percentage: number | null | undefined, - formatOptions: FormatOptions = {} + formatOptions: FormatOptions = {}, ): string { const options = { ...FORMAT_DEFAULT_OPTIONS, ...formatOptions }; options.suffix = "%" + (options.suffix ?? ""); @@ -49,7 +49,7 @@ export class Formatting { accuracy( accuracy: number | null | undefined, - formatOptions: FormatOptions = {} + formatOptions: FormatOptions = {}, ): string { return this.percentage(accuracy, { rounding: Math.floor, @@ -59,7 +59,7 @@ export class Formatting { decimals( value: number | null | undefined, - formatOptions: FormatOptions = {} + formatOptions: FormatOptions = {}, ): string { const options = { ...FORMAT_DEFAULT_OPTIONS, ...formatOptions }; return this.number(value, options); @@ -67,7 +67,7 @@ export class Formatting { private number( value: number | null | undefined, - formatOptions: FormatOptions + formatOptions: FormatOptions, ): string { if (value === undefined || value === null) return formatOptions.fallback ?? ""; @@ -85,7 +85,7 @@ export class Formatting { rank( position: number | null | undefined, - formatOptions: FallbackOptions = {} + formatOptions: FallbackOptions = {}, ): string { const options = { fallback: "-", ...formatOptions }; diff --git a/frontend/src/ts/utils/ip-addresses.ts b/frontend/src/ts/utils/ip-addresses.ts index cf88850cd030..fa25468a35a5 100644 --- a/frontend/src/ts/utils/ip-addresses.ts +++ b/frontend/src/ts/utils/ip-addresses.ts @@ -5,7 +5,7 @@ function getRandomIPvXaddress( parts: number, base: number, pad: boolean, - separator: string + separator: string, ): string { const addr: string[] = []; const b = Math.round(bits / parts); @@ -27,7 +27,7 @@ function getIPCidr( base: number, separator: string, address: string, - maskSize: number + maskSize: number, ): string { const addr = address.split(separator).map((a) => parseInt(a, base)); const b = Math.round(bits / parts); diff --git a/frontend/src/ts/utils/json-data.ts b/frontend/src/ts/utils/json-data.ts index 706c8d9fb8f8..29252857467b 100644 --- a/frontend/src/ts/utils/json-data.ts +++ b/frontend/src/ts/utils/json-data.ts @@ -43,7 +43,7 @@ async function fetchJson(url: string): Promise { */ export function memoizeAsync(...args: P[]) => Promise>( fn: T, - getKey?: (...args: Parameters) => P + getKey?: (...args: Parameters) => P, ): T { const cache = new Map>>(); @@ -71,7 +71,7 @@ export function memoizeAsync(...args: P[]) => Promise>( * @returns A promise that resolves to the cached JSON data. */ export const cachedFetchJson = memoizeAsync( - fetchJson + fetchJson, ); /** @@ -101,7 +101,7 @@ export async function getLanguage(lang: Language): Promise { // try { if (currentLanguage === undefined || currentLanguage.name !== lang) { const loaded = await cachedFetchJson( - `/languages/${lang}.json` + `/languages/${lang}.json`, ); if (!isDevEnvironment()) { @@ -112,7 +112,7 @@ export async function getLanguage(lang: Language): Promise { const hash = toHex(hashBuffer); if (hash !== languageHashes[lang]) { throw new Error( - "Integrity check failed. Try refreshing the page. If this error persists, please contact support." + "Integrity check failed. Try refreshing the page. If this error persists, please contact support.", ); } } @@ -122,7 +122,7 @@ export async function getLanguage(lang: Language): Promise { } export async function checkIfLanguageSupportsZipf( - language: Language + language: Language, ): Promise<"yes" | "no" | "unknown"> { const lang = await getLanguage(language); if (lang.orderedByFrequency === true) return "yes"; @@ -136,7 +136,7 @@ export async function checkIfLanguageSupportsZipf( * @returns A promise that resolves to the current language object. */ export async function getCurrentLanguage( - languageName: Language + languageName: Language, ): Promise { return await getLanguage(languageName); } @@ -233,7 +233,7 @@ type GithubRelease = { export async function getLatestReleaseFromGitHub(): Promise { type releaseType = { name: string }; const releases = await cachedFetchJson( - "https://api.github.com/repos/monkeytypegame/monkeytype/releases?per_page=1" + "https://api.github.com/repos/monkeytypegame/monkeytype/releases?per_page=1", ); if (releases[0] === undefined || releases[0].name === undefined) { throw new Error("No release found"); @@ -247,6 +247,6 @@ export async function getLatestReleaseFromGitHub(): Promise { */ export async function getReleasesFromGitHub(): Promise { return cachedFetchJson( - "https://api.github.com/repos/monkeytypegame/monkeytype/releases?per_page=5" + "https://api.github.com/repos/monkeytypegame/monkeytype/releases?per_page=5", ); } diff --git a/frontend/src/ts/utils/key-converter.ts b/frontend/src/ts/utils/key-converter.ts index b414abc4e8d2..328f0f144700 100644 --- a/frontend/src/ts/utils/key-converter.ts +++ b/frontend/src/ts/utils/key-converter.ts @@ -237,7 +237,7 @@ const rightSideKeys: Set = new Set([ */ export function layoutKeyToKeycode( key: string, - layout: LayoutObject + layout: LayoutObject, ): Keycode | undefined { const rows: string[][][] = Object.values(layout.keys); diff --git a/frontend/src/ts/utils/local-storage-with-schema.ts b/frontend/src/ts/utils/local-storage-with-schema.ts index 64637f182973..00365b510115 100644 --- a/frontend/src/ts/utils/local-storage-with-schema.ts +++ b/frontend/src/ts/utils/local-storage-with-schema.ts @@ -10,7 +10,7 @@ export class LocalStorageWithSchema { private fallback: T; private migrate?: ( value: Record | unknown[], - zodIssues?: ZodIssue[] + zodIssues?: ZodIssue[], ) => T; private cache?: T; @@ -20,7 +20,7 @@ export class LocalStorageWithSchema { fallback: T; migrate?: ( value: Record | unknown[], - zodIssues?: ZodIssue[] + zodIssues?: ZodIssue[], ) => T; }) { this.key = options.key; @@ -53,24 +53,24 @@ export class LocalStorageWithSchema { migrated = true; if (this.migrate) { console.debug( - `LS ${this.key} Migrating from old format to new format` + `LS ${this.key} Migrating from old format to new format`, ); this.cache = this.migrate(oldData, zodIssues); return this.cache; } else { console.debug( - `LS ${this.key} No migration function provided, returning fallback` + `LS ${this.key} No migration function provided, returning fallback`, ); this.cache = this.fallback; return this.cache; } }, - }) + }), ); if (error) { console.error( - `LS ${this.key} Failed to parse from localStorage: ${error.message}` + `LS ${this.key} Failed to parse from localStorage: ${error.message}`, ); window.localStorage.setItem(this.key, JSON.stringify(this.fallback)); this.cache = this.fallback; diff --git a/frontend/src/ts/utils/logger.ts b/frontend/src/ts/utils/logger.ts index 71783f2454f4..478f5189258a 100644 --- a/frontend/src/ts/utils/logger.ts +++ b/frontend/src/ts/utils/logger.ts @@ -29,7 +29,7 @@ function info(...args: unknown[]): void { nativeLog( "%cINFO", "background:#4CAF50;color: #111;padding:0 5px;border-radius:10px", - ...args + ...args, ); } @@ -37,7 +37,7 @@ function warn(...args: unknown[]): void { nativeWarn( "%cWRN", "background:#FFC107;color: #111;padding:0 5px;border-radius:10px", - ...args + ...args, ); } @@ -45,7 +45,7 @@ function error(...args: unknown[]): void { nativeError( "%cERR", "background:#F44336;color: #111;padding:0 5px;border-radius:10px", - ...args + ...args, ); } @@ -54,7 +54,7 @@ function debug(...args: unknown[]): void { nativeLog( "%cDEBG", "background:#2196F3;color: #111;padding:0 5px;border-radius:10px", - ...args + ...args, ); } diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index 2fbe06363193..9d4c26c8bfee 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -11,7 +11,7 @@ import { animate, AnimationParams } from "animejs"; export function whorf(speed: number, wordlen: number): number { return Math.min( speed, - Math.floor(speed * Math.pow(1.03, -2 * (wordlen - 3))) + Math.floor(speed * Math.pow(1.03, -2 * (wordlen - 3))), ); } @@ -54,7 +54,7 @@ export function convertNumberToHindi(numString: string): string { export function findGetParameter( parameterName: string, - getOverride?: string + getOverride?: string, ): string | null { let result = null; let tmp = []; @@ -77,7 +77,7 @@ export function findGetParameter( export function checkIfGetParameterExists( parameterName: string, - getOverride?: string + getOverride?: string, ): boolean { let result = false; let tmp = []; @@ -98,14 +98,16 @@ export function checkIfGetParameterExists( } export function objectToQueryString( - obj: Record + obj: Record, ): string { const str = []; for (const p in obj) { if (Object.prototype.hasOwnProperty.call(obj, p)) { // Arrays get encoded as a comma(%2C)-separated list str.push( - encodeURIComponent(p) + "=" + encodeURIComponent(obj[p] as unknown as T) + encodeURIComponent(p) + + "=" + + encodeURIComponent(obj[p] as unknown as T), ); } } @@ -162,7 +164,7 @@ export function clearTimeouts(timeouts: (number | NodeJS.Timeout)[]): void { export function regexIndexOf( string: string, regex: RegExp, - startpos: number + startpos: number, ): number { const indexOf = string.substring(startpos || 0).search(regex); return indexOf >= 0 ? indexOf + (startpos || 0) : indexOf; @@ -175,7 +177,7 @@ type LastIndex = { // TODO INVESTIGATE IF THIS IS NEEDED // eslint-disable-next-line no-extend-native (String.prototype as LastIndex).lastIndexOfRegex = function ( - regex: RegExp + regex: RegExp, ): number { const match = this.match(regex); return match ? this.lastIndexOf(lastElementFromArray(match) as string) : -1; @@ -192,7 +194,7 @@ export async function swapElements( }, middleCallback = async function (): Promise { return Promise.resolve(); - } + }, ): Promise { if (el1 === null || el2 === null) { return; @@ -247,7 +249,7 @@ export async function swapElements( export function getMode2( config: Config, - randomQuote: { id: number } | null + randomQuote: { id: number } | null, ): Mode2 { const mode = config.mode; let retVal: string; @@ -393,7 +395,7 @@ export function isPopupVisible(popupId: string): boolean { export function isAnyPopupVisible(): boolean { const popups = document.querySelectorAll( - "#popups .popupWrapper, #popups .backdrop, #popups .modalWrapper" + "#popups .popupWrapper, #popups .backdrop, #popups .modalWrapper", ); let popupVisible = false; for (const popup of popups) { @@ -441,7 +443,7 @@ export type JQueryEasing = export async function promiseAnimate( el: HTMLElement, - options: AnimationParams + options: AnimationParams, ): Promise { return new Promise((resolve) => { animate(el, { @@ -553,7 +555,7 @@ export function getBoundingRectOfElements(elements: HTMLElement[]): DOMRect { } export function typedKeys( - obj: T + obj: T, ): T extends T ? (keyof T)[] : never { return Object.keys(obj) as unknown as T extends T ? (keyof T)[] : never; } @@ -623,15 +625,15 @@ export function promiseWithResolvers(): { */ export function debounceUntilResolved( fn: (...args: TArgs) => TResult, - options?: { rejectSkippedCalls?: true } + options?: { rejectSkippedCalls?: true }, ): (...args: TArgs) => Promise; export function debounceUntilResolved( fn: (...args: TArgs) => TResult, - options: { rejectSkippedCalls: false } + options: { rejectSkippedCalls: false }, ): (...args: TArgs) => Promise; export function debounceUntilResolved( fn: (...args: TArgs) => TResult, - { rejectSkippedCalls = true }: { rejectSkippedCalls?: boolean } = {} + { rejectSkippedCalls = true }: { rejectSkippedCalls?: boolean } = {}, ): (...args: TArgs) => Promise { let isLocked = false; let next: { @@ -659,7 +661,7 @@ export function debounceUntilResolved( if (next) { if (rejectSkippedCalls) { next.reject( - new Error("skipped call: call was superseded by a more recent one") + new Error("skipped call: call was superseded by a more recent one"), ); } else { next.resolve(null); @@ -734,7 +736,7 @@ export function formatTypingStatsRatio(stats: { } return { completedPercentage: Math.floor( - (stats.completedTests / stats.startedTests) * 100 + (stats.completedTests / stats.startedTests) * 100, ).toString(), restartRatio: ( (stats.startedTests - stats.completedTests) / diff --git a/frontend/src/ts/utils/numbers.ts b/frontend/src/ts/utils/numbers.ts index 7e2a30a0a6cf..7141d1e7a852 100644 --- a/frontend/src/ts/utils/numbers.ts +++ b/frontend/src/ts/utils/numbers.ts @@ -84,7 +84,7 @@ export function abbreviateNumber(num: number, decimalPoints = 1): string { * or null if the array is empty. */ export function findLineByLeastSquares( - values_y: number[] + values_y: number[], ): [[number, number], [number, number]] | null { let sum_x = 0; let sum_y = 0; @@ -129,7 +129,7 @@ export function findLineByLeastSquares( const returnpoint1 = [1, 1 * m + b] as [number, number]; const returnpoint2 = [values_length, values_length * m + b] as [ number, - number + number, ]; return [returnpoint1, returnpoint2]; } @@ -143,7 +143,7 @@ export function findLineByLeastSquares( */ export function parseIntOptional( value: T, - radix: number = 10 + radix: number = 10, ): T extends string ? number : undefined { return ( value !== null && value !== undefined ? parseInt(value, radix) : undefined diff --git a/frontend/src/ts/utils/quick-restart.ts b/frontend/src/ts/utils/quick-restart.ts index 4bf06b45dde3..31a77c539589 100644 --- a/frontend/src/ts/utils/quick-restart.ts +++ b/frontend/src/ts/utils/quick-restart.ts @@ -5,7 +5,7 @@ export function canQuickRestart( words: number, time: number, CustomText: CustomTextSettings, - customTextIsLong: boolean + customTextIsLong: boolean, ): boolean { const wordsLong = mode === "words" && (words >= 1000 || words === 0); const timeLong = mode === "time" && (time >= 900 || time === 0); diff --git a/frontend/src/ts/utils/remote-validation.ts b/frontend/src/ts/utils/remote-validation.ts index 0b90198fdaaa..3aac4366e4b1 100644 --- a/frontend/src/ts/utils/remote-validation.ts +++ b/frontend/src/ts/utils/remote-validation.ts @@ -5,13 +5,13 @@ type IsValidResonseOrFunction = | IsValidResponse; export function remoteValidation( call: ( - val: V + val: V, ) => Promise<{ status: number; body: { data?: T; message: string } }>, options?: { check?: (data: T) => IsValidResponse; on4xx?: IsValidResonseOrFunction; on5xx?: IsValidResonseOrFunction; - } + }, ): (val: V) => Promise { return async (val) => { const result = await call(val); diff --git a/frontend/src/ts/utils/results.ts b/frontend/src/ts/utils/results.ts index 18f742978939..fc10e6ba3cc7 100644 --- a/frontend/src/ts/utils/results.ts +++ b/frontend/src/ts/utils/results.ts @@ -16,7 +16,7 @@ export async function syncNotSignedInLastResult(uid: string): Promise { if (response.status !== 200) { Notifications.add( "Failed to save last result: " + response.body.message, - -1 + -1, ); return; } @@ -25,7 +25,7 @@ export async function syncNotSignedInLastResult(uid: string): Promise { // but now with the stronger types it shows that we are forcing completed event // into a snapshot result - might not cuase issues but worth investigating const result = structuredClone( - notSignedInLastResult + notSignedInLastResult, ) as unknown as SnapshotResult; const dataToSave: DB.SaveLocalResultData = { @@ -43,6 +43,6 @@ export async function syncNotSignedInLastResult(uid: string): Promise { TestLogic.clearNotSignedInResult(); Notifications.add( `Last test result saved ${response.body.data.isPb ? `(new pb!)` : ""}`, - 1 + 1, ); } diff --git a/frontend/src/ts/utils/sanitize.ts b/frontend/src/ts/utils/sanitize.ts index d09d9b129e39..9398db54d76f 100644 --- a/frontend/src/ts/utils/sanitize.ts +++ b/frontend/src/ts/utils/sanitize.ts @@ -2,7 +2,7 @@ import { z } from "zod"; function removeProblems( obj: T, - problems: (number | string)[] + problems: (number | string)[], ): T | undefined { if (Array.isArray(obj)) { if (problems.length === obj.length) return undefined; @@ -13,7 +13,7 @@ function removeProblems( if (problems.length === entries.length) return undefined; return Object.fromEntries( - entries.filter(([key]) => !problems.includes(key)) + entries.filter(([key]) => !problems.includes(key)), ) as T; } } @@ -32,7 +32,7 @@ function getNestedValue(obj: [] | object, path: string[]): [] | object { */ export function sanitize( schema: T, - obj: z.infer + obj: z.infer, ): z.infer { const maxAttempts = 2; let result; diff --git a/frontend/src/ts/utils/search-service.ts b/frontend/src/ts/utils/search-service.ts index 14644c21dbeb..2773f3c29c2c 100644 --- a/frontend/src/ts/utils/search-service.ts +++ b/frontend/src/ts/utils/search-service.ts @@ -36,7 +36,7 @@ const DEFAULT_OPTIONS: SearchServiceOptions = { function inverseDocumentFrequency( numberOfDocuments: number, - numberOfDocumentsWithTerm: number + numberOfDocumentsWithTerm: number, ): number { if (numberOfDocumentsWithTerm === 0) { return 0; @@ -49,7 +49,7 @@ const ALPHA = 0.4; // Smoothing term that dampens the contribution of tf/max tf function normalizedTermFrequency( term: string, - document: InternalDocument + document: InternalDocument, ): number { return ( ALPHA + @@ -65,7 +65,7 @@ function tokenize(text: string): string[] { export const buildSearchService = ( documents: T[], getSearchableText: TextExtractor, - options: SearchServiceOptions = DEFAULT_OPTIONS + options: SearchServiceOptions = DEFAULT_OPTIONS, ): SearchService => { const reverseIndex: ReverseIndex = {}; const normalizedTokenToOriginal: TokenMap = {}; @@ -101,7 +101,7 @@ export const buildSearchService = ( (internalDocument.termFrequencies[stemmedToken] as number)++; maxTermFrequency = Math.max( maxTermFrequency, - internalDocument.termFrequencies[stemmedToken] as number + internalDocument.termFrequencies[stemmedToken] as number, ); }); @@ -117,7 +117,7 @@ export const buildSearchService = ( }; const normalizedSearchQuery = new Set( - tokenize(searchQuery).map((token) => stemmer(token)) + tokenize(searchQuery).map((token) => stemmer(token)), ); if (normalizedSearchQuery.size === 0) { return searchResult; @@ -138,7 +138,7 @@ export const buildSearchService = ( const idf = inverseDocumentFrequency( documents.length, - documentMatches.size + documentMatches.size, ); documentMatches.forEach((document) => { const currentScore = results.get(document.id) ?? 0; diff --git a/frontend/src/ts/utils/simple-modal.ts b/frontend/src/ts/utils/simple-modal.ts index 599d821b8102..b1452dadf3e2 100644 --- a/frontend/src/ts/utils/simple-modal.ts +++ b/frontend/src/ts/utils/simple-modal.ts @@ -36,7 +36,7 @@ type CommonInput = { */ isValid?: ( value: string, - thisPopup: SimpleModal + thisPopup: SimpleModal, ) => Promise; }; }; @@ -231,7 +231,7 @@ export class SimpleModal { classes, attributes, innerHTML: input.initVal, - }) + }), ); } else if (input.type === "checkbox") { let html = buildTag({ tagname, classes, attributes }); @@ -278,19 +278,19 @@ export class SimpleModal { if (input.min !== undefined) { attributes["min"] = dateFormat( input.min, - "yyyy-MM-dd'T'HH:mm:ss" + "yyyy-MM-dd'T'HH:mm:ss", ); } if (input.max !== undefined) { attributes["max"] = dateFormat( input.max, - "yyyy-MM-dd'T'HH:mm:ss" + "yyyy-MM-dd'T'HH:mm:ss", ); } if (input.initVal !== undefined) { attributes["value"] = dateFormat( input.initVal, - "yyyy-MM-dd'T'HH:mm:ss" + "yyyy-MM-dd'T'HH:mm:ss", ); } break; @@ -316,7 +316,7 @@ export class SimpleModal { inputs.append(buildTag({ tagname, classes, attributes })); } const element = document.querySelector( - "#" + attributes["id"] + "#" + attributes["id"], ) as HTMLInputElement; const originalOnInput = element.oninput; @@ -387,7 +387,7 @@ export class SimpleModal { } else { this.enableInputs(); $($("#simpleModal").find("input")[0] as HTMLInputElement).trigger( - "focus" + "focus", ); } }); @@ -447,7 +447,7 @@ export class SimpleModal { updateSubmitButtonState(): void { const button = this.element.querySelector( - ".submitButton" + ".submitButton", ) as HTMLButtonElement; if (button === null) return; diff --git a/frontend/src/ts/utils/sorted-table.ts b/frontend/src/ts/utils/sorted-table.ts index 43b3afd7ec5f..62d536c01732 100644 --- a/frontend/src/ts/utils/sorted-table.ts +++ b/frontend/src/ts/utils/sorted-table.ts @@ -97,7 +97,7 @@ export class SortedTable { .append( `` + } aria-hidden="true">`, ); this.data.sort((a, b) => { @@ -132,7 +132,7 @@ export class SortedTable { data.element = this.buildRow(data.source); } return data.element; - }) + }), ); } protected getData(): { source: T; element?: HTMLTableRowElement }[] { diff --git a/frontend/src/ts/utils/strings.ts b/frontend/src/ts/utils/strings.ts index 576029df0b6a..ff2cdfa1083b 100644 --- a/frontend/src/ts/utils/strings.ts +++ b/frontend/src/ts/utils/strings.ts @@ -112,7 +112,7 @@ export function highlightMatches(text: string, matches: string[]): string { // matches that don't have a letter before or after them const pattern = new RegExp( `(?$&
'); @@ -126,7 +126,7 @@ export function highlightMatches(text: string, matches: string[]): string { */ export function getLanguageDisplayString( language: Language, - noSizeString = false + noSizeString = false, ): string { let out = ""; if (noSizeString) { @@ -171,7 +171,7 @@ export function cleanTypographySymbols(textToClean: string): string { }; return textToClean.replace( /[“”’‘—,…«»–\u2007\u202F\u00A0]/g, - (char) => specials[char as keyof typeof specials] || "" + (char) => specials[char as keyof typeof specials] || "", ); } @@ -239,7 +239,7 @@ export function clearWordDirectionCache(): void { export function isWordRightToLeft( word: string | undefined, languageRTL: boolean, - reverseDirection?: boolean + reverseDirection?: boolean, ): boolean { if (word === undefined || word.length === 0) { return reverseDirection ? !languageRTL : languageRTL; @@ -284,7 +284,7 @@ export const LANGUAGE_EQUIVALENCE_SETS: Partial>> = export function areCharactersVisuallyEqual( char1: string, char2: string, - language?: Language + language?: Language, ): boolean { // If characters are exactly the same, they're equivalent if (char1 === char2) { diff --git a/frontend/src/ts/utils/typing-speed-units.ts b/frontend/src/ts/utils/typing-speed-units.ts index ed2d17486de5..7539f1e54102 100644 --- a/frontend/src/ts/utils/typing-speed-units.ts +++ b/frontend/src/ts/utils/typing-speed-units.ts @@ -20,7 +20,7 @@ class Unit implements TypingSpeedUnitSettings { convertFactor: number, fullUnitString: string, histogramDataBucketSize: number, - historyStepSize: number + historyStepSize: number, ) { this.unit = unit; this.convertFactor = convertFactor; diff --git a/frontend/src/ts/utils/url-handler.ts b/frontend/src/ts/utils/url-handler.ts index 8f719cd577bd..cb205a6105e2 100644 --- a/frontend/src/ts/utils/url-handler.ts +++ b/frontend/src/ts/utils/url-handler.ts @@ -87,7 +87,7 @@ export function loadCustomThemeFromUrl(getOverride?: string): void { if (getValue === null) return; const { data: decoded, error } = tryCatchSync(() => - parseJsonWithSchema(atob(getValue), customThemeUrlDataSchema) + parseJsonWithSchema(atob(getValue), customThemeUrlDataSchema), ); if (error) { console.log("Custom theme URL decoding failed", error); @@ -167,13 +167,13 @@ export function loadTestSettingsFromUrl(getOverride?: string): void { // otherwise eiko will be sad const { data: de, error } = tryCatchSync(() => - parseJsonWithSchema(decompressFromURI(getValue) ?? "", TestSettingsSchema) + parseJsonWithSchema(decompressFromURI(getValue) ?? "", TestSettingsSchema), ); if (error) { console.error("Failed to parse test settings:", error); Notifications.add( "Failed to load test settings from URL: " + error.message, - 0 + 0, ); return; } diff --git a/frontend/static/funbox/crt.css b/frontend/static/funbox/crt.css index 4225586e43ac..c09a984186d1 100644 --- a/frontend/static/funbox/crt.css +++ b/frontend/static/funbox/crt.css @@ -57,8 +57,10 @@ body.crtmode input, body.crtmode button, body.crtmode textarea, body.crtmode #bannerCenter .banner { - text-shadow: 3px 0 1px color-mix(in srgb, currentColor 20%, transparent), - -3px 0 color-mix(in srgb, currentColor 30%, transparent), 0 0 3px; + text-shadow: + 3px 0 1px color-mix(in srgb, currentColor 20%, transparent), + -3px 0 color-mix(in srgb, currentColor 30%, transparent), + 0 0 3px; } body.crtmode #testConfig, @@ -68,37 +70,46 @@ body.crtmode #testModesNotice { body.crtmode #testConfig .textButton, body.crtmode #testModesNotice .textButton { - text-shadow: 3px 0 1px var(--crt-sub-color-glow), - -3px 0 var(--crt-sub-color-glow), 0 0 3px; + text-shadow: + 3px 0 1px var(--crt-sub-color-glow), + -3px 0 var(--crt-sub-color-glow), + 0 0 3px; } body.crtmode #testConfig .textButton:hover, body.crtmode #testModesNotice .textButton:hover { - text-shadow: 3px 0 1px var(--crt-text-color-glow), - -3px 0 var(--crt-text-color-glow), 0 0 3px; + text-shadow: + 3px 0 1px var(--crt-text-color-glow), + -3px 0 var(--crt-text-color-glow), + 0 0 3px; } body.crtmode #testConfig .textButton.active, body.crtmode #testModesNotice .textButton.active { - text-shadow: 3px 0 1px var(--crt-main-color-glow), - -3px 0 var(--crt-main-color-glow), 0 0 3px; + text-shadow: + 3px 0 1px var(--crt-main-color-glow), + -3px 0 var(--crt-main-color-glow), + 0 0 3px; } body.crtmode #testConfig .row, body.crtmode #testModesNotice .row { - box-shadow: 3px 0 1px var(--crt-sub-alt-color-glow), + box-shadow: + 3px 0 1px var(--crt-sub-alt-color-glow), -3px 0 var(--crt-sub-alt-color-glow); } body.crtmode #caret { - box-shadow: 3px 0 1px var(--crt-caret-color-glow), + box-shadow: + 3px 0 1px var(--crt-caret-color-glow), -3px 0 var(--crt-caret-color-glow); } body.crtmode #paceCaret, body.crtmode key, body.crtmode #bannerCenter .banner { - box-shadow: 3px 0 1px var(--crt-sub-color-glow), + box-shadow: + 3px 0 1px var(--crt-sub-color-glow), -3px 0 var(--crt-sub-color-glow); } @@ -132,28 +143,38 @@ body.crtmode nav .accountButtonAndMenu .view-account .xpBar .xpBreakdown { body.crtmode .button, body.crtmode .scrollToTopButton { - box-shadow: 3px 0 1px var(--crt-sub-alt-color-glow), - -3px 0 var(--crt-sub-alt-color-glow), 0 0 3px var(--crt-sub-alt-color-glow); + box-shadow: + 3px 0 1px var(--crt-sub-alt-color-glow), + -3px 0 var(--crt-sub-alt-color-glow), + 0 0 3px var(--crt-sub-alt-color-glow); } body.crtmode .button.active, body.crtmode .scrollToTopButton.active { - box-shadow: 3px 0 1px var(--crt-main-color-glow), - -3px 0 var(--crt-main-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-main-color-glow), + -3px 0 var(--crt-main-color-glow), + 0 0 3px; } body.crtmode .button:hover, body.crtmode .scrollToTopButton:hover { - box-shadow: 3px 0 1px var(--crt-text-color-glow), - -3px 0 var(--crt-text-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-text-color-glow), + -3px 0 var(--crt-text-color-glow), + 0 0 3px; } body.crtmode #keymap .keymapKey { - box-shadow: 3px 0 1px var(--crt-sub-color-glow), - -3px 0 var(--crt-sub-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-sub-color-glow), + -3px 0 var(--crt-sub-color-glow), + 0 0 3px; } body.crtmode #keymap .keymapKey.activeKey { - box-shadow: 3px 0 1px var(--crt-main-color-glow), - -3px 0 var(--crt-main-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-main-color-glow), + -3px 0 var(--crt-main-color-glow), + 0 0 3px; } diff --git a/frontend/static/themes/chaos_theory.css b/frontend/static/themes/chaos_theory.css index dee141b79fb0..b83c69612526 100644 --- a/frontend/static/themes/chaos_theory.css +++ b/frontend/static/themes/chaos_theory.css @@ -147,43 +147,59 @@ nav > .textButton:nth-child(8) { } body.crtmode nav .textButton:nth-child(1) { - box-shadow: 3px 0 1px color-mix(in srgb, #ab92e1 20%, transparent), - -3px 0 color-mix(in srgb, #ab92e1 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #ab92e1 20%, transparent), + -3px 0 color-mix(in srgb, #ab92e1 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(2) { - box-shadow: 3px 0 1px color-mix(in srgb, #f3ea5d 20%, transparent), - -3px 0 color-mix(in srgb, #f3ea5d 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #f3ea5d 20%, transparent), + -3px 0 color-mix(in srgb, #f3ea5d 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(3) { - box-shadow: 3px 0 1px color-mix(in srgb, #7ae1bf 20%, transparent), - -3px 0 color-mix(in srgb, #7ae1bf 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #7ae1bf 20%, transparent), + -3px 0 color-mix(in srgb, #7ae1bf 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(4) { - box-shadow: 3px 0 1px color-mix(in srgb, #ff5869 20%, transparent), - -3px 0 color-mix(in srgb, #ff5869 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #ff5869 20%, transparent), + -3px 0 color-mix(in srgb, #ff5869 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(5) { - box-shadow: 3px 0 1px color-mix(in srgb, #fc76d9 20%, transparent), - -3px 0 color-mix(in srgb, #fc76d9 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #fc76d9 20%, transparent), + -3px 0 color-mix(in srgb, #fc76d9 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(6) { - box-shadow: 3px 0 1px color-mix(in srgb, #fc76d9 20%, transparent), - -3px 0 color-mix(in srgb, #fc76d9 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #fc76d9 20%, transparent), + -3px 0 color-mix(in srgb, #fc76d9 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(7) { - box-shadow: 3px 0 1px color-mix(in srgb, #ab92e1 20%, transparent), - -3px 0 color-mix(in srgb, #ab92e1 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #ab92e1 20%, transparent), + -3px 0 color-mix(in srgb, #ab92e1 30%, transparent), + 0 0 3px; } body.crtmode nav .textButton:nth-child(8) { - box-shadow: 3px 0 1px color-mix(in srgb, #f3ea5d 20%, transparent), - -3px 0 color-mix(in srgb, #f3ea5d 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #f3ea5d 20%, transparent), + -3px 0 color-mix(in srgb, #f3ea5d 30%, transparent), + 0 0 3px; } body.crtmode #caret { @@ -193,6 +209,7 @@ body.crtmode #caret { } body.crtmode header.focus nav .textButton { - box-shadow: 3px 0 1px var(--crt-sub-color-glow), + box-shadow: + 3px 0 1px var(--crt-sub-color-glow), -3px 0 var(--crt-sub-color-glow); } diff --git a/frontend/static/themes/dmg.css b/frontend/static/themes/dmg.css index 2c5fdb48aff9..265e47bd1243 100644 --- a/frontend/static/themes/dmg.css +++ b/frontend/static/themes/dmg.css @@ -36,8 +36,10 @@ nav > .textButton { } body.crtmode nav > .textButton { - box-shadow: 3px 0 1px var(--crt-main-color-glow), - -3px 0 var(--crt-main-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-main-color-glow), + -3px 0 var(--crt-main-color-glow), + 0 0 3px; } body.crtmode header.focus nav > .textButton, @@ -46,6 +48,8 @@ body.crtmode nav > .textButton:hover { } body.crtmode header.focus nav > .textButton:nth-child(1) { - box-shadow: 3px 0 1px color-mix(in srgb, #e34c6c 20%, transparent), - -3px 0 color-mix(in srgb, #e34c6c 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #e34c6c 20%, transparent), + -3px 0 color-mix(in srgb, #e34c6c 30%, transparent), + 0 0 3px; } diff --git a/frontend/static/themes/dots.css b/frontend/static/themes/dots.css index 64d825ebca09..fc10096afd99 100644 --- a/frontend/static/themes/dots.css +++ b/frontend/static/themes/dots.css @@ -93,37 +93,50 @@ nav > .textButton.view-account .xpBar { } body.crtmode nav > .textButton:nth-child(1) { - box-shadow: 3px 0 1px color-mix(in srgb, #f94348 20%, transparent), - -3px 0 color-mix(in srgb, #f94348 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #f94348 20%, transparent), + -3px 0 color-mix(in srgb, #f94348 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(2) { - box-shadow: 3px 0 1px color-mix(in srgb, #9261ff 20%, transparent), - -3px 0 color-mix(in srgb, #9261ff 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #9261ff 20%, transparent), + -3px 0 color-mix(in srgb, #9261ff 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(3) { - box-shadow: 3px 0 1px color-mix(in srgb, #3cc5f8 20%, transparent), - -3px 0 color-mix(in srgb, #3cc5f8 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #3cc5f8 20%, transparent), + -3px 0 color-mix(in srgb, #3cc5f8 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(4) { - box-shadow: 3px 0 1px color-mix(in srgb, #4acb8a 20%, transparent), - -3px 0 color-mix(in srgb, #4acb8a 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #4acb8a 20%, transparent), + -3px 0 color-mix(in srgb, #4acb8a 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(7) { - box-shadow: 3px 0 1px color-mix(in srgb, #ffd543 20%, transparent), - -3px 0 color-mix(in srgb, #ffd543 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #ffd543 20%, transparent), + -3px 0 color-mix(in srgb, #ffd543 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(8) { - box-shadow: 3px 0 1px color-mix(in srgb, #ff9349 20%, transparent), - -3px 0 color-mix(in srgb, #ff9349 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #ff9349 20%, transparent), + -3px 0 color-mix(in srgb, #ff9349 30%, transparent), + 0 0 3px; } body.crtmode header.focus nav > .textButton { - box-shadow: 3px 0 1px var(--crt-sub-color-glow), + box-shadow: + 3px 0 1px var(--crt-sub-color-glow), -3px 0 var(--crt-sub-color-glow); } diff --git a/frontend/static/themes/lavender.css b/frontend/static/themes/lavender.css index eb9660965142..4c7b513e3ba8 100644 --- a/frontend/static/themes/lavender.css +++ b/frontend/static/themes/lavender.css @@ -23,6 +23,8 @@ nav .textButton:hover { } body.crtmode nav .textButton { - box-shadow: 3px 0 1px var(--crt-text-color-glow), - -3px 0 var(--crt-text-color-glow), 0 0 3px; + box-shadow: + 3px 0 1px var(--crt-text-color-glow), + -3px 0 var(--crt-text-color-glow), + 0 0 3px; } diff --git a/frontend/static/themes/moonlight.css b/frontend/static/themes/moonlight.css index e2761f6440e0..916bae0336b0 100644 --- a/frontend/static/themes/moonlight.css +++ b/frontend/static/themes/moonlight.css @@ -51,8 +51,10 @@ body.crtmode nav > .textButton:nth-child(1), body.crtmode nav > .textButton:nth-child(2), body.crtmode nav > .textButton:nth-child(3), body.crtmode nav > .textButton:nth-child(4) { - box-shadow: 3px 0 1px color-mix(in srgb, #c69f68 20%, transparent), - -3px 0 color-mix(in srgb, #c69f68 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #c69f68 20%, transparent), + -3px 0 color-mix(in srgb, #c69f68 30%, transparent), + 0 0 3px; } body.crtmode header.focus nav > .textButton { diff --git a/frontend/static/themes/phantom.css b/frontend/static/themes/phantom.css index ea1f5e63f5c9..718de9968d02 100644 --- a/frontend/static/themes/phantom.css +++ b/frontend/static/themes/phantom.css @@ -14,27 +14,39 @@ @keyframes tokyo-glow { 0% { color: #c0caf5; - text-shadow: 0 0 5px #7aa2f7, 0 0 10px #bb9af7; + text-shadow: + 0 0 5px #7aa2f7, + 0 0 10px #bb9af7; } 50% { color: #c0caf5; - text-shadow: 0 0 8px #7dcfff, 0 0 15px #bb9af7; + text-shadow: + 0 0 8px #7dcfff, + 0 0 15px #bb9af7; } 100% { color: #c0caf5; - text-shadow: 0 0 5px #7aa2f7, 0 0 10px #bb9af7; + text-shadow: + 0 0 5px #7aa2f7, + 0 0 10px #bb9af7; } } @keyframes tokyo-glow-incorrect { 0% { - text-shadow: 0 0 5px #f7768e, 0 0 10px #db4b4b; + text-shadow: + 0 0 5px #f7768e, + 0 0 10px #db4b4b; } 50% { - text-shadow: 0 0 8px #ff7a93, 0 0 15px #ff9e64; + text-shadow: + 0 0 8px #ff7a93, + 0 0 15px #ff9e64; } 100% { - text-shadow: 0 0 5px #f7768e, 0 0 10px #db4b4b; + text-shadow: + 0 0 5px #f7768e, + 0 0 10px #db4b4b; } } diff --git a/frontend/static/themes/rainbow_trail.css b/frontend/static/themes/rainbow_trail.css index 9bc10e2a1a86..f7a8c466eb24 100644 --- a/frontend/static/themes/rainbow_trail.css +++ b/frontend/static/themes/rainbow_trail.css @@ -264,27 +264,43 @@ button:not(.textButton):not(.text):hover { @keyframes glowing-button { 0% { - box-shadow: 0 0 7.5px 2.5px #60b6ce, 0 0 12.5px 2.5px #60b6ce; + box-shadow: + 0 0 7.5px 2.5px #60b6ce, + 0 0 12.5px 2.5px #60b6ce; } 14% { - box-shadow: 0 0 7.5px 2.5px #7ce3e1, 0 0 12.5px 2.5px #7ce3e1; + box-shadow: + 0 0 7.5px 2.5px #7ce3e1, + 0 0 12.5px 2.5px #7ce3e1; } 28% { - box-shadow: 0 0 7.5px 2.5px #b2e259, 0 0 12.5px 2.5px #b2e259; + box-shadow: + 0 0 7.5px 2.5px #b2e259, + 0 0 12.5px 2.5px #b2e259; } 42% { - box-shadow: 0 0 7.5px 2.5px #f6ee75, 0 0 12.5px 2.5px #f6ee75; + box-shadow: + 0 0 7.5px 2.5px #f6ee75, + 0 0 12.5px 2.5px #f6ee75; } 57% { - box-shadow: 0 0 7.5px 2.5px #f5b83d, 0 0 12.5px 2.5px #f5b83d; + box-shadow: + 0 0 7.5px 2.5px #f5b83d, + 0 0 12.5px 2.5px #f5b83d; } 71% { - box-shadow: 0 0 7.5px 2.5px #f49a98, 0 0 12.5px 2.5px #f49a98; + box-shadow: + 0 0 7.5px 2.5px #f49a98, + 0 0 12.5px 2.5px #f49a98; } 85% { - box-shadow: 0 0 7.5px 2.5px #ed7abd, 0 0 12.5px 2.5px #ed7abd; + box-shadow: + 0 0 7.5px 2.5px #ed7abd, + 0 0 12.5px 2.5px #ed7abd; } 100% { - box-shadow: 0 0 7.5px 2.5px #dea2fa, 0 0 12.5px 2.5px #dea2fa; + box-shadow: + 0 0 7.5px 2.5px #dea2fa, + 0 0 12.5px 2.5px #dea2fa; } } diff --git a/frontend/static/themes/snes.css b/frontend/static/themes/snes.css index ed3148931f8f..460250393071 100644 --- a/frontend/static/themes/snes.css +++ b/frontend/static/themes/snes.css @@ -60,42 +60,58 @@ header.focus nav > .textButton.discord::after { } body.crtmode nav > .textButton:nth-child(1) { - box-shadow: 3px 0 1px color-mix(in srgb, #553d94 20%, transparent), - -3px 0 color-mix(in srgb, #553d94 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #553d94 20%, transparent), + -3px 0 color-mix(in srgb, #553d94 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(2) { - box-shadow: 3px 0 1px color-mix(in srgb, #6851a4 20%, transparent), - -3px 0 color-mix(in srgb, #6851a4 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #6851a4 20%, transparent), + -3px 0 color-mix(in srgb, #6851a4 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(3) { - box-shadow: 3px 0 1px color-mix(in srgb, #7962b3 20%, transparent), - -3px 0 color-mix(in srgb, #7962b3 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #7962b3 20%, transparent), + -3px 0 color-mix(in srgb, #7962b3 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(4) { - box-shadow: 3px 0 1px color-mix(in srgb, #8c76c3 20%, transparent), - -3px 0 color-mix(in srgb, #8c76c3 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #8c76c3 20%, transparent), + -3px 0 color-mix(in srgb, #8c76c3 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(5) { - box-shadow: 3px 0 1px color-mix(in srgb, #9f8ad4 20%, transparent), - -3px 0 color-mix(in srgb, #9f8ad4 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #9f8ad4 20%, transparent), + -3px 0 color-mix(in srgb, #9f8ad4 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(6), body.crtmode nav > .textButton:nth-child(7) { - box-shadow: 3px 0 1px color-mix(in srgb, #9f8ad4 20%, transparent), - -3px 0 color-mix(in srgb, #9f8ad4 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #9f8ad4 20%, transparent), + -3px 0 color-mix(in srgb, #9f8ad4 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(8) { - box-shadow: 3px 0 1px color-mix(in srgb, #a692d7 20%, transparent), - -3px 0 color-mix(in srgb, #a692d7 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #a692d7 20%, transparent), + -3px 0 color-mix(in srgb, #a692d7 30%, transparent), + 0 0 3px; } body.crtmode header.focus nav > .textButton { - box-shadow: 3px 0 1px color-mix(in srgb, #99989f 20%, transparent), - -3px 0 color-mix(in srgb, #99989f 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #99989f 20%, transparent), + -3px 0 color-mix(in srgb, #99989f 30%, transparent), + 0 0 3px; } diff --git a/frontend/static/themes/taro.css b/frontend/static/themes/taro.css index cab169918a7d..2ba361b2f0c6 100644 --- a/frontend/static/themes/taro.css +++ b/frontend/static/themes/taro.css @@ -27,11 +27,13 @@ nav > .textButton:nth-child(2) { } body.crtmode nav > .textButton:nth-child(1) { - box-shadow: 3px 0 1px var(--crt-caret-color-glow), + box-shadow: + 3px 0 1px var(--crt-caret-color-glow), -3px 0 var(--crt-caret-color-glow); } body.crtmode nav > .textButton:nth-child(2) { - box-shadow: 3px 0 1px var(--crt-error-color-glow), + box-shadow: + 3px 0 1px var(--crt-error-color-glow), -3px 0 var(--crt-error-color-glow); } diff --git a/frontend/static/themes/terrazzo.css b/frontend/static/themes/terrazzo.css index 265fc2397cdb..852ded94039e 100644 --- a/frontend/static/themes/terrazzo.css +++ b/frontend/static/themes/terrazzo.css @@ -51,20 +51,28 @@ nav > .textButton:nth-child(4):hover { } body.crtmode nav > .textButton:nth-child(1) { - box-shadow: 3px 0 1px color-mix(in srgb, var(--sub-color) 20%, transparent), - -3px 0 color-mix(in srgb, var(--sub-color) 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, var(--sub-color) 20%, transparent), + -3px 0 color-mix(in srgb, var(--sub-color) 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(2) { - box-shadow: 3px 0 1px color-mix(in srgb, #9a7a61 20%, transparent), - -3px 0 color-mix(in srgb, #9a7a61 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, #9a7a61 20%, transparent), + -3px 0 color-mix(in srgb, #9a7a61 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(3) { - box-shadow: 3px 0 1px color-mix(in srgb, var(--main-color) 20%, transparent), - -3px 0 color-mix(in srgb, var(--main-color) 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, var(--main-color) 20%, transparent), + -3px 0 color-mix(in srgb, var(--main-color) 30%, transparent), + 0 0 3px; } body.crtmode nav > .textButton:nth-child(4) { - box-shadow: 3px 0 1px color-mix(in srgb, var(--text-color) 20%, transparent), - -3px 0 color-mix(in srgb, var(--text-color) 30%, transparent), 0 0 3px; + box-shadow: + 3px 0 1px color-mix(in srgb, var(--text-color) 20%, transparent), + -3px 0 color-mix(in srgb, var(--text-color) 30%, transparent), + 0 0 3px; } body.crtmode header.focus nav > .textButton { box-shadow: none; diff --git a/frontend/vite-plugins/env-config.ts b/frontend/vite-plugins/env-config.ts index f74e9c4c5713..414f509fbc0e 100644 --- a/frontend/vite-plugins/env-config.ts +++ b/frontend/vite-plugins/env-config.ts @@ -28,7 +28,7 @@ export function envConfig( | { isDevelopment: false; clientVersion: string; - } + }, ): Plugin { return { name: "virtual-env-config", diff --git a/frontend/vite-plugins/font-preview.ts b/frontend/vite-plugins/font-preview.ts index 84c0e1ad2472..100cb50ea698 100644 --- a/frontend/vite-plugins/font-preview.ts +++ b/frontend/vite-plugins/font-preview.ts @@ -27,7 +27,7 @@ export function fontPreview(): Plugin { const end = performance.now(); console.log( - `Creating webfonts preview took ${Math.round(end - start)} ms` + `Creating webfonts preview took ${Math.round(end - start)} ms`, ); }, }; @@ -50,11 +50,11 @@ async function generatePreviewFonts(debug: boolean = false): Promise { await generateSubset( srcDir + "/" + fileName, targetDir + "/" + fileName, - includedCharacters + includedCharacters, ); if (debug) { console.log( - `Processing ${name} with file ${fileName} to display "${includedCharacters}".` + `Processing ${name} with file ${fileName} to display "${includedCharacters}".`, ); } } @@ -63,7 +63,7 @@ async function generatePreviewFonts(debug: boolean = false): Promise { async function generateSubset( source: string, target: string, - includedCharacters: string + includedCharacters: string, ): Promise { const font = fs.readFileSync(source); const subset = await subsetFont(font, includedCharacters, { diff --git a/frontend/vite-plugins/fontawesome-subset.ts b/frontend/vite-plugins/fontawesome-subset.ts index 3b47eea55469..49b0e1f2cbec 100644 --- a/frontend/vite-plugins/fontawesome-subset.ts +++ b/frontend/vite-plugins/fontawesome-subset.ts @@ -23,12 +23,12 @@ export function fontawesomeSubset(): Plugin { "src/webfonts-generated", { targetFormats: ["woff2"], - } + }, ); const end = performance.now(); console.log( - `Creating fontawesome subset took ${Math.round(end - start)} ms` + `Creating fontawesome subset took ${Math.round(end - start)} ms`, ); }, }; @@ -94,11 +94,11 @@ function getFontawesomeConfig(debug = false): FontawesomeConfig { "./src", (filename) => !filename.endsWith("fontawesome-5.scss") && - !filename.endsWith("fontawesome-6.scss") //ignore our own css + !filename.endsWith("fontawesome-6.scss"), //ignore our own css ); const staticFiles = findAllFiles( "./static", - (filename) => filename.endsWith(".html") || filename.endsWith(".css") + (filename) => filename.endsWith(".html") || filename.endsWith(".css"), ); const allFiles = [...srcFiles, ...staticFiles]; @@ -127,11 +127,12 @@ function getFontawesomeConfig(debug = false): FontawesomeConfig { const brands = usedClasses.filter((it) => iconSet.brands.includes(it)); const leftOvers = icons.filter( - (it) => !(solid.includes(it) || regular.includes(it) || brands.includes(it)) + (it) => + !(solid.includes(it) || regular.includes(it) || brands.includes(it)), ); if (leftOvers.length !== 0) { throw new Error( - "Fontawesome failed with unknown icons: " + leftOvers.toString() + "Fontawesome failed with unknown icons: " + leftOvers.toString(), ); } @@ -142,7 +143,7 @@ function getFontawesomeConfig(debug = false): FontawesomeConfig { .filter((it) => usedClasses.filter((c) => it[1].includes(c)).length > 0) .map((it) => it[0]) .filter((it) => it !== "brands") - .join(", ") + .join(", "), ); console.debug( @@ -151,7 +152,7 @@ function getFontawesomeConfig(debug = false): FontawesomeConfig { regular, solid, brands, - }) + }), ); console.debug("Detected fontawesome classes in", Date.now() - time, "ms"); } @@ -175,7 +176,7 @@ function toFileAndDir(dir: string, file: string): FileObject { function findAllFiles( dir: string, - filter: (filename: string) => boolean = (_it): boolean => true + filter: (filename: string) => boolean = (_it): boolean => true, ): string[] { const files = fs .readdirSync(dir) @@ -196,7 +197,7 @@ function findAllFiles( function parseIcons(iconSet: string): string[] { const require = createRequire(import.meta.url); const path = require.resolve( - `@fortawesome/fontawesome-free/js/${iconSet}.js` + `@fortawesome/fontawesome-free/js/${iconSet}.js`, ); const file: string | null = fs.readFileSync(path).toString(); diff --git a/frontend/vite-plugins/language-hashes.ts b/frontend/vite-plugins/language-hashes.ts index da53914740f4..48faf83ce105 100644 --- a/frontend/vite-plugins/language-hashes.ts +++ b/frontend/vite-plugins/language-hashes.ts @@ -37,7 +37,7 @@ function getHashes(): Record { const hashes = Object.fromEntries( readdirSync("./static/languages").map((file) => { return [file.slice(0, -5), calcHash(file)]; - }) + }), ); const end = performance.now(); @@ -51,7 +51,7 @@ function calcHash(file: string): string { const currentLanguage = JSON.stringify( JSON.parse(readFileSync("./static/languages/" + file).toString()), null, - 0 + 0, ); const encoder = new TextEncoder(); const data = encoder.encode(currentLanguage); diff --git a/frontend/vite-plugins/minify-json.ts b/frontend/vite-plugins/minify-json.ts index 73283a769055..a99416ad9f80 100644 --- a/frontend/vite-plugins/minify-json.ts +++ b/frontend/vite-plugins/minify-json.ts @@ -68,8 +68,8 @@ export function minifyJson(): Plugin { 1024 ).toFixed(2)} mB\x1b[0m\n` + ` \x1b[32mTotal savings: ${totalSavings.toFixed( - 2 - )}%\x1b[0m took ${Math.round(end - start)} ms\n` + 2, + )}%\x1b[0m took ${Math.round(end - start)} ms\n`, ); }, }; diff --git a/frontend/vite.config.prod.js b/frontend/vite.config.prod.js index 4dd63bbfa2ac..218de3e4f46d 100644 --- a/frontend/vite.config.prod.js +++ b/frontend/vite.config.prod.js @@ -17,7 +17,7 @@ import { versionFile } from "./vite-plugins/version-file"; function pad(numbers, maxLength, fillString) { return numbers.map((number) => - number.toString().padStart(maxLength, fillString) + number.toString().padStart(maxLength, fillString), ); } @@ -26,10 +26,10 @@ const CLIENT_VERSION = (() => { const versionPrefix = pad( [date.getFullYear(), date.getMonth() + 1, date.getDate()], 2, - "0" + "0", ).join("."); const versionSuffix = pad([date.getHours(), date.getMinutes()], 2, "0").join( - "." + ".", ); const version = [versionPrefix, versionSuffix].join("_"); diff --git a/monkeytype.code-workspace b/monkeytype.code-workspace index ca04277d85f9..14ef606b7c1c 100644 --- a/monkeytype.code-workspace +++ b/monkeytype.code-workspace @@ -3,26 +3,26 @@ //root needs to be first { "name": "root", - "path": "./" + "path": "./", }, { "name": "backend", - "path": "backend" + "path": "backend", }, { "name": "frontend", - "path": "frontend" + "path": "frontend", }, { "name": "packages", - "path": "packages" - } + "path": "packages", + }, ], "settings": { "files.exclude": { "frontend": true, "backend": true, - "packages": true + "packages": true, }, "search.exclude": { //defaults @@ -36,19 +36,19 @@ "**/coverage/**": true, "**/logs/**": true, "**/.firebase/**": true, - "**/.turbo/**": true + "**/.turbo/**": true, }, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSaveMode": "file", "editor.formatOnSave": true, "testing.automaticallyOpenTestResults": "neverOpen", "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, "[html]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, - "vitest.maximumConfigs": 10 + "vitest.maximumConfigs": 10, }, "launch": { @@ -59,7 +59,7 @@ "request": "attach", "name": "Backend: Attach", "port": 9229, - "skipFiles": ["/**", "**/node_modules/**"] + "skipFiles": ["/**", "**/node_modules/**"], }, { "type": "chrome", @@ -68,10 +68,10 @@ "port": 9222, "skipFiles": ["**/node_modules/**"], "webRoot": "${workspaceFolder:frontend}/src", - "url": "http://localhost:3000" - } + "url": "http://localhost:3000", + }, ], - "compounds": [] + "compounds": [], }, "extensions": { "recommendations": [ @@ -79,7 +79,7 @@ "vitest.explorer", "huntertran.auto-markdown-toc", "dbaeumer.vscode-eslint", - "oxc.oxc-vscode" - ] - } + "oxc.oxc-vscode", + ], + }, } diff --git a/package.json b/package.json index a9924f5dcc1c..e70577d512d0 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "lint-staged": "13.2.3", "only-allow": "1.2.1", "oxlint": "1.29.0", - "prettier": "2.8.8", + "prettier": "3.6.2", "turbo": "2.5.6", "vitest": "4.0.8" }, diff --git a/packages/contracts/__test__/validation/validation.spec.ts b/packages/contracts/__test__/validation/validation.spec.ts index 6d56e01b2901..4af8689fc913 100644 --- a/packages/contracts/__test__/validation/validation.spec.ts +++ b/packages/contracts/__test__/validation/validation.spec.ts @@ -36,7 +36,7 @@ describe("validation", () => { testCases.forEach((testCase) => { expect(Validation.containsProfanity(testCase.text, "substring")).toBe( - testCase.expected + testCase.expected, ); }); }); diff --git a/packages/contracts/src/admin.ts b/packages/contracts/src/admin.ts index 5bab6e0d456e..34cc28d6740f 100644 --- a/packages/contracts/src/admin.ts +++ b/packages/contracts/src/admin.ts @@ -27,7 +27,7 @@ export type ClearStreakHourOffsetRequest = z.infer< export const ToggleBanResponseSchema = responseWithData( z.object({ banned: z.boolean(), - }) + }), ).strict(); export type ToggleBanResponse = z.infer; @@ -44,7 +44,7 @@ export const RejectReportsRequestSchema = z .array( z .object({ reportId: z.string(), reason: z.string().optional() }) - .strict() + .strict(), ) .nonempty(), }) @@ -138,5 +138,5 @@ export const adminContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/ape-keys.ts b/packages/contracts/src/ape-keys.ts index dcf42a4d49cd..b44af6e20030 100644 --- a/packages/contracts/src/ape-keys.ts +++ b/packages/contracts/src/ape-keys.ts @@ -24,7 +24,7 @@ export const AddApeKeyResponseSchema = responseWithData( apeKeyId: IdSchema, apeKey: z.string().base64(), apeKeyDetails: ApeKeySchema, - }) + }), ); export type AddApeKeyResponse = z.infer; @@ -106,5 +106,5 @@ export const apeKeysContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/configs.ts b/packages/contracts/src/configs.ts index bd3ce16c480f..f64adcddaa57 100644 --- a/packages/contracts/src/configs.ts +++ b/packages/contracts/src/configs.ts @@ -65,5 +65,5 @@ export const configsContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/configuration.ts b/packages/contracts/src/configuration.ts index cfb969830178..2327b8f5c838 100644 --- a/packages/contracts/src/configuration.ts +++ b/packages/contracts/src/configuration.ts @@ -98,5 +98,5 @@ export const configurationContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/connections.ts b/packages/contracts/src/connections.ts index bf0ff95cfc4d..6a9349b189f2 100644 --- a/packages/contracts/src/connections.ts +++ b/packages/contracts/src/connections.ts @@ -17,7 +17,7 @@ import { IdSchema } from "@monkeytype/schemas/util"; const c = initContract(); export const GetConnectionsResponseSchema = responseWithData( - z.array(ConnectionSchema) + z.array(ConnectionSchema), ); export type GetConnectionsResponse = z.infer< typeof GetConnectionsResponseSchema @@ -85,7 +85,7 @@ export const connectionsContract = c.router( 200: CreateConnectionResponseSchema, 404: MonkeyResponseSchema.describe("ReceiverUid unknown"), 409: MonkeyResponseSchema.describe( - "Duplicate connection, blocked or max connections reached" + "Duplicate connection, blocked or max connections reached", ), }, metadata: meta({ @@ -132,5 +132,5 @@ export const connectionsContract = c.router( }, }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/dev.ts b/packages/contracts/src/dev.ts index e6f9e2f50163..71620150f5ae 100644 --- a/packages/contracts/src/dev.ts +++ b/packages/contracts/src/dev.ts @@ -9,7 +9,7 @@ export const GenerateDataRequestSchema = z.object({ .boolean() .optional() .describe( - "If `true` create user with @example.com and password `password`. If false user has to exist." + "If `true` create user with @example.com and password `password`. If false user has to exist.", ), firstTestTimestamp: z.number().int().nonnegative().optional(), lastTestTimestamp: z.number().int().nonnegative().optional(), @@ -22,7 +22,7 @@ export const GenerateDataResponseSchema = responseWithData( z.object({ uid: IdSchema, email: z.string().email(), - }) + }), ); export type GenerateDataResponse = z.infer; @@ -50,5 +50,5 @@ export const devContract = c.router( }, }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/leaderboards.ts b/packages/contracts/src/leaderboards.ts index 54ccbbc877e7..767b96375140 100644 --- a/packages/contracts/src/leaderboards.ts +++ b/packages/contracts/src/leaderboards.ts @@ -43,14 +43,14 @@ const LeaderboardResponseSchema = z.object({ //-------------------------------------------------------------------------- export const GetLeaderboardQuerySchema = LanguageAndModeQuerySchema.merge( - PaginationQuerySchema + PaginationQuerySchema, ).merge(FriendsOnlyQuerySchema); export type GetLeaderboardQuery = z.infer; export const GetLeaderboardResponseSchema = responseWithData( LeaderboardResponseSchema.extend({ entries: z.array(LeaderboardEntrySchema), - }) + }), ); export type GetLeaderboardResponse = z.infer< typeof GetLeaderboardResponseSchema @@ -59,13 +59,13 @@ export type GetLeaderboardResponse = z.infer< //-------------------------------------------------------------------------- export const GetLeaderboardRankQuerySchema = LanguageAndModeQuerySchema.merge( - FriendsOnlyQuerySchema + FriendsOnlyQuerySchema, ); export type GetLeaderboardRankQuery = z.infer< typeof GetLeaderboardRankQuerySchema >; export const GetLeaderboardRankResponseSchema = responseWithNullableData( - LeaderboardEntrySchema + LeaderboardEntrySchema, ); export type GetLeaderboardRankResponse = z.infer< typeof GetLeaderboardRankResponseSchema @@ -79,7 +79,7 @@ export const DailyLeaderboardQuerySchema = LanguageAndModeQuerySchema.extend({ export type DailyLeaderboardQuery = z.infer; export const GetDailyLeaderboardQuerySchema = DailyLeaderboardQuerySchema.merge( - PaginationQuerySchema + PaginationQuerySchema, ); export type GetDailyLeaderboardQuery = z.infer< typeof GetDailyLeaderboardQuerySchema @@ -88,7 +88,7 @@ export const GetDailyLeaderboardResponseSchema = responseWithData( LeaderboardResponseSchema.extend({ entries: z.array(LeaderboardEntrySchema), minWpm: z.number().nonnegative(), - }) + }), ); export type GetDailyLeaderboardResponse = z.infer< typeof GetDailyLeaderboardResponseSchema @@ -102,7 +102,7 @@ export type GetDailyLeaderboardRankQuery = z.infer< typeof GetDailyLeaderboardRankQuerySchema >; export const GetLeaderboardDailyRankResponseSchema = responseWithNullableData( - LeaderboardEntrySchema + LeaderboardEntrySchema, ); export type GetLeaderboardDailyRankResponse = z.infer< typeof GetLeaderboardDailyRankResponseSchema @@ -125,7 +125,7 @@ export type GetWeeklyXpLeaderboardQuery = z.infer< export const GetWeeklyXpLeaderboardResponseSchema = responseWithData( LeaderboardResponseSchema.extend({ entries: z.array(XpLeaderboardEntrySchema), - }) + }), ); export type GetWeeklyXpLeaderboardResponse = z.infer< typeof GetWeeklyXpLeaderboardResponseSchema @@ -256,5 +256,5 @@ export const leaderboardsContract = c.router( rateLimit: "leaderboardsGet", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/presets.ts b/packages/contracts/src/presets.ts index e47d75edf927..8832ef8f6c76 100644 --- a/packages/contracts/src/presets.ts +++ b/packages/contracts/src/presets.ts @@ -20,7 +20,7 @@ export const AddPresetRequestSchema = PresetSchema.omit({ _id: true }); export type AddPresetRequest = z.infer; export const AddPresetResponseSchemna = responseWithData( - z.object({ presetId: IdSchema }) + z.object({ presetId: IdSchema }), ); export type AddPresetResponse = z.infer; @@ -94,5 +94,5 @@ export const presetsContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/psas.ts b/packages/contracts/src/psas.ts index 7fae5086e39e..133ebf263540 100644 --- a/packages/contracts/src/psas.ts +++ b/packages/contracts/src/psas.ts @@ -30,5 +30,5 @@ export const psasContract = c.router( rateLimit: "psaGet", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/public.ts b/packages/contracts/src/public.ts index 8286ae2d643f..eb80c57246d9 100644 --- a/packages/contracts/src/public.ts +++ b/packages/contracts/src/public.ts @@ -66,5 +66,5 @@ export const publicContract = c.router( rateLimit: "publicStatsGet", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/quotes.ts b/packages/contracts/src/quotes.ts index b2de99c23272..fab5ed9c1deb 100644 --- a/packages/contracts/src/quotes.ts +++ b/packages/contracts/src/quotes.ts @@ -24,7 +24,7 @@ export type GetQuotesResponse = z.infer; export const IsSubmissionEnabledResponseSchema = responseWithData( z.object({ isEnabled: z.boolean(), - }) + }), ); export type IsSubmissionEnabledResponse = z.infer< typeof IsSubmissionEnabledResponseSchema @@ -213,5 +213,5 @@ export const quotesContract = c.router( openApiTags: "quotes", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/require-configuration/index.ts b/packages/contracts/src/require-configuration/index.ts index 74e01920ac06..78742cdb97de 100644 --- a/packages/contracts/src/require-configuration/index.ts +++ b/packages/contracts/src/require-configuration/index.ts @@ -6,12 +6,12 @@ type BooleanPaths = { ? K : `${P}.${Extract}` : T[K] extends object - ? `${P}.${Extract}` extends infer D - ? D extends string - ? BooleanPaths + ? `${P}.${Extract}` extends infer D + ? D extends string + ? BooleanPaths + : never : never - : never - : never; + : never; }[keyof T]; // Helper type to remove leading dot diff --git a/packages/contracts/src/results.ts b/packages/contracts/src/results.ts index 642f05b1784a..cec92f4dadfc 100644 --- a/packages/contracts/src/results.ts +++ b/packages/contracts/src/results.ts @@ -22,7 +22,7 @@ export const GetResultsQuerySchema = z.object({ .min(1589428800000) .optional() .describe( - "Timestamp of the earliest result to fetch. If omitted the most recent results are fetched." + "Timestamp of the earliest result to fetch. If omitted the most recent results are fetched.", ), offset: z .number() @@ -41,7 +41,7 @@ export const GetResultsQuerySchema = z.object({ export type GetResultsQuery = z.infer; export const GetResultsResponseSchema = responseWithData( - z.array(ResultMinifiedSchema) + z.array(ResultMinifiedSchema), ); export type GetResultsResponse = z.infer; @@ -60,7 +60,7 @@ export const AddResultRequestSchema = z.object({ export type AddResultRequest = z.infer; export const AddResultResponseSchema = responseWithData( - PostResultResponseSchema + PostResultResponseSchema, ); export type AddResultResponse = z.infer; @@ -74,7 +74,7 @@ export type UpdateResultTagsRequest = z.infer< export const UpdateResultTagsResponseSchema = responseWithData( z.object({ tagPbs: z.array(IdSchema), - }) + }), ); export type UpdateResultTagsResponse = z.infer< typeof UpdateResultTagsResponseSchema @@ -200,5 +200,5 @@ export const resultsContract = c.router( openApiTags: "results", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/users.ts b/packages/contracts/src/users.ts index 6058384e790b..7a01febb6648 100644 --- a/packages/contracts/src/users.ts +++ b/packages/contracts/src/users.ts @@ -40,7 +40,7 @@ import { CustomThemeColorsSchema } from "@monkeytype/schemas/configs"; export const GetUserResponseSchema = responseWithData( UserSchema.extend({ inboxUnreadSize: z.number().int().nonnegative(), - }) + }), ); export type GetUserResponse = z.infer; @@ -62,7 +62,7 @@ export type CheckNamePathParameters = z.infer< export const CheckNameResponseSchema = responseWithData( z.object({ available: z.boolean(), - }) + }), ); export type CheckNameResponse = z.infer; @@ -109,7 +109,7 @@ export type AddResultFilterPresetRequest = z.infer< typeof AddResultFilterPresetRequestSchema >; export const AddResultFilterPresetResponseSchema = responseWithData( - IdSchema.describe("Id of the created result filter preset") + IdSchema.describe("Id of the created result filter preset"), ); export type AddResultFilterPresetResponse = z.infer< typeof AddResultFilterPresetResponseSchema @@ -145,7 +145,7 @@ export const TagIdPathParamsSchema = z.object({ export type TagIdPathParams = z.infer; export const GetCustomThemesResponseSchema = responseWithData( - z.array(CustomThemeSchema) + z.array(CustomThemeSchema), ); export type GetCustomThemesResponse = z.infer< typeof GetCustomThemesResponseSchema @@ -158,7 +158,7 @@ export const AddCustomThemeRequestSchema = z.object({ export type AddCustomThemeRequest = z.infer; export const AddCustomThemeResponseSchema = responseWithData( - CustomThemeSchema.pick({ _id: true, name: true }) + CustomThemeSchema.pick({ _id: true, name: true }), ); export type AddCustomThemeResponse = z.infer< typeof AddCustomThemeResponseSchema @@ -180,7 +180,7 @@ export type EditCustomThemeRequst = z.infer; export const GetDiscordOauthLinkResponseSchema = responseWithData( z.object({ url: z.string().url(), - }) + }), ); export type GetDiscordOauthLinkResponse = z.infer< typeof GetDiscordOauthLinkResponseSchema @@ -194,7 +194,7 @@ export const LinkDiscordRequestSchema = z.object({ export type LinkDiscordRequest = z.infer; export const LinkDiscordResponseSchema = responseWithData( - UserSchema.pick({ discordId: true, discordAvatar: true }) + UserSchema.pick({ discordId: true, discordAvatar: true }), ); export type LinkDiscordResponse = z.infer; @@ -203,7 +203,7 @@ export const GetStatsResponseSchema = responseWithData( completedTests: true, startedTests: true, timeTyping: true, - }) + }), ); export type GetStatsResponse = z.infer; @@ -268,7 +268,7 @@ export type UpdateUserProfileRequest = z.infer< >; export const UpdateUserProfileResponseSchema = responseWithData( - UserProfileDetailsSchema + UserProfileDetailsSchema, ); export type UpdateUserProfileResponse = z.infer< typeof UpdateUserProfileResponseSchema @@ -278,7 +278,7 @@ export const GetUserInboxResponseSchema = responseWithData( z.object({ inbox: z.array(MonkeyMailSchema), maxMail: z.number().int(), - }) + }), ); export type GetUserInboxResponse = z.infer; @@ -312,7 +312,7 @@ export type ForgotPasswordEmailRequest = z.infer< >; export const GetTestActivityResponseSchema = responseWithNullableData( - CountByYearAndDaySchema + CountByYearAndDaySchema, ); export type GetTestActivityResponse = z.infer< typeof GetTestActivityResponseSchema @@ -961,5 +961,5 @@ export const usersContract = c.router( }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/contracts/src/util/api.ts b/packages/contracts/src/util/api.ts index c0b091d7f9db..275e4b8fc606 100644 --- a/packages/contracts/src/util/api.ts +++ b/packages/contracts/src/util/api.ts @@ -84,7 +84,7 @@ export const MonkeyServerError = MonkeyClientError.extend({ export type MonkeyServerErrorType = z.infer; export function responseWithNullableData( - dataSchema: T + dataSchema: T, ): z.ZodObject< z.objectUtil.extendShape< typeof MonkeyResponseSchema.shape, @@ -99,7 +99,7 @@ export function responseWithNullableData( } export function responseWithData( - dataSchema: T + dataSchema: T, ): z.ZodObject< z.objectUtil.extendShape< typeof MonkeyResponseSchema.shape, @@ -116,7 +116,7 @@ export function responseWithData( export const CommonResponses = { 400: MonkeyClientError.describe("Generic client error"), 401: MonkeyClientError.describe( - "Authentication required but not provided or invalid" + "Authentication required but not provided or invalid", ), 403: MonkeyClientError.describe("Operation not permitted"), 422: MonkeyValidationErrorSchema.describe("Request validation failed"), @@ -127,6 +127,6 @@ export const CommonResponses = { 479: MonkeyClientError.describe("ApeKey rate limit exceeded"), 500: MonkeyServerError.describe("Generic server error"), 503: MonkeyServerError.describe( - "Endpoint disabled or server is under maintenance" + "Endpoint disabled or server is under maintenance", ), }; diff --git a/packages/contracts/src/webhooks.ts b/packages/contracts/src/webhooks.ts index 48a74bf05c71..593ff89d90ba 100644 --- a/packages/contracts/src/webhooks.ts +++ b/packages/contracts/src/webhooks.ts @@ -56,5 +56,5 @@ export const webhooksContract = c.router( rateLimit: "webhookLimit", }), commonResponses: CommonResponses, - } + }, ); diff --git a/packages/funbox/__test__/validation.spec.ts b/packages/funbox/__test__/validation.spec.ts index 91b499e1a9a8..de27659acbc0 100644 --- a/packages/funbox/__test__/validation.spec.ts +++ b/packages/funbox/__test__/validation.spec.ts @@ -27,7 +27,7 @@ describe("validation", () => { //WHEN / THEN expect(Validation.checkCompatibility(["plus_one", "plus_two"])).toBe( - false + false, ); }); @@ -39,7 +39,7 @@ describe("validation", () => { //WHEN / THEN expect( - Validation.checkCompatibility(["plus_one", "plus_two"], "plus_three") + Validation.checkCompatibility(["plus_one", "plus_two"], "plus_three"), ).toBe(false); }); @@ -65,7 +65,7 @@ describe("validation", () => { //WHEN const result = Validation.checkCompatibility( ["plus_one", "plus_two"], - "plus_three" + "plus_three", ); //THEN @@ -93,7 +93,7 @@ describe("validation", () => { //WHEN / THEN expect(Validation.checkCompatibility(["plus_one", "plus_two"])).toBe( - false + false, ); }); @@ -112,7 +112,7 @@ describe("validation", () => { //WHEN / THEN expect(Validation.checkCompatibility(["plus_one", "plus_two"])).toBe( - true + true, ); }); describe("should validate two funboxes modifying the wordset", () => { @@ -151,9 +151,9 @@ describe("validation", () => { //WHEN / THEN expect(Validation.checkCompatibility(["plus_one", "plus_two"])).toBe( - compatible + compatible, ); - } + }, ); }); }); diff --git a/packages/funbox/src/list.ts b/packages/funbox/src/list.ts index 3c18199824ec..bae05e7f6f77 100644 --- a/packages/funbox/src/list.ts +++ b/packages/funbox/src/list.ts @@ -479,7 +479,7 @@ const list: Record = { export function getFunbox(name: FunboxName): FunboxMetadata; export function getFunbox(names: FunboxName[]): FunboxMetadata[]; export function getFunbox( - nameOrNames: FunboxName | FunboxName[] + nameOrNames: FunboxName | FunboxName[], ): FunboxMetadata | FunboxMetadata[] { if (nameOrNames === undefined) return []; if (Array.isArray(nameOrNames)) { @@ -488,7 +488,7 @@ export function getFunbox( //@ts-expect-error sanity check if (out.includes(undefined)) { throw new Error( - "One of the funboxes is invalid: " + nameOrNames.toString() + "One of the funboxes is invalid: " + nameOrNames.toString(), ); } diff --git a/packages/funbox/src/validation.ts b/packages/funbox/src/validation.ts index d20e25aefc40..8d0cee679736 100644 --- a/packages/funbox/src/validation.ts +++ b/packages/funbox/src/validation.ts @@ -6,7 +6,7 @@ import { safeNumber } from "@monkeytype/util/numbers"; export function checkCompatibility( funboxNames: FunboxName[], - withFunbox?: FunboxName + withFunbox?: FunboxName, ): boolean { if (funboxNames.length === 0) return true; @@ -22,7 +22,7 @@ export function checkCompatibility( } catch (error) { console.error( "Error when getting funboxes for a compatibility check:", - error + error, ); return false; } @@ -35,55 +35,55 @@ export function checkCompatibility( (f) => f.frontendFunctions?.includes("getWord") || f.frontendFunctions?.includes("pullSection") || - f.frontendFunctions?.includes("withWords") + f.frontendFunctions?.includes("withWords"), ).length <= 1; const oneWordOrderMax = funboxesToCheck.filter( (f) => - f.properties?.find((fp) => fp.startsWith("wordOrder")) !== undefined + f.properties?.find((fp) => fp.startsWith("wordOrder")) !== undefined, ).length <= 1; const layoutUsability = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesLayout") + f.properties?.find((fp) => fp === "changesLayout"), ).length === 0 || funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "ignoresLayout" || fp === "usesLayout") + f.properties?.find((fp) => fp === "ignoresLayout" || fp === "usesLayout"), ).length === 0; const oneNospaceOrToPushMax = funboxesToCheck.filter( (f) => f.properties?.find( - (fp) => fp === "nospace" || fp.startsWith("toPush") - ) !== undefined + (fp) => fp === "nospace" || fp.startsWith("toPush"), + ) !== undefined, ).length <= 1; const oneChangesWordsVisibilityMax = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesWordsVisibility") + f.properties?.find((fp) => fp === "changesWordsVisibility"), ).length <= 1; const oneFrequencyChangesMax = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesWordsFrequency") + f.properties?.find((fp) => fp === "changesWordsFrequency"), ).length <= 1; const noFrequencyChangesConflicts = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesWordsFrequency") + f.properties?.find((fp) => fp === "changesWordsFrequency"), ).length === 0 || funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "ignoresLanguage") + f.properties?.find((fp) => fp === "ignoresLanguage"), ).length === 0; const capitalisationChangePosibility = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "noLetters") + f.properties?.find((fp) => fp === "noLetters"), ).length === 0 || funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesCapitalisation") + f.properties?.find((fp) => fp === "changesCapitalisation"), ).length === 0; const noConflictsWithSymmetricChars = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "conflictsWithSymmetricChars") + f.properties?.find((fp) => fp === "conflictsWithSymmetricChars"), ).length === 0 || funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "symmetricChars") + f.properties?.find((fp) => fp === "symmetricChars"), ).length === 0; const oneCanSpeakMax = funboxesToCheck.filter((f) => f.properties?.find((fp) => fp === "speaks")) @@ -94,35 +94,35 @@ export function checkCompatibility( (funboxesToCheck.filter((f) => f.properties?.find((fp) => fp === "speaks")) .length === 1 && funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "unspeakable") + f.properties?.find((fp) => fp === "unspeakable"), ).length === 0) || funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "ignoresLanguage") + f.properties?.find((fp) => fp === "ignoresLanguage"), ).length === 0; const oneToPushOrPullSectionMax = funboxesToCheck.filter( (f) => f.properties?.find((fp) => fp.startsWith("toPush:")) !== undefined || - f.frontendFunctions?.includes("pullSection") + f.frontendFunctions?.includes("pullSection"), ).length <= 1; const onePunctuateWordMax = funboxesToCheck.filter((f) => - f.frontendFunctions?.includes("punctuateWord") + f.frontendFunctions?.includes("punctuateWord"), ).length <= 1; const oneGetEmulatedCharMax = funboxesToCheck.filter((f) => - f.frontendFunctions?.includes("getEmulatedChar") + f.frontendFunctions?.includes("getEmulatedChar"), ).length <= 1; const oneCharCheckerMax = funboxesToCheck.filter((f) => - f.frontendFunctions?.includes("isCharCorrect") + f.frontendFunctions?.includes("isCharCorrect"), ).length <= 1; const oneCharReplacerMax = funboxesToCheck.filter((f) => f.frontendFunctions?.includes("getWordHtml")) .length <= 1; const oneChangesCapitalisationMax = funboxesToCheck.filter((f) => - f.properties?.find((fp) => fp === "changesCapitalisation") + f.properties?.find((fp) => fp === "changesCapitalisation"), ).length <= 1; const oneCssModificationPerElement = Object.values( @@ -134,7 +134,7 @@ export function checkCompatibility( counts[cssModification] = (safeNumber(counts[cssModification]) ?? 0) + 1; return counts; - }, {}) + }, {}), ).every((c) => c <= 1); const allowedConfig = {} as FunboxForcedConfig; @@ -147,7 +147,7 @@ export function checkCompatibility( intersect( allowedConfig[key], f.frontendForcedConfig[key] as string[] | boolean[], - true + true, ).length === 0 ) { noConfigConflicts = false; diff --git a/packages/oxlint-config/index.jsonc b/packages/oxlint-config/index.jsonc index 3ca4a686a342..ed86cd72349f 100644 --- a/packages/oxlint-config/index.jsonc +++ b/packages/oxlint-config/index.jsonc @@ -3,7 +3,7 @@ "categories": { "correctness": "error", "suspicious": "error", - "perf": "error" + "perf": "error", }, "plugins": ["typescript", "unicorn", "oxc", "import", "node", "promise"], "rules": { @@ -25,8 +25,8 @@ { "argsIgnorePattern": "^(_|e|event)", "caughtErrorsIgnorePattern": "^(_|e|error)", - "varsIgnorePattern": "^_" - } + "varsIgnorePattern": "^_", + }, ], "no-var": "error", "no-non-null-assertion": "error", @@ -36,14 +36,14 @@ "explicit-function-return-type": [ "error", { - "allowExpressions": true - } + "allowExpressions": true, + }, ], "no-unused-expressions": [ "error", { - "allowTernary": true - } + "allowTernary": true, + }, ], "no-unsafe-function-type": "error", "prefer-for-of": "error", @@ -60,8 +60,8 @@ "no-empty": [ "error", { - "allowEmptyCatch": true - } + "allowEmptyCatch": true, + }, ], "no-self-compare": "error", "no-throw-literal": "error", @@ -86,14 +86,14 @@ "max-depth": [ "error", { - "max": 5 - } + "max": 5, + }, ], "always-return": [ "error", { - "ignoreLastCallback": true - } + "ignoreLastCallback": true, + }, ], "unicorn/prefer-includes": "error", @@ -104,6 +104,6 @@ "no-cycle": "off", "no-nested-ternary": "off", "no-array-sort": "off", - "preserve-caught-error": "off" - } + "preserve-caught-error": "off", + }, } diff --git a/packages/release/src/buildChangelog.js b/packages/release/src/buildChangelog.js index d84ef17b064f..9293c93b3b31 100644 --- a/packages/release/src/buildChangelog.js +++ b/packages/release/src/buildChangelog.js @@ -51,8 +51,8 @@ async function getLog() { return execPromise(`git describe --tags --abbrev=0 HEAD^`).then((lastTag) => execPromise( - `git log --oneline ${lastTag.trim()}..HEAD --pretty="format:${lineDelimiter}%H${logDelimiter}%h${logDelimiter}%s${logDelimiter}%b"` - ) + `git log --oneline ${lastTag.trim()}..HEAD --pretty="format:${lineDelimiter}%H${logDelimiter}%h${logDelimiter}%s${logDelimiter}%b"`, + ), ); } @@ -124,7 +124,7 @@ function buildSection(type, allItems) { let ret = `### ${titles[type]}\n\n`; const items = allItems.filter( - (item) => item.type === type && !item.body.includes("!nuf") + (item) => item.type === type && !item.body.includes("!nuf"), ); if (items.length === 0) { @@ -139,13 +139,13 @@ function buildFooter(logs) { "\n### Nerd stuff\n\nThese changes will not be visible to users, but are included for completeness and to credit contributors.\n\n"; const featLogs = logs.filter( - (item) => item.type === "feat" && item.body.includes("!nuf") + (item) => item.type === "feat" && item.body.includes("!nuf"), ); const imprLogs = logs.filter( - (item) => item.type === "impr" && item.body.includes("!nuf") + (item) => item.type === "impr" && item.body.includes("!nuf"), ); const fixLogs = logs.filter( - (item) => item.type === "fix" && item.body.includes("!nuf") + (item) => item.type === "fix" && item.body.includes("!nuf"), ); const styleLogs = logs.filter((item) => item.type === "style"); const docLogs = logs.filter((item) => item.type === "docs"); @@ -173,7 +173,7 @@ function buildFooter(logs) { //remove dupes based on hash const uniqueOtherLogs = allOtherLogs.filter( (item, index, self) => - index === self.findIndex((t) => t.hashes[0].full === item.hashes[0].full) + index === self.findIndex((t) => t.hashes[0].full === item.hashes[0].full), ); // console.log(uniqueOtherLogs); @@ -255,7 +255,7 @@ function convertStringToLog(logString) { //split message using regex based on fix(language): spelling mistakes in Nepali wordlist and quotes (sapradhan) (#4528) //scope is optional, username is optional, pr number is optional const [_, type, scope, message, username, pr] = title.split( - /^(\w+)(?:\(([^)]+)\))?:\s+(.+?)(?:\s*\((@[^)]+)\))?(?:\s+\((#[^)]+)\))?$/ + /^(\w+)(?:\(([^)]+)\))?:\s+(.+?)(?:\s*\((@[^)]+)\))?(?:\s+\((#[^)]+)\))?$/, ); const usernames = username ? username.split(", ") : []; @@ -345,7 +345,7 @@ async function main() { log = log.filter((item) => !itemIsAddingQuotes(item)); let quoteReportCommits = log.filter((item) => - itemIsAddressingQuoteReports(item) + itemIsAddressingQuoteReports(item), ); log = log.filter((item) => !itemIsAddressingQuoteReports(item)); diff --git a/packages/release/src/index.js b/packages/release/src/index.js index caf8fea93219..f48ed7071096 100755 --- a/packages/release/src/index.js +++ b/packages/release/src/index.js @@ -60,11 +60,11 @@ const runProjectRootCommand = (command, force) => { const checkBranchSync = () => { console.log("Checking if local branch is master..."); const currentBranch = runProjectRootCommand( - "git branch --show-current" + "git branch --show-current", ).trim(); if (currentBranch !== "master") { console.error( - "Local branch is not master. Please checkout the master branch." + "Local branch is not master. Please checkout the master branch.", ); process.exit(1); } @@ -83,12 +83,12 @@ const checkBranchSync = () => { // Get the commit hashes of the local and remote master branches const localMaster = runProjectRootCommand("git rev-parse master").trim(); const remoteMaster = runProjectRootCommand( - "git rev-parse origin/master" + "git rev-parse origin/master", ).trim(); if (localMaster !== remoteMaster) { console.error( - "Local master branch is not in sync with origin. Please pull the latest changes before proceeding." + "Local master branch is not in sync with origin. Please pull the latest changes before proceeding.", ); process.exit(1); } @@ -104,7 +104,7 @@ const getCurrentVersion = () => { console.log("Getting current version..."); const rootPackageJson = JSON.parse( - readFileSync(`${PROJECT_ROOT}/package.json`, "utf-8") + readFileSync(`${PROJECT_ROOT}/package.json`, "utf-8"), ); return rootPackageJson.version; @@ -146,7 +146,7 @@ const updatePackage = (newVersion) => { fs.writeFileSync( packagePath, JSON.stringify(packageJson, null, 2) + "\n", - "utf8" + "utf8", ); console.log(`Updated package.json to version ${newVersion}`); @@ -159,7 +159,7 @@ const checkUncommittedChanges = () => { console.log("[Dry Run] Checking uncommitted changes..."); } else if (status) { console.error( - "You have uncommitted changes. Please commit or stash them before proceeding." + "You have uncommitted changes. Please commit or stash them before proceeding.", ); process.exit(1); } @@ -179,15 +179,15 @@ const buildProject = () => { if (isFrontend && !isBackend) { runProjectRootCommand( - "SENTRY=1 npx turbo lint test check-assets build --filter @monkeytype/frontend --force" + "SENTRY=1 npx turbo lint test check-assets build --filter @monkeytype/frontend --force", ); } else if (isBackend && !isFrontend) { runProjectRootCommand( - "SENTRY=1 npx turbo lint test build --filter @monkeytype/backend --force" + "SENTRY=1 npx turbo lint test build --filter @monkeytype/backend --force", ); } else { runProjectRootCommand( - "SENTRY=1 npx turbo lint test check-assets build --force" + "SENTRY=1 npx turbo lint test check-assets build --force", ); } }; @@ -201,7 +201,7 @@ const deployBackend = () => { const deployFrontend = () => { console.log("Deploying frontend..."); runProjectRootCommand( - "cd frontend && npx firebase deploy -P live --only hosting" + "cd frontend && npx firebase deploy -P live --only hosting", ); }; @@ -233,7 +233,7 @@ const createGithubRelease = async (version, changelogContent) => { console.log("Creating GitHub release..."); if (isDryRun) { console.log( - `[Dry Run] Sent release request to GitHub for version ${version}` + `[Dry Run] Sent release request to GitHub for version ${version}`, ); } else { const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); diff --git a/packages/schemas/src/challenges.ts b/packages/schemas/src/challenges.ts index 7a417ce51488..a8b30853f80e 100644 --- a/packages/schemas/src/challenges.ts +++ b/packages/schemas/src/challenges.ts @@ -25,7 +25,7 @@ export const ChallengeSchema = z .or(z.null()) .or(z.number()) .or(z.boolean()) - .or(z.array(FunboxNameSchema)) + .or(z.array(FunboxNameSchema)), ), requirements: z .object({ diff --git a/packages/schemas/src/configs.ts b/packages/schemas/src/configs.ts index e7a88b2ccf87..9eaf3b8b5667 100644 --- a/packages/schemas/src/configs.ts +++ b/packages/schemas/src/configs.ts @@ -32,7 +32,7 @@ export const QuoteLengthConfigSchema = z "|1|Medium quotes|", "|2|Long quotes|", "|3|Thicc quotes|", - ].join("\n") + ].join("\n"), ); export type QuoteLengthConfig = z.infer; @@ -359,7 +359,7 @@ export type CustomBackground = z.infer; export const PlayTimeWarningSchema = z .enum(["off", "1", "3", "5", "10"]) .describe( - "How many seconds before the end of the test to play a warning sound." + "How many seconds before the end of the test to play a warning sound.", ); export type PlayTimeWarning = z.infer; diff --git a/packages/schemas/src/configuration.ts b/packages/schemas/src/configuration.ts index cae68d952b7e..af453988173a 100644 --- a/packages/schemas/src/configuration.ts +++ b/packages/schemas/src/configuration.ts @@ -115,7 +115,7 @@ export const ConfigurationSchema = z.object({ .number() .min(0) .describe( - "Minimum typing time (in seconds) the user needs to get on a leaderboard" + "Minimum typing time (in seconds) the user needs to get on a leaderboard", ), weeklyXp: z.object({ enabled: z.boolean(), diff --git a/packages/schemas/src/fonts.ts b/packages/schemas/src/fonts.ts index fc8a6483b984..2bd38967ee9a 100644 --- a/packages/schemas/src/fonts.ts +++ b/packages/schemas/src/fonts.ts @@ -45,7 +45,7 @@ const KnownFontNameSchema = z.enum( ], { errorMap: customEnumErrorHandler("Must be a known font family"), - } + }, ); export type KnownFontName = z.infer; @@ -53,6 +53,6 @@ export const FontNameSchema = KnownFontNameSchema.or( z .string() .max(50) - .regex(/^[a-zA-Z0-9_\-+.]+$/) + .regex(/^[a-zA-Z0-9_\-+.]+$/), ); export type FontName = z.infer; diff --git a/packages/schemas/src/languages.ts b/packages/schemas/src/languages.ts index 5952e9a695a1..d199e0e8acf3 100644 --- a/packages/schemas/src/languages.ts +++ b/packages/schemas/src/languages.ts @@ -431,7 +431,7 @@ export const LanguageSchema = z.enum( ], { errorMap: customEnumErrorHandler("Must be a supported language"), - } + }, ); export type Language = z.infer; diff --git a/packages/schemas/src/layouts.ts b/packages/schemas/src/layouts.ts index 3b3be1bffcf6..7c29b79416e8 100644 --- a/packages/schemas/src/layouts.ts +++ b/packages/schemas/src/layouts.ts @@ -232,7 +232,7 @@ export const LayoutNameSchema = z.enum( ], { errorMap: customEnumErrorHandler("Must be a supported layout"), - } + }, ); export type LayoutName = z.infer; diff --git a/packages/schemas/src/presets.ts b/packages/schemas/src/presets.ts index 61312d52b726..5faeb2a68224 100644 --- a/packages/schemas/src/presets.ts +++ b/packages/schemas/src/presets.ts @@ -24,7 +24,7 @@ const PresetSettingsGroupsSchema = z const duplicateElemExits: boolean = settingList.filter( (settingGroup: ConfigGroupName) => - settingGroup === presetSettingGroup + settingGroup === presetSettingGroup, ).length > 1; if (duplicateElemExits) { ctx.addIssue({ @@ -32,7 +32,7 @@ const PresetSettingsGroupsSchema = z message: `No duplicates allowed.`, }); } - } + }, ); }); diff --git a/packages/schemas/src/public.ts b/packages/schemas/src/public.ts index 5a89122eb1f7..0b321f16d8c9 100644 --- a/packages/schemas/src/public.ts +++ b/packages/schemas/src/public.ts @@ -3,7 +3,7 @@ import { StringNumberSchema } from "./util"; export const SpeedHistogramSchema = z.record( StringNumberSchema, - z.number().int() + z.number().int(), ); export type SpeedHistogram = z.infer; diff --git a/packages/schemas/src/shared.ts b/packages/schemas/src/shared.ts index 40aec71dc235..7a1f5b570d07 100644 --- a/packages/schemas/src/shared.ts +++ b/packages/schemas/src/shared.ts @@ -25,11 +25,11 @@ export type PersonalBest = z.infer; export const PersonalBestsSchema = z.object({ time: z.record( StringNumberSchema.describe("Number of seconds as string"), - z.array(PersonalBestSchema) + z.array(PersonalBestSchema), ), words: z.record( StringNumberSchema.describe("Number of words as string"), - z.array(PersonalBestSchema) + z.array(PersonalBestSchema), ), quote: z.record(StringNumberSchema, z.array(PersonalBestSchema)), custom: z.record(z.literal("custom"), z.array(PersonalBestSchema)), @@ -74,7 +74,7 @@ export const Mode2Schema = z.union( errorMap: () => ({ message: 'Needs to be either a number, "zen" or "custom".', }), - } + }, ); export type Mode2 = M extends M diff --git a/packages/schemas/src/themes.ts b/packages/schemas/src/themes.ts index ac5463a465e8..0633201c7a25 100644 --- a/packages/schemas/src/themes.ts +++ b/packages/schemas/src/themes.ts @@ -192,5 +192,5 @@ export const ThemeNameSchema = z.enum( ], { errorMap: customEnumErrorHandler("Must be a known theme"), - } + }, ); diff --git a/packages/schemas/src/users.ts b/packages/schemas/src/users.ts index 10e51372a5ae..ad6041bf898c 100644 --- a/packages/schemas/src/users.ts +++ b/packages/schemas/src/users.ts @@ -83,7 +83,7 @@ export const UserTagSchema = z export type UserTag = z.infer; function profileDetailsBase( - schema: ZodString + schema: ZodString, ): ZodEffects>> { return doesNotContainProfanity("word", schema) .optional() @@ -94,18 +94,18 @@ export const TwitterProfileSchema = profileDetailsBase( z .string() .max(20) - .regex(/^[0-9a-zA-Z_.-]+$/) + .regex(/^[0-9a-zA-Z_.-]+$/), ).or(z.literal("")); export const GithubProfileSchema = profileDetailsBase( z .string() .max(39) - .regex(/^[0-9a-zA-Z_.-]+$/) + .regex(/^[0-9a-zA-Z_.-]+$/), ).or(z.literal("")); export const WebsiteSchema = profileDetailsBase( - z.string().url().max(200).startsWith("https://") + z.string().url().max(200).startsWith("https://"), ).or(z.literal("")); export const UserProfileDetailsSchema = z @@ -154,8 +154,8 @@ export const UserQuoteRatingsSchema = z.record( LanguageSchema, z.record( StringNumberSchema.describe("quoteId as string"), - z.number().nonnegative() - ) + z.number().nonnegative(), + ), ); export type UserQuoteRatings = z.infer; @@ -163,8 +163,8 @@ export const UserLbMemorySchema = z.record( ModeSchema, z.record( Mode2Schema, - z.record(LanguageSchema, z.number().int().nonnegative()) - ) + z.record(LanguageSchema, z.number().int().nonnegative()), + ), ); export type UserLbMemory = z.infer; @@ -177,7 +177,7 @@ export type RankAndCount = z.infer; export const AllTimeLbsSchema = z.object({ time: z.record( Mode2Schema, - z.record(LanguageSchema, RankAndCountSchema.optional()) + z.record(LanguageSchema, RankAndCountSchema.optional()), ), }); export type AllTimeLbs = z.infer; @@ -208,7 +208,7 @@ export const TestActivitySchema = z testsByDays: z .array(z.number().int().nonnegative().or(z.null())) .describe( - "Number of tests by day. Last element of the array is on the date `lastDay`. `null` means no tests on that day." + "Number of tests by day. Last element of the array is on the date `lastDay`. `null` means no tests on that day.", ), lastDay: z .number() @@ -227,15 +227,17 @@ export const CountByYearAndDaySchema = z.record( .int() .nonnegative() .nullable() - .describe("number of tests, position in the array is the day of the year") - ) + .describe( + "number of tests, position in the array is the day of the year", + ), + ), ); export type CountByYearAndDay = z.infer; //Record; @@ -248,8 +250,8 @@ export const UserNameSchema = doesNotContainProfanity( .max(16) .regex( /^[\da-zA-Z_-]+$/, - "Can only contain lower/uppercase letters, underscore and minus." - ) + "Can only contain lower/uppercase letters, underscore and minus.", + ), ); export const UserSchema = z.object({ diff --git a/packages/schemas/src/util.ts b/packages/schemas/src/util.ts index 45255e718ddb..6098b9ab3a7b 100644 --- a/packages/schemas/src/util.ts +++ b/packages/schemas/src/util.ts @@ -4,7 +4,7 @@ export const StringNumberSchema = z .string() .regex( /^\d+$/, - 'Needs to be a number or a number represented as a string e.g. "10".' + 'Needs to be a number or a number represented as a string e.g. "10".', ) .or(z.number().transform(String)); export type StringNumber = z.infer; @@ -41,6 +41,6 @@ export function customEnumErrorHandler(message: string): ZodErrorMap { message: issue.code === "invalid_enum_value" ? `Invalid enum value. ${message}` - : issue.message ?? "Required", + : (issue.message ?? "Required"), }); } diff --git a/packages/schemas/src/validation/validation.ts b/packages/schemas/src/validation/validation.ts index 4533e5ee0fc9..3e3e289ffcbf 100644 --- a/packages/schemas/src/validation/validation.ts +++ b/packages/schemas/src/validation/validation.ts @@ -3,7 +3,7 @@ import { ZodEffects, ZodString } from "zod"; export function containsProfanity( text: string, - mode: "word" | "substring" + mode: "word" | "substring", ): boolean { const normalizedText = text .toLowerCase() @@ -37,7 +37,7 @@ function sanitizeString(str: string | undefined): string | undefined { export function doesNotContainProfanity( mode: "word" | "substring", - schema: ZodString + schema: ZodString, ): ZodEffects { return schema.refine( (val) => { @@ -45,7 +45,7 @@ export function doesNotContainProfanity( }, (val) => ({ message: `Profanity detected. Please remove it. If you believe this is a mistake, please contact us. (${val})`, - }) + }), ); } diff --git a/packages/tsup-config/src/index.ts b/packages/tsup-config/src/index.ts index 266bf16cab6e..77733cf96901 100644 --- a/packages/tsup-config/src/index.ts +++ b/packages/tsup-config/src/index.ts @@ -1,7 +1,7 @@ import { defineConfig, Options } from "tsup"; export function extendConfig( - customizer?: (options: Options) => Options + customizer?: (options: Options) => Options, // tsup uses MaybePromise which is not exported // eslint-disable-next-line @typescript-eslint/no-explicit-any ): (options: Options) => any { diff --git a/packages/util/__test__/date-and-time.spec.ts b/packages/util/__test__/date-and-time.spec.ts index e54c636ddc9f..42ac09e9214a 100644 --- a/packages/util/__test__/date-and-time.spec.ts +++ b/packages/util/__test__/date-and-time.spec.ts @@ -100,7 +100,7 @@ describe("date-and-time", () => { testCases.forEach(({ input, offset, expected }) => { expect( - DateAndTime.getStartOfDayTimestamp(input, offset * 3600000) + DateAndTime.getStartOfDayTimestamp(input, offset * 3600000), ).toEqual(expected); }); }); diff --git a/packages/util/__test__/json.spec.ts b/packages/util/__test__/json.spec.ts index 421f78046a39..c0100f9ed642 100644 --- a/packages/util/__test__/json.spec.ts +++ b/packages/util/__test__/json.spec.ts @@ -12,8 +12,8 @@ describe("json", () => { it("should throw with invalid json", () => { expect(() => parseWithSchema("blah", schema)).toThrowError( new Error( - `Invalid JSON: Unexpected token 'b', "blah" is not valid JSON` - ) + `Invalid JSON: Unexpected token 'b', "blah" is not valid JSON`, + ), ); }); it("should parse", () => { @@ -42,8 +42,8 @@ describe("json", () => { expect(() => parseWithSchema(json, schema)).toThrowError( new Error( - `JSON does not match schema: "test" expected boolean, received string, "name" required, "nested.foo" expected string, received number` - ) + `JSON does not match schema: "test" expected boolean, received string, "name" required, "nested.foo" expected string, received number`, + ), ); }); it("should migrate if valid json", () => { @@ -97,8 +97,8 @@ describe("json", () => { }); }).toThrowError( new Error( - `Migrated value does not match schema: "test" expected boolean, received string, "name" expected string, received null` - ) + `Migrated value does not match schema: "test" expected boolean, received string, "name" expected string, received null`, + ), ); }); it("should revert to fallback if migration fails", () => { diff --git a/packages/util/__test__/numbers.spec.ts b/packages/util/__test__/numbers.spec.ts index 0c73c53161a4..fd365517ee84 100644 --- a/packages/util/__test__/numbers.spec.ts +++ b/packages/util/__test__/numbers.spec.ts @@ -92,8 +92,8 @@ describe("numbers", () => { input.inMax, input.outMin, input.outMax, - input.clamp - ) + input.clamp, + ), ).toEqual(expected); }); }); @@ -122,7 +122,7 @@ describe("numbers", () => { "should return $expected for $input", ({ input, expected }) => { expect(Numbers.isSafeNumber(input)).toEqual(expected); - } + }, ); }); }); @@ -150,7 +150,7 @@ describe("numbers", () => { "should return $expected for $input", ({ input, expected }) => { expect(Numbers.safeNumber(input as number)).toEqual(expected); - } + }, ); }); }); diff --git a/packages/util/__test__/predicates.spec.ts b/packages/util/__test__/predicates.spec.ts index 01bde604f1a2..64ffb71b88c2 100644 --- a/packages/util/__test__/predicates.spec.ts +++ b/packages/util/__test__/predicates.spec.ts @@ -22,7 +22,7 @@ describe("predicates", () => { const containsLetter = ( str1: string, str2: string, - letter: string + letter: string, ): boolean => str1.includes(letter) || str2.includes(letter); const doesNotContainLetter = not(containsLetter); diff --git a/packages/util/__test__/strings.spec.ts b/packages/util/__test__/strings.spec.ts index 6b39b0ccae2e..9ce93dc6ccb0 100644 --- a/packages/util/__test__/strings.spec.ts +++ b/packages/util/__test__/strings.spec.ts @@ -7,7 +7,7 @@ describe("strings", () => { expect(kebabToCamelCase("hello-world")).toEqual("helloWorld"); expect(kebabToCamelCase("helloWorld")).toEqual("helloWorld"); expect( - kebabToCamelCase("one-two-three-four-five-six-seven-eight-nine-ten") + kebabToCamelCase("one-two-three-four-five-six-seven-eight-nine-ten"), ).toEqual("oneTwoThreeFourFiveSixSevenEightNineTen"); }); }); diff --git a/packages/util/__test__/trycatch.spec.ts b/packages/util/__test__/trycatch.spec.ts index 0ed36b79803d..f0ead4858c78 100644 --- a/packages/util/__test__/trycatch.spec.ts +++ b/packages/util/__test__/trycatch.spec.ts @@ -26,7 +26,7 @@ describe("tryCatch", () => { const customError = new CustomError("custom error", "E123"); const result = await tryCatch( - Promise.reject(customError) + Promise.reject(customError), ); expect(result.data).toBeNull(); expect(result.error).toBe(customError); diff --git a/packages/util/src/date-and-time.ts b/packages/util/src/date-and-time.ts index 901b179bc57b..6287b8827a97 100644 --- a/packages/util/src/date-and-time.ts +++ b/packages/util/src/date-and-time.ts @@ -20,7 +20,7 @@ export function getCurrentDayTimestamp(hourOffset = 0): number { */ export function getStartOfDayTimestamp( timestamp: number, - offsetMilis = 0 + offsetMilis = 0, ): number { return timestamp - ((timestamp - offsetMilis) % MILLISECONDS_IN_DAY); } @@ -35,7 +35,7 @@ export function isYesterday(timestamp: number, hourOffset = 0): boolean { const offsetMilis = hourOffset * MILISECONDS_IN_HOUR; const yesterday = getStartOfDayTimestamp( Date.now() - MILLISECONDS_IN_DAY, - offsetMilis + offsetMilis, ); const date = getStartOfDayTimestamp(timestamp, offsetMilis); diff --git a/packages/util/src/json.ts b/packages/util/src/json.ts index 97e794bb0c23..0c106eb520fa 100644 --- a/packages/util/src/json.ts +++ b/packages/util/src/json.ts @@ -17,14 +17,14 @@ export function parseWithSchema( fallback?: z.infer; migrate?: ( value: Record | unknown[], - zodIssues?: ZodIssue[] + zodIssues?: ZodIssue[], ) => z.infer; - } + }, ): z.infer { const { fallback, migrate } = fallbackAndMigrate ?? {}; const { data: jsonParsed, error } = tryCatchSync( - () => JSON.parse(json) as Record + () => JSON.parse(json) as Record, ); if (error) { @@ -45,7 +45,7 @@ export function parseWithSchema( throw new Error( `JSON does not match schema: ${safeParse.error.issues .map(prettyErrorMessage) - .join(", ")}` + .join(", ")}`, ); } @@ -57,7 +57,7 @@ export function parseWithSchema( throw new Error( `Migrated value does not match schema: ${safeParseMigrated.error.issues .map(prettyErrorMessage) - .join(", ")}` + .join(", ")}`, ); } // todo fix me diff --git a/packages/util/src/numbers.ts b/packages/util/src/numbers.ts index a18370d38d19..14445a3fdfd9 100644 --- a/packages/util/src/numbers.ts +++ b/packages/util/src/numbers.ts @@ -31,7 +31,7 @@ export function stdDev(array: number[]): number { const n = array.length; const mean = array.reduce((a, b) => a + b) / n; return Math.sqrt( - array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n + array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n, ); } catch (e) { return 0; @@ -111,7 +111,7 @@ export function mapRange( inMax: number, outMin: number, outMax: number, - clamp = true + clamp = true, ): number { if (inMin === inMax) { return outMin; @@ -149,7 +149,7 @@ export function isSafeNumber(value: unknown): value is number { * @returns The input number if it is safe, undefined otherwise. */ export function safeNumber( - value: number | undefined | null + value: number | undefined | null, ): number | undefined { if (isSafeNumber(value)) { return value; diff --git a/packages/util/src/predicates.ts b/packages/util/src/predicates.ts index 66fce3427ccc..3ea41349c419 100644 --- a/packages/util/src/predicates.ts +++ b/packages/util/src/predicates.ts @@ -6,7 +6,7 @@ export type Predicate = (...args: Args) => boolean; * @returns A new function that returns the negated boolean result. */ export function not( - predicate: Predicate + predicate: Predicate, ): Predicate { return (...args: T) => !predicate(...args); } diff --git a/packages/util/src/trycatch.ts b/packages/util/src/trycatch.ts index 6d78237caf9c..73385a10da92 100644 --- a/packages/util/src/trycatch.ts +++ b/packages/util/src/trycatch.ts @@ -13,7 +13,7 @@ type Failure = { type Result = Success | Failure; export async function tryCatch( - promiseOrFunction: Promise + promiseOrFunction: Promise, ): Promise> { try { let data = await promiseOrFunction; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02ddc1d0beca..ee79d73d589b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: 1.29.0 version: 1.29.0 prettier: - specifier: 2.8.8 - version: 2.8.8 + specifier: 3.6.2 + version: 3.6.2 turbo: specifier: 2.5.6 version: 2.5.6 @@ -654,7 +654,7 @@ importers: dependencies: tsup: specifier: 8.4.0 - version: 8.4.0(postcss@8.5.6)(tsx@4.16.2)(typescript@5.5.4)(yaml@2.8.1) + version: 8.4.0(postcss@8.5.6)(tsx@4.16.2)(typescript@5.9.3)(yaml@2.8.1) devDependencies: '@monkeytype/typescript-config': specifier: workspace:* @@ -4862,8 +4862,8 @@ packages: electron-to-chromium@1.5.144: resolution: {integrity: sha512-eJIaMRKeAzxfBSxtjYnoIAw/tdD6VIH6tHBZepZnAbE3Gyqqs5mGN87DvcldPUbVkIljTK8pY0CMcUljP64lfQ==} - electron-to-chromium@1.5.259: - resolution: {integrity: sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==} + electron-to-chromium@1.5.261: + resolution: {integrity: sha512-cmyHEWFqEt3ICUNF93ShneOF47DHoSDbLb7E/AonsWcbzg95N+kPXeLNfkdzgTT/vEUcoW76fxbLBkeYtfoM8A==} electron-to-chromium@1.5.5: resolution: {integrity: sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==} @@ -7810,9 +7810,9 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} hasBin: true pretty-bytes@5.6.0: @@ -9219,11 +9219,6 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -13571,7 +13566,7 @@ snapshots: dependencies: baseline-browser-mapping: 2.8.31 caniuse-lite: 1.0.30001757 - electron-to-chromium: 1.5.259 + electron-to-chromium: 1.5.261 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -14549,7 +14544,7 @@ snapshots: electron-to-chromium@1.5.144: {} - electron-to-chromium@1.5.259: {} + electron-to-chromium@1.5.261: {} electron-to-chromium@1.5.5: {} @@ -18270,7 +18265,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@2.8.8: {} + prettier@3.6.2: {} pretty-bytes@5.6.0: {} @@ -19848,33 +19843,6 @@ snapshots: tsscmp@1.0.6: {} - tsup@8.4.0(postcss@8.5.6)(tsx@4.16.2)(typescript@5.5.4)(yaml@2.8.1): - dependencies: - bundle-require: 5.1.0(esbuild@0.25.0) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.0 - debug: 4.4.1 - esbuild: 0.25.0 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.6)(tsx@4.16.2)(yaml@2.8.1) - resolve-from: 5.0.0 - rollup: 4.40.0 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.13 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.6 - typescript: 5.5.4 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - tsup@8.4.0(postcss@8.5.6)(tsx@4.16.2)(typescript@5.9.3)(yaml@2.8.1): dependencies: bundle-require: 5.1.0(esbuild@0.25.0) @@ -20036,9 +20004,6 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript@5.5.4: - optional: true - typescript@5.9.3: {} ua-parser-js@0.7.33: {} diff --git a/vitest.config.ts b/vitest.config.ts index e846816434ea..5702907d3c2c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,7 @@ export default defineConfig({ projects: [ ...backendProjects.map( (it) => - ({ test: { ...it.test, root: "backend" } } as UserWorkspaceConfig) + ({ test: { ...it.test, root: "backend" } }) as UserWorkspaceConfig, ), "frontend/vitest.config.ts", "packages/**/vitest.config.ts",