diff --git a/backend/src/RegExpRunner.ts b/backend/src/RegExpRunner.ts index ea37fe03..a2320bcb 100644 --- a/backend/src/RegExpRunner.ts +++ b/backend/src/RegExpRunner.ts @@ -2,15 +2,18 @@ import { CooldownManager } from "knub"; import { EventEmitter } from "node:events"; import { RegExpWorker, TimeoutError } from "regexp-worker"; import { MINUTES, SECONDS } from "./utils.js"; -import Timeout = NodeJS.Timeout; const isTimeoutError = (a): a is TimeoutError => { return a.message != null && a.elapsedTimeMs != null; }; export class RegExpTimeoutError extends Error { - constructor(message: string, public elapsedTimeMs: number) { + public elapsedTimeMs: number; + + constructor(message: string, elapsedTimeMs: number) { super(message); + + this.elapsedTimeMs = elapsedTimeMs; } } @@ -47,7 +50,7 @@ export interface RegExpRunner { */ export class RegExpRunner extends EventEmitter { private _worker: RegExpWorker | null; - private readonly _failedTimesInterval: Timeout; + private readonly _failedTimesInterval: NodeJS.Timeout; private cooldown: CooldownManager; private failedTimes: Map; diff --git a/backend/src/SimpleCache.ts b/backend/src/SimpleCache.ts index 4161ec79..bdda1ce3 100644 --- a/backend/src/SimpleCache.ts +++ b/backend/src/SimpleCache.ts @@ -1,12 +1,10 @@ -import Timeout = NodeJS.Timeout; - const CLEAN_INTERVAL = 1000; export class SimpleCache { protected readonly retentionTime: number; protected readonly maxItems: number; - protected cleanTimeout: Timeout; + protected cleanTimeout: NodeJS.Timeout; protected unloaded: boolean; protected store: Map; diff --git a/backend/src/data/loops/expiringMutesLoop.ts b/backend/src/data/loops/expiringMutesLoop.ts index 6f1a68ff..21e6b73a 100644 --- a/backend/src/data/loops/expiringMutesLoop.ts +++ b/backend/src/data/loops/expiringMutesLoop.ts @@ -5,12 +5,11 @@ import { lazyMemoize, MINUTES, SECONDS } from "../../utils.js"; import { Mute } from "../entities/Mute.js"; import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; import { Mutes, TIMEOUT_RENEWAL_THRESHOLD } from "../Mutes.js"; -import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; const MAX_TRIES_PER_SERVER = 3; const getMutesRepository = lazyMemoize(() => new Mutes()); -const timeouts = new Map(); +const timeouts = new Map(); function muteToKey(mute: Mute) { return `${mute.guild_id}/${mute.user_id}`; diff --git a/backend/src/data/loops/expiringTempbansLoop.ts b/backend/src/data/loops/expiringTempbansLoop.ts index 1d1f63a2..291c405e 100644 --- a/backend/src/data/loops/expiringTempbansLoop.ts +++ b/backend/src/data/loops/expiringTempbansLoop.ts @@ -5,12 +5,11 @@ import { lazyMemoize, MINUTES } from "../../utils.js"; import { Tempban } from "../entities/Tempban.js"; import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; import { Tempbans } from "../Tempbans.js"; -import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; const MAX_TRIES_PER_SERVER = 3; const getBansRepository = lazyMemoize(() => new Tempbans()); -const timeouts = new Map(); +const timeouts = new Map(); function tempbanToKey(tempban: Tempban) { return `${tempban.guild_id}/${tempban.user_id}`; diff --git a/backend/src/data/loops/expiringVCAlertsLoop.ts b/backend/src/data/loops/expiringVCAlertsLoop.ts index d8a09b4d..da2b2bb0 100644 --- a/backend/src/data/loops/expiringVCAlertsLoop.ts +++ b/backend/src/data/loops/expiringVCAlertsLoop.ts @@ -5,12 +5,11 @@ import { lazyMemoize, MINUTES } from "../../utils.js"; import { VCAlert } from "../entities/VCAlert.js"; import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; import { VCAlerts } from "../VCAlerts.js"; -import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; const MAX_TRIES_PER_SERVER = 3; const getVCAlertsRepository = lazyMemoize(() => new VCAlerts()); -const timeouts = new Map(); +const timeouts = new Map(); function broadcastExpiredVCAlert(alert: VCAlert, tries = 0) { console.log(`[EXPIRING VCALERTS LOOP] Broadcasting expired vcalert: ${alert.guild_id}/${alert.user_id}`); diff --git a/backend/src/data/loops/upcomingRemindersLoop.ts b/backend/src/data/loops/upcomingRemindersLoop.ts index 8bfd8b76..e7e30ca6 100644 --- a/backend/src/data/loops/upcomingRemindersLoop.ts +++ b/backend/src/data/loops/upcomingRemindersLoop.ts @@ -5,12 +5,11 @@ import { lazyMemoize, MINUTES } from "../../utils.js"; import { Reminder } from "../entities/Reminder.js"; import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; import { Reminders } from "../Reminders.js"; -import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; const MAX_TRIES_PER_SERVER = 3; const getRemindersRepository = lazyMemoize(() => new Reminders()); -const timeouts = new Map(); +const timeouts = new Map(); function broadcastReminder(reminder: Reminder, tries = 0) { if (!hasGuildEventListener(reminder.guild_id, "reminder")) { diff --git a/backend/src/data/loops/upcomingScheduledPostsLoop.ts b/backend/src/data/loops/upcomingScheduledPostsLoop.ts index 2138687a..aebe7544 100644 --- a/backend/src/data/loops/upcomingScheduledPostsLoop.ts +++ b/backend/src/data/loops/upcomingScheduledPostsLoop.ts @@ -5,12 +5,11 @@ import { lazyMemoize, MINUTES } from "../../utils.js"; import { ScheduledPost } from "../entities/ScheduledPost.js"; import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; import { ScheduledPosts } from "../ScheduledPosts.js"; -import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; const MAX_TRIES_PER_SERVER = 3; const getScheduledPostsRepository = lazyMemoize(() => new ScheduledPosts()); -const timeouts = new Map(); +const timeouts = new Map(); function broadcastScheduledPost(post: ScheduledPost, tries = 0) { if (!hasGuildEventListener(post.guild_id, "scheduledPost")) { diff --git a/backend/src/plugins/AutoDelete/types.ts b/backend/src/plugins/AutoDelete/types.ts index 32260d61..5f7b29c1 100644 --- a/backend/src/plugins/AutoDelete/types.ts +++ b/backend/src/plugins/AutoDelete/types.ts @@ -4,7 +4,6 @@ import { GuildLogs } from "../../data/GuildLogs.js"; import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; import { SavedMessage } from "../../data/entities/SavedMessage.js"; import { MINUTES, zDelayString } from "../../utils.js"; -import Timeout = NodeJS.Timeout; export const MAX_DELAY = 5 * MINUTES; @@ -26,7 +25,7 @@ export interface AutoDeletePluginType extends BasePluginType { deletionQueue: IDeletionQueueItem[]; nextDeletion: number | null; - nextDeletionTimeout: Timeout | null; + nextDeletionTimeout: NodeJS.Timeout | null; maxDelayWarningSent: boolean; diff --git a/backend/src/plugins/Automod/actions/changePerms.ts b/backend/src/plugins/Automod/actions/changePerms.ts index e70bbb05..f92b9306 100644 --- a/backend/src/plugins/Automod/actions/changePerms.ts +++ b/backend/src/plugins/Automod/actions/changePerms.ts @@ -175,7 +175,7 @@ export const ChangePermsAction = automodAction({ const realKey = legacyPermMap[key] ?? key; perms[realKey] = actionConfig.perms[key]; } - const permsArray = Object.keys(perms).filter((key) => perms[key]); + const permsArray = (Object.keys(perms) as PermissionsString[]).filter((key) => perms[key]); await role.setPermissions(new PermissionsBitField(permsArray)).catch(noop); }, }); diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 51fc9375..9e207541 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -17,8 +17,6 @@ import { availableActions } from "./actions/availableActions.js"; import { RecentActionType } from "./constants.js"; import { availableTriggers } from "./triggers/availableTriggers.js"; -import Timeout = NodeJS.Timeout; - export type ZTriggersMapHelper = { [TriggerName in keyof typeof availableTriggers]: (typeof availableTriggers)[TriggerName]["configSchema"]; }; @@ -86,7 +84,7 @@ export interface AutomodPluginType extends BasePluginType { * Recent actions are used for spam triggers */ recentActions: RecentAction[]; - clearRecentActionsInterval: Timeout; + clearRecentActionsInterval: NodeJS.Timeout; /** * After a spam trigger is tripped and the rule's action carried out, a unique identifier is placed here so further @@ -95,10 +93,10 @@ export interface AutomodPluginType extends BasePluginType { * Key: rule_name-match_identifier */ recentSpam: RecentSpam[]; - clearRecentSpamInterval: Timeout; + clearRecentSpamInterval: NodeJS.Timeout; recentNicknameChanges: Map; - clearRecentNicknameChangesInterval: Timeout; + clearRecentNicknameChangesInterval: NodeJS.Timeout; ignoredRoleChanges: Set<{ memberId: string; diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index 82b5eebc..777054f6 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -10,7 +10,6 @@ import { } from "../../data/entities/CounterTrigger.js"; import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils.js"; import { CommonPlugin } from "../Common/CommonPlugin.js"; -import Timeout = NodeJS.Timeout; const MAX_COUNTERS = 5; const MAX_TRIGGERS_PER_COUNTER = 5; @@ -89,7 +88,7 @@ export interface CountersPluginType extends BasePluginType { state: { counters: GuildCounters; counterIds: Record; - decayTimers: Timeout[]; + decayTimers: NodeJS.Timeout[]; events: CounterEventEmitter; counterTriggersByCounterId: Map; common: pluginUtils.PluginPublicInterface; diff --git a/backend/src/plugins/GuildConfigReloader/types.ts b/backend/src/plugins/GuildConfigReloader/types.ts index ae054856..14e582b7 100644 --- a/backend/src/plugins/GuildConfigReloader/types.ts +++ b/backend/src/plugins/GuildConfigReloader/types.ts @@ -1,7 +1,6 @@ import { BasePluginType } from "knub"; import { z } from "zod/v4"; import { Configs } from "../../data/Configs.js"; -import Timeout = NodeJS.Timeout; export const zGuildConfigReloaderPluginConfig = z.strictObject({}); @@ -11,6 +10,6 @@ export interface GuildConfigReloaderPluginType extends BasePluginType { guildConfigs: Configs; unloaded: boolean; highestConfigId: number; - nextCheckTimeout: Timeout; + nextCheckTimeout: NodeJS.Timeout; }; } diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index fbb6497b..58f24b54 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -81,7 +81,7 @@ export async function muteUser( await member.roles.set(newRoles as Snowflake[]); } } else { - newRoles = currentUserRoles.filter((x) => !(removeRoles).includes(x)); + newRoles = currentUserRoles.filter((x) => !removeRoles.includes(x)); await member.roles.set(newRoles as Snowflake[]); } @@ -91,7 +91,7 @@ export async function muteUser( rolesToRestore = currentUserRoles; } } else { - rolesToRestore = currentUserRoles.filter((x) => (restoreRoles).includes(x)); + rolesToRestore = currentUserRoles.filter((x) => restoreRoles.includes(x)); } if (muteType === MuteTypes.Role) { diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index 0d313546..bd358a19 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -1,10 +1,9 @@ import { Message } from "discord.js"; import { TStarboardOpts } from "../types.js"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage.js"; -import Timeout = NodeJS.Timeout; const DEBOUNCE_DELAY = 1000; -const debouncedUpdates: Record = {}; +const debouncedUpdates: Record = {}; export async function updateStarboardMessageStarCount( starboard: TStarboardOpts, diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 73981b42..130db796 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -31,7 +31,6 @@ import { searchCmdSignature } from "./commands/SearchCmd.js"; import { getUserInfoEmbed } from "./functions/getUserInfoEmbed.js"; import { refreshMembersIfNeeded } from "./refreshMembers.js"; import { UtilityPluginType } from "./types.js"; -import Timeout = NodeJS.Timeout; const SEARCH_RESULTS_PER_PAGE = 15; const SEARCH_ID_RESULTS_PER_PAGE = 50; @@ -93,7 +92,7 @@ export async function displaySearch( let searching = false; let currentPage = args.page || 1; let stopCollectionFn: () => void; - let stopCollectionTimeout: Timeout; + let stopCollectionTimeout: NodeJS.Timeout; const perPage = args.ids ? SEARCH_ID_RESULTS_PER_PAGE : SEARCH_RESULTS_PER_PAGE; diff --git a/backend/src/utils/DecayingCounter.ts b/backend/src/utils/DecayingCounter.ts index baa59ae0..e65a6fa2 100644 --- a/backend/src/utils/DecayingCounter.ts +++ b/backend/src/utils/DecayingCounter.ts @@ -3,8 +3,11 @@ */ export class DecayingCounter { protected value = 0; + protected decayInterval: number; + + constructor(decayInterval: number) { + this.decayInterval = decayInterval; - constructor(protected decayInterval: number) { setInterval(() => { this.value = Math.max(0, this.value - 1); }, decayInterval); diff --git a/backend/src/utils/MessageBuffer.ts b/backend/src/utils/MessageBuffer.ts index ab1380df..bb32f051 100644 --- a/backend/src/utils/MessageBuffer.ts +++ b/backend/src/utils/MessageBuffer.ts @@ -1,6 +1,5 @@ import { StrictMessageContent } from "../utils.js"; import { calculateEmbedSize } from "./calculateEmbedSize.js"; -import Timeout = NodeJS.Timeout; type ConsumeFn = (part: StrictMessageContent) => void; @@ -35,7 +34,7 @@ export class MessageBuffer { protected chunk: Chunk | null = null; - protected chunkTimeout: Timeout | null = null; + protected chunkTimeout: NodeJS.Timeout | null = null; protected finalizedChunks: MessageBufferContent[] = []; diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index e7671584..a89a16a4 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -2,7 +2,6 @@ import { Client, Message, MessageReaction, PartialMessageReaction, PartialUser, import { ContextResponseOptions, fetchContextChannel, GenericCommandSource } from "../pluginUtils.js"; import { MINUTES, noop } from "../utils.js"; import { Awaitable } from "./typeUtils.js"; -import Timeout = NodeJS.Timeout; export type LoadPageFn = (page: number) => Awaitable; @@ -81,7 +80,7 @@ export async function createPaginatedMessage( // The timeout after which reactions are removed and the pagination stops working // is refreshed each time the page is changed - let timeout: Timeout; + let timeout: NodeJS.Timeout; const refreshTimeout = () => { clearTimeout(timeout); timeout = setTimeout(() => { diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index f1ca6fc6..45cf88b6 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,10 +1,9 @@ import { MessagePayload, User } from "discord.js"; import { logger } from "../logger.js"; import { HOURS, createChunkedMessage, isDiscordAPIError } from "../utils.js"; -import Timeout = NodeJS.Timeout; let dmsDisabled = false; -let dmsDisabledTimeout: Timeout; +let dmsDisabledTimeout: NodeJS.Timeout; function disableDMs(duration) { dmsDisabled = true; diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 17e10137..7a98c5d0 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -6,7 +6,8 @@ "baseUrl": "./src", "rootDir": "./src", "outDir": "./dist", - "composite": true + "composite": true, + "erasableSyntaxOnly": true }, "include": ["src/**/*.ts", "src/**/*.json"], "references": [