diff --git a/.eslintrc.js b/.eslintrc.js index e31438fc..4ba6dfe6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -12,5 +12,17 @@ module.exports = { "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/ban-ts-comment": 0, "@typescript-eslint/no-non-null-assertion": 0, + "no-async-promise-executor": 0, + "@typescript-eslint/no-empty-interface": 0, + "no-constant-condition": ["error", { + checkLoops: false, + }], + "prefer-const": ["error", { + destructuring: "all", + ignoreReadBeforeAssign: true, + }], + "@typescript-eslint/no-namespace": ["error", { + allowDeclarations: true, + }], }, }; diff --git a/backend/src/SimpleError.ts b/backend/src/SimpleError.ts index 550bbbd3..4ae1ae6f 100644 --- a/backend/src/SimpleError.ts +++ b/backend/src/SimpleError.ts @@ -7,7 +7,7 @@ export class SimpleError extends Error { super(message); } - [util.inspect.custom](depth, options) { + [util.inspect.custom]() { return `Error: ${this.message}`; } } diff --git a/backend/src/api/auth.ts b/backend/src/api/auth.ts index 66ba015e..f4486356 100644 --- a/backend/src/api/auth.ts +++ b/backend/src/api/auth.ts @@ -18,7 +18,6 @@ interface IPassportApiUser { declare global { namespace Express { - // tslint:disable-next-line:no-empty-interface interface User extends IPassportApiUser {} } } @@ -151,6 +150,7 @@ export function initAuth(app: express.Express) { export function apiTokenAuthHandlers() { return [ passport.authenticate("api-token", { failWithError: true }), + // eslint-disable-next-line @typescript-eslint/no-unused-vars (err, req: Request, res: Response, next) => { return res.status(401).json({ error: err.message }); }, diff --git a/backend/src/api/guilds/importExport.ts b/backend/src/api/guilds/importExport.ts index 35428347..a7bb6e2e 100644 --- a/backend/src/api/guilds/importExport.ts +++ b/backend/src/api/guilds/importExport.ts @@ -50,7 +50,7 @@ export function initGuildsImportExportAPI(guildRouter: express.Router) { importExportRouter.get( "/:guildId/pre-import", requireGuildPermission(ApiPermissions.ManageAccess), - async (req: Request, res: Response) => { + async (req: Request) => { const guildCases = GuildCases.getGuildInstance(req.params.guildId); const minNum = await guildCases.getMinCaseNumber(); const maxNum = await guildCases.getMaxCaseNumber(); diff --git a/backend/src/api/responses.ts b/backend/src/api/responses.ts index 8f7f8a37..53b44345 100644 --- a/backend/src/api/responses.ts +++ b/backend/src/api/responses.ts @@ -4,7 +4,7 @@ export function unauthorized(res: Response) { res.status(403).json({ error: "Unauthorized" }); } -export function error(res: Response, message: string, statusCode: number = 500) { +export function error(res: Response, message: string, statusCode = 500) { res.status(statusCode).json({ error: message }); } diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index 8e542cc0..9006959a 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -35,6 +35,7 @@ app.get("/", (req, res) => { }); // Error response +// eslint-disable-next-line @typescript-eslint/no-unused-vars app.use((err, req, res, next) => { if (err instanceof TokenError) { clientError(res, "Invalid code"); @@ -45,6 +46,7 @@ app.use((err, req, res, next) => { }); // 404 response +// eslint-disable-next-line @typescript-eslint/no-unused-vars app.use((req, res, next) => { return notFound(res); }); diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index bdc25f17..47ad0405 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -96,7 +96,7 @@ export const commandTypes = { throw new TypeConversionError(`Could not parse ID: \`${escapeInlineCode(value)}\``); }, - regex(value: string, context: CommandContext): RegExp { + regex(value: string): RegExp { try { return inputPatternToRegExp(value); } catch (e) { diff --git a/backend/src/data/BaseGuildRepository.ts b/backend/src/data/BaseGuildRepository.ts index 7d756fce..4ee2d757 100644 --- a/backend/src/data/BaseGuildRepository.ts +++ b/backend/src/data/BaseGuildRepository.ts @@ -1,6 +1,6 @@ import { BaseRepository } from "./BaseRepository"; -export class BaseGuildRepository extends BaseRepository { +export class BaseGuildRepository extends BaseRepository { private static guildInstances: Map; protected guildId: string; diff --git a/backend/src/data/BaseRepository.ts b/backend/src/data/BaseRepository.ts index 1364b23a..27b08578 100644 --- a/backend/src/data/BaseRepository.ts +++ b/backend/src/data/BaseRepository.ts @@ -1,6 +1,6 @@ import { asyncMap } from "../utils/async"; -export class BaseRepository { +export class BaseRepository { private nextRelations: string[]; constructor() { diff --git a/backend/src/data/Configs.ts b/backend/src/data/Configs.ts index 2b3e4089..cbd3c8de 100644 --- a/backend/src/data/Configs.ts +++ b/backend/src/data/Configs.ts @@ -6,15 +6,16 @@ import { cleanupConfigs } from "./cleanup/configs"; import { connection } from "./db"; import { Config } from "./entities/Config"; +const CLEANUP_INTERVAL = 1 * HOURS; + +async function cleanup() { + await cleanupConfigs(); + setTimeout(cleanup, CLEANUP_INTERVAL); +} + if (isAPI()) { - const CLEANUP_INTERVAL = 1 * HOURS; - - async function cleanup() { - await cleanupConfigs(); - setTimeout(cleanup, CLEANUP_INTERVAL); - } - // Start first cleanup 30 seconds after startup + // TODO: Move to bot startup code setTimeout(cleanup, 30 * SECONDS); } diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 22b389e7..8eb3df95 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -7,8 +7,6 @@ import { connection } from "./db"; import { Case } from "./entities/Case"; import { CaseNote } from "./entities/CaseNote"; -const CASE_SUMMARY_REASON_MAX_LENGTH = 300; - export class GuildCases extends BaseGuildRepository { private cases: Repository; private caseNotes: Repository; diff --git a/backend/src/data/GuildNicknameHistory.ts b/backend/src/data/GuildNicknameHistory.ts index 9f75d24e..5be3b6ae 100644 --- a/backend/src/data/GuildNicknameHistory.ts +++ b/backend/src/data/GuildNicknameHistory.ts @@ -5,15 +5,16 @@ import { BaseGuildRepository } from "./BaseGuildRepository"; import { cleanupNicknames } from "./cleanup/nicknames"; import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry"; +const CLEANUP_INTERVAL = 5 * MINUTES; + +async function cleanup() { + await cleanupNicknames(); + setTimeout(cleanup, CLEANUP_INTERVAL); +} + if (!isAPI()) { - const CLEANUP_INTERVAL = 5 * MINUTES; - - async function cleanup() { - await cleanupNicknames(); - setTimeout(cleanup, CLEANUP_INTERVAL); - } - // Start first cleanup 30 seconds after startup + // TODO: Move to bot startup code setTimeout(cleanup, 30 * SECONDS); } diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 7ec06fbc..b650be6f 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -126,7 +126,7 @@ export class GuildSavedMessages extends BaseGuildRepository { return entity; } - entity.data = await decryptJson(entity.data as unknown as string); + entity.data = (await decryptJson(entity.data as unknown as string)) as ISavedMessageData; return entity; } diff --git a/backend/src/data/UsernameHistory.ts b/backend/src/data/UsernameHistory.ts index 7aa4331a..224ba99a 100644 --- a/backend/src/data/UsernameHistory.ts +++ b/backend/src/data/UsernameHistory.ts @@ -5,15 +5,16 @@ import { BaseRepository } from "./BaseRepository"; import { cleanupUsernames } from "./cleanup/usernames"; import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry"; +const CLEANUP_INTERVAL = 5 * MINUTES; + +async function cleanup() { + await cleanupUsernames(); + setTimeout(cleanup, CLEANUP_INTERVAL); +} + if (!isAPI()) { - const CLEANUP_INTERVAL = 5 * MINUTES; - - async function cleanup() { - await cleanupUsernames(); - setTimeout(cleanup, CLEANUP_INTERVAL); - } - // Start first cleanup 30 seconds after startup + // TODO: Move to bot startup code setTimeout(cleanup, 30 * SECONDS); } diff --git a/backend/src/data/apiAuditLogTypes.ts b/backend/src/data/apiAuditLogTypes.ts index 8e9075af..e75a071f 100644 --- a/backend/src/data/apiAuditLogTypes.ts +++ b/backend/src/data/apiAuditLogTypes.ts @@ -19,8 +19,6 @@ export type RemoveApiPermissionEventData = { target_id: string; }; -export type EditConfigEventData = {}; - export interface AuditLogEventData extends Record { ADD_API_PERMISSION: { type: ApiPermissionTypes; @@ -41,7 +39,7 @@ export interface AuditLogEventData extends Record { target_id: string; }; - EDIT_CONFIG: {}; + EDIT_CONFIG: Record; } export type AnyAuditLogEventData = AuditLogEventData[AuditLogEventType]; diff --git a/backend/src/data/buildEntity.ts b/backend/src/data/buildEntity.ts index c174efc4..0a608aa4 100644 --- a/backend/src/data/buildEntity.ts +++ b/backend/src/data/buildEntity.ts @@ -1,4 +1,4 @@ -export function buildEntity(Entity: new () => T, data: Partial): T { +export function buildEntity(Entity: new () => T, data: Partial): T { const instance = new Entity(); for (const [key, value] of Object.entries(data)) { instance[key] = value; diff --git a/backend/src/data/db.ts b/backend/src/data/db.ts index 82c4c3f5..798b077c 100644 --- a/backend/src/data/db.ts +++ b/backend/src/data/db.ts @@ -5,6 +5,7 @@ import { backendDir } from "../paths"; import { QueryLogger } from "./queryLogger"; const ormconfigPath = path.join(backendDir, "ormconfig.js"); +// eslint-disable-next-line @typescript-eslint/no-var-requires const connectionOptions = require(ormconfigPath); let connectionPromise: Promise; diff --git a/backend/src/data/entities/ApiLogin.ts b/backend/src/data/entities/ApiLogin.ts index 0cc35f39..76460068 100644 --- a/backend/src/data/entities/ApiLogin.ts +++ b/backend/src/data/entities/ApiLogin.ts @@ -19,7 +19,7 @@ export class ApiLogin { @Column() expires_at: string; - @ManyToOne((type) => ApiUserInfo, (userInfo) => userInfo.logins) + @ManyToOne(() => ApiUserInfo, (userInfo) => userInfo.logins) @JoinColumn({ name: "user_id" }) userInfo: ApiUserInfo; } diff --git a/backend/src/data/entities/ApiPermissionAssignment.ts b/backend/src/data/entities/ApiPermissionAssignment.ts index 49e07878..98ef500f 100644 --- a/backend/src/data/entities/ApiPermissionAssignment.ts +++ b/backend/src/data/entities/ApiPermissionAssignment.ts @@ -22,7 +22,7 @@ export class ApiPermissionAssignment { @Column({ type: String, nullable: true }) expires_at: string | null; - @ManyToOne((type) => ApiUserInfo, (userInfo) => userInfo.permissionAssignments) + @ManyToOne(() => ApiUserInfo, (userInfo) => userInfo.permissionAssignments) @JoinColumn({ name: "target_id" }) userInfo: ApiUserInfo; } diff --git a/backend/src/data/entities/ApiUserInfo.ts b/backend/src/data/entities/ApiUserInfo.ts index b6146b23..bb0844b5 100644 --- a/backend/src/data/entities/ApiUserInfo.ts +++ b/backend/src/data/entities/ApiUserInfo.ts @@ -20,9 +20,9 @@ export class ApiUserInfo { @Column() updated_at: string; - @OneToMany((type) => ApiLogin, (login) => login.userInfo) + @OneToMany(() => ApiLogin, (login) => login.userInfo) logins: ApiLogin[]; - @OneToMany((type) => ApiPermissionAssignment, (p) => p.userInfo) + @OneToMany(() => ApiPermissionAssignment, (p) => p.userInfo) permissionAssignments: ApiPermissionAssignment[]; } diff --git a/backend/src/data/entities/Case.ts b/backend/src/data/entities/Case.ts index 84d24618..5fb52003 100644 --- a/backend/src/data/entities/Case.ts +++ b/backend/src/data/entities/Case.ts @@ -35,6 +35,6 @@ export class Case { */ @Column({ type: String, nullable: true }) log_message_id: string | null; - @OneToMany((type) => CaseNote, (note) => note.case) + @OneToMany(() => CaseNote, (note) => note.case) notes: CaseNote[]; } diff --git a/backend/src/data/entities/CaseNote.ts b/backend/src/data/entities/CaseNote.ts index f883d79f..e82aa405 100644 --- a/backend/src/data/entities/CaseNote.ts +++ b/backend/src/data/entities/CaseNote.ts @@ -15,7 +15,7 @@ export class CaseNote { @Column() created_at: string; - @ManyToOne((type) => Case, (theCase) => theCase.notes) + @ManyToOne(() => Case, (theCase) => theCase.notes) @JoinColumn({ name: "case_id" }) case: Case; } diff --git a/backend/src/data/entities/Config.ts b/backend/src/data/entities/Config.ts index d5e391b4..6d4a38c7 100644 --- a/backend/src/data/entities/Config.ts +++ b/backend/src/data/entities/Config.ts @@ -22,7 +22,7 @@ export class Config { @Column() edited_at: string; - @ManyToOne((type) => ApiUserInfo) + @ManyToOne(() => ApiUserInfo) @JoinColumn({ name: "edited_by" }) userInfo: ApiUserInfo; } diff --git a/backend/src/data/entities/StarboardMessage.ts b/backend/src/data/entities/StarboardMessage.ts index 2d8839e6..88512adf 100644 --- a/backend/src/data/entities/StarboardMessage.ts +++ b/backend/src/data/entities/StarboardMessage.ts @@ -16,7 +16,7 @@ export class StarboardMessage { @Column() guild_id: string; - @OneToOne((type) => SavedMessage) + @OneToOne(() => SavedMessage) @JoinColumn({ name: "message_id" }) message: SavedMessage; } diff --git a/backend/src/data/entities/StarboardReaction.ts b/backend/src/data/entities/StarboardReaction.ts index c2cb0258..9cc02850 100644 --- a/backend/src/data/entities/StarboardReaction.ts +++ b/backend/src/data/entities/StarboardReaction.ts @@ -16,7 +16,7 @@ export class StarboardReaction { @Column() reactor_id: string; - @OneToOne((type) => SavedMessage) + @OneToOne(() => SavedMessage) @JoinColumn({ name: "message_id" }) message: SavedMessage; } diff --git a/backend/src/data/queryLogger.ts b/backend/src/data/queryLogger.ts index 269c19bf..c5fb3ee8 100644 --- a/backend/src/data/queryLogger.ts +++ b/backend/src/data/queryLogger.ts @@ -1,4 +1,3 @@ -import type { QueryRunner } from "typeorm"; import { AdvancedConsoleLogger } from "typeorm/logger/AdvancedConsoleLogger"; let groupedQueryStats: Map = new Map(); @@ -9,7 +8,7 @@ const deleteTableRegex = /FROM `?([^\s`]+)/; const insertTableRegex = /INTO `?([^\s`]+)/; export class QueryLogger extends AdvancedConsoleLogger { - logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner): any { + logQuery(query: string): any { let type: string | undefined; let table: string | undefined; diff --git a/backend/src/index.ts b/backend/src/index.ts index c0f2a822..468b4a0f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -242,11 +242,6 @@ connect().then(async (connection) => { // FIXME: TS doesn't see Client as a child of EventEmitter for some reason (client as unknown as EventEmitter).setMaxListeners(200); - client.rest.on(RESTEvents.RateLimited, (data) => { - // tslint:disable-next-line:no-console - // console.log(`[DEBUG] [RATE_LIMIT] ${JSON.stringify(data)}`); - }); - const safe429DecayInterval = 5 * SECONDS; const safe429MaxCount = 5; const safe429Counter = new DecayingCounter(safe429DecayInterval); @@ -453,7 +448,7 @@ connect().then(async (connection) => { logger.info("Received SIGINT, exiting..."); cleanupAndStop(0); }); - process.on("SIGTERM", (code) => { + process.on("SIGTERM", () => { logger.info("Received SIGTERM, exiting..."); cleanupAndStop(0); }); diff --git a/backend/src/migrations/1540519249973-CreatePreTypeORMTables.ts b/backend/src/migrations/1540519249973-CreatePreTypeORMTables.ts index 9b0044ad..46448cf2 100644 --- a/backend/src/migrations/1540519249973-CreatePreTypeORMTables.ts +++ b/backend/src/migrations/1540519249973-CreatePreTypeORMTables.ts @@ -106,7 +106,7 @@ export class CreatePreTypeORMTables1540519249973 implements MigrationInterface { `); } - public async down(queryRunner: QueryRunner): Promise { + public async down(): Promise { // No down function since we're migrating (hehe) from another migration system (knex) } } diff --git a/backend/src/migrations/1556909512501-MigrateUsernamesToNewHistoryTable.ts b/backend/src/migrations/1556909512501-MigrateUsernamesToNewHistoryTable.ts index a42c0c7f..33dc43c3 100644 --- a/backend/src/migrations/1556909512501-MigrateUsernamesToNewHistoryTable.ts +++ b/backend/src/migrations/1556909512501-MigrateUsernamesToNewHistoryTable.ts @@ -77,6 +77,6 @@ export class MigrateUsernamesToNewHistoryTable1556909512501 implements Migration await queryRunner.query("START TRANSACTION"); } - // tslint:disable-next-line:no-empty - public async down(queryRunner: QueryRunner): Promise {} + // eslint-disable-next-line @typescript-eslint/no-empty-function + public async down(): Promise {} } diff --git a/backend/src/migrations/1573158035867-AddTypeAndPermissionsToApiPermissions.ts b/backend/src/migrations/1573158035867-AddTypeAndPermissionsToApiPermissions.ts index 5186b0a0..6b9c9861 100644 --- a/backend/src/migrations/1573158035867-AddTypeAndPermissionsToApiPermissions.ts +++ b/backend/src/migrations/1573158035867-AddTypeAndPermissionsToApiPermissions.ts @@ -4,7 +4,7 @@ export class AddTypeAndPermissionsToApiPermissions1573158035867 implements Migra public async up(queryRunner: QueryRunner): Promise { try { await queryRunner.dropPrimaryKey("api_permissions"); - } catch {} // tslint:disable-line + } catch {} // eslint-disable-line no-empty const table = (await queryRunner.getTable("api_permissions"))!; if (table.indices.length) { diff --git a/backend/src/migrations/1608753440716-CreateTempBansTable.ts b/backend/src/migrations/1608753440716-CreateTempBansTable.ts index 7345d34c..09f743c3 100644 --- a/backend/src/migrations/1608753440716-CreateTempBansTable.ts +++ b/backend/src/migrations/1608753440716-CreateTempBansTable.ts @@ -2,7 +2,7 @@ import { MigrationInterface, QueryRunner, Table, TableIndex } from "typeorm"; export class CreateTempBansTable1608753440716 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - const table = await queryRunner.createTable( + await queryRunner.createTable( new Table({ name: "tempbans", columns: [ diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 4d7cf6a7..8e6c6da2 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -77,28 +77,6 @@ const PluginOverrideCriteriaType: t.Type> = t.re }), ); -const validTopLevelOverrideKeys = [ - "channel", - "category", - "thread", - "is_thread", - "level", - "user", - "role", - "all", - "any", - "not", - "extra", - "config", -]; - -const BasicPluginStructureType = t.type({ - enabled: tNullable(t.boolean), - config: tNullable(t.unknown), - overrides: tNullable(t.array(t.union([PluginOverrideCriteriaType, t.type({ config: t.unknown })]))), - replaceDefaultOverrides: tNullable(t.boolean), -}); - export function strictValidationErrorToConfigValidationError(err: StrictValidationError) { return new ConfigValidationError( err diff --git a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts index af3ff607..0a8e0438 100644 --- a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts +++ b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts @@ -45,7 +45,7 @@ export const AutoDeletePlugin = zeppelinGuildPlugin()({ }, afterLoad(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.onMessageCreateFn = (msg) => onMessageCreate(pluginData, msg); state.guildSavedMessages.events.on("create", state.onMessageCreateFn); @@ -58,7 +58,7 @@ export const AutoDeletePlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.guildSavedMessages.events.off("create", state.onMessageCreateFn); state.guildSavedMessages.events.off("delete", state.onMessageDeleteFn); diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 306a5ad1..ff4f01fd 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -248,7 +248,7 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ }, async afterLoad(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.clearRecentActionsInterval = setInterval(() => clearOldRecentActions(pluginData), 1 * MINUTES); state.clearRecentSpamInterval = setInterval(() => clearOldRecentSpam(pluginData), 1 * SECONDS); diff --git a/backend/src/plugins/Automod/actions/addToCounter.ts b/backend/src/plugins/Automod/actions/addToCounter.ts index 842534ef..c3a72dae 100644 --- a/backend/src/plugins/Automod/actions/addToCounter.ts +++ b/backend/src/plugins/Automod/actions/addToCounter.ts @@ -11,7 +11,7 @@ export const AddToCounterAction = automodAction({ defaultConfig: {}, - async apply({ pluginData, contexts, actionConfig, matchResult, ruleName }) { + async apply({ pluginData, contexts, actionConfig, ruleName }) { const countersPlugin = pluginData.getPlugin(CountersPlugin); if (!countersPlugin.counterExists(actionConfig.counter)) { pluginData.getPlugin(LogsPlugin).logBotAlert({ diff --git a/backend/src/plugins/Automod/actions/changeNickname.ts b/backend/src/plugins/Automod/actions/changeNickname.ts index 9cd4790e..d63a3b60 100644 --- a/backend/src/plugins/Automod/actions/changeNickname.ts +++ b/backend/src/plugins/Automod/actions/changeNickname.ts @@ -20,7 +20,7 @@ export const ChangeNicknameAction = automodAction({ if (pluginData.state.recentNicknameChanges.has(member.id)) continue; const newName = typeof actionConfig === "string" ? actionConfig : actionConfig.name; - member.edit({ nick: newName }).catch((err) => { + member.edit({ nick: newName }).catch(() => { pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Failed to change the nickname of \`${member.id}\``, }); diff --git a/backend/src/plugins/Automod/actions/changePerms.ts b/backend/src/plugins/Automod/actions/changePerms.ts index 6c67eb8d..1eaa6dd5 100644 --- a/backend/src/plugins/Automod/actions/changePerms.ts +++ b/backend/src/plugins/Automod/actions/changePerms.ts @@ -70,7 +70,7 @@ export const ChangePermsAction = automodAction({ }), defaultConfig: {}, - async apply({ pluginData, contexts, actionConfig, ruleName }) { + async apply({ pluginData, contexts, actionConfig }) { const user = contexts.find((c) => c.user)?.user; const message = contexts.find((c) => c.message)?.message; diff --git a/backend/src/plugins/Automod/actions/exampleAction.ts b/backend/src/plugins/Automod/actions/exampleAction.ts index 760b2879..05bea0de 100644 --- a/backend/src/plugins/Automod/actions/exampleAction.ts +++ b/backend/src/plugins/Automod/actions/exampleAction.ts @@ -8,6 +8,7 @@ export const ExampleAction = automodAction({ defaultConfig: {}, + // eslint-disable-next-line @typescript-eslint/no-unused-vars async apply({ pluginData, contexts, actionConfig }) { // TODO: Everything }, diff --git a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts index a1722aae..ecddabd9 100644 --- a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts @@ -7,7 +7,7 @@ export const SetAntiraidLevelAction = automodAction({ configType: tNullable(t.string), defaultConfig: "", - async apply({ pluginData, contexts, actionConfig }) { + async apply({ pluginData, actionConfig }) { setAntiraidLevel(pluginData, actionConfig ?? null); }, }); diff --git a/backend/src/plugins/Automod/actions/setCounter.ts b/backend/src/plugins/Automod/actions/setCounter.ts index 3088f848..5db5a80d 100644 --- a/backend/src/plugins/Automod/actions/setCounter.ts +++ b/backend/src/plugins/Automod/actions/setCounter.ts @@ -11,7 +11,7 @@ export const SetCounterAction = automodAction({ defaultConfig: {}, - async apply({ pluginData, contexts, actionConfig, matchResult, ruleName }) { + async apply({ pluginData, contexts, actionConfig, ruleName }) { const countersPlugin = pluginData.getPlugin(CountersPlugin); if (!countersPlugin.counterExists(actionConfig.counter)) { pluginData.getPlugin(LogsPlugin).logBotAlert({ diff --git a/backend/src/plugins/Automod/actions/startThread.ts b/backend/src/plugins/Automod/actions/startThread.ts index b5d75285..cf1d4ad7 100644 --- a/backend/src/plugins/Automod/actions/startThread.ts +++ b/backend/src/plugins/Automod/actions/startThread.ts @@ -31,7 +31,7 @@ export const StartThreadAction = automodAction({ limit_per_channel: 5, }, - async apply({ pluginData, contexts, actionConfig, ruleName }) { + async apply({ pluginData, contexts, actionConfig }) { // check if the message still exists, we don't want to create threads for deleted messages const threads = contexts.filter((c) => { if (!c.message || !c.user) return false; diff --git a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts index 79c8dbea..cd7e70e4 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts @@ -9,7 +9,7 @@ export async function runAutomodOnModAction( modAction: ModActionType, userId: string, reason?: string, - isAutomodAction: boolean = false, + isAutomodAction = false, ) { const [user, member] = await Promise.all([ resolveUser(pluginData.client, userId), diff --git a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts index 74451c9e..9b5b8800 100644 --- a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts +++ b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts @@ -1,13 +1,12 @@ import { GuildPluginData } from "knub"; import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; -import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants"; +import { RecentActionType } from "../constants"; import { AutomodContext, AutomodPluginType } from "../types"; export function addRecentActionsFromMessage(pluginData: GuildPluginData, context: AutomodContext) { const message = context.message!; const globalIdentifier = message.user_id; const perChannelIdentifier = `${message.channel_id}-${message.user_id}`; - const expiresAt = Date.now() + RECENT_ACTION_EXPIRY_TIME; pluginData.state.recentActions.push({ context, diff --git a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts index 1dbd233d..a1858d37 100644 --- a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts +++ b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts @@ -14,7 +14,6 @@ const MessageSpamTriggerConfig = t.type({ within: tDelayString, per_channel: tNullable(t.boolean), }); -type TMessageSpamTriggerConfig = t.TypeOf; interface TMessageSpamMatchResultType { archiveId: string; diff --git a/backend/src/plugins/Automod/helpers.ts b/backend/src/plugins/Automod/helpers.ts index 15afc545..5c5f55c7 100644 --- a/backend/src/plugins/Automod/helpers.ts +++ b/backend/src/plugins/Automod/helpers.ts @@ -12,7 +12,7 @@ interface BaseAutomodTriggerMatchResult { fullSummary?: string; } -export type AutomodTriggerMatchResult = unknown extends TExtra +export type AutomodTriggerMatchResult = unknown extends TExtra ? BaseAutomodTriggerMatchResult : BaseAutomodTriggerMatchResult & { extra: TExtra }; diff --git a/backend/src/plugins/Automod/triggers/antiraidLevel.ts b/backend/src/plugins/Automod/triggers/antiraidLevel.ts index 24959c66..7c6d17af 100644 --- a/backend/src/plugins/Automod/triggers/antiraidLevel.ts +++ b/backend/src/plugins/Automod/triggers/antiraidLevel.ts @@ -2,7 +2,6 @@ import * as t from "io-ts"; import { tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; -// tslint:disable-next-line interface AntiraidLevelTriggerResult {} export const AntiraidLevelTrigger = automodTrigger()({ @@ -12,7 +11,7 @@ export const AntiraidLevelTrigger = automodTrigger() defaultConfig: {}, - async match({ triggerConfig, context, pluginData }) { + async match({ triggerConfig, context }) { if (!context.antiraid) { return; } @@ -26,7 +25,7 @@ export const AntiraidLevelTrigger = automodTrigger() }; }, - renderMatchInformation({ matchResult, pluginData, contexts, triggerConfig }) { + renderMatchInformation({ contexts }) { const newLevel = contexts[0].antiraid!.level; return newLevel ? `Antiraid level was set to ${newLevel}` : `Antiraid was turned off`; }, diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 8ed6eedc..5b611334 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -3,7 +3,6 @@ import * as t from "io-ts"; import { verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; -// tslint:disable-next-line:no-empty-interface interface AnyMessageResultType {} export const AnyMessageTrigger = automodTrigger()({ @@ -11,7 +10,7 @@ export const AnyMessageTrigger = automodTrigger()({ defaultConfig: {}, - async match({ pluginData, context, triggerConfig: trigger }) { + async match({ context }) { if (!context.message) { return; } @@ -21,7 +20,7 @@ export const AnyMessageTrigger = automodTrigger()({ }; }, - renderMatchInformation({ pluginData, contexts, matchResult }) { + renderMatchInformation({ pluginData, contexts }) { const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id as Snowflake); return `Matched message (\`${contexts[0].message!.id}\`) in ${ channel ? verboseChannelMention(channel) : "Unknown Channel" diff --git a/backend/src/plugins/Automod/triggers/ban.ts b/backend/src/plugins/Automod/triggers/ban.ts index e9012ff5..f8a4730b 100644 --- a/backend/src/plugins/Automod/triggers/ban.ts +++ b/backend/src/plugins/Automod/triggers/ban.ts @@ -30,7 +30,7 @@ export const BanTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was banned`; }, }); diff --git a/backend/src/plugins/Automod/triggers/counterTrigger.ts b/backend/src/plugins/Automod/triggers/counterTrigger.ts index a446164b..58f21402 100644 --- a/backend/src/plugins/Automod/triggers/counterTrigger.ts +++ b/backend/src/plugins/Automod/triggers/counterTrigger.ts @@ -14,7 +14,7 @@ export const CounterTrigger = automodTrigger()({ defaultConfig: {}, - async match({ triggerConfig, context, pluginData }) { + async match({ triggerConfig, context }) { if (!context.counterTrigger) { return; } @@ -37,7 +37,7 @@ export const CounterTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult, pluginData, contexts, triggerConfig }) { + renderMatchInformation({ contexts }) { let str = `Matched counter trigger \`${contexts[0].counterTrigger!.prettyCounter} / ${ contexts[0].counterTrigger!.prettyTrigger }\``; diff --git a/backend/src/plugins/Automod/triggers/kick.ts b/backend/src/plugins/Automod/triggers/kick.ts index 116f1252..163d6bf3 100644 --- a/backend/src/plugins/Automod/triggers/kick.ts +++ b/backend/src/plugins/Automod/triggers/kick.ts @@ -29,7 +29,7 @@ export const KickTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was kicked`; }, }); diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 8328caef..659be65b 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -23,7 +23,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ whitelist_enabled: false, }, - async match({ pluginData, context, triggerConfig: trigger }) { + async match({ context, triggerConfig: trigger }) { if (!context.message) { return; } diff --git a/backend/src/plugins/Automod/triggers/memberJoin.ts b/backend/src/plugins/Automod/triggers/memberJoin.ts index 014c992b..f62d87aa 100644 --- a/backend/src/plugins/Automod/triggers/memberJoin.ts +++ b/backend/src/plugins/Automod/triggers/memberJoin.ts @@ -13,7 +13,7 @@ export const MemberJoinTrigger = automodTrigger()({ new_threshold: "1h", }, - async match({ pluginData, context, triggerConfig }) { + async match({ context, triggerConfig }) { if (!context.joined || !context.member) { return; } @@ -26,7 +26,7 @@ export const MemberJoinTrigger = automodTrigger()({ return {}; }, - renderMatchInformation({ pluginData, contexts, triggerConfig }) { + renderMatchInformation() { return ""; }, }); diff --git a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts index 60ad02a7..c55c8895 100644 --- a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts +++ b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts @@ -45,7 +45,7 @@ export const MemberJoinSpamTrigger = automodTrigger()({ } }, - renderMatchInformation({ pluginData, contexts, triggerConfig }) { + renderMatchInformation() { return ""; }, }); diff --git a/backend/src/plugins/Automod/triggers/memberLeave.ts b/backend/src/plugins/Automod/triggers/memberLeave.ts index 9af9bc4f..c5a25033 100644 --- a/backend/src/plugins/Automod/triggers/memberLeave.ts +++ b/backend/src/plugins/Automod/triggers/memberLeave.ts @@ -6,7 +6,7 @@ export const MemberLeaveTrigger = automodTrigger()({ defaultConfig: {}, - async match({ pluginData, context, triggerConfig }) { + async match({ context }) { if (!context.joined || !context.member) { return; } @@ -14,7 +14,7 @@ export const MemberLeaveTrigger = automodTrigger()({ return {}; }, - renderMatchInformation({ pluginData, contexts, triggerConfig }) { + renderMatchInformation() { return ""; }, }); diff --git a/backend/src/plugins/Automod/triggers/mute.ts b/backend/src/plugins/Automod/triggers/mute.ts index c5e2d2ba..144c30f2 100644 --- a/backend/src/plugins/Automod/triggers/mute.ts +++ b/backend/src/plugins/Automod/triggers/mute.ts @@ -29,7 +29,7 @@ export const MuteTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was muted`; }, }); diff --git a/backend/src/plugins/Automod/triggers/note.ts b/backend/src/plugins/Automod/triggers/note.ts index 14ef0abc..c6d11be7 100644 --- a/backend/src/plugins/Automod/triggers/note.ts +++ b/backend/src/plugins/Automod/triggers/note.ts @@ -18,7 +18,7 @@ export const NoteTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `Note was added on user`; }, }); diff --git a/backend/src/plugins/Automod/triggers/threadCreateSpam.ts b/backend/src/plugins/Automod/triggers/threadCreateSpam.ts index 7778ce80..b1d02f47 100644 --- a/backend/src/plugins/Automod/triggers/threadCreateSpam.ts +++ b/backend/src/plugins/Automod/triggers/threadCreateSpam.ts @@ -45,7 +45,7 @@ export const ThreadCreateSpamTrigger = automodTrigger()({ } }, - renderMatchInformation({ pluginData, contexts, triggerConfig }) { + renderMatchInformation() { return ""; }, }); diff --git a/backend/src/plugins/Automod/triggers/unban.ts b/backend/src/plugins/Automod/triggers/unban.ts index 38e86db9..c653f615 100644 --- a/backend/src/plugins/Automod/triggers/unban.ts +++ b/backend/src/plugins/Automod/triggers/unban.ts @@ -18,7 +18,7 @@ export const UnbanTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was unbanned`; }, }); diff --git a/backend/src/plugins/Automod/triggers/unmute.ts b/backend/src/plugins/Automod/triggers/unmute.ts index 9ccb5031..fbd946c6 100644 --- a/backend/src/plugins/Automod/triggers/unmute.ts +++ b/backend/src/plugins/Automod/triggers/unmute.ts @@ -18,7 +18,7 @@ export const UnmuteTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was unmuted`; }, }); diff --git a/backend/src/plugins/Automod/triggers/warn.ts b/backend/src/plugins/Automod/triggers/warn.ts index 545c4437..5c350dad 100644 --- a/backend/src/plugins/Automod/triggers/warn.ts +++ b/backend/src/plugins/Automod/triggers/warn.ts @@ -29,7 +29,7 @@ export const WarnTrigger = automodTrigger()({ }; }, - renderMatchInformation({ matchResult }) { + renderMatchInformation() { return `User was warned`; }, }); diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index c97b6c55..46d2a0e0 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -10,7 +10,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ signature: {}, - async run({ pluginData, message: msg, args }) { + async run({ pluginData, message: msg }) { const logItems = getRateLimitStats(); if (logItems.length === 0) { sendSuccessMessage(pluginData, msg.channel, `No rate limits hit`); diff --git a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts index a32eb8dc..0c8c6e8e 100644 --- a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts @@ -13,7 +13,7 @@ export const RestPerformanceCmd = botControlCmd({ count: ct.number({ required: false }), }, - async run({ pluginData, message: msg, args }) { + async run({ message: msg, args }) { const count = Math.max(1, Math.min(25, args.count || 5)); const stats = getTopRestCallStats(count); const formatted = stats.map((callStats) => { diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index 09573ccc..92520b7d 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -39,7 +39,7 @@ export async function createCaseNote(pluginData: GuildPluginData, caseOrCaseId: Case | number, diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index e11e0f01..211d1844 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -68,7 +68,7 @@ export async function postCaseToCaseLogChannel( } } return; - } catch {} // tslint:disable-line:no-empty + } catch {} // eslint-disable-line no-empty } try { diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts index b7968b3a..024edf3d 100644 --- a/backend/src/plugins/ChannelArchiver/types.ts +++ b/backend/src/plugins/ChannelArchiver/types.ts @@ -1,7 +1,5 @@ import { BasePluginType, guildPluginMessageCommand } from "knub"; -export interface ChannelArchiverPluginType extends BasePluginType { - state: {}; -} +export interface ChannelArchiverPluginType extends BasePluginType {} export const channelArchiverCmd = guildPluginMessageCommand(); diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index 58b5712b..84a0a272 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -10,7 +10,7 @@ export const CountersListCmd = guildPluginMessageCommand()({ signature: {}, - async run({ pluginData, message, args }) { + async run({ pluginData, message }) { const config = await pluginData.config.getForMessage(message); const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false); diff --git a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts index c3203389..d8d766b5 100644 --- a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts +++ b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts @@ -20,7 +20,7 @@ export async function createCaseAction( action: TCreateCaseAction, values: TemplateSafeValueContainer, event: TCustomEvent, - eventData: any, + eventData: any, // eslint-disable-line @typescript-eslint/no-unused-vars ) { const modId = await renderTemplate(action.mod, values, false); const targetId = await renderTemplate(action.target, values, false); diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts index a372bb0e..bf314429 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts @@ -18,7 +18,7 @@ export async function makeRoleMentionableAction( action: TMakeRoleMentionableAction, values: TemplateSafeValueContainer, event: TCustomEvent, - eventData: any, + eventData: any, // eslint-disable-line @typescript-eslint/no-unused-vars ) { const role = pluginData.guild.roles.cache.get(action.role as Snowflake); if (!role) { diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index f5ab5bc8..e86d03b5 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -16,7 +16,7 @@ export async function makeRoleUnmentionableAction( action: TMakeRoleUnmentionableAction, values: TemplateSafeValueContainer, event: TCustomEvent, - eventData: any, + eventData: any, // eslint-disable-line @typescript-eslint/no-unused-vars ) { const role = pluginData.guild.roles.cache.get(action.role as Snowflake); if (!role) { diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index 71cf8785..6bae4c35 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -22,9 +22,9 @@ export type TSetChannelPermissionOverridesAction = t.TypeOf, action: TSetChannelPermissionOverridesAction, - values: TemplateSafeValueContainer, - event: TCustomEvent, - eventData: any, + values: TemplateSafeValueContainer, // eslint-disable-line @typescript-eslint/no-unused-vars + event: TCustomEvent, // eslint-disable-line @typescript-eslint/no-unused-vars + eventData: any, // eslint-disable-line @typescript-eslint/no-unused-vars ) { const channel = pluginData.guild.channels.cache.get(action.channel as Snowflake); if (!channel || channel.isThread() || !("guild" in channel)) { diff --git a/backend/src/plugins/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index 48628376..e273e7b6 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -15,10 +15,8 @@ const CommandTrigger = t.type({ params: t.string, can_use: t.boolean, }); -type TCommandTrigger = t.TypeOf; const AnyTrigger = CommandTrigger; // TODO: Make into a union once we have more triggers -type TAnyTrigger = t.TypeOf; const AnyAction = t.union([ AddRoleAction, @@ -29,7 +27,6 @@ const AnyAction = t.union([ MakeRoleUnmentionableAction, SetChannelPermissionOverridesAction, ]); -type TAnyAction = t.TypeOf; export const CustomEvent = t.type({ name: t.string, diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index 447094c2..c4f7eaaf 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -8,7 +8,6 @@ import { makeIoTsConfigParser } from "../../pluginUtils"; import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; interface GuildAccessMonitorPluginType extends BasePluginType { - config: {}; state: { allowedGuilds: AllowedGuilds; }; diff --git a/backend/src/plugins/GuildConfigReloader/types.ts b/backend/src/plugins/GuildConfigReloader/types.ts index 4ab03116..8477d60d 100644 --- a/backend/src/plugins/GuildConfigReloader/types.ts +++ b/backend/src/plugins/GuildConfigReloader/types.ts @@ -3,7 +3,6 @@ import { Configs } from "../../data/Configs"; import Timeout = NodeJS.Timeout; export interface GuildConfigReloaderPluginType extends BasePluginType { - config: {}; state: { guildConfigs: Configs; unloaded: boolean; diff --git a/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts b/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts index 336e86c8..8015aa9d 100644 --- a/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts +++ b/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts @@ -1,9 +1,6 @@ import { guildPluginEventListener } from "knub"; -import { MINUTES } from "../../../utils"; import { GuildMemberCachePluginType } from "../types"; -const DELETION_DELAY = 2 * MINUTES; - export const removeMemberCacheOnMemberLeave = guildPluginEventListener()({ event: "guildMemberRemove", async listener({ pluginData, args: { member } }) { diff --git a/backend/src/plugins/InternalPoster/types.ts b/backend/src/plugins/InternalPoster/types.ts index 7a3e4d41..e5f1a1a3 100644 --- a/backend/src/plugins/InternalPoster/types.ts +++ b/backend/src/plugins/InternalPoster/types.ts @@ -7,9 +7,6 @@ import { Webhooks } from "../../data/Webhooks"; export const ConfigSchema = t.type({}); export type TConfigSchema = t.TypeOf; -// -type ChannelWebhookMap = Map; - export interface InternalPosterPluginType extends BasePluginType { config: TConfigSchema; diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index fc3e4303..51d47945 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -76,7 +76,7 @@ export const LocateUserPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.unregisterGuildEventListener?.(); }, diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index b6c7441e..5a9259d6 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -9,13 +9,6 @@ import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin" import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types"; import { getLogMessage } from "./getLogMessage"; -const excludedUserProps = ["user", "member", "mod"]; -const excludedRoleProps = ["message.member.roles", "member.roles"]; - -function isRoleArray(value: any): value is string[] { - return Array.isArray(value); -} - interface ExclusionData { userId?: Snowflake | null; bot?: boolean | null; @@ -86,7 +79,7 @@ export async function log( const logChannels: TLogChannelMap = pluginData.config.get().channels; const typeStr = LogType[type]; - logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) { + for (const [channelId, opts] of Object.entries(logChannels)) { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel?.isTextBased()) continue; if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue; diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index dae2aea2..bf83b13e 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -219,7 +219,7 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.unloaded = true; state.unregisterGuildEventListener?.(); diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index 0add34bf..1a205bbe 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -60,8 +60,6 @@ const defaultOptions = { ], }; -const EXPIRED_MUTE_CHECK_INTERVAL = 60 * 1000; - export const MutesPlugin = zeppelinGuildPlugin()({ name: "mutes", showInDocs: true, @@ -135,7 +133,7 @@ export const MutesPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.unregisterExpiredRoleMuteListener?.(); state.unregisterTimeoutMuteToRenewListener?.(); diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts index 4b8aa784..da6e24e5 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts @@ -6,7 +6,7 @@ import { mutesEvt } from "../types"; */ export const ClearActiveMuteOnRoleRemovalEvt = mutesEvt({ event: "guildMemberUpdate", - async listener({ pluginData, args: { oldMember, newMember: member } }) { + async listener({ pluginData, args: { newMember: member } }) { const muteRole = pluginData.config.get().mute_role; if (!muteRole) return; diff --git a/backend/src/plugins/Mutes/functions/clearMute.ts b/backend/src/plugins/Mutes/functions/clearMute.ts index 9156c9e8..0bef1881 100644 --- a/backend/src/plugins/Mutes/functions/clearMute.ts +++ b/backend/src/plugins/Mutes/functions/clearMute.ts @@ -29,7 +29,7 @@ export async function clearMute( try { const defaultMuteRole = pluginData.config.get().mute_role; if (mute) { - const muteRoleId = mute.mute_role || pluginData.config.get().mute_role; + const muteRoleId = mute.mute_role || defaultMuteRole; if (mute.type === MuteTypes.Role) { if (muteRoleId) { @@ -41,8 +41,7 @@ export async function clearMute( if (mute.roles_to_restore) { const guildRoles = pluginData.guild.roles.cache; - const newRoles = [...member.roles.cache.keys()].filter((roleId) => roleId !== muteRoleId); - for (const roleIdToRestore of mute?.roles_to_restore) { + for (const roleIdToRestore of mute?.roles_to_restore ?? []) { if (guildRoles.has(roleIdToRestore) && roleIdToRestore !== muteRoleId) { roleManagerPlugin.addRole(member.id, roleIdToRestore); } @@ -50,7 +49,7 @@ export async function clearMute( } } else { // Unmuting someone without an active mute -> remove timeouts and/or mute role - const muteRole = pluginData.config.get().mute_role; + const muteRole = defaultMuteRole; if (muteRole && member.roles.cache.has(muteRole)) { roleManagerPlugin.removePriorityRole(member.id, muteRole); } diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 12db3e8f..71081e8c 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -127,7 +127,7 @@ export async function muteUser( // TODO: Add back the voiceState check once we figure out how to get voice state for guild members that are loaded on-demand try { await member.edit({ channel: moveToVoiceChannel as Snowflake }); - } catch {} // tslint:disable-line + } catch {} // eslint-disable-line no-empty } } diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 7db23931..e5b880cc 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,4 +1,4 @@ -import { GuildMemberEditOptions, PermissionFlagsBits } from "discord.js"; +import { PermissionFlagsBits } from "discord.js"; import intersection from "lodash.intersection"; import { canAssignRole } from "../../../utils/canAssignRole"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; @@ -22,9 +22,6 @@ export const LoadDataEvt = persistEvt({ } await pluginData.state.persistedData.clear(member.id); - const toRestore: GuildMemberEditOptions = { - reason: "Restored upon rejoin", - }; const config = await pluginData.config.getForMember(member); const restoredData: string[] = []; diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 70f0c31c..2ac364f1 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -7,8 +7,6 @@ import { rgbToInt } from "../../../utils/rgbToInt"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; -const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/; - export const EditEmbedCmd = postCmd({ trigger: "edit_embed", permission: "can_post", diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 8fb5ad8c..e4b4c1e6 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -12,7 +12,7 @@ export async function postMessage( channel: GuildTextBasedChannel, content: MessageCreateOptions, attachments: Attachment[] = [], - enableMentions: boolean = false, + enableMentions = false, ): Promise { if (typeof content === "string") { content = { content }; diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 99d0a8d6..ac68de33 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -81,7 +81,7 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; if (state.autoRefreshTimeout) { clearTimeout(state.autoRefreshTimeout); diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index ca61ceb8..ce914a34 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -9,7 +9,7 @@ export const RemindersCmd = remindersCmd({ trigger: "reminders", permission: "can_use", - async run({ message: msg, args, pluginData }) { + async run({ message: msg, pluginData }) { const reminders = await pluginData.state.reminders.getRemindersByUserId(msg.author.id); if (reminders.length === 0) { sendErrorMessage(pluginData, msg.channel, "No reminders"); diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index a79ca25a..4f6c0996 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -81,7 +81,7 @@ export const SlowmodePlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.savedMessages.events.off("create", state.onMessageCreateFn); clearInterval(state.clearInterval); diff --git a/backend/src/plugins/Spam/SpamPlugin.ts b/backend/src/plugins/Spam/SpamPlugin.ts index e4935ca3..e1a7efc0 100644 --- a/backend/src/plugins/Spam/SpamPlugin.ts +++ b/backend/src/plugins/Spam/SpamPlugin.ts @@ -88,7 +88,7 @@ export const SpamPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.savedMessages.events.off("create", state.onMessageCreateFn); clearInterval(state.expiryInterval); diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index f700e1a4..050b9037 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -41,8 +41,8 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ To specify emoji in the config, you need to use the emoji's "raw form". To obtain this, post the emoji with a backslash in front of it. - - Example with a default emoji: "\:star:" => "⭐" - - Example with a custom emoji: "\:mrvnSmile:" => "<:mrvnSmile:543000534102310933>" + - Example with a default emoji: ":star:" => "⭐" + - Example with a custom emoji: ":mrvnSmile:" => "<:mrvnSmile:543000534102310933>" ### Basic starboard Any message on the server that gets 5 star reactions will be posted into the starboard channel (604342689038729226). @@ -127,7 +127,7 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ const boards = (input as any).boards; if (boards) { for (const [name, opts] of Object.entries(boards)) { - boards[name] = Object.assign({}, defaultStarboardOpts, boards[name]); + boards[name] = Object.assign({}, defaultStarboardOpts, opts); } } @@ -163,7 +163,7 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.savedMessages.events.off("delete", state.onMessageDeleteFn); }, diff --git a/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts b/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts index 708b4a89..57258759 100644 --- a/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts +++ b/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts @@ -4,7 +4,7 @@ import { defaultStarboardOpts, PartialConfigSchema } from "../types"; export function preprocessStaticConfig(config: t.TypeOf) { if (config.boards) { for (const [name, opts] of Object.entries(config.boards)) { - config.boards[name] = Object.assign({}, defaultStarboardOpts, config.boards[name]); + config.boards[name] = Object.assign({}, defaultStarboardOpts, opts); } } diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 2fea2bb9..3e0a5bb4 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -107,9 +107,8 @@ export const TagsPlugin = zeppelinGuildPlugin()({ // Check each category for conflicting options if (input.categories) { - for (const [name, opts] of Object.entries(input.categories)) { - const cat = input.categories[name]; - if (cat.delete_with_command && cat.auto_delete_command) { + for (const [name, cat] of Object.entries(input.categories)) { + if ((cat as any).delete_with_command && (cat as any).auto_delete_command) { throw new StrictValidationError([ `Cannot have both (category specific) delete_with_command and category_delete_invoke enabled at `, ]); @@ -279,7 +278,7 @@ export const TagsPlugin = zeppelinGuildPlugin()({ }, beforeUnload(pluginData) { - const { state, guild } = pluginData; + const { state } = pluginData; state.savedMessages.events.off("create", state.onMessageCreateFn); }, diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index b2d40a7a..8e90fe82 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -46,14 +46,7 @@ export async function matchAndRenderTagFromString( for (const [tagName, tagBody] of Object.entries(category.tags)) { const regex = new RegExp(`^${escapeStringRegexp(tagName)}(?:\\s|$)`); if (regex.test(withoutPrefix)) { - const renderedContent = await renderTagFromString( - pluginData, - str, - prefix, - tagName, - category.tags[tagName], - member, - ); + const renderedContent = await renderTagFromString(pluginData, str, prefix, tagName, tagBody, member); if (renderedContent == null) { return null; diff --git a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts index 0c72bc4e..86585abd 100644 --- a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts @@ -7,7 +7,7 @@ export const ViewTimezoneCmd = timeAndDateCmd({ signature: {}, - async run({ pluginData, message, args }) { + async run({ pluginData, message }) { const memberTimezone = await pluginData.state.memberTimezones.get(message.author.id); if (memberTimezone) { message.channel.send(`Your timezone is currently set to **${memberTimezone.timezone}**`); diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 3e6443ef..74091452 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -25,7 +25,7 @@ export const AboutCmd = utilityCmd({ try { const lcl = new LCL(rootDir); lastCommit = await lcl.getLastCommit(); - } catch {} // tslint:disable-line:no-empty + } catch {} // eslint-disable-line no-empty let lastUpdate; let version; diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index bc9f70ab..bbbcd50e 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -31,8 +31,6 @@ function resizeBuffer(input: Buffer, width: number, height: number): Buffer { return photonImageToBuffer(photonImage); } -const CDN_URL = "https://twemoji.maxcdn.com/"; - export const JumboCmd = utilityCmd({ trigger: "jumbo", description: "Makes an emoji jumbo", @@ -75,7 +73,7 @@ export const JumboCmd = utilityCmd({ let image: Buffer | undefined; try { const downloadedBuffer = await getBufferFromUrl(url); - image = resizeBuffer(await getBufferFromUrl(url), size, size); + image = resizeBuffer(downloadedBuffer, size, size); } catch (err) { if (url.toLocaleLowerCase().endsWith("fe0f.png")) { url = url.slice(0, url.lastIndexOf("-fe0f")) + ".png"; diff --git a/backend/src/plugins/Utility/commands/PingCmd.ts b/backend/src/plugins/Utility/commands/PingCmd.ts index 2ddc1623..0777cdc9 100644 --- a/backend/src/plugins/Utility/commands/PingCmd.ts +++ b/backend/src/plugins/Utility/commands/PingCmd.ts @@ -1,9 +1,8 @@ import { Message } from "discord.js"; +import { performance } from "perf_hooks"; import { noop, trimLines } from "../../../utils"; import { utilityCmd } from "../types"; -const { performance } = require("perf_hooks"); - export const PingCmd = utilityCmd({ trigger: ["ping", "pong"], description: "Test the bot's ping to the Discord API", diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index 48734fe0..2b8b2f32 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -7,7 +7,7 @@ export const ReloadGuildCmd = utilityCmd({ description: "Reload the Zeppelin configuration and all plugins for the server. This can sometimes fix issues.", permission: "can_reload_guild", - async run({ message: msg, args, pluginData }) { + async run({ message: msg, pluginData }) { if (activeReloads.has(pluginData.guild.id)) return; activeReloads.set(pluginData.guild.id, msg.channel as TextChannel); diff --git a/backend/src/templateFormatter.test.ts b/backend/src/templateFormatter.test.ts index 24aaa881..ff2e809f 100644 --- a/backend/src/templateFormatter.test.ts +++ b/backend/src/templateFormatter.test.ts @@ -97,6 +97,7 @@ test("Supports base values in renderTemplate", async (t) => { }); test("Edge case #1", async (t) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const result = await renderTemplate("{foo} {bar()}"); // No "Unclosed function" exception = success t.pass(); diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index ecf773a3..f5c9f935 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -51,6 +51,7 @@ test("delay strings: reverse conversion (conservative)", (t) => { test("tAllowedMentions matches Eris's AllowedMentions", (t) => { type TAllowedMentions = ioTs.TypeOf; + // eslint-disable-next-line @typescript-eslint/no-unused-vars const typeTest: AssertEquals = true; t.pass(); }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index a79ef928..831a8a11 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -95,19 +95,11 @@ export function tNullable>(type: T) { return t.union([type, t.undefined, t.null], `Nullable<${type.name}>`); } -function typeHasProps(type: any): type is t.TypeC { - return type.props != null; -} - -function typeIsArray(type: any): type is t.ArrayC { - return type._tag === "ArrayType"; -} - export const tNormalizedNullOrUndefined = new t.Type( "tNormalizedNullOrUndefined", (v): v is undefined => typeof v === "undefined", (v, c) => (v == null ? t.success(undefined) : t.failure(v, c, "Value must be null or undefined")), - (s) => undefined, + () => undefined, ); /** @@ -166,16 +158,6 @@ export function tDeepPartial(type: T): TDeepPartial { } } -function tDeepPartialProp(prop: any) { - if (typeHasProps(prop)) { - return tDeepPartial(prop); - } else if (typeIsArray(prop)) { - return t.array(tDeepPartialProp(prop.type)); - } else { - return prop; - } -} - export function getScalarDifference( base: T, object: T, @@ -480,7 +462,9 @@ export const tAllowedMentions = t.type({ }); export function dropPropertiesByName(obj, propName) { - if (obj.hasOwnProperty(propName)) delete obj[propName]; + if (Object.hasOwn(obj, propName)) { + delete obj[propName]; + } for (const value of Object.values(obj)) { if (typeof value === "object" && value !== null && !Array.isArray(value)) { dropPropertiesByName(value, propName); @@ -584,8 +568,8 @@ export function get(obj, path, def?): any { .map((s) => s.trim()) .filter((s) => s !== ""); for (const part of pathParts) { - // hasOwnProperty check here is necessary to prevent prototype traversal in tags - if (!cursor.hasOwnProperty(part)) return def; + // hasOwn check here is necessary to prevent prototype traversal in tags + if (!Object.hasOwn(cursor, part)) return def; cursor = cursor[part]; if (cursor === undefined) return def; if (cursor == null) return null; @@ -691,10 +675,10 @@ export function isNotNull(value: T): value is Exclude { // discord.gg/ // discord.com/friend-invite/ const quickInviteDetection = - /discord(?:app)?\.com\/(?:friend-)?invite\/([a-z0-9\-]+)|discord\.gg\/(?:\S+\/)?([a-z0-9\-]+)/gi; + /discord(?:app)?\.com\/(?:friend-)?invite\/([a-z0-9-]+)|discord\.gg\/(?:\S+\/)?([a-z0-9-]+)/gi; const isInviteHostRegex = /(?:^|\.)(?:discord.gg|discord.com|discordapp.com)$/i; -const longInvitePathRegex = /^\/(?:friend-)?invite\/([a-z0-9\-]+)$/i; +const longInvitePathRegex = /^\/(?:friend-)?invite\/([a-z0-9-]+)$/i; export function getInviteCodesInString(str: string): string[] { const inviteCodes: string[] = []; @@ -1187,12 +1171,12 @@ const keyMods = ["+", "-", "="]; export function deepKeyIntersect(obj, keyReference) { const result = {}; for (let [key, value] of Object.entries(obj)) { - if (!keyReference.hasOwnProperty(key)) { + if (!Object.hasOwn(keyReference, key)) { // Temporary solution so we don't erase keys with modifiers // Modifiers will be removed soon(tm) so we can remove this when that happens as well let found = false; for (const mod of keyMods) { - if (keyReference.hasOwnProperty(mod + key)) { + if (Object.hasOwn(keyReference, mod + key)) { key = mod + key; found = true; break; @@ -1267,7 +1251,7 @@ export function getUser(client: Client, userResolvable: string): User | UnknownU */ export async function resolveUser(bot: Client, value: string): Promise; export async function resolveUser(bot: Client, value: Not): Promise; -export async function resolveUser(bot, value) { +export async function resolveUser(bot, value) { if (typeof value !== "string") { return new UnknownUser(); } @@ -1386,22 +1370,22 @@ export function resolveRole(guild: Guild, roleResolvable: RoleResolvable) { const inviteCache = new SimpleCache>(10 * MINUTES, 200); -type ResolveInviteReturnType = Promise; +type ResolveInviteReturnType = Promise; export async function resolveInvite( client: Client, code: string, withCounts?: T, -): ResolveInviteReturnType { +): ResolveInviteReturnType { const key = `${code}:${withCounts ? 1 : 0}`; if (inviteCache.has(key)) { - return inviteCache.get(key) as ResolveInviteReturnType; + return inviteCache.get(key) as ResolveInviteReturnType; } const promise = client.fetchInvite(code).catch(() => null); inviteCache.set(key, promise); - return promise as ResolveInviteReturnType; + return promise as ResolveInviteReturnType; } const internalStickerCache: LimitedCollection = new LimitedCollection({ maxSize: 500 }); @@ -1605,7 +1589,7 @@ export function inviteHasCounts(invite: Invite): invite is Invite { } export function asyncMap(arr: T[], fn: (item: T) => Promise): Promise { - return Promise.all(arr.map((item, index) => fn(item))); + return Promise.all(arr.map((item) => fn(item))); } export function unique(arr: T[]): T[] { diff --git a/backend/src/utils/MessageBuffer.ts b/backend/src/utils/MessageBuffer.ts index 7cef009c..ea0a0a0e 100644 --- a/backend/src/utils/MessageBuffer.ts +++ b/backend/src/utils/MessageBuffer.ts @@ -31,7 +31,7 @@ export class MessageBuffer { protected timeoutMs: number | null = null; - protected textSeparator: string = ""; + protected textSeparator = ""; protected chunk: Chunk | null = null; diff --git a/backend/src/utils/async.ts b/backend/src/utils/async.ts index 196067be..4c8e9bf2 100644 --- a/backend/src/utils/async.ts +++ b/backend/src/utils/async.ts @@ -15,7 +15,7 @@ export async function asyncReduce( arrayToIterate = arr.slice(1); } - for (const [i, currentValue] of arr.entries()) { + for (const [i, currentValue] of arrayToIterate.entries()) { accumulator = await callback(accumulator, currentValue, i, arr); } diff --git a/backend/src/utils/categorize.ts b/backend/src/utils/categorize.ts index ca1b98dc..5d62a5de 100644 --- a/backend/src/utils/categorize.ts +++ b/backend/src/utils/categorize.ts @@ -6,17 +6,14 @@ type CategoryReturnType> = { [key in keyof C]: T[]; }; -function initCategories>(categories: C): CategoryReturnType { +function initCategories>(categories: C): CategoryReturnType { return Object.keys(categories).reduce((map, key) => { map[key] = []; return map; }, {}) as CategoryReturnType; } -export function categorize>( - arr: T[], - categories: C, -): CategoryReturnType { +export function categorize>(arr: T[], categories: C): CategoryReturnType { const result = initCategories(categories); const categoryEntries = Object.entries(categories); diff --git a/backend/src/utils/cryptHelpers.ts b/backend/src/utils/cryptHelpers.ts index 209ef0f6..c0920436 100644 --- a/backend/src/utils/cryptHelpers.ts +++ b/backend/src/utils/cryptHelpers.ts @@ -5,7 +5,7 @@ export async function encryptJson(obj: any): Promise { return encrypt(serialized); } -export async function decryptJson(encrypted: string): Promise { +export async function decryptJson(encrypted: string): Promise { const decrypted = await decrypt(encrypted); return JSON.parse(decrypted); } diff --git a/backend/src/utils/getChunkedEmbedFields.ts b/backend/src/utils/getChunkedEmbedFields.ts index 0568e840..062f6224 100644 --- a/backend/src/utils/getChunkedEmbedFields.ts +++ b/backend/src/utils/getChunkedEmbedFields.ts @@ -1,7 +1,7 @@ import { EmbedField } from "discord.js"; import { chunkMessageLines, emptyEmbedValue } from "../utils"; -export function getChunkedEmbedFields(name: string, value: string, inline?: boolean): EmbedField[] { +export function getChunkedEmbedFields(name: string, value: string): EmbedField[] { const fields: EmbedField[] = []; const chunks = chunkMessageLines(value, 1014); diff --git a/backend/src/utils/getMissingPermissions.ts b/backend/src/utils/getMissingPermissions.ts index 14ac7e03..92c32646 100644 --- a/backend/src/utils/getMissingPermissions.ts +++ b/backend/src/utils/getMissingPermissions.ts @@ -12,7 +12,7 @@ export function getMissingPermissions( const allowedPermissions = resolvedPermissions; const nRequiredPermissions = requiredPermissions; - if (Boolean(allowedPermissions.bitfield & PermissionsBitField.Flags.Administrator)) { + if (allowedPermissions.bitfield & PermissionsBitField.Flags.Administrator) { return BigInt(0); } diff --git a/backend/src/utils/hasDiscordPermissions.ts b/backend/src/utils/hasDiscordPermissions.ts index e56b4fbb..e6e07945 100644 --- a/backend/src/utils/hasDiscordPermissions.ts +++ b/backend/src/utils/hasDiscordPermissions.ts @@ -17,5 +17,5 @@ export function hasDiscordPermissions( } const nRequiredPermissions = BigInt(requiredPermissions); - return Boolean((resolvedPermissions?.bitfield! & nRequiredPermissions) === nRequiredPermissions); + return Boolean((resolvedPermissions.bitfield! & nRequiredPermissions) === nRequiredPermissions); } diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index 0db5931e..55580a3e 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -2,7 +2,7 @@ import { MessageCreateOptions } from "discord.js"; import { StrictMessageContent } from "../utils.js"; function embedHasContent(embed: any) { - for (const [key, value] of Object.entries(embed)) { + for (const [, value] of Object.entries(embed)) { if (typeof value === "string" && value.trim() !== "") { return true; } diff --git a/backend/src/utils/parseCustomId.ts b/backend/src/utils/parseCustomId.ts index 7988e5ef..b2ca1009 100644 --- a/backend/src/utils/parseCustomId.ts +++ b/backend/src/utils/parseCustomId.ts @@ -25,6 +25,6 @@ export function parseCustomId(customId: string): { namespace: string; data: any return { namespace: parts[1], // Skipping timestamp - data: JSON.parse(parts[2]), + data: parsedData, }; } diff --git a/backend/src/utils/parseFuzzyTimezone.ts b/backend/src/utils/parseFuzzyTimezone.ts index d4989681..0a361ba2 100644 --- a/backend/src/utils/parseFuzzyTimezone.ts +++ b/backend/src/utils/parseFuzzyTimezone.ts @@ -1,7 +1,7 @@ import escapeStringRegexp from "escape-string-regexp"; import moment from "moment-timezone"; -const normalizeTzName = (str) => str.replace(/[^a-zA-Z0-9+\-]/g, "").toLowerCase(); +const normalizeTzName = (str) => str.replace(/[^a-zA-Z0-9+-]/g, "").toLowerCase(); const validTimezones = moment.tz.names(); const normalizedTimezoneMap = validTimezones.reduce((map, tz) => { diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 1c7e7c3c..2e3258a4 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -3,7 +3,7 @@ import { GuildPluginData } from "knub"; import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; import { isSnowflake } from "../utils"; -const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/; +const channelAndMessageIdRegex = /^(\d+)[-/](\d+)$/; const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i; export interface MessageTarget { diff --git a/backend/src/utils/validateNoObjectAliases.ts b/backend/src/utils/validateNoObjectAliases.ts index 76039d6e..32630c4d 100644 --- a/backend/src/utils/validateNoObjectAliases.ts +++ b/backend/src/utils/validateNoObjectAliases.ts @@ -5,12 +5,12 @@ export class ObjectAliasError extends Error {} /** * Removes object aliases/anchors from a loaded YAML object */ -export function validateNoObjectAliases(obj: T, seen?: WeakSet): void { +export function validateNoObjectAliases(obj: T, seen?: WeakSet): void { if (!seen) { seen = new WeakSet(); } - for (const [key, value] of Object.entries(obj)) { + for (const [, value] of Object.entries(obj)) { if (value == null || scalarTypes.includes(typeof value)) { continue; } @@ -19,7 +19,7 @@ export function validateNoObjectAliases(obj: T, seen?: WeakSet, value: any): StrictValidationError pipe( validationResult, fold( - (err) => report(validationResult), - (result) => null, + () => report(validationResult), + () => null, ), ) || null ); @@ -127,7 +114,7 @@ export function decodeAndValidateStrict( return pipe( validationResult, fold( - (err) => report(validationResult), + () => report(validationResult), (result) => { // Make sure there are no extra properties if (debug) {