Skip to content

Commit

Permalink
refactor: enable no-unsafe-argument rule (@Miodec) (#5872)
Browse files Browse the repository at this point in the history
  • Loading branch information
Miodec authored Sep 11, 2024
1 parent 4f75a00 commit 93d6fff
Show file tree
Hide file tree
Showing 31 changed files with 157 additions and 55 deletions.
6 changes: 5 additions & 1 deletion backend/src/api/controllers/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ export async function handleReports(
});
await UserDAL.addToInbox(report.uid, [mail], inboxConfig);
} catch (e) {
throw new MonkeyError(e.status, e.message);
if (e instanceof MonkeyError) {
throw new MonkeyError(e.status, e.message);
} else {
throw new MonkeyError(500, "Error handling reports: " + e.message);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions backend/src/api/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,9 @@ export function generateCurrentTestActivity(
//make sure lastYearData covers the full year
if (lastYearData.length < Dates.getDaysInYear(lastYear)) {
lastYearData.push(
...new Array(Dates.getDaysInYear(lastYear) - lastYearData.length).fill(
...(new Array(Dates.getDaysInYear(lastYear) - lastYearData.length).fill(
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
Expand Down
6 changes: 3 additions & 3 deletions backend/src/dal/new-quotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ export async function add(
const quoteFile = await readFile(fileDir);
const quoteFileJSON = JSON.parse(quoteFile.toString());
quoteFileJSON.quotes.every((old) => {
if (compareTwoStrings(old.text, quote.text) > 0.9) {
if (compareTwoStrings(old.text as string, quote.text) > 0.9) {
duplicateId = old.id;
similarityScore = compareTwoStrings(old.text, quote.text);
similarityScore = compareTwoStrings(old.text as string, quote.text);
return false;
}
return true;
Expand Down Expand Up @@ -157,7 +157,7 @@ export async function approve(
const quoteFile = await readFile(fileDir);
const quoteObject = JSON.parse(quoteFile.toString());
quoteObject.quotes.every((old) => {
if (compareTwoStrings(old.text, quote.text) > 0.8) {
if (compareTwoStrings(old.text as string, quote.text) > 0.8) {
throw new MonkeyError(409, "Duplicate quote");
}
});
Expand Down
4 changes: 2 additions & 2 deletions backend/src/dal/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ export async function getStats(
}

export async function getFavoriteQuotes(
uid
uid: string
): Promise<NonNullable<MonkeyTypes.DBUser["favoriteQuotes"]>> {
const user = await getPartialUser(uid, "get favorite quotes", [
"favoriteQuotes",
Expand Down Expand Up @@ -1072,7 +1072,7 @@ export async function updateStreak(
} else if (!isToday(streak.lastResultTimestamp, streak.hourOffset ?? 0)) {
void addImportantLog(
"streak_lost",
JSON.parse(JSON.stringify(streak)),
JSON.parse(JSON.stringify(streak)) as Record<string, unknown>,
uid
);
streak.length = 1;
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function mergeConfigurations(
const isSourceValueObject = _.isPlainObject(sourceValue);

if (isBaseValueObject && isSourceValueObject) {
merge(baseValue, sourceValue);
merge(baseValue as object, sourceValue as object);
} else if (identity(baseValue) === identity(sourceValue)) {
base[key] = sourceValue;
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function connect(): Promise<void> {
await mongoClient.connect();
db = mongoClient.db(DB_NAME);
} catch (error) {
Logger.error(error.message);
Logger.error(error.message as string);
Logger.error(
"Failed to connect to database. Exiting with exit status code 1."
);
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/email-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export async function init(): Promise<void> {
Logger.success("Email client configuration verified");
} catch (error) {
transportInitialized = false;
Logger.error(error.message);
Logger.error(error.message as string);
Logger.error("Failed to verify email client configuration.");
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export async function connect(): Promise<void> {

connected = true;
} catch (error) {
Logger.error(error.message);
Logger.error(error.message as string);
if (isDevEnvironment()) {
await connection.quit();
Logger.warning(
Expand Down
8 changes: 6 additions & 2 deletions backend/src/middlewares/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import crypto from "crypto";
import { performance } from "perf_hooks";
import { TsRestRequestHandler } from "@ts-rest/express";
import { AppRoute, AppRouter } from "@ts-rest/core";
import { RequestAuthenticationOptions } from "@monkeytype/contracts/schemas/api";
import {
EndpointMetadata,
RequestAuthenticationOptions,
} from "@monkeytype/contracts/schemas/api";
import { Configuration } from "@monkeytype/contracts/schemas/configuration";

const DEFAULT_OPTIONS: RequestAuthenticationOptions = {
Expand Down Expand Up @@ -45,7 +48,8 @@ export function authenticateTsRestRequest<
): Promise<void> => {
const options = {
...DEFAULT_OPTIONS,
...(req.tsRestRoute["metadata"]?.["authenticationOptions"] ?? {}),
...((req.tsRestRoute["metadata"]?.["authenticationOptions"] ??
{}) as EndpointMetadata),
};
return _authenticateRequestInternal(req, _res, next, options);
};
Expand Down
2 changes: 1 addition & 1 deletion backend/src/middlewares/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function verifyRequiredConfiguration<
next: NextFunction
): Promise<void> => {
const requiredConfigurations = getRequireConfigurations(
req.tsRestRoute["metadata"]
req.tsRestRoute["metadata"] as EndpointMetadata | undefined
);

if (requiredConfigurations === undefined) {
Expand Down
13 changes: 9 additions & 4 deletions backend/src/middlewares/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ async function errorHandlingMiddleware(
) {
recordServerErrorByVersion(version);

const { uid, errorId } = monkeyResponse.data;
const { uid, errorId } = monkeyResponse.data as {
uid: string;
errorId: string;
};

try {
await addLog(
Expand All @@ -77,7 +80,7 @@ async function errorHandlingMiddleware(
uid
);
await db.collection<DBError>("errors").insertOne({
_id: errorId,
_id: new ObjectId(errorId),
timestamp: Date.now(),
status: monkeyResponse.status,
uid,
Expand All @@ -89,7 +92,8 @@ async function errorHandlingMiddleware(
});
} catch (e) {
Logger.error("Logging to db failed.");
Logger.error(e);
Logger.error(e.message as string);
console.error(e);
}
} else {
Logger.error(`Error: ${error.message} Stack: ${error.stack}`);
Expand All @@ -103,7 +107,8 @@ async function errorHandlingMiddleware(
return;
} catch (e) {
Logger.error("Error handling middleware failed.");
Logger.error(e);
Logger.error(e.message as string);
console.error(e);
}

handleMonkeyResponse(
Expand Down
2 changes: 1 addition & 1 deletion backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async function bootServer(port: number): Promise<Server> {
recordServerVersion(version);
} catch (error) {
Logger.error("Failed to boot server");
Logger.error(error.message);
Logger.error(error.message as string);
console.error(error);
return process.exit(1);
}
Expand Down
4 changes: 2 additions & 2 deletions backend/src/services/weekly-xp-leaderboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,15 @@ export class WeeklyXpLeaderboard {
}

//TODO parse with zod?
const parsed = JSON.parse(result ?? "null") as Omit<
const parsed = JSON.parse((result as string) ?? "null") as Omit<
XpLeaderboardEntry,
"rank" | "count" | "totalXp"
>;

return {
rank: rank + 1,
count: count ?? 0,
totalXp: parseInt(totalXp, 10),
totalXp: parseInt(totalXp as string, 10),
...parsed,
};
}
Expand Down
16 changes: 12 additions & 4 deletions backend/src/utils/daily-leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,25 @@ export class DailyLeaderboard {
const { leaderboardScoresKey, leaderboardResultsKey } =
this.getTodaysLeaderboardKeys();

// @ts-expect-error
const [[, rank], [, count], [, result], [, minScore]] = await connection
const redisExecResult = (await connection
.multi()
.zrevrank(leaderboardScoresKey, uid)
.zcard(leaderboardScoresKey)
.hget(leaderboardResultsKey, uid)
.zrange(leaderboardScoresKey, 0, 0, "WITHSCORES")
.exec();
.exec()) as [
[null, number | null],
[null, number | null],
[null, string | null],
[null, [string, string] | null]
];

const [[, rank], [, count], [, result], [, minScore]] = redisExecResult;

const minWpm =
minScore.length > 0 ? parseInt(minScore[1]?.slice(1, 6)) / 100 : 0;
minScore !== null && minScore.length > 0
? parseInt(minScore[1]?.slice(1, 6)) / 100
: 0;
if (rank === null) {
return {
minWpm,
Expand Down
3 changes: 2 additions & 1 deletion backend/src/utils/monkey-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export function handleMonkeyResponse(
//@ts-expect-error ignored so that we can see message in swagger stats
res.monkeyMessage = message;
if ([301, 302].includes(status)) {
res.redirect(data);
// todo add stronger types here, maybe a MonkeyRedirectResponse
res.redirect(data as string);
return;
}

Expand Down
6 changes: 5 additions & 1 deletion frontend/src/ts/commandline/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ import * as TestStats from "../test/test-stats";
import * as QuoteSearchModal from "../modals/quote-search";
import * as FPSCounter from "../elements/fps-counter";
import { migrateConfig } from "../utils/config";
import { PartialConfigSchema } from "@monkeytype/contracts/schemas/configs";

const layoutsPromise = JSONData.getLayoutsList();
layoutsPromise
Expand Down Expand Up @@ -372,7 +373,10 @@ export const commands: MonkeyTypes.CommandsSubgroup = {
exec: async ({ input }): Promise<void> => {
if (input === undefined || input === "") return;
try {
await UpdateConfig.apply(migrateConfig(JSON.parse(input)));
const parsedConfig = PartialConfigSchema.strip().parse(
JSON.parse(input)
);
await UpdateConfig.apply(migrateConfig(parsedConfig));
UpdateConfig.saveFullConfigToLocalStorage();
void Settings.update();
Notifications.add("Done", 1);
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/ts/controllers/input-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,11 @@ $(document).on("keydown", async (event) => {
);
if (funbox?.functions?.preventDefaultEvent) {
if (
await funbox.functions.preventDefaultEvent(event as JQuery.KeyDownEvent)
await funbox.functions.preventDefaultEvent(
//i cant figure this type out, but it works fine
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
event as JQuery.KeyDownEvent
)
) {
event.preventDefault();
handleChar(event.key, TestInput.input.current.length);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ts/controllers/theme-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export function preview(
debouncedPreview(themeIdentifier, customColorsOverride);
}

const debouncedPreview = debounce(
const debouncedPreview = debounce<(t: string, c?: string[]) => void>(
250,
(themeIdenfitier, customColorsOverride) => {
isPreviewingTheme = true;
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/ts/elements/account/result-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,9 @@ export async function appendButtons(
): void | boolean => {
return selectBeforeChangeFn(
"language",
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
selectedOptions,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
oldSelectedOptions
);
},
Expand Down Expand Up @@ -855,7 +857,9 @@ export async function appendButtons(
): void | boolean => {
return selectBeforeChangeFn(
"funbox",
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
selectedOptions,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
oldSelectedOptions
);
},
Expand Down Expand Up @@ -910,7 +914,9 @@ export async function appendButtons(
): void | boolean => {
return selectBeforeChangeFn(
"tags",
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
selectedOptions,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
oldSelectedOptions
);
},
Expand Down Expand Up @@ -945,7 +951,7 @@ $(".group.presetFilterButtons .filterBtns").on(
"click",
".filterPresets .delete-filter-preset",
(e) => {
void deleteFilterPreset($(e.currentTarget).data("id"));
void deleteFilterPreset($(e.currentTarget).data("id") as string);
}
);

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ts/elements/settings/settings-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default class SettingsGroup<T extends ConfigValue> {
return;
}

const debounced = debounce(250, (val) => {
const debounced = debounce<(val: T) => void>(250, (val) => {
this.setValue(val);
});

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ts/event-handlers/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ $(accountPage).on("click", ".group.history .resultEditTagsButton", (e) => {
const tags = $(e.target).attr("data-tags");
EditResultTagsModal.show(
resultid ?? "",
JSON.parse(tags ?? "[]"),
JSON.parse(tags ?? "[]") as string[],
"accountPage"
);
});
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ts/event-handlers/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ window.onerror = function (message, url, line, column, error): void {
window.onunhandledrejection = function (e): void {
if (Misc.isDevEnvironment()) {
const message = e.reason.message ?? e.reason;
Notifications.add(message, -1, {
Notifications.add(`${message}`, -1, {
customTitle: "DEV: Unhandled rejection",
duration: 5,
});
Expand Down
15 changes: 13 additions & 2 deletions frontend/src/ts/modals/import-export-settings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PartialConfigSchema } from "@monkeytype/contracts/schemas/configs";
import * as UpdateConfig from "../config";
import * as Notifications from "../elements/notifications";
import AnimatedModal from "../utils/animated-modal";
Expand Down Expand Up @@ -46,10 +47,20 @@ const modal = new AnimatedModal({
return;
}
try {
await UpdateConfig.apply(migrateConfig(JSON.parse(state.value)));
const parsedConfig = PartialConfigSchema.strip().parse(
JSON.parse(state.value)
);
await UpdateConfig.apply(migrateConfig(parsedConfig));
} catch (e) {
Notifications.add("Failed to import settings: " + e, -1);
Notifications.add(
"Failed to import settings: incorrect data schema",
0
);
console.error(e);
void modal.hide();
return;
}
Notifications.add("Settings imported", 1);
UpdateConfig.saveFullConfigToLocalStorage();
void modal.hide();
});
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/ts/modals/save-custom-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ function hide(): void {

function save(): boolean {
const name = $("#saveCustomTextModal .textName").val() as string;
const checkbox = $("#saveCustomTextModal .isLongText").prop("checked");
const checkbox = $("#saveCustomTextModal .isLongText").prop(
"checked"
) as boolean;

if (!name) {
Notifications.add("Custom text needs a name", 0);
Expand All @@ -54,7 +56,9 @@ function save(): boolean {

function updateIndicatorAndButton(): void {
const val = $("#saveCustomTextModal .textName").val() as string;
const checkbox = $("#saveCustomTextModal .isLongText").prop("checked");
const checkbox = $("#saveCustomTextModal .isLongText").prop(
"checked"
) as boolean;

if (!val) {
indicator?.hide();
Expand Down
Loading

0 comments on commit 93d6fff

Please sign in to comment.